From 385329e5d042dce66197d282563a306ce8feed24 Mon Sep 17 00:00:00 2001 From: mhscott Date: Mon, 6 Sep 2021 12:20:36 -0700 Subject: [PATCH 001/261] Adding Itpack solver to interpreters --- SRC/interpreter/OpenSeesCommands.cpp | 10 +++++++ SRC/interpreter/OpenSeesCommands.h | 1 + .../linearSOE/itpack/ItpackLinSolver.cpp | 16 ++++++++++++ SRC/tcl/commands.cpp | 26 +++++++++---------- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/SRC/interpreter/OpenSeesCommands.cpp b/SRC/interpreter/OpenSeesCommands.cpp index c96f8666be..fee9dd90e8 100644 --- a/SRC/interpreter/OpenSeesCommands.cpp +++ b/SRC/interpreter/OpenSeesCommands.cpp @@ -104,6 +104,11 @@ UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #endif #include +#ifdef _ITPACK +#include +#include +#endif + #ifdef _PARALLEL_INTERPRETERS bool setMPIDSOEFlag = false; @@ -1247,6 +1252,11 @@ int OPS_System() } else if (strcmp(type,"Mumps") == 0) { theSOE = (LinearSOE*)OPS_MumpsSolver(); +#ifdef _ITPACK + } else if (strcmp(type,"Itpack") == 0) { + theSOE = (LinearSOE*)OPS_ItpackLinSolver(); +#endif + } else { opserr<<"WARNING unknown system type "< #include #include +#include + +void* OPS_ItpackLinSolver() +{ + int method = 1; + int numData = 1; + + int nArgs = OPS_GetNumRemainingInputArgs(); + if (nArgs > 0 && OPS_GetIntInput(&numData,&method) < 0) { + opserr << "WARNING Itpack -- error reading method\n"; + return 0; + } + + ItpackLinSolver *theSolver = new ItpackLinSolver(method); + return new ItpackLinSOE(*theSolver); +} ItpackLinSolver::ItpackLinSolver(int meth, int iter, double om) :LinearSOESolver(SOLVER_TAGS_Itpack), diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index 7d2561e809..ba93a01837 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -266,8 +266,8 @@ extern void OPS_ResponseSpectrumAnalysis(void); #include #ifdef _ITPACK -//#include -//#include +#include +#include #endif #include @@ -3359,17 +3359,17 @@ specifySOE(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) } #ifdef _ITPACK -// else if (strcmp(argv[1],"Itpack") == 0) { -// -// // now must determine the type of solver to create from rest of args -// int method = 1; -// if (argc == 3) { -// if (Tcl_GetInt(interp, argv[2], &method) != TCL_OK) -// return TCL_ERROR; -// } -// ItpackLinSolver *theSolver = new ItpackLinSolver(method); -// theSOE = new ItpackLinSOE(*theSolver); -// } + else if (strcmp(argv[1],"Itpack") == 0) { + + // now must determine the type of solver to create from rest of args + int method = 1; + if (argc == 3) { + if (Tcl_GetInt(interp, argv[2], &method) != TCL_OK) + return TCL_ERROR; + } + ItpackLinSolver *theSolver = new ItpackLinSolver(method); + theSOE = new ItpackLinSOE(*theSolver); + } #endif else if (strcmp(argv[1],"FullGeneral") == 0) { // now must determine the type of solver to create from rest of args From 7ea1bdba08787d0baaf847e5809ebe8a36255b5c Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 11 Mar 2022 10:34:14 -0800 Subject: [PATCH 002/261] Adding input options for ITPACK solver --- .../linearSOE/itpack/ItpackLinSolver.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp index 6d239ab817..1a3798e8e1 100644 --- a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp +++ b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp @@ -47,7 +47,21 @@ void* OPS_ItpackLinSolver() return 0; } - ItpackLinSolver *theSolver = new ItpackLinSolver(method); + int iter = 100; + double omega = 1.0; + while (OPS_GetNumRemainingInputArgs() > 1) { + const char *arg = OPS_GetString(); + if (strcmp(arg,"-iter") == 0) { + if (OPS_GetIntInput(&numData,&iter) < 0) + return 0; + } + if (strcmp(arg,"-omega") == 0) { + if (OPS_GetDoubleInput(&numData,&omega) < 0) + return 0; + } + } + + ItpackLinSolver *theSolver = new ItpackLinSolver(method, iter, omega); return new ItpackLinSOE(*theSolver); } From 17d272bcef8c0447e82dce5dcf455f1cc3b0e364 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Sun, 13 Mar 2022 12:57:59 -0700 Subject: [PATCH 003/261] Updating Itpack system command options --- .../linearSOE/itpack/ItpackLinSolver.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp index 1a3798e8e1..583ab4d38c 100644 --- a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp +++ b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp @@ -42,6 +42,10 @@ void* OPS_ItpackLinSolver() int numData = 1; int nArgs = OPS_GetNumRemainingInputArgs(); + if (nArgs == 0) { + opserr << "WARNING Itpack -- no method specified\n"; + return 0; + } if (nArgs > 0 && OPS_GetIntInput(&numData,&method) < 0) { opserr << "WARNING Itpack -- error reading method\n"; return 0; @@ -318,6 +322,9 @@ ItpackLinSolver::solve(void) // Overwrite default max number of iterations iparm[0] = maxIter; + // Print flag + iparm[1] = 1; + // Sparse matrix storage scheme (0 = symmetric, 1 = nonsymmetric) iparm[4] = 1; @@ -390,8 +397,11 @@ ItpackLinSolver::solve(void) if (ier > 0) { opserr << "ItpackLinSolver::solve() -- returned ier = " << ier << endln; + opserr << "Maximum iterations: " << iparm[0] << ", rparm = " << rparm[0] << endln; return -ier; } - else + else { + opserr << "Converged in " << iparm[0] << " iterations" << endln; return 0; + } } From a1d979eb66c9ea1f564e635658b71f85de211415 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Thu, 3 Aug 2023 17:02:59 -0700 Subject: [PATCH 004/261] Initial attempt at symmetric eigensolver - does not compile --- OTHER/LAPACK/Makefile | 3 +- OTHER/LAPACK/dsygvx.f | 462 ++++++++++++++++++ SRC/system_of_eqn/eigenSOE/Makefile | 4 +- .../eigenSOE/SymmGeneralizedEigenSOE.cpp | 258 ++++++++++ .../eigenSOE/SymmGeneralizedEigenSOE.h | 78 +++ .../eigenSOE/SymmGeneralizedEigenSolver.cpp | 429 ++++++++++++++++ .../eigenSOE/SymmGeneralizedEigenSolver.h | 71 +++ 7 files changed, 1303 insertions(+), 2 deletions(-) create mode 100644 OTHER/LAPACK/dsygvx.f create mode 100644 SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.cpp create mode 100644 SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.h create mode 100644 SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp create mode 100644 SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.h diff --git a/OTHER/LAPACK/Makefile b/OTHER/LAPACK/Makefile index 06d6ab8502..59da8e04de 100644 --- a/OTHER/LAPACK/Makefile +++ b/OTHER/LAPACK/Makefile @@ -20,7 +20,8 @@ DOBJ = dgeqr2.o dlabad.o dlacon.o dlacpy.o dladiv.o dlae2.o dlaev2.o\ chla_transtype.o dla_gercond.o dla_wwaddw.o ilaprec.o ilatrans.o dgecon.o \ dla_geamv.o dlacn2.o dla_lin_berr.o drscl.o dlatrs.o dla_rpvgrw.o dla_gerpvgrw.o \ BLAS_dgemv2_x.o BLAS_dgemv2_x-f2c.o \ - BLAS_dgemv_x.o BLAS_dgemv_x-f2c.o BLAS_error.o BLAS_error.o + BLAS_dgemv_x.o BLAS_dgemv_x-f2c.o BLAS_error.o BLAS_error.o \ + dsygvx.o diff --git a/OTHER/LAPACK/dsygvx.f b/OTHER/LAPACK/dsygvx.f new file mode 100644 index 0000000000..3fa55b97c1 --- /dev/null +++ b/OTHER/LAPACK/dsygvx.f @@ -0,0 +1,462 @@ +*> \brief \b DSYGVX +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DSYGVX + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DSYGVX( ITYPE, JOBZ, RANGE, UPLO, N, A, LDA, B, LDB, +* VL, VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK, +* LWORK, IWORK, IFAIL, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER JOBZ, RANGE, UPLO +* INTEGER IL, INFO, ITYPE, IU, LDA, LDB, LDZ, LWORK, M, N +* DOUBLE PRECISION ABSTOL, VL, VU +* .. +* .. Array Arguments .. +* INTEGER IFAIL( * ), IWORK( * ) +* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * ), +* $ Z( LDZ, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DSYGVX computes selected eigenvalues, and optionally, eigenvectors +*> of a real generalized symmetric-definite eigenproblem, of the form +*> A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A +*> and B are assumed to be symmetric and B is also positive definite. +*> Eigenvalues and eigenvectors can be selected by specifying either a +*> range of values or a range of indices for the desired eigenvalues. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] ITYPE +*> \verbatim +*> ITYPE is INTEGER +*> Specifies the problem type to be solved: +*> = 1: A*x = (lambda)*B*x +*> = 2: A*B*x = (lambda)*x +*> = 3: B*A*x = (lambda)*x +*> \endverbatim +*> +*> \param[in] JOBZ +*> \verbatim +*> JOBZ is CHARACTER*1 +*> = 'N': Compute eigenvalues only; +*> = 'V': Compute eigenvalues and eigenvectors. +*> \endverbatim +*> +*> \param[in] RANGE +*> \verbatim +*> RANGE is CHARACTER*1 +*> = 'A': all eigenvalues will be found. +*> = 'V': all eigenvalues in the half-open interval (VL,VU] +*> will be found. +*> = 'I': the IL-th through IU-th eigenvalues will be found. +*> \endverbatim +*> +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> = 'U': Upper triangle of A and B are stored; +*> = 'L': Lower triangle of A and B are stored. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrix pencil (A,B). N >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA, N) +*> On entry, the symmetric matrix A. If UPLO = 'U', the +*> leading N-by-N upper triangular part of A contains the +*> upper triangular part of the matrix A. If UPLO = 'L', +*> the leading N-by-N lower triangular part of A contains +*> the lower triangular part of the matrix A. +*> +*> On exit, the lower triangle (if UPLO='L') or the upper +*> triangle (if UPLO='U') of A, including the diagonal, is +*> destroyed. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,N). +*> \endverbatim +*> +*> \param[in,out] B +*> \verbatim +*> B is DOUBLE PRECISION array, dimension (LDB, N) +*> On entry, the symmetric matrix B. If UPLO = 'U', the +*> leading N-by-N upper triangular part of B contains the +*> upper triangular part of the matrix B. If UPLO = 'L', +*> the leading N-by-N lower triangular part of B contains +*> the lower triangular part of the matrix B. +*> +*> On exit, if INFO <= N, the part of B containing the matrix is +*> overwritten by the triangular factor U or L from the Cholesky +*> factorization B = U**T*U or B = L*L**T. +*> \endverbatim +*> +*> \param[in] LDB +*> \verbatim +*> LDB is INTEGER +*> The leading dimension of the array B. LDB >= max(1,N). +*> \endverbatim +*> +*> \param[in] VL +*> \verbatim +*> VL is DOUBLE PRECISION +*> If RANGE='V', the lower bound of the interval to +*> be searched for eigenvalues. VL < VU. +*> Not referenced if RANGE = 'A' or 'I'. +*> \endverbatim +*> +*> \param[in] VU +*> \verbatim +*> VU is DOUBLE PRECISION +*> If RANGE='V', the upper bound of the interval to +*> be searched for eigenvalues. VL < VU. +*> Not referenced if RANGE = 'A' or 'I'. +*> \endverbatim +*> +*> \param[in] IL +*> \verbatim +*> IL is INTEGER +*> If RANGE='I', the index of the +*> smallest eigenvalue to be returned. +*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0. +*> Not referenced if RANGE = 'A' or 'V'. +*> \endverbatim +*> +*> \param[in] IU +*> \verbatim +*> IU is INTEGER +*> If RANGE='I', the index of the +*> largest eigenvalue to be returned. +*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0. +*> Not referenced if RANGE = 'A' or 'V'. +*> \endverbatim +*> +*> \param[in] ABSTOL +*> \verbatim +*> ABSTOL is DOUBLE PRECISION +*> The absolute error tolerance for the eigenvalues. +*> An approximate eigenvalue is accepted as converged +*> when it is determined to lie in an interval [a,b] +*> of width less than or equal to +*> +*> ABSTOL + EPS * max( |a|,|b| ) , +*> +*> where EPS is the machine precision. If ABSTOL is less than +*> or equal to zero, then EPS*|T| will be used in its place, +*> where |T| is the 1-norm of the tridiagonal matrix obtained +*> by reducing C to tridiagonal form, where C is the symmetric +*> matrix of the standard symmetric problem to which the +*> generalized problem is transformed. +*> +*> Eigenvalues will be computed most accurately when ABSTOL is +*> set to twice the underflow threshold 2*DLAMCH('S'), not zero. +*> If this routine returns with INFO>0, indicating that some +*> eigenvectors did not converge, try setting ABSTOL to +*> 2*DLAMCH('S'). +*> \endverbatim +*> +*> \param[out] M +*> \verbatim +*> M is INTEGER +*> The total number of eigenvalues found. 0 <= M <= N. +*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1. +*> \endverbatim +*> +*> \param[out] W +*> \verbatim +*> W is DOUBLE PRECISION array, dimension (N) +*> On normal exit, the first M elements contain the selected +*> eigenvalues in ascending order. +*> \endverbatim +*> +*> \param[out] Z +*> \verbatim +*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M)) +*> If JOBZ = 'N', then Z is not referenced. +*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z +*> contain the orthonormal eigenvectors of the matrix A +*> corresponding to the selected eigenvalues, with the i-th +*> column of Z holding the eigenvector associated with W(i). +*> The eigenvectors are normalized as follows: +*> if ITYPE = 1 or 2, Z**T*B*Z = I; +*> if ITYPE = 3, Z**T*inv(B)*Z = I. +*> +*> If an eigenvector fails to converge, then that column of Z +*> contains the latest approximation to the eigenvector, and the +*> index of the eigenvector is returned in IFAIL. +*> Note: the user must ensure that at least max(1,M) columns are +*> supplied in the array Z; if RANGE = 'V', the exact value of M +*> is not known in advance and an upper bound must be used. +*> \endverbatim +*> +*> \param[in] LDZ +*> \verbatim +*> LDZ is INTEGER +*> The leading dimension of the array Z. LDZ >= 1, and if +*> JOBZ = 'V', LDZ >= max(1,N). +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) +*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The length of the array WORK. LWORK >= max(1,8*N). +*> For optimal efficiency, LWORK >= (NB+3)*N, +*> where NB is the blocksize for DSYTRD returned by ILAENV. +*> +*> If LWORK = -1, then a workspace query is assumed; the routine +*> only calculates the optimal size of the WORK array, returns +*> this value as the first entry of the WORK array, and no error +*> message related to LWORK is issued by XERBLA. +*> \endverbatim +*> +*> \param[out] IWORK +*> \verbatim +*> IWORK is INTEGER array, dimension (5*N) +*> \endverbatim +*> +*> \param[out] IFAIL +*> \verbatim +*> IFAIL is INTEGER array, dimension (N) +*> If JOBZ = 'V', then if INFO = 0, the first M elements of +*> IFAIL are zero. If INFO > 0, then IFAIL contains the +*> indices of the eigenvectors that failed to converge. +*> If JOBZ = 'N', then IFAIL is not referenced. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> > 0: DPOTRF or DSYEVX returned an error code: +*> <= N: if INFO = i, DSYEVX failed to converge; +*> i eigenvectors failed to converge. Their indices +*> are stored in array IFAIL. +*> > N: if INFO = N + i, for 1 <= i <= N, then the leading +*> minor of order i of B is not positive definite. +*> The factorization of B could not be completed and +*> no eigenvalues or eigenvectors were computed. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup doubleSYeigen +* +*> \par Contributors: +* ================== +*> +*> Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA +* +* ===================================================================== + SUBROUTINE DSYGVX( ITYPE, JOBZ, RANGE, UPLO, N, A, LDA, B, LDB, + $ VL, VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK, + $ LWORK, IWORK, IFAIL, INFO ) +* +* -- LAPACK driver routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER JOBZ, RANGE, UPLO + INTEGER IL, INFO, ITYPE, IU, LDA, LDB, LDZ, LWORK, M, N + DOUBLE PRECISION ABSTOL, VL, VU +* .. +* .. Array Arguments .. + INTEGER IFAIL( * ), IWORK( * ) + DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * ), + $ Z( LDZ, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL ALLEIG, INDEIG, LQUERY, UPPER, VALEIG, WANTZ + CHARACTER TRANS + INTEGER LWKMIN, LWKOPT, NB +* .. +* .. External Functions .. + LOGICAL LSAME + INTEGER ILAENV + EXTERNAL LSAME, ILAENV +* .. +* .. External Subroutines .. + EXTERNAL DPOTRF, DSYEVX, DSYGST, DTRMM, DTRSM, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + UPPER = LSAME( UPLO, 'U' ) + WANTZ = LSAME( JOBZ, 'V' ) + ALLEIG = LSAME( RANGE, 'A' ) + VALEIG = LSAME( RANGE, 'V' ) + INDEIG = LSAME( RANGE, 'I' ) + LQUERY = ( LWORK.EQ.-1 ) +* + INFO = 0 + IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN + INFO = -1 + ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN + INFO = -2 + ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THEN + INFO = -3 + ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN + INFO = -4 + ELSE IF( N.LT.0 ) THEN + INFO = -5 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -7 + ELSE IF( LDB.LT.MAX( 1, N ) ) THEN + INFO = -9 + ELSE + IF( VALEIG ) THEN + IF( N.GT.0 .AND. VU.LE.VL ) + $ INFO = -11 + ELSE IF( INDEIG ) THEN + IF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THEN + INFO = -12 + ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THEN + INFO = -13 + END IF + END IF + END IF + IF (INFO.EQ.0) THEN + IF (LDZ.LT.1 .OR. (WANTZ .AND. LDZ.LT.N)) THEN + INFO = -18 + END IF + END IF +* + IF( INFO.EQ.0 ) THEN + LWKMIN = MAX( 1, 8*N ) + NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 ) + LWKOPT = MAX( LWKMIN, ( NB + 3 )*N ) + WORK( 1 ) = LWKOPT +* + IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN + INFO = -20 + END IF + END IF +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DSYGVX', -INFO ) + RETURN + ELSE IF( LQUERY ) THEN + RETURN + END IF +* +* Quick return if possible +* + M = 0 + IF( N.EQ.0 ) THEN + RETURN + END IF +* +* Form a Cholesky factorization of B. +* + CALL DPOTRF( UPLO, N, B, LDB, INFO ) + IF( INFO.NE.0 ) THEN + INFO = N + INFO + RETURN + END IF +* +* Transform problem to standard eigenvalue problem and solve. +* + CALL DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO ) + CALL DSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU, ABSTOL, + $ M, W, Z, LDZ, WORK, LWORK, IWORK, IFAIL, INFO ) +* + IF( WANTZ ) THEN +* +* Backtransform eigenvectors to the original problem. +* + IF( INFO.GT.0 ) + $ M = INFO - 1 + IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN +* +* For A*x=(lambda)*B*x and A*B*x=(lambda)*x; +* backtransform eigenvectors: x = inv(L)**T*y or inv(U)*y +* + IF( UPPER ) THEN + TRANS = 'N' + ELSE + TRANS = 'T' + END IF +* + CALL DTRSM( 'Left', UPLO, TRANS, 'Non-unit', N, M, ONE, B, + $ LDB, Z, LDZ ) +* + ELSE IF( ITYPE.EQ.3 ) THEN +* +* For B*A*x=(lambda)*x; +* backtransform eigenvectors: x = L*y or U**T*y +* + IF( UPPER ) THEN + TRANS = 'T' + ELSE + TRANS = 'N' + END IF +* + CALL DTRMM( 'Left', UPLO, TRANS, 'Non-unit', N, M, ONE, B, + $ LDB, Z, LDZ ) + END IF + END IF +* +* Set WORK(1) to optimal workspace size. +* + WORK( 1 ) = LWKOPT +* + RETURN +* +* End of DSYGVX +* + END diff --git a/SRC/system_of_eqn/eigenSOE/Makefile b/SRC/system_of_eqn/eigenSOE/Makefile index bf8821b61d..2104083f27 100644 --- a/SRC/system_of_eqn/eigenSOE/Makefile +++ b/SRC/system_of_eqn/eigenSOE/Makefile @@ -7,7 +7,9 @@ OBJS = EigenSOE.o \ SymBandEigenSOE.o \ SymBandEigenSolver.o \ FullGenEigenSOE.o \ - FullGenEigenSolver.o + FullGenEigenSolver.o \ + SymmGeneralizedEigenSOE.o \ + SymmGeneralizedEigenSolver.o all: $(OBJS) diff --git a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.cpp b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.cpp new file mode 100644 index 0000000000..14b4b9dc5b --- /dev/null +++ b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.cpp @@ -0,0 +1,258 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.2 $ +// $Date: 2009-05-20 17:31:36 $ +// $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/eigenSOE/FullGenEigenSOE.cpp,v $ + +// Written: Andreas Schellenberg (andreas.schellenberg@gmx.net) +// Created: 11/07 +// Revision: A +// +// Description: This file contains the implementation of the +// FullGenEigenSOE class. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using std::nothrow; + +FullGenEigenSOE::FullGenEigenSOE(FullGenEigenSolver &theSolver, + AnalysisModel &aModel) + : EigenSOE(theSolver, EigenSOE_TAGS_FullGenEigenSOE), + size(0), A(0), Asize(0), M(0), Msize(0), + factored(false), theModel(&aModel) +{ + theSolver.setEigenSOE(*this); +} + + +FullGenEigenSOE::~FullGenEigenSOE() +{ + if (A != 0) + delete [] A; + if (M != 0) + delete [] M; +} + + +int FullGenEigenSOE::getNumEqn(void) const +{ + return size; +} + + +int FullGenEigenSOE::setSize(Graph &theGraph) +{ + int result = 0; + size = theGraph.getNumVertex(); + + int newSize = size*size; + + // we have to get another space for A + if (newSize > Asize) { + if (A != 0) + delete [] A; + + A = new (nothrow) double[newSize]; + if (A == 0) { + opserr << "WARNING FullGenEigenSOE::setSize() - " + << "ran out of memory for A (size,size) (" + << size << ", " << size << ")\n"; + Asize = 0; size = 0; + result= -1; + } + else + Asize = newSize; + } + + // zero the matrix + for (int i=0; i Msize) { + if (M != 0) + delete [] M; + + M = new (nothrow) double[newSize]; + if (M == 0) { + opserr << "WARNING FullGenEigenSOE::setSize() - " + << "ran out of memory for M (size,size) (" + << size << ", " << size << ")\n"; + Msize = 0; size = 0; + result= -1; + } + else + Msize = newSize; + } + + // zero the matrix + for (int i=0; igetSolver(); + int solverOK = theSolver->setSize(); + if (solverOK < 0) { + opserr << "WARNING FullGenEigenSOE::setSize() - "; + opserr << "solver failed in setSize()\n"; + return solverOK; + } + + return result; +} + + +int FullGenEigenSOE::addA(const Matrix &m, const ID &id, double fact) +{ + // check for quick return + if (fact == 0.0) + return 0; + + // check that m and id are of similar size + int idSize = id.Size(); + if (idSize != m.noRows() && idSize != m.noCols()) { + opserr << "FullGenEigenSOE::addA() - Matrix and ID not of similar sizes\n"; + return -1; + } + + if (fact == 1.0) { // do not need to multiply + for (int i=0; i= 0) { + double *startColiPtr = A + col*size; + for (int j=0; j= 0) { + double *APtr = startColiPtr + row; + *APtr += m(j,i); + } + } // for j + } + } // for i + } else { + for (int i=0; i= 0) { + double *startColiPtr = A + col*size; + for (int j=0; j= 0) { + double *APtr = startColiPtr + row; + *APtr += m(j,i)*fact; + } + } // for j + } + } // for i + } + + return 0; +} + + +int FullGenEigenSOE::addM(const Matrix &m, const ID &id, double fact) +{ + // check for quick return + if (fact == 0.0) + return 0; + + // check that m and id are of similar size + int idSize = id.Size(); + if (idSize != m.noRows() && idSize != m.noCols()) { + opserr << "FullGenEigenSOE::addM() - Matrix and ID not of similar sizes\n"; + return -1; + } + + if (fact == 1.0) { // do not need to multiply + for (int i=0; i= 0) { + double *startColiPtr = M + col*size; + for (int j=0; j= 0) { + double *MPtr = startColiPtr + row; + *MPtr += m(j,i); + } + } // for j + } + } // for i + } else { + for (int i=0; i= 0) { + double *startColiPtr = M + col*size; + for (int j=0; j= 0) { + double *MPtr = startColiPtr + row; + *MPtr += m(j,i)*fact; + } + } // for j + } + } // for i + } + + return 0; +} + + +void FullGenEigenSOE::zeroA(void) +{ + double *Aptr = A; + for (int i = 0; i < Asize; i++) + *Aptr++ = 0; + + factored = false; +} + + +void FullGenEigenSOE::zeroM(void) +{ + double *Mptr = M; + for (int i = 0; i < Msize; i++) + *Mptr++ = 0; + + factored = false; +} + + +int FullGenEigenSOE::sendSelf(int commitTag, Channel &theChannel) +{ + return 0; +} + + +int FullGenEigenSOE::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + return 0; +} diff --git a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.h b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.h new file mode 100644 index 0000000000..6e012fac67 --- /dev/null +++ b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.h @@ -0,0 +1,78 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.1 $ +// $Date: 2007-11-29 19:31:08 $ +// $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/eigenSOE/FullGenEigenSOE.h,v $ + + +#ifndef FullGenEigenSOE_h +#define FullGenEigenSOE_h + +// Written: Andreas Schellenberg (andreas.schellenberg@gmx.net) +// Created: 11/07 +// Revision: A +// +// Description: This file contains the class definition for +// FullGenEigenSOE, which stores full nonsymmetric matrices, +// A and M, for generalized eigenvalue computations. + +#include +#include + +class AnalysisModel; +class FullGenEigenSolver; + +class FullGenEigenSOE : public EigenSOE +{ +public: + FullGenEigenSOE(FullGenEigenSolver &theSolver, + AnalysisModel &theModel); + + virtual ~FullGenEigenSOE(); + + virtual int getNumEqn(void) const; + virtual int setSize(Graph &theGraph); + + virtual int addA(const Matrix &, const ID &, double fact = 1.0); + virtual int addM(const Matrix &, const ID &, double fact = 1.0); + + virtual void zeroA(void); + virtual void zeroM(void); + + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + + friend class FullGenEigenSolver; + +protected: + +private: + int size; + double *A; + int Asize; + double *M; + int Msize; + bool factored; + AnalysisModel *theModel; +}; + +#endif diff --git a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp new file mode 100644 index 0000000000..a4a67cd621 --- /dev/null +++ b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp @@ -0,0 +1,429 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.6 $ +// $Date: 2009-05-19 21:54:55 $ +// $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/eigenSOE/FullGenEigenSolver.cpp,v $ + +// Written: Andreas Schellenberg (andreas.schellenberg@gmx.net) +// Created: 11/07 +// Revision: A +// +// Description: This file contains the implementation of the +// FullGenEigenSolver class. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef _WIN32 + +extern "C" int DSYGVX(int *ITPYE, char *JOBZ, char *RANGE, char *UPLO, + int *N, double *A, int *LDA, double *B, int *LDB, + double *VL, double *VU, int *IL, int *IU, + double *ABSTOL, int *M, double *W, double *Z, int *LDZ, + double *WORK, int *LWORK, int *IWORK, int *IFAIL, + int *INFO); + +#else + +extern "C" int dsygvx_(int *ITPYE, char *JOBZ, char *RANGE, char *UPLO, + int *N, double *A, int *LDA, double *B, int *LDB, + double *VL, double *VU, int *IL, int *IU, + double *ABSTOL, int *M, double *W, double *Z, int *LDZ, + double *WORK, int *LWORK, int *IWORK, int *IFAIL, + int *INFO); + +#endif + + +FullGenEigenSolver::FullGenEigenSolver() + : EigenSolver(EigenSOLVER_TAGS_FullGenEigenSolver), + theSOE(0), numEigen(0), eigenvalue(0), + eigenvector(0), sortingID(0), eigenV(0) +{ + +} + + +FullGenEigenSolver::~FullGenEigenSolver() +{ + if (eigenvalue != 0) + delete [] eigenvalue; + if (eigenvector != 0) + delete [] eigenvector; + if (sortingID != 0) + delete [] sortingID; + if (eigenV != 0) + delete eigenV; +} + + +int FullGenEigenSolver::solve(int nEigen, bool generalized, bool findSmallest) +{ + if (generalized == false) { + opserr << "FullGenEigenSolver::solve() - only solves generalized problem\n"; + return -1; + } + + if (theSOE == 0) { + opserr << "FullGenEigenSolver::solve()- " + << " No EigenSOE object has been set yet\n"; + return -1; + } + + // check for quick return + if (nEigen < 1) { + numEigen = 0; + return 0; + } + + // get the number of equations + int n = theSOE->size; + + // set the number of eigenvalues + numEigen = nEigen; + if (numEigen > n) + numEigen = n; + + // Lower and upper range of eigenpairs + int il = 1; + int iu = numEigen; + + // solve K*x = lam*M*x + int itype = 1; + + // compute eigenvalues and eigenvectors + char *jobz = "V"; + + // compute range of eigenvalues + char *range = "I"; + + // upper or lower triangle of A and B + char *uplo = "U"; + + // stiffness matrix data + double *Kptr = theSOE->A; + + double *kCopy = new double[n*n]; + for (int i = 0; i < n*n; i++) + kCopy[i] = Kptr[i]; + + // leading dimension of K + int ldK = n; + + // mass matrix data + double *Mptr = theSOE->M; + + double *mCopy = new double[n*n]; + for (int i=0; i 0) { + opserr << "FullGenEigenSolver::solve() - the LAPACK dggev routine " + << "returned error code " << info << endln; + return -info; + } + + theSOE->factored = true; + + for (int i=0; i= 0) { + factor=1.0/sqrt(factor); + + for (int i=0; isort(n, eigenvalue, sortingID); + + for (int i=0; isize; + + if (eigenV == 0 || eigenV->Size() != size) { + if (eigenV != 0) + delete eigenV; + + eigenV = new Vector(size); + if (eigenV == 0 || eigenV->Size() != size) { + opserr << "FullGenEigenSolver::setSize() "; + opserr << " - ran out of memory for eigenVector of size "; + opserr << theSOE->size << endln; + return -2; + } + } + + return 0; +} + + +int FullGenEigenSolver::setEigenSOE(FullGenEigenSOE &thesoe) +{ + theSOE = &thesoe; + + return 0; +} + + +const Vector& FullGenEigenSolver::getEigenvector(int mode) +{ + if (mode <= 0 || mode > numEigen) { + opserr << "FullGenEigenSolver::getEigenVector() - mode " + << mode << " is out of range (1 - " << numEigen << ")\n"; + eigenV->Zero(); + return *eigenV; + } + + int size = theSOE->size; + int index = size*sortingID[mode-1]; + + if (eigenvector != 0) { + for (int i=0; iZero(); + } + + //opserr << "EIGEN VECTOR: " << *eigenV; + + return *eigenV; + +} + + +double FullGenEigenSolver::getEigenvalue(int mode) +{ + if (mode <= 0 || mode > numEigen) { + opserr << "FullGenEigenSolver::getEigenvalue() - mode " + << mode << " is out of range (1 - " << numEigen << ")\n"; + return 0.0; + } + + if (eigenvalue != 0) { + return eigenvalue[mode-1]; + } + else { + opserr << "FullGenEigenSolver::getEigenvalue() - " + << "eigenvalues not yet computed\n"; + return 0.0; + } +} + + +int FullGenEigenSolver::sendSelf(int commitTag, Channel &theChannel) +{ + return 0; +} + + +int FullGenEigenSolver::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + return 0; +} + + +void FullGenEigenSolver::sort(int length, double *x, int *id) +{ + // this is an implementation of shell sort that + // additionally keeps track of the sorting order + + int flag = 1; + int d = length; + int i, idTmp; + double xTmp; + + while (flag || d>1) { + flag = 0; + d = (d+1)/2; + for (i=0; i<(length-d); i++) { + if (x[i+d] < x[i]) { + // swap items at positions i+d and d + xTmp = x[i+d]; idTmp = id[i+d]; + x[i+d] = x[i]; id[i+d] = id[i]; + x[i] = xTmp; id[i] = idTmp; + // indicate that a swap has occurred + flag = 1; + } + } + } + + return; +} diff --git a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.h b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.h new file mode 100644 index 0000000000..02e3a0f60c --- /dev/null +++ b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.h @@ -0,0 +1,71 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.3 $ +// $Date: 2009-05-11 21:01:10 $ +// $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/eigenSOE/FullGenEigenSolver.h,v $ + + +#ifndef FullGenEigenSolver_h +#define FullGenEigenSolver_h + +// Written: Andreas Schellenberg (andreas.schellenberg@gmx.net) +// Created: 11/07 +// Revision: A +// +// Description: This file contains the class definition for +// FullGenEigenSolver. It computes the generalized eigenvalues +// and eigenvectors of a pair of real nonsymmetric matrices using +// the LAPACK subroutine DGGEV. + +#include +#include + +class FullGenEigenSolver : public EigenSolver +{ +public: + FullGenEigenSolver(); + virtual ~FullGenEigenSolver(); + + virtual int solve(int numEigen, bool generalized, bool findSmallest = true); + virtual int setSize(void); + virtual int setEigenSOE(FullGenEigenSOE &theSOE); + + virtual const Vector &getEigenvector(int mode); + virtual double getEigenvalue(int mode); + + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + +protected: + +private: + void sort(int length, double *x, int *id); + FullGenEigenSOE *theSOE; + int numEigen; + + double *eigenvalue; + double *eigenvector; + int *sortingID; + Vector *eigenV; +}; + +#endif From f829a310c6a47f662257b62ae76c4c0aea56d52a Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Wed, 31 Jul 2024 10:39:40 +0200 Subject: [PATCH 005/261] add-weight-parameter-parallel3D --- SRC/material/nD/Parallel3DMaterial.cpp | 31 ++++++++++++++++++++++++-- SRC/material/nD/Parallel3DMaterial.h | 1 + 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/SRC/material/nD/Parallel3DMaterial.cpp b/SRC/material/nD/Parallel3DMaterial.cpp index 7a694525c8..2ca47d3bca 100644 --- a/SRC/material/nD/Parallel3DMaterial.cpp +++ b/SRC/material/nD/Parallel3DMaterial.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -227,6 +228,7 @@ Parallel3DMaterial::Parallel3DMaterial( m_materials[i] = the_copy; } computeInitialTangent(); + computeTangent(); } Parallel3DMaterial::Parallel3DMaterial() @@ -257,7 +259,7 @@ int Parallel3DMaterial::setTrialStrain(const Vector& v) m_strain = v; int result = 0; for (std::size_t i = 0; i < m_materials.size(); ++i) { - if (!m_materials[i]->setTrialStrain(v)) + if (m_materials[i]->setTrialStrain(v) != 0) result = -1; } computeStress(); @@ -270,7 +272,7 @@ int Parallel3DMaterial::setTrialStrain(const Vector& v, const Vector& r) m_strain = v; int result = 0; for (std::size_t i = 0; i < m_materials.size(); ++i) { - if (!m_materials[i]->setTrialStrain(v, r)) + if (m_materials[i]->setTrialStrain(v, r) != 0) result = -1; } computeStress(); @@ -513,6 +515,18 @@ int Parallel3DMaterial::recvSelf(int commitTag, Channel & theChannel, FEM_Object int Parallel3DMaterial::setParameter(const char** argv, int argc, Parameter& param) { + // handle parameters + if (argc > 0) { + if (strcmp(argv[0], "parallelWeight") == 0 || strcmp(argv[0], "ParallelWeight") == 0) { + if (argc == 2) { + int imat = atoi(argv[1]) - 1; + if (imat >= 0 && imat < static_cast(m_weights.size())) { + param.setValue(m_weights[static_cast(imat)]); + return param.addObject(1000 + imat, this); + } + } + } + } // forward to the sub-materials int res = -1; for (NDMaterial* item : m_materials) { @@ -522,6 +536,19 @@ int Parallel3DMaterial::setParameter(const char** argv, int argc, Parameter& par return res; } +int Parallel3DMaterial::updateParameter(int parameterID, Information& info) +{ + if (parameterID >= 1000) { + int imat = parameterID - 1000; + if (imat >= 0 && imat < static_cast(m_weights.size())) { + m_weights[static_cast(imat)] = info.theDouble; + computeInitialTangent(); + return 0; + } + } + return -1; +} + Response* Parallel3DMaterial::setResponse(const char** argv, int argc, OPS_Stream& output) { if (argc > 0) { diff --git a/SRC/material/nD/Parallel3DMaterial.h b/SRC/material/nD/Parallel3DMaterial.h index af137a1a86..34ec282807 100644 --- a/SRC/material/nD/Parallel3DMaterial.h +++ b/SRC/material/nD/Parallel3DMaterial.h @@ -83,6 +83,7 @@ class Parallel3DMaterial : public NDMaterial // parameters and responses int setParameter(const char** argv, int argc, Parameter& param); + int updateParameter(int parameterID, Information& info); Response* setResponse(const char** argv, int argc, OPS_Stream& output); int getResponse(int responseID, Information& matInformation); From 1dc6c4f1a0b5cd1247b13eee60b73d4f2651c66a Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Tue, 7 Jan 2025 09:49:45 +0100 Subject: [PATCH 006/261] first implementation base steel --- SRC/Makefile | 1 + .../FEM_ObjectBrokerAllClasses.cpp | 12 +- SRC/classTags.h | 1 + .../OpenSeesUniaxialMaterialCommands.cpp | 3 + SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 524 ++++++++++++++++++ SRC/material/uniaxial/ASDSteel1DMaterial.h | 122 ++++ SRC/material/uniaxial/CMakeLists.txt | 2 + SRC/material/uniaxial/Makefile | 1 + ...TclModelBuilderUniaxialMaterialCommand.cpp | 13 +- Win32/proj/material/material.vcxproj | 2 + Win32/proj/material/material.vcxproj.filters | 6 + Win64/proj/material/material.vcxproj | 2 + Win64/proj/material/material.vcxproj.filters | 6 + 13 files changed, 689 insertions(+), 6 deletions(-) create mode 100644 SRC/material/uniaxial/ASDSteel1DMaterial.cpp create mode 100644 SRC/material/uniaxial/ASDSteel1DMaterial.h diff --git a/SRC/Makefile b/SRC/Makefile index fee49cb0dc..9e13d8eff4 100644 --- a/SRC/Makefile +++ b/SRC/Makefile @@ -775,6 +775,7 @@ MATERIAL_LIBS = $(FE)/material/Material.o \ $(FE)/material/uniaxial/Neoprene.o \ $(FE)/material/uniaxial/ASD_SMA_3K.o \ $(FE)/material/uniaxial/ASDConcrete1DMaterial.o \ + $(FE)/material/uniaxial/ASDSteel1DMaterial.o \ $(FE)/material/uniaxial/Concrete01.o \ $(FE)/material/uniaxial/Concrete02.o \ $(FE)/material/uniaxial/Concrete02IS.o \ diff --git a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp index 3f68d3b046..149ff410ef 100644 --- a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp +++ b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp @@ -74,6 +74,7 @@ #include "TensionOnlyMaterial.h" #include "ASD_SMA_3K.h" #include "ASDConcrete1DMaterial.h" +#include "ASDSteel1DMaterial.h" #include "Concrete01.h" #include "Concrete01WithSITC.h" #include "Concrete02.h" @@ -1726,6 +1727,9 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) case MAT_TAG_ASDConcrete1DMaterial: return new ASDConcrete1DMaterial(); + case MAT_TAG_ASDSteel1DMaterial: + return new ASDSteel1DMaterial(); + case MAT_TAG_Concrete01: return new Concrete01(); @@ -1837,11 +1841,11 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) case MAT_TAG_QzLiq1: return new QzLiq1(); - case MAT_TAG_TzSandCPT: - return new TzSandCPT(); + //case MAT_TAG_TzSandCPT: + // return new TzSandCPT(); - case MAT_TAG_QbSandCPT: - return new QbSandCPT(); + //case MAT_TAG_QbSandCPT: + // return new QbSandCPT(); case MAT_TAG_Hysteretic: return new HystereticMaterial(); diff --git a/SRC/classTags.h b/SRC/classTags.h index 46ec11f767..3e880bff6c 100644 --- a/SRC/classTags.h +++ b/SRC/classTags.h @@ -258,6 +258,7 @@ #define MAT_TAG_PipeMaterial 232 #define MAT_TAG_TzSandCPT 233 #define MAT_TAG_QbSandCPT 234 +#define MAT_TAG_ASDSteel1DMaterial 235 #define MAT_TAG_FedeasMaterial 1000 #define MAT_TAG_FedeasBond1 1001 diff --git a/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp b/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp index cc74befc67..84eaacf877 100644 --- a/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp +++ b/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp @@ -150,6 +150,7 @@ void* OPS_ECC01(); void* OPS_SelfCenteringMaterial(); void* OPS_ASD_SMA_3K(); void* OPS_ASDConcrete1DMaterial(); +void* OPS_ASDSteel1DMaterial(); void* OPS_ViscousMaterial(); void* OPS_BoucWenMaterial(); void* OPS_BoucWenOriginal(); @@ -462,6 +463,8 @@ static int setUpUniaxialMaterials(void) { std::make_pair("ASD_SMA_3K", &OPS_ASD_SMA_3K)); uniaxialMaterialsMap.insert( std::make_pair("ASDConcrete1D", &OPS_ASDConcrete1DMaterial)); + uniaxialMaterialsMap.insert( + std::make_pair("ASDSteel1D", &OPS_ASDSteel1DMaterial)); uniaxialMaterialsMap.insert( std::make_pair("Viscous", &OPS_ViscousMaterial)); uniaxialMaterialsMap.insert( diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp new file mode 100644 index 0000000000..e9461131d8 --- /dev/null +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -0,0 +1,524 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.0 $ +// $Date: 2042-06-14 11:29:01 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/ASDSteel1DMaterial.cpp,v $ + +// Massimo Petracca - ASDEA Software, Italy +// +// A Simple and robust plastic-damage model for concrete and masonry +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// anonymous namespace for utilities +namespace { + + /** + Converts a string into a vector of doubles using whitespace as delimiter + */ + bool string_to_double(const std::string& text, double& num) { + num = 0.0; + try { + num = std::stod(text); + return true; + } + catch (...) { + return false; + } + } + + inline double sign(double x) { return x == 0.0 ? 0.0 : (x > 0.0 ? 1.0 : -1.0); } + +} + +void* OPS_ASDSteel1DMaterial() +{ + // some kudos + static bool first_done = false; + if (!first_done) { + opserr << "Using ASDSteel1D - Developed by: Alessia Casalucci, Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; + first_done = true; + } + static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu"; + + // check arguments + int numArgs = OPS_GetNumRemainingInputArgs(); + if (numArgs < 5) { + opserr << + "nDMaterial ASDSteel1D Error: Few arguments (< 5).\n" << msg << "\n"; + return nullptr; + } + + // numData + int numData = 1; + + // data + int tag; + double E; + double sy; + double su; + double eu; + + // get tag + if (OPS_GetInt(&numData, &tag) != 0) { + opserr << "nDMaterial ASDSteel1D Error: invalid 'tag'.\n"; + return nullptr; + } + + // get steel base arguments + auto lam_get_dparam = [&numData](double* val, const char* valname) -> bool { + if (OPS_GetDouble(&numData, val) != 0) { + opserr << "nDMaterial ASDSteel1D Error: invalid '" << valname << "'.\n" << msg << "\n"; + return false; + } + if (*val <= 0.0) { + opserr << "nDMaterial ASDSteel1D Error: invalid value for '" << valname << "' (" << *val << "). It should be strictly positive.\n" << msg << "\n"; + return false; + } + return true; + }; + if (!lam_get_dparam(&E, "E")) return nullptr; + if (!lam_get_dparam(&sy, "sy")) return nullptr; + if (!lam_get_dparam(&su, "su")) return nullptr; + if (!lam_get_dparam(&eu, "eu")) return nullptr; + if (sy >= su) { + opserr << "nDMaterial ASDSteel1D Error: invalid value for 'su' (" << su << "). It should be larger than sy.\n" << msg << "\n"; + return nullptr; + } + + // obtain chaboche params from E, sy, su, eu + // we want to use 2 hardening functions as per chaboche model. + // so that the initial slope is close to E and the the stress apporaches su at eu + double dy = su - sy; + double H1 = E / 1000.0 / eu * dy / 40.0; + double gamma1 = H1 / dy; + double H2 = H1 * 50; + double gamma2 = gamma1 * 50; + double alpha = 0.9; + + // create the material + UniaxialMaterial* instance = new ASDSteel1DMaterial( + // tag + tag, + // base steel args + E, sy, H1*alpha, gamma1, H2*(1.0-alpha), gamma2 + // others.. + ); + if (instance == nullptr) { + opserr << "UniaxialMaterial ASDSteel1D Error: failed to allocate a new material.\n"; + return nullptr; + } + return instance; +} + +ASDSteel1DMaterial::ASDSteel1DMaterial( + int _tag, + double _E, + double _sy, + double _H1, + double _gamma1, + double _H2, + double _gamma2) + : UniaxialMaterial(_tag, MAT_TAG_ASDSteel1DMaterial) + , E(_E) + , sy(_sy) + , H1(_H1) + , H2(_H2) + , gamma1(_gamma1) + , gamma2(_gamma2) +{ + // intialize C as C0 + C = getInitialTangent(); +} + +ASDSteel1DMaterial::ASDSteel1DMaterial() + : UniaxialMaterial(0, MAT_TAG_ASDSteel1DMaterial) +{ +} + +ASDSteel1DMaterial::~ASDSteel1DMaterial() +{ +} + +int ASDSteel1DMaterial::setTrialStrain(double v, double r) +{ + // retval + int retval = 0; + + // perturbation + constexpr double pert = 1.0e-10; + + // compute forward response + retval = computeBaseSteel(v + pert); + if (retval < 0) return retval; + double pert_sigma = stress; + + // compute real response + retval = computeBaseSteel(v); + if (retval < 0) return retval; + + // compute numerical tangent + Cnum = (pert_sigma - stress) / pert; +} + +double ASDSteel1DMaterial::getStress(void) +{ + return stress; +} + +double ASDSteel1DMaterial::getTangent(void) +{ + return C; +} + +double ASDSteel1DMaterial::getInitialTangent(void) +{ + return E; +} + +double ASDSteel1DMaterial::getStrain(void) +{ + return strain; +} + +int ASDSteel1DMaterial::commitState(void) +{ + // compute energy + energy += 0.5 * (stress_commit + stress) * (strain - strain_commit); + + // store committed variables + alpha1_commit = alpha1; + alpha2_commit = alpha2; + lambda_commit = lambda; + strain_commit = strain; + stress_commit = stress; + + // done + return 0; +} + +int ASDSteel1DMaterial::revertToLastCommit(void) +{ + // restore converged values + alpha1 = alpha1_commit; + alpha2 = alpha2_commit; + lambda = lambda_commit; + strain = strain_commit; + stress = stress_commit; + + // done + return 0; +} + +int ASDSteel1DMaterial::revertToStart(void) +{ + // state variables + alpha1 = 0.0; + alpha1_commit = 0.0; + alpha2 = 0.0; + alpha2_commit = 0.0; + lambda = 0.0; + lambda_commit = 0.0; + + // strain, stress and tangent + strain = 0.0; + strain_commit = 0.0; + stress = 0.0; + stress_commit = 0.0; + C = getInitialTangent(); + + // output variables + energy = 0.0; + + // done + return 0; +} + +UniaxialMaterial* ASDSteel1DMaterial::getCopy(void) +{ + // we can safely use the default copy-constructor according to the member variables we're using + return new ASDSteel1DMaterial(*this); +} + +void ASDSteel1DMaterial::Print(OPS_Stream& s, int flag) +{ + s << "ASDSteel1D Material, tag: " << this->getTag() << "\n"; +} + +int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) +{ + // aux + int counter; + + // send DBL data + Vector ddata(19); + counter = 0; + ddata(counter++) = static_cast(getTag()); + ddata(counter++) = E; + ddata(counter++) = sy; + ddata(counter++) = H1; + ddata(counter++) = H2; + ddata(counter++) = gamma1; + ddata(counter++) = gamma2; + ddata(counter++) = alpha1; + ddata(counter++) = alpha1_commit; + ddata(counter++) = alpha2; + ddata(counter++) = alpha2_commit; + ddata(counter++) = lambda; + ddata(counter++) = lambda_commit; + ddata(counter++) = strain; + ddata(counter++) = strain_commit; + ddata(counter++) = stress; + ddata(counter++) = stress_commit; + ddata(counter++) = C; + ddata(counter++) = energy; + if (theChannel.sendVector(getDbTag(), commitTag, ddata) < 0) { + opserr << "ASDSteel1DMaterial::sendSelf() - failed to send DBL data\n"; + return -1; + } + + // done + return 0; +} + +int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker) +{ + // aux + int counter; + + // recv DBL data + Vector ddata(19); + if (theChannel.recvVector(getDbTag(), commitTag, ddata) < 0) { + opserr << "ASDSteel1DMaterial::recvSelf() - failed to receive DBL data\n"; + return -1; + } + counter = 0; + setTag(ddata(counter++)); + E = ddata(counter++); + sy = ddata(counter++); + H1 = ddata(counter++); + H2 = ddata(counter++); + gamma1 = ddata(counter++); + gamma2 = ddata(counter++); + alpha1 = ddata(counter++); + alpha1_commit = ddata(counter++); + alpha2 = ddata(counter++); + alpha2_commit = ddata(counter++); + lambda = ddata(counter++); + lambda_commit = ddata(counter++); + strain = ddata(counter++); + strain_commit = ddata(counter++); + stress = ddata(counter++); + stress_commit = ddata(counter++); + C = ddata(counter++); + energy = ddata(counter++); + + // done + return 0; +} + +int ASDSteel1DMaterial::setParameter(const char** argv, int argc, Parameter& param) +{ + // default + return -1; +} + +int ASDSteel1DMaterial::updateParameter(int parameterID, Information& info) +{ + switch (parameterID) { + // default + default: + return -1; + } +} + +Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Stream& output) +{ + // utils + auto make_resp = [&output, this](int rid, const Vector& v, const std::vector* labels = nullptr) -> MaterialResponse* { + output.tag("UniaxialMaterialOutput"); + output.attr("matType", getClassType()); + output.attr("matTag", getTag()); + if (labels) { + for (const auto& item : (*labels)) + output.tag("ResponseType", item.c_str()); + } + MaterialResponse* resp = new MaterialResponse(this, rid, v); + output.endTag(); + return resp; + }; + + // labels + static std::vector lb_eqpl_strain = { "PLE" }; + static std::vector lb_plastic_iter = { "PITER" }; + static std::vector lb_plastic_tangent_error = { "PK_ERROR (%)" }; + + // all outputs are 1D + static Vector out1(1); + + // check specific responses + if (argc > 0) { + // 1000 - base steel output + if (strcmp(argv[0], "equivalentPlasticStrain") == 0 || strcmp(argv[0], "EquivalentPlasticStrain") == 0) { + out1(0) = lambda; + return make_resp(1001, out1, &lb_eqpl_strain); + } + if (strcmp(argv[0], "plasticIter") == 0 || strcmp(argv[0], "PlasticIter") == 0) { + out1(0) = niter; + return make_resp(1002, out1, &lb_plastic_iter); + } + if (strcmp(argv[0], "plasticTangentError") == 0) { + out1(0) = 100.0 * std::abs((Cnum - C) / C); + return make_resp(1003, out1, &lb_plastic_tangent_error); + } + } + + // otherwise return base-class response + return UniaxialMaterial::setResponse(argv, argc, output); +} + +int ASDSteel1DMaterial::getResponse(int responseID, Information& matInformation) +{ + // all outputs are 1D + static Vector out1(1); + + switch (responseID) { + // 1000 - base steel output + case 1001: + out1(0) = lambda; + return matInformation.setVector(out1); + case 1002: + out1(0) = niter; + return matInformation.setVector(out1); + case 1003: + out1(0) = 100.0 * std::abs((Cnum - C) / C);; + return matInformation.setVector(out1); + default: + break; + } + return UniaxialMaterial::getResponse(responseID, matInformation); +} + +double ASDSteel1DMaterial::getEnergy(void) +{ + return energy; +} + +int ASDSteel1DMaterial::computeBaseSteel(double trial_strain) +{ + // return value + int retval = 0; + + // settings + constexpr int MAX_ITER = 100; + constexpr double F_REL_TOL = 1.0e-6; + constexpr double L_ABS_TOL = 1.0e-8; + // base steel response + alpha1 = alpha1_commit; + alpha2 = alpha2_commit; + lambda = lambda_commit; + // elastic predictor + strain = trial_strain; + double dstrain = strain - strain_commit; + double sigma = stress_commit + E * dstrain; + double tangent = E; + // plastic utilities + auto lam_rel_stress = [this, &sigma]() -> double { + return sigma - alpha1 - alpha2; + }; + auto lam_yield_function = [this, &lam_rel_stress]() -> double { + return std::abs(lam_rel_stress()) - sy; + }; + auto lam_yield_derivative = [this, &lam_rel_stress](double dlambda) -> double { + // plastic flow direction + double sg = sign(lam_rel_stress()); + // d stress / d lambda + double dsigma = -E * sg; + // d backstress / d lambda + double dalpha1 = H1 * sg - gamma1 * alpha1; + double dalpha2 = H2 * sg - gamma2 * alpha2; + return sg * (dsigma - dalpha1 - dalpha2); + }; + auto lam_yield_update = [this, &sigma, &lam_rel_stress](double dlambda, double delta_lambda) { + // plastic flow direction + double sg = sign(lam_rel_stress()); + // update stress + sigma -= sg * dlambda * E; + // update backstress + alpha1 = sg * H1 / gamma1 - (sg * H1 / gamma1 - alpha1_commit) * std::exp(-gamma1 * delta_lambda); + alpha2 = sg * H2 / gamma2 - (sg * H2 / gamma2 - alpha2_commit) * std::exp(-gamma2 * delta_lambda); + }; + // plastic corrector + niter = 0; + double F = lam_yield_function(); + if (F > 0.0) { + double delta_lambda = 0.0; + double dlambda = 0.0; + bool converged = false; + for (niter = 0; niter < MAX_ITER; ++niter) { + // form tangent + double dF = lam_yield_derivative(dlambda); + if (dF == 0.0) break; + // solve for dlambda + dlambda = -F / dF; + delta_lambda += dlambda; + // update plastic multiplier increment and sigma + lam_yield_update(dlambda, delta_lambda); + // update residual + F = lam_yield_function(); + // check convergence + if (std::abs(F) < F_REL_TOL * sy && std::abs(dlambda) < L_ABS_TOL) { + converged = true; + // update plastic multiplier + lambda += delta_lambda; + // compute tangent + double sg = sign(lam_rel_stress()); + double PE = + gamma1 * (H1 / gamma1 - sg * alpha1) + + gamma2 * (H2 / gamma2 - sg * alpha2); + tangent = (E * PE) / (E + PE); + break; + } + } + if (!converged) + retval = -1; + } + // accept solution + stress = sigma; + C = tangent; + + // done + return retval; +} diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h new file mode 100644 index 0000000000..ee8e30d460 --- /dev/null +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -0,0 +1,122 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.0 $ +// $Date: 2025-01-03 11:29:01 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/ASDSteel1DMaterial.cpp,v $ + +// Alessia Casalucci - ASDEA Software, Italy +// +// todo... +// + +#ifndef ASDSteel1DMaterial_h +#define ASDSteel1DMaterial_h + +#include +#include +#include +#include +#include +#include +#include + +class ASDSteel1DMaterial : public UniaxialMaterial +{ + +public: + // life-cycle + ASDSteel1DMaterial( + int _tag, + double _E, + double _sy, + double _H1, + double _gamma1, + double _H2, + double _gamma2); + ASDSteel1DMaterial(); + ~ASDSteel1DMaterial(); + + // info + const char* getClassType(void) const { return "ASDSteel1DMaterial"; } + + // set strain + int setTrialStrain(double v, double r = 0.0); + + // get state + double getStrain(void); + double getStress(void); + double getTangent(void); + double getInitialTangent(void); + + // handle state + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + // copy and others... + UniaxialMaterial* getCopy(void); + void Print(OPS_Stream& s, int flag = 0); + + // send/recv self + int sendSelf(int commitTag, Channel& theChannel); + int recvSelf(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker); + + // parameters and responses + int setParameter(const char** argv, int argc, Parameter& param); + int updateParameter(int parameterID, Information& info); + Response* setResponse(const char** argv, int argc, OPS_Stream& output); + int getResponse(int responseID, Information& matInformation); + double getEnergy(void); + +private: + int computeBaseSteel(double trial_strain); + + private: + // Young's modulus + double E = 0.0; + // Yield stress + double sy = 0.0; + // Chaboche kinematic hardening parameters + double H1 = 0.0; + double H2 = 0.0; + double gamma1 = 0.0; + double gamma2 = 0.0; + // state variables - backstresses + double alpha1 = 0.0; + double alpha1_commit = 0.0; + double alpha2 = 0.0; + double alpha2_commit = 0.0; + // state variables - plastic multiplier + double lambda = 0.0; + double lambda_commit = 0.0; + // strain, stress and tangent + double strain = 0.0; + double strain_commit = 0.0; + double stress = 0.0; + double stress_commit = 0.0; + double C = 0.0; + // other variables for output purposes + double energy = 0.0; + int niter = 0; + double Cnum = 0.0; +}; + +#endif diff --git a/SRC/material/uniaxial/CMakeLists.txt b/SRC/material/uniaxial/CMakeLists.txt index ac1be9fe26..a78d03e16a 100644 --- a/SRC/material/uniaxial/CMakeLists.txt +++ b/SRC/material/uniaxial/CMakeLists.txt @@ -73,6 +73,7 @@ target_sources(OPS_Material PRIVATE ASD_SMA_3K.cpp ASDConcrete1DMaterial.cpp + ASDSteel1DMaterial.cpp BackboneMaterial.cpp BarSlipMaterial.cpp BilinearOilDamper.cpp @@ -200,6 +201,7 @@ target_sources(OPS_Material PUBLIC ASD_SMA_3K.h ASDConcrete1DMaterial.h + ASDSteel1DMaterial.h BackboneMaterial.h BarSlipMaterial.h BilinearOilDamper.h diff --git a/SRC/material/uniaxial/Makefile b/SRC/material/uniaxial/Makefile index 9b58a4d1a2..d702c16ab5 100644 --- a/SRC/material/uniaxial/Makefile +++ b/SRC/material/uniaxial/Makefile @@ -38,6 +38,7 @@ OBJS = UniaxialMaterial.o \ HardeningMaterial2.o \ ASD_SMA_3K.o \ ASDConcrete1DMaterial.o \ + ASDSteel1DMaterial.o \ Concrete01.o \ Concrete02Thermal.o \ Steel02Thermal.o \ diff --git a/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp b/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp index 613008ba09..aabefbf071 100644 --- a/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp +++ b/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp @@ -151,6 +151,7 @@ extern void *OPS_ElasticMaterialThermal(void); //L.Jiang[SIF] //extern void *OPS_PlateBearingConnectionThermal(void); extern void* OPS_ASD_SMA_3K(void); // Luca Aceto extern void* OPS_ASDConcrete1DMaterial(void); +extern void* OPS_ASDSteel1DMaterial(void); extern void *OPS_BWBN(void); extern void *OPS_IMKPeakOriented(void); extern void *OPS_IMKBilin(void); @@ -2021,6 +2022,14 @@ TclModelBuilderUniaxialMaterialCommand (ClientData clientData, Tcl_Interp *inter return TCL_ERROR; } + if (strcmp(argv[1], "ASDSteel1D") == 0) { + void *theMat = OPS_ASDSteel1DMaterial(); + if (theMat != 0) + theMaterial = (UniaxialMaterial *)theMat; + else + return TCL_ERROR; + } + if (strcmp(argv[1],"SelfCentering") == 0) { void *theMat = OPS_SelfCenteringMaterial(); if (theMat != 0) @@ -2160,7 +2169,7 @@ TclModelBuilderUniaxialMaterialCommand (ClientData clientData, Tcl_Interp *inter else return TCL_ERROR; } - if (strcmp(argv[1], "TzSandCPT") == 0) { + /* if (strcmp(argv[1], "TzSandCPT") == 0) { void* theMat = OPS_TzSandCPT(); if (theMat != 0) theMaterial = (UniaxialMaterial*)theMat; @@ -2173,7 +2182,7 @@ TclModelBuilderUniaxialMaterialCommand (ClientData clientData, Tcl_Interp *inter theMaterial = (UniaxialMaterial*)theMat; else return TCL_ERROR; - } + } */ // Fedeas #if defined(_STEEL2) || defined(OPSDEF_UNIAXIAL_FEDEAS) if (theMaterial == 0) diff --git a/Win32/proj/material/material.vcxproj b/Win32/proj/material/material.vcxproj index 53d4a95339..f914defedc 100644 --- a/Win32/proj/material/material.vcxproj +++ b/Win32/proj/material/material.vcxproj @@ -195,6 +195,7 @@ + @@ -623,6 +624,7 @@ + diff --git a/Win32/proj/material/material.vcxproj.filters b/Win32/proj/material/material.vcxproj.filters index b8938fc449..5e159f4511 100644 --- a/Win32/proj/material/material.vcxproj.filters +++ b/Win32/proj/material/material.vcxproj.filters @@ -151,6 +151,9 @@ uniaxial + + uniaxial + uniaxial @@ -1426,6 +1429,9 @@ uniaxial + + uniaxial + uniaxial diff --git a/Win64/proj/material/material.vcxproj b/Win64/proj/material/material.vcxproj index 40ab00643b..c020c6b4b2 100644 --- a/Win64/proj/material/material.vcxproj +++ b/Win64/proj/material/material.vcxproj @@ -294,6 +294,7 @@ + @@ -759,6 +760,7 @@ + diff --git a/Win64/proj/material/material.vcxproj.filters b/Win64/proj/material/material.vcxproj.filters index 80943d15b6..74107ddca7 100644 --- a/Win64/proj/material/material.vcxproj.filters +++ b/Win64/proj/material/material.vcxproj.filters @@ -160,6 +160,9 @@ uniaxial + + uniaxial + uniaxial @@ -1594,6 +1597,9 @@ uniaxial + + uniaxial + uniaxial From 46c69a184d40a69a689b8a20800b01a30f607d67 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Wed, 8 Jan 2025 10:37:57 +0100 Subject: [PATCH 007/261] base steel done --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 240 ++++++++++-------- SRC/material/uniaxial/ASDSteel1DMaterial.h | 72 ++++-- Win64/OpenSees.sln | 232 ++++++++++++++++- Win64/proj/actor/Debug/Actor.sbr | 0 Win64/proj/actor/Debug/Channel.sbr | 0 Win64/proj/actor/Debug/ChannelAddress.sbr | 0 Win64/proj/actor/Debug/FEM_ObjectBroker.sbr | 0 .../Debug/FEM_ObjectBrokerAllClasses.sbr | 0 Win64/proj/actor/Debug/HTTP.sbr | 0 Win64/proj/actor/Debug/Message.sbr | 0 Win64/proj/actor/Debug/MovableObject.sbr | 0 Win64/proj/actor/Debug/ObjectBroker.sbr | 0 Win64/proj/actor/Debug/Shadow.sbr | 0 Win64/proj/actor/Debug/Socket.sbr | 0 Win64/proj/actor/Debug/TCP_Socket.sbr | 0 Win64/proj/actor/Debug/UDP_Socket.sbr | 0 .../proj/actor/Debug/actor.Build.CppClean.log | 0 Win64/proj/actor/Debug/actor.lib.recipe | 7 + .../actor/Debug/actor.tlog/CL.command.1.tlog | Bin 0 -> 128506 bytes .../actor/Debug/actor.tlog/CL.read.1.tlog | Bin 0 -> 251234 bytes .../actor/Debug/actor.tlog/CL.write.1.tlog | Bin 0 -> 7428 bytes .../proj/actor/Debug/actor.tlog/Cl.items.tlog | 13 + .../Debug/actor.tlog/Lib-link.read.1.tlog | Bin 0 -> 3182 bytes .../Debug/actor.tlog/Lib-link.write.1.tlog | Bin 0 -> 1594 bytes .../actor/Debug/actor.tlog/Lib.command.1.tlog | Bin 0 -> 2664 bytes .../Debug/actor.tlog/actor.lastbuildstate | 2 + .../Debug/actor.tlog/bscmake.command.1.tlog | Bin 0 -> 2194 bytes .../Debug/actor.tlog/bscmake.read.1.tlog | Bin 0 -> 3134 bytes .../Debug/actor.tlog/bscmake.write.1.tlog | Bin 0 -> 1612 bytes .../Debug/actor.vcxproj.FileListAbsolute.txt | 0 Win64/proj/actor/actor.vcxproj | 164 ++++++++++++ Win64/proj/openSeesPy/OpenSeesPy.vcxproj | 2 +- 32 files changed, 591 insertions(+), 141 deletions(-) create mode 100644 Win64/proj/actor/Debug/Actor.sbr create mode 100644 Win64/proj/actor/Debug/Channel.sbr create mode 100644 Win64/proj/actor/Debug/ChannelAddress.sbr create mode 100644 Win64/proj/actor/Debug/FEM_ObjectBroker.sbr create mode 100644 Win64/proj/actor/Debug/FEM_ObjectBrokerAllClasses.sbr create mode 100644 Win64/proj/actor/Debug/HTTP.sbr create mode 100644 Win64/proj/actor/Debug/Message.sbr create mode 100644 Win64/proj/actor/Debug/MovableObject.sbr create mode 100644 Win64/proj/actor/Debug/ObjectBroker.sbr create mode 100644 Win64/proj/actor/Debug/Shadow.sbr create mode 100644 Win64/proj/actor/Debug/Socket.sbr create mode 100644 Win64/proj/actor/Debug/TCP_Socket.sbr create mode 100644 Win64/proj/actor/Debug/UDP_Socket.sbr create mode 100644 Win64/proj/actor/Debug/actor.Build.CppClean.log create mode 100644 Win64/proj/actor/Debug/actor.lib.recipe create mode 100644 Win64/proj/actor/Debug/actor.tlog/CL.command.1.tlog create mode 100644 Win64/proj/actor/Debug/actor.tlog/CL.read.1.tlog create mode 100644 Win64/proj/actor/Debug/actor.tlog/CL.write.1.tlog create mode 100644 Win64/proj/actor/Debug/actor.tlog/Cl.items.tlog create mode 100644 Win64/proj/actor/Debug/actor.tlog/Lib-link.read.1.tlog create mode 100644 Win64/proj/actor/Debug/actor.tlog/Lib-link.write.1.tlog create mode 100644 Win64/proj/actor/Debug/actor.tlog/Lib.command.1.tlog create mode 100644 Win64/proj/actor/Debug/actor.tlog/actor.lastbuildstate create mode 100644 Win64/proj/actor/Debug/actor.tlog/bscmake.command.1.tlog create mode 100644 Win64/proj/actor/Debug/actor.tlog/bscmake.read.1.tlog create mode 100644 Win64/proj/actor/Debug/actor.tlog/bscmake.write.1.tlog create mode 100644 Win64/proj/actor/Debug/actor.vcxproj.FileListAbsolute.txt diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index e9461131d8..0b6dfaf7d8 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -127,15 +127,22 @@ void* OPS_ASDSteel1DMaterial() double H2 = H1 * 50; double gamma2 = gamma1 * 50; double alpha = 0.9; + ASDSteel1DMaterial::InputParameters params; + params.E = E; + params.sy = sy; + params.H1 = H1 * alpha; + params.gamma1 = gamma1; + params.H2 = H2 * (1.0 - alpha); + params.gamma2 = gamma2; // create the material UniaxialMaterial* instance = new ASDSteel1DMaterial( // tag - tag, + tag, params); // base steel args - E, sy, H1*alpha, gamma1, H2*(1.0-alpha), gamma2 + //E, sy, H1*alpha, gamma1, H2*(1.0-alpha), gamma2 // others.. - ); + //); if (instance == nullptr) { opserr << "UniaxialMaterial ASDSteel1D Error: failed to allocate a new material.\n"; return nullptr; @@ -143,21 +150,65 @@ void* OPS_ASDSteel1DMaterial() return instance; } +void ASDSteel1DMaterial::StateVariablesSteel::commit(const ASDSteel1DMaterial::InputParameters& params) +{ + // state variables + alpha1_commit = alpha1; + alpha2_commit = alpha2; + lambda_commit = lambda; + strain_commit = strain; + stress_commit = stress; +} + +void ASDSteel1DMaterial::StateVariablesSteel::revertToLastCommit(const ASDSteel1DMaterial::InputParameters& params) +{ + // state variables + alpha1 = alpha1_commit; + alpha2 = alpha2_commit; + lambda = lambda_commit; + strain = strain_commit; + stress = stress_commit; +} + +void ASDSteel1DMaterial::StateVariablesSteel::revertToStart(const ASDSteel1DMaterial::InputParameters& params) +{ + // state variables + alpha1 = 0.0; + alpha1_commit = 0.0; + alpha2 = 0.0; + alpha2_commit = 0.0; + lambda = 0.0; + lambda_commit = 0.0; + + // strain, stress and tangent + strain = 0.0; + strain_commit = 0.0; + stress = 0.0; + stress_commit = 0.0; + C = params.E; +} +void ASDSteel1DMaterial::StateVariablesSteel::sendSelf(int& counter, Vector& ddata) { + ddata(counter++) = alpha1; + ddata(counter++) = alpha1_commit; + ddata(counter++) = alpha2; + ddata(counter++) = alpha2_commit; + ddata(counter++) = lambda; + ddata(counter++) = lambda_commit; +} +void ASDSteel1DMaterial::StateVariablesSteel::recvSelf(int& counter, Vector& ddata) { + alpha1 = ddata(counter++); + alpha1_commit = ddata(counter++); + alpha2 = ddata(counter++); + alpha2_commit = ddata(counter++); + lambda = ddata(counter++); + lambda_commit = ddata(counter++); +} + ASDSteel1DMaterial::ASDSteel1DMaterial( int _tag, - double _E, - double _sy, - double _H1, - double _gamma1, - double _H2, - double _gamma2) + const InputParameters& _params) : UniaxialMaterial(_tag, MAT_TAG_ASDSteel1DMaterial) - , E(_E) - , sy(_sy) - , H1(_H1) - , H2(_H2) - , gamma1(_gamma1) - , gamma2(_gamma2) + , params(_params) { // intialize C as C0 C = getInitialTangent(); @@ -177,20 +228,19 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) // retval int retval = 0; - // perturbation - constexpr double pert = 1.0e-10; - - // compute forward response - retval = computeBaseSteel(v + pert); - if (retval < 0) return retval; - double pert_sigma = stress; - // compute real response - retval = computeBaseSteel(v); + steel.strain = v; + retval = computeBaseSteel(steel); if (retval < 0) return retval; - // compute numerical tangent - Cnum = (pert_sigma - stress) / pert; + // todo: homogenize + strain = steel.strain; + stress = steel.stress; + C = steel.C; + + // done + return retval; + } double ASDSteel1DMaterial::getStress(void) @@ -205,7 +255,7 @@ double ASDSteel1DMaterial::getTangent(void) double ASDSteel1DMaterial::getInitialTangent(void) { - return E; + return params.E; } double ASDSteel1DMaterial::getStrain(void) @@ -219,9 +269,9 @@ int ASDSteel1DMaterial::commitState(void) energy += 0.5 * (stress_commit + stress) * (strain - strain_commit); // store committed variables - alpha1_commit = alpha1; - alpha2_commit = alpha2; - lambda_commit = lambda; + steel.commit(params); + + // state variables strain_commit = strain; stress_commit = stress; @@ -232,9 +282,9 @@ int ASDSteel1DMaterial::commitState(void) int ASDSteel1DMaterial::revertToLastCommit(void) { // restore converged values - alpha1 = alpha1_commit; - alpha2 = alpha2_commit; - lambda = lambda_commit; + steel.revertToLastCommit(params); + + // state variables strain = strain_commit; stress = stress_commit; @@ -245,12 +295,7 @@ int ASDSteel1DMaterial::revertToLastCommit(void) int ASDSteel1DMaterial::revertToStart(void) { // state variables - alpha1 = 0.0; - alpha1_commit = 0.0; - alpha2 = 0.0; - alpha2_commit = 0.0; - lambda = 0.0; - lambda_commit = 0.0; + steel.revertToStart(params); // strain, stress and tangent strain = 0.0; @@ -283,21 +328,16 @@ int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) int counter; // send DBL data - Vector ddata(19); + Vector ddata(InputParameters::NDATA + 1*StateVariablesSteel::NDATA + 7); counter = 0; ddata(counter++) = static_cast(getTag()); - ddata(counter++) = E; - ddata(counter++) = sy; - ddata(counter++) = H1; - ddata(counter++) = H2; - ddata(counter++) = gamma1; - ddata(counter++) = gamma2; - ddata(counter++) = alpha1; - ddata(counter++) = alpha1_commit; - ddata(counter++) = alpha2; - ddata(counter++) = alpha2_commit; - ddata(counter++) = lambda; - ddata(counter++) = lambda_commit; + ddata(counter++) = params.E; + ddata(counter++) = params.sy; + ddata(counter++) = params.H1; + ddata(counter++) = params.H2; + ddata(counter++) = params.gamma1; + ddata(counter++) = params.gamma2; + steel.sendSelf(counter, ddata); ddata(counter++) = strain; ddata(counter++) = strain_commit; ddata(counter++) = stress; @@ -319,25 +359,20 @@ int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectB int counter; // recv DBL data - Vector ddata(19); + Vector ddata(InputParameters::NDATA + 1 * StateVariablesSteel::NDATA + 7); if (theChannel.recvVector(getDbTag(), commitTag, ddata) < 0) { opserr << "ASDSteel1DMaterial::recvSelf() - failed to receive DBL data\n"; return -1; } counter = 0; setTag(ddata(counter++)); - E = ddata(counter++); - sy = ddata(counter++); - H1 = ddata(counter++); - H2 = ddata(counter++); - gamma1 = ddata(counter++); - gamma2 = ddata(counter++); - alpha1 = ddata(counter++); - alpha1_commit = ddata(counter++); - alpha2 = ddata(counter++); - alpha2_commit = ddata(counter++); - lambda = ddata(counter++); - lambda_commit = ddata(counter++); + params.E = ddata(counter++); + params.sy = ddata(counter++); + params.H1 = ddata(counter++); + params.H2 = ddata(counter++); + params.gamma1 = ddata(counter++); + params.gamma2 = ddata(counter++); + steel.recvSelf(counter, ddata); strain = ddata(counter++); strain_commit = ddata(counter++); stress = ddata(counter++); @@ -382,8 +417,6 @@ Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Strea // labels static std::vector lb_eqpl_strain = { "PLE" }; - static std::vector lb_plastic_iter = { "PITER" }; - static std::vector lb_plastic_tangent_error = { "PK_ERROR (%)" }; // all outputs are 1D static Vector out1(1); @@ -392,17 +425,9 @@ Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Strea if (argc > 0) { // 1000 - base steel output if (strcmp(argv[0], "equivalentPlasticStrain") == 0 || strcmp(argv[0], "EquivalentPlasticStrain") == 0) { - out1(0) = lambda; + out1(0) = steel.lambda; return make_resp(1001, out1, &lb_eqpl_strain); } - if (strcmp(argv[0], "plasticIter") == 0 || strcmp(argv[0], "PlasticIter") == 0) { - out1(0) = niter; - return make_resp(1002, out1, &lb_plastic_iter); - } - if (strcmp(argv[0], "plasticTangentError") == 0) { - out1(0) = 100.0 * std::abs((Cnum - C) / C); - return make_resp(1003, out1, &lb_plastic_tangent_error); - } } // otherwise return base-class response @@ -417,13 +442,7 @@ int ASDSteel1DMaterial::getResponse(int responseID, Information& matInformation) switch (responseID) { // 1000 - base steel output case 1001: - out1(0) = lambda; - return matInformation.setVector(out1); - case 1002: - out1(0) = niter; - return matInformation.setVector(out1); - case 1003: - out1(0) = 100.0 * std::abs((Cnum - C) / C);; + out1(0) = steel.lambda; return matInformation.setVector(out1); default: break; @@ -436,7 +455,7 @@ double ASDSteel1DMaterial::getEnergy(void) return energy; } -int ASDSteel1DMaterial::computeBaseSteel(double trial_strain) +int ASDSteel1DMaterial::computeBaseSteel(ASDSteel1DMaterial::StateVariablesSteel& sv) { // return value int retval = 0; @@ -446,48 +465,46 @@ int ASDSteel1DMaterial::computeBaseSteel(double trial_strain) constexpr double F_REL_TOL = 1.0e-6; constexpr double L_ABS_TOL = 1.0e-8; // base steel response - alpha1 = alpha1_commit; - alpha2 = alpha2_commit; - lambda = lambda_commit; + sv.alpha1 = sv.alpha1_commit; + sv.alpha2 = sv.alpha2_commit; + sv.lambda = sv.lambda_commit; // elastic predictor - strain = trial_strain; - double dstrain = strain - strain_commit; - double sigma = stress_commit + E * dstrain; - double tangent = E; + double dstrain = sv.strain - sv.strain_commit; + double sigma = sv.stress_commit + params.E * dstrain; + double tangent = params.E; // plastic utilities - auto lam_rel_stress = [this, &sigma]() -> double { - return sigma - alpha1 - alpha2; + auto lam_rel_stress = [&sv, &sigma]() -> double { + return sigma - sv.alpha1 - sv.alpha2; }; auto lam_yield_function = [this, &lam_rel_stress]() -> double { - return std::abs(lam_rel_stress()) - sy; + return std::abs(lam_rel_stress()) - params.sy; }; - auto lam_yield_derivative = [this, &lam_rel_stress](double dlambda) -> double { + auto lam_yield_derivative = [this, &lam_rel_stress, &sv](double dlambda) -> double { // plastic flow direction double sg = sign(lam_rel_stress()); // d stress / d lambda - double dsigma = -E * sg; + double dsigma = -params.E * sg; // d backstress / d lambda - double dalpha1 = H1 * sg - gamma1 * alpha1; - double dalpha2 = H2 * sg - gamma2 * alpha2; + double dalpha1 = params.H1 * sg - params.gamma1 * sv.alpha1; + double dalpha2 = params.H2 * sg - params.gamma2 * sv.alpha2; return sg * (dsigma - dalpha1 - dalpha2); }; - auto lam_yield_update = [this, &sigma, &lam_rel_stress](double dlambda, double delta_lambda) { + auto lam_yield_update = [this, &sigma, &lam_rel_stress, &sv](double dlambda, double delta_lambda) { // plastic flow direction double sg = sign(lam_rel_stress()); // update stress - sigma -= sg * dlambda * E; + sigma -= sg * dlambda * params.E; // update backstress - alpha1 = sg * H1 / gamma1 - (sg * H1 / gamma1 - alpha1_commit) * std::exp(-gamma1 * delta_lambda); - alpha2 = sg * H2 / gamma2 - (sg * H2 / gamma2 - alpha2_commit) * std::exp(-gamma2 * delta_lambda); + sv.alpha1 = sg * params.H1 / params.gamma1 - (sg * params.H1 / params.gamma1 - sv.alpha1_commit) * std::exp(-params.gamma1 * delta_lambda); + sv.alpha2 = sg * params.H2 / params.gamma2 - (sg * params.H2 / params.gamma2 - sv.alpha2_commit) * std::exp(-params.gamma2 * delta_lambda); }; // plastic corrector - niter = 0; double F = lam_yield_function(); if (F > 0.0) { double delta_lambda = 0.0; double dlambda = 0.0; bool converged = false; - for (niter = 0; niter < MAX_ITER; ++niter) { + for (int niter = 0; niter < MAX_ITER; ++niter) { // form tangent double dF = lam_yield_derivative(dlambda); if (dF == 0.0) break; @@ -499,16 +516,16 @@ int ASDSteel1DMaterial::computeBaseSteel(double trial_strain) // update residual F = lam_yield_function(); // check convergence - if (std::abs(F) < F_REL_TOL * sy && std::abs(dlambda) < L_ABS_TOL) { + if (std::abs(F) < F_REL_TOL * params.sy && std::abs(dlambda) < L_ABS_TOL) { converged = true; // update plastic multiplier - lambda += delta_lambda; + sv.lambda += delta_lambda; // compute tangent double sg = sign(lam_rel_stress()); double PE = - gamma1 * (H1 / gamma1 - sg * alpha1) + - gamma2 * (H2 / gamma2 - sg * alpha2); - tangent = (E * PE) / (E + PE); + params.gamma1 * (params.H1 / params.gamma1 - sg * sv.alpha1) + + params.gamma2 * (params.H2 / params.gamma2 - sg * sv.alpha2); + tangent = (params.E * PE) / (params.E + PE); break; } } @@ -516,9 +533,10 @@ int ASDSteel1DMaterial::computeBaseSteel(double trial_strain) retval = -1; } // accept solution - stress = sigma; - C = tangent; + sv.stress = sigma; + sv.C = tangent; // done return retval; } + diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index ee8e30d460..0390034c9b 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -40,17 +40,50 @@ class ASDSteel1DMaterial : public UniaxialMaterial { +public: + class InputParameters { + public: + // Young's modulus + double E = 0.0; + // Yield stress + double sy = 0.0; + // Chaboche kinematic hardening parameters + double H1 = 0.0; + double H2 = 0.0; + double gamma1 = 0.0; + double gamma2 = 0.0; + static constexpr int NDATA = 6; + }; + class StateVariablesSteel { + public: + // state variables - backstresses + double alpha1 = 0.0; + double alpha1_commit = 0.0; + double alpha2 = 0.0; + double alpha2_commit = 0.0; + // state variables - plastic multiplier + double lambda = 0.0; + double lambda_commit = 0.0; + // strain, stress and tangent + double strain = 0.0; + double strain_commit = 0.0; + double stress = 0.0; + double stress_commit = 0.0; + double C = 0.0; + // methods + static constexpr int NDATA = 11; + void commit(const InputParameters& params); + void revertToLastCommit(const InputParameters& params); + void revertToStart(const InputParameters& params); + void sendSelf(int &counter, Vector& ddata); + void recvSelf(int& counterg, Vector& ddata); + }; public: // life-cycle ASDSteel1DMaterial( int _tag, - double _E, - double _sy, - double _H1, - double _gamma1, - double _H2, - double _gamma2); + const InputParameters& _params); ASDSteel1DMaterial(); ~ASDSteel1DMaterial(); @@ -87,27 +120,14 @@ class ASDSteel1DMaterial : public UniaxialMaterial double getEnergy(void); private: - int computeBaseSteel(double trial_strain); + int computeBaseSteel(StateVariablesSteel& sv); private: - // Young's modulus - double E = 0.0; - // Yield stress - double sy = 0.0; - // Chaboche kinematic hardening parameters - double H1 = 0.0; - double H2 = 0.0; - double gamma1 = 0.0; - double gamma2 = 0.0; - // state variables - backstresses - double alpha1 = 0.0; - double alpha1_commit = 0.0; - double alpha2 = 0.0; - double alpha2_commit = 0.0; - // state variables - plastic multiplier - double lambda = 0.0; - double lambda_commit = 0.0; - // strain, stress and tangent + // common input parameters + InputParameters params; + // state variables - steel + StateVariablesSteel steel; + // strain, stress and tangent (homogenized) double strain = 0.0; double strain_commit = 0.0; double stress = 0.0; @@ -115,8 +135,6 @@ class ASDSteel1DMaterial : public UniaxialMaterial double C = 0.0; // other variables for output purposes double energy = 0.0; - int niter = 0; - double Cnum = 0.0; }; #endif diff --git a/Win64/OpenSees.sln b/Win64/OpenSees.sln index c36a6f938f..5f17bf8677 100644 --- a/Win64/OpenSees.sln +++ b/Win64/OpenSees.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.32413.511 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35527.113 d17.12 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "actor", "proj\actor\actor.vcxproj", "{D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}" EndProject @@ -60,354 +60,582 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "quickMain", "proj\quickMain EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug.DLL|Win32 = Debug.DLL|Win32 Debug.DLL|x64 = Debug.DLL|x64 Debug.DLL|x86 = Debug.DLL|x86 + Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 + Release.DLL|Win32 = Release.DLL|Win32 Release.DLL|x64 = Release.DLL|x64 Release.DLL|x86 = Release.DLL|x86 + Release|Win32 = Release|Win32 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|Win32 + {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug.DLL|Win32.Build.0 = Debug.DLL|Win32 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug|Win32.ActiveCfg = Debug|Win32 + {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug|Win32.Build.0 = Debug|Win32 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug|x64.ActiveCfg = Debug|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug|x64.Build.0 = Debug|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug|x86.ActiveCfg = Debug|x64 + {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release.DLL|Win32.ActiveCfg = Release.DLL|Win32 + {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release.DLL|Win32.Build.0 = Release.DLL|Win32 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release.DLL|x64.Build.0 = Release.DLL|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release|Win32.ActiveCfg = Release|Win32 + {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release|Win32.Build.0 = Release|Win32 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release|x64.ActiveCfg = Release|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release|x64.Build.0 = Release|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release|x86.ActiveCfg = Release|x64 + {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug|Win32.ActiveCfg = Debug|x64 + {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug|Win32.Build.0 = Debug|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug|x64.ActiveCfg = Debug|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug|x64.Build.0 = Debug|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug|x86.ActiveCfg = Debug|x64 + {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release.DLL|x64.Build.0 = Release.DLL|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release|Win32.ActiveCfg = Release|x64 + {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release|Win32.Build.0 = Release|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release|x64.ActiveCfg = Release|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release|x64.Build.0 = Release|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release|x86.ActiveCfg = Release|x64 + {310DC5FA-1613-D953-4008-15056952E467}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {310DC5FA-1613-D953-4008-15056952E467}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {310DC5FA-1613-D953-4008-15056952E467}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {310DC5FA-1613-D953-4008-15056952E467}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {310DC5FA-1613-D953-4008-15056952E467}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {310DC5FA-1613-D953-4008-15056952E467}.Debug|Win32.ActiveCfg = Debug|x64 + {310DC5FA-1613-D953-4008-15056952E467}.Debug|Win32.Build.0 = Debug|x64 {310DC5FA-1613-D953-4008-15056952E467}.Debug|x64.ActiveCfg = Debug|x64 {310DC5FA-1613-D953-4008-15056952E467}.Debug|x64.Build.0 = Debug|x64 {310DC5FA-1613-D953-4008-15056952E467}.Debug|x86.ActiveCfg = Debug|x64 + {310DC5FA-1613-D953-4008-15056952E467}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {310DC5FA-1613-D953-4008-15056952E467}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {310DC5FA-1613-D953-4008-15056952E467}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {310DC5FA-1613-D953-4008-15056952E467}.Release.DLL|x64.Build.0 = Release.DLL|x64 {310DC5FA-1613-D953-4008-15056952E467}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {310DC5FA-1613-D953-4008-15056952E467}.Release|Win32.ActiveCfg = Release|x64 + {310DC5FA-1613-D953-4008-15056952E467}.Release|Win32.Build.0 = Release|x64 {310DC5FA-1613-D953-4008-15056952E467}.Release|x64.ActiveCfg = Release|x64 {310DC5FA-1613-D953-4008-15056952E467}.Release|x64.Build.0 = Release|x64 {310DC5FA-1613-D953-4008-15056952E467}.Release|x86.ActiveCfg = Release|x64 + {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug|Win32.ActiveCfg = Debug|x64 + {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug|Win32.Build.0 = Debug|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug|x64.ActiveCfg = Debug|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug|x64.Build.0 = Debug|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug|x86.ActiveCfg = Debug|x64 + {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release.DLL|x64.Build.0 = Release.DLL|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release|Win32.ActiveCfg = Release|x64 + {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release|Win32.Build.0 = Release|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release|x64.ActiveCfg = Release|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release|x64.Build.0 = Release|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release|x86.ActiveCfg = Release|x64 + {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug|Win32.ActiveCfg = Debug|x64 + {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug|Win32.Build.0 = Debug|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug|x64.ActiveCfg = Debug|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug|x64.Build.0 = Debug|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug|x86.ActiveCfg = Debug|x64 + {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release.DLL|x64.Build.0 = Release.DLL|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release|Win32.ActiveCfg = Release|x64 + {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release|Win32.Build.0 = Release|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release|x64.ActiveCfg = Release|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release|x64.Build.0 = Release|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release|x86.ActiveCfg = Release|x64 + {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug|Win32.ActiveCfg = Debug|x64 + {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug|Win32.Build.0 = Debug|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug|x64.ActiveCfg = Debug|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug|x64.Build.0 = Debug|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug|x86.ActiveCfg = Debug|x64 + {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release.DLL|x64.Build.0 = Release.DLL|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release|Win32.ActiveCfg = Release|x64 + {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release|Win32.Build.0 = Release|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release|x64.ActiveCfg = Release|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release|x64.Build.0 = Release|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release|x86.ActiveCfg = Release|x64 + {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug|Win32.ActiveCfg = Debug|x64 + {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug|Win32.Build.0 = Debug|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug|x64.ActiveCfg = Debug|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug|x64.Build.0 = Debug|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug|x86.ActiveCfg = Debug|x64 + {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release.DLL|x64.Build.0 = Release.DLL|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release|Win32.ActiveCfg = Release|x64 + {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release|Win32.Build.0 = Release|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release|x64.ActiveCfg = Release|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release|x64.Build.0 = Release|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release|x86.ActiveCfg = Release|x64 + {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug|Win32.ActiveCfg = Debug|x64 + {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug|Win32.Build.0 = Debug|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug|x64.ActiveCfg = Debug|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug|x64.Build.0 = Debug|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug|x86.ActiveCfg = Debug|x64 + {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release.DLL|x64.Build.0 = Release.DLL|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release|Win32.ActiveCfg = Release|x64 + {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release|Win32.Build.0 = Release|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release|x64.ActiveCfg = Release|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release|x64.Build.0 = Release|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release|x86.ActiveCfg = Release|x64 + {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug.DLL|x86.ActiveCfg = Release|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug.DLL|x86.Build.0 = Release|x64 + {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug|Win32.ActiveCfg = Debug|x64 + {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug|Win32.Build.0 = Debug|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug|x64.ActiveCfg = Debug|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug|x64.Build.0 = Debug|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug|x86.ActiveCfg = Debug|x64 + {8062B50D-A609-33D0-8223-81D898DE05D5}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {8062B50D-A609-33D0-8223-81D898DE05D5}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release.DLL|x64.Build.0 = Release.DLL|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release.DLL|x86.ActiveCfg = Release|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release.DLL|x86.Build.0 = Release|x64 + {8062B50D-A609-33D0-8223-81D898DE05D5}.Release|Win32.ActiveCfg = Release|x64 + {8062B50D-A609-33D0-8223-81D898DE05D5}.Release|Win32.Build.0 = Release|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release|x64.ActiveCfg = Release|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release|x64.Build.0 = Release|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release|x86.ActiveCfg = Release|x64 + {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug|Win32.ActiveCfg = Debug|x64 + {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug|Win32.Build.0 = Debug|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug|x64.ActiveCfg = Debug|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug|x64.Build.0 = Debug|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug|x86.ActiveCfg = Debug|x64 + {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release.DLL|x64.Build.0 = Release.DLL|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release|Win32.ActiveCfg = Release|x64 + {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release|Win32.Build.0 = Release|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release|x64.ActiveCfg = Release|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release|x64.Build.0 = Release|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release|x86.ActiveCfg = Release|x64 + {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug|Win32.ActiveCfg = Debug|x64 + {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug|Win32.Build.0 = Debug|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug|x64.ActiveCfg = Debug|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug|x64.Build.0 = Debug|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug|x86.ActiveCfg = Debug|x64 + {A6947A93-DFD1-060E-F426-AE10230F7861}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {A6947A93-DFD1-060E-F426-AE10230F7861}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Release.DLL|x64.Build.0 = Release.DLL|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {A6947A93-DFD1-060E-F426-AE10230F7861}.Release|Win32.ActiveCfg = Release|x64 + {A6947A93-DFD1-060E-F426-AE10230F7861}.Release|Win32.Build.0 = Release|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Release|x64.ActiveCfg = Release|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Release|x64.Build.0 = Release|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Release|x86.ActiveCfg = Release|x64 + {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug|Win32.ActiveCfg = Debug|x64 + {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug|Win32.Build.0 = Debug|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug|x64.ActiveCfg = Debug|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug|x64.Build.0 = Debug|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug|x86.ActiveCfg = Debug|x64 + {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release.DLL|x64.Build.0 = Release.DLL|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release|Win32.ActiveCfg = Release|x64 + {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release|Win32.Build.0 = Release|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release|x64.ActiveCfg = Release|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release|x64.Build.0 = Release|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release|x86.ActiveCfg = Release|x64 + {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug|Win32.ActiveCfg = Debug|x64 + {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug|Win32.Build.0 = Debug|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug|x64.ActiveCfg = Debug|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug|x64.Build.0 = Debug|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug|x86.ActiveCfg = Debug|x64 + {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release.DLL|x64.Build.0 = Release.DLL|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release|Win32.ActiveCfg = Release|x64 + {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release|Win32.Build.0 = Release|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release|x64.ActiveCfg = Release|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release|x64.Build.0 = Release|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release|x86.ActiveCfg = Release|x64 + {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug|Win32.ActiveCfg = Debug|x64 + {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug|Win32.Build.0 = Debug|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug|x64.ActiveCfg = Debug|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug|x64.Build.0 = Debug|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug|x86.ActiveCfg = Debug|x64 + {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release.DLL|x64.Build.0 = Release.DLL|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release|Win32.ActiveCfg = Release|x64 + {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release|Win32.Build.0 = Release|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release|x64.ActiveCfg = Release|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release|x64.Build.0 = Release|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release|x86.ActiveCfg = Release|x64 + {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug|Win32.ActiveCfg = Debug|x64 + {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug|Win32.Build.0 = Debug|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug|x64.ActiveCfg = Debug|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug|x64.Build.0 = Debug|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug|x86.ActiveCfg = Debug|x64 + {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release.DLL|x64.Build.0 = Release.DLL|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release|Win32.ActiveCfg = Release|x64 + {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release|Win32.Build.0 = Release|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release|x64.ActiveCfg = Release|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release|x64.Build.0 = Release|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release|x86.ActiveCfg = Release|x64 + {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug|Win32.ActiveCfg = Debug|x64 + {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug|Win32.Build.0 = Debug|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug|x64.ActiveCfg = Debug|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug|x64.Build.0 = Debug|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug|x86.ActiveCfg = Debug|x64 + {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release.DLL|x64.Build.0 = Release.DLL|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release|Win32.ActiveCfg = Release|x64 + {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release|Win32.Build.0 = Release|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release|x64.ActiveCfg = Release|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release|x64.Build.0 = Release|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release|x86.ActiveCfg = Release|x64 + {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug|Win32.ActiveCfg = Debug|x64 + {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug|Win32.Build.0 = Debug|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug|x64.ActiveCfg = Debug|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug|x64.Build.0 = Debug|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug|x86.ActiveCfg = Debug|x64 + {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release.DLL|x64.Build.0 = Release.DLL|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release|Win32.ActiveCfg = Release|x64 + {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release|Win32.Build.0 = Release|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release|x64.ActiveCfg = Release|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release|x64.Build.0 = Release|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release|x86.ActiveCfg = Release|x64 + {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug|Win32.ActiveCfg = Debug|x64 + {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug|Win32.Build.0 = Debug|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug|x64.ActiveCfg = Debug|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug|x64.Build.0 = Debug|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug|x86.ActiveCfg = Debug|x64 + {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release.DLL|x64.Build.0 = Release.DLL|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release|Win32.ActiveCfg = Release|x64 + {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release|Win32.Build.0 = Release|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release|x64.ActiveCfg = Release|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release|x64.Build.0 = Release|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release|x86.ActiveCfg = Release|x64 + {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug|Win32.ActiveCfg = Debug|x64 + {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug|Win32.Build.0 = Debug|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug|x64.ActiveCfg = Debug|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug|x64.Build.0 = Debug|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug|x86.ActiveCfg = Debug|x64 + {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release.DLL|x64.Build.0 = Release.DLL|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release|Win32.ActiveCfg = Release|x64 + {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release|Win32.Build.0 = Release|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release|x64.ActiveCfg = Release|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release|x64.Build.0 = Release|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release|x86.ActiveCfg = Release|x64 + {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug|Win32.ActiveCfg = Debug|x64 + {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug|Win32.Build.0 = Debug|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug|x64.ActiveCfg = Debug|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug|x64.Build.0 = Debug|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug|x86.ActiveCfg = Debug|x64 + {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release.DLL|x64.Build.0 = Release.DLL|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release|Win32.ActiveCfg = Release|x64 + {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release|Win32.Build.0 = Release|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release|x64.ActiveCfg = Release|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release|x64.Build.0 = Release|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release|x86.ActiveCfg = Release|x64 + {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug|Win32.ActiveCfg = Debug|x64 + {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug|Win32.Build.0 = Debug|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug|x64.ActiveCfg = Debug|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug|x64.Build.0 = Debug|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug|x86.ActiveCfg = Debug|x64 + {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release.DLL|x64.Build.0 = Release.DLL|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release|Win32.ActiveCfg = Release|x64 + {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release|Win32.Build.0 = Release|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release|x64.ActiveCfg = Release|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release|x64.Build.0 = Release|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release|x86.ActiveCfg = Release|x64 + {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug|Win32.ActiveCfg = Debug|x64 + {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug|Win32.Build.0 = Debug|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug|x64.ActiveCfg = Debug|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug|x64.Build.0 = Debug|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug|x86.ActiveCfg = Debug|x64 + {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release.DLL|x64.Build.0 = Release.DLL|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release|Win32.ActiveCfg = Release|x64 + {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release|Win32.Build.0 = Release|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release|x64.ActiveCfg = Release|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release|x64.Build.0 = Release|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release|x86.ActiveCfg = Release|x64 + {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug|Win32.ActiveCfg = Debug|x64 + {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug|Win32.Build.0 = Debug|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug|x64.ActiveCfg = Debug|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug|x64.Build.0 = Debug|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug|x86.ActiveCfg = Debug|x64 + {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release.DLL|x64.Build.0 = Release.DLL|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release|Win32.ActiveCfg = Release|x64 + {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release|Win32.Build.0 = Release|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release|x64.ActiveCfg = Release|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release|x64.Build.0 = Release|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release|x86.ActiveCfg = Release|x64 + {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug|Win32.ActiveCfg = Debug|x64 + {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug|Win32.Build.0 = Debug|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug|x64.ActiveCfg = Debug|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug|x64.Build.0 = Debug|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug|x86.ActiveCfg = Debug|x64 + {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release.DLL|x64.Build.0 = Release.DLL|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release|Win32.ActiveCfg = Release|x64 + {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release|Win32.Build.0 = Release|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release|x64.ActiveCfg = Release|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release|x64.Build.0 = Release|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release|x86.ActiveCfg = Release|x64 + {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug|Win32.ActiveCfg = Debug|x64 + {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug|Win32.Build.0 = Debug|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug|x64.ActiveCfg = Debug|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug|x64.Build.0 = Debug|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug|x86.ActiveCfg = Debug|x64 + {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release.DLL|x64.Build.0 = Release.DLL|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release|Win32.ActiveCfg = Release|x64 + {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release|Win32.Build.0 = Release|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release|x64.ActiveCfg = Release|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release|x64.Build.0 = Release|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release|x86.ActiveCfg = Release|x64 + {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug|Win32.ActiveCfg = Debug|x64 + {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug|Win32.Build.0 = Debug|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug|x64.ActiveCfg = Debug|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug|x64.Build.0 = Debug|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug|x86.ActiveCfg = Debug|x64 + {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release.DLL|x64.Build.0 = Release.DLL|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release|Win32.ActiveCfg = Release|x64 + {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release|Win32.Build.0 = Release|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release|x64.ActiveCfg = Release|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release|x64.Build.0 = Release|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release|x86.ActiveCfg = Release|x64 + {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 + {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 + {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug|Win32.ActiveCfg = Debug|x64 + {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug|Win32.Build.0 = Debug|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug|x64.ActiveCfg = Debug|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug|x64.Build.0 = Debug|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug|x86.ActiveCfg = Debug|x64 + {F26CA968-C7ED-4246-A732-388C23BF8822}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 + {F26CA968-C7ED-4246-A732-388C23BF8822}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Release.DLL|x64.Build.0 = Release.DLL|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 + {F26CA968-C7ED-4246-A732-388C23BF8822}.Release|Win32.ActiveCfg = Release|x64 + {F26CA968-C7ED-4246-A732-388C23BF8822}.Release|Win32.Build.0 = Release|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Release|x64.ActiveCfg = Release|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Release|x64.Build.0 = Release|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Release|x86.ActiveCfg = Release|x64 + {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug.DLL|Win32.ActiveCfg = Debug|Win32 + {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug.DLL|Win32.Build.0 = Debug|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug.DLL|x64.ActiveCfg = Debug|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug.DLL|x64.Build.0 = Debug|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug.DLL|x86.ActiveCfg = Debug|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug.DLL|x86.Build.0 = Debug|Win32 + {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug|Win32.ActiveCfg = Debug|Win32 + {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug|Win32.Build.0 = Debug|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug|x64.ActiveCfg = Debug|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug|x64.Build.0 = Debug|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug|x86.ActiveCfg = Debug|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug|x86.Build.0 = Debug|Win32 + {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release.DLL|Win32.ActiveCfg = Release|Win32 + {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release.DLL|Win32.Build.0 = Release|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release.DLL|x64.ActiveCfg = Release|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release.DLL|x64.Build.0 = Release|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release.DLL|x86.ActiveCfg = Release|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release.DLL|x86.Build.0 = Release|Win32 + {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release|Win32.ActiveCfg = Release|Win32 + {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release|Win32.Build.0 = Release|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release|x64.ActiveCfg = Release|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release|x64.Build.0 = Release|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release|x86.ActiveCfg = Release|Win32 diff --git a/Win64/proj/actor/Debug/Actor.sbr b/Win64/proj/actor/Debug/Actor.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/Channel.sbr b/Win64/proj/actor/Debug/Channel.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/ChannelAddress.sbr b/Win64/proj/actor/Debug/ChannelAddress.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/FEM_ObjectBroker.sbr b/Win64/proj/actor/Debug/FEM_ObjectBroker.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/FEM_ObjectBrokerAllClasses.sbr b/Win64/proj/actor/Debug/FEM_ObjectBrokerAllClasses.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/HTTP.sbr b/Win64/proj/actor/Debug/HTTP.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/Message.sbr b/Win64/proj/actor/Debug/Message.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/MovableObject.sbr b/Win64/proj/actor/Debug/MovableObject.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/ObjectBroker.sbr b/Win64/proj/actor/Debug/ObjectBroker.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/Shadow.sbr b/Win64/proj/actor/Debug/Shadow.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/Socket.sbr b/Win64/proj/actor/Debug/Socket.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/TCP_Socket.sbr b/Win64/proj/actor/Debug/TCP_Socket.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/UDP_Socket.sbr b/Win64/proj/actor/Debug/UDP_Socket.sbr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/actor.Build.CppClean.log b/Win64/proj/actor/Debug/actor.Build.CppClean.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/Debug/actor.lib.recipe b/Win64/proj/actor/Debug/actor.lib.recipe new file mode 100644 index 0000000000..a53f9611dc --- /dev/null +++ b/Win64/proj/actor/Debug/actor.lib.recipe @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Win64/proj/actor/Debug/actor.tlog/CL.command.1.tlog b/Win64/proj/actor/Debug/actor.tlog/CL.command.1.tlog new file mode 100644 index 0000000000000000000000000000000000000000..d50b3e41da95765a765f09ce0f27e5f2d99d783f GIT binary patch literal 128506 zcmeHQU5^{bv7P4t`47gv+k)d4LvQ;*Zq^c)yj;?j1mYTktRw~$C6ILyJ3l_T=S;EP zU&E;$k}C(n!D4s$G2PSM(_K|vb^6r5|MkD!b@#N}bvNCt`xd{?yJfe+d;Xnu_uT{j z&hU4K-!-n?b(i?N!T0NfufM<*EBySv`(5{>d((Y}zjxgi_}OKDLyZg6xxro5xatxu z;Js%3UG8w7d%R!c{i^?KElI!iYGIC6^J9(nTzAj*J-x!~sWq(dOl`)cGtaA~<>@|0s}}g( zV76@fJ{~h}^;{gPcZX*l?sna;8On$0y|~A$;i}v0*Y86wYbaURkC*7rvj60{TX*@S zHr;pq+zI9R{GUy(g|%Mx?OXOzf>P)jvvP({`TDr^ZoS^3h2?Yg*Lm4b){=iVy$+5( z&fdSXFRpQCC1ZVEoEQ%-egLYB@5KYC$Pm+xp(hh*2uQ= zvoP|9t*Npkb@l_s-d4zIt(c<+v;z4IC?BWQR?CA@gU``c*6csmvX^Wb?YevXr!C7l z-(uI*Z90cta=dPidfjy9sTN{dAIHU>p!K@VKB`A3tuyHLX_c;mbO;|JuqwoHP*NU2tKvE{%MxH z*P526<<)U`O?xHH8?%D_y2G=e_U7v;rS2gg7JIw!xY0blhEx;nFo%w}Lh7fH*Ug=S zjT2|PuWP*e%#X_zNNA4;_7)j8~2NN2n4PpRXM^O11=GOiGJOhZ0}(6aN!fKI!&c|$4Lym^(cy&d{{ zN}u_(Ia+hbIquJXtGiP}y+m6+bqmZ_>1&bWM*XoyGkBub{VvDX=f|~v2MdWldXwBi zk3LqP+WmB;WPGd^<)h}^CDm2*+E{FJS}BtPAtvIL&D*!@UiIsT{^0glZCMBH#$#e9 zoF!Y>HokRJ-Z4n%ub`i%_BfRNLqpke*3^+B@9wD`OFu9pR&7!Cv?Ngj9H%x7M;`#? zGBu)aY5RR-6l;b$`IP-<)lwfv!E9S^{K_Z)HS`Ym0E}l$kFmCwZ0W`7sL|!qq0O@F z?W?K%|E4cTpQcx`?t$GoU#%AyN8)bGJ8b(s`dOo&I9NUx`#ZLm*!5Nd?YV6~d#r|6 z-H&}u@4LTs@9_I){IW0KbzklOzd(GBpZtI;U*mgT`BV21@8015Q~YJg|LgvWZ+P7j zSK9wy_9ZD5zVGizJJxVA_8INGtNvC z^zQ>|XFvbmy-mLP5j}o~ad^M~bdD<+`^@o7wqMToAY8pR7Eksu&pFyOy=;_9UtrGM zpiXH8A~Z5$C@THnH;<=C>+TPX~h$?kH_@Vzi-!9ou*skVxQL90(+1pJyXXdD4s zUyKh5gLVk##(m`28K1-Wfnn5KirQgW`bNg@P{$PMKM)2@7_=6YrZ8w@7*=7>C`+gd z%qQ7`M->K*`@*0-Yv~*?f$^-0C*cq45U*s!oe6_xXLw7zi!f+mriR$LFlZ?bD2z@X zIcL0v(E)G$<$F`_YTKg;gC-2x&YK@$e89Zx6>n&GsJU&PZtxwdK_<-DAC zmt2zygVq{F3OF)h(1x_5FlfP2%~vDO(Y2!2>KH*C1s4Wwi6}17g!IhTs5N2Ggh6`( zG}&*9LCY~=V;Hg1uxL5LxV%sPt&nLg@|EZCgiI4VTF~Y#b4JLtl;=>$wA4Pf*I_o5 zwxN(|fkV&RwU#3%WLiG6giMS3_(Q9Wb4bWEA=5lrQ|o+Mg@#rWGA+i|g-jb`VDo0# zVN`*TX>pE?jZ)-!5<8mD>^U})DH}%M4-_&@$TUMB=Mkg)osen9`C9WFd-7k%G_j+J z9j)HAe~y!UO19j%q=PRKMN)0m@#Cu(AjF0rGH zou#b(q9s1b-}9t7+{BJX``@w}i5-pXv)=qE*Q?mk#EvF*v}u_$Q>ojI7&{H8c8Jm4 zm?kZs%`oS?P;0){Jx@%s)a6#IF?}niXIsvyQa>?wfpU5>8&$-}DW~T+pGdvljmK3v zJ<}a)&CE=B#na_}#;tOdj$_G`(^EM;Ee;yFa5>lLi)O4sIX#cdEUKKIb?mE_{SkTQ z?TyFEp2tFrZK2OXIXyYz#?QkOY0Bw2gd!53TFC+?)S7a79%3_$SvQr_lbn~S^P!$VBb?t)uzM={XcL6rY;-)RfcnqL;w`xj8-0gCF~?Fl_XfJO>WQ*hiT6=>a)h zuYpupb-(X^2i^C^)qu5xFY`yypT(@ctex?`8SX$Xvn5awQ}ycuvgoeCuE>Ztb#H5) za_aL{9}}}2yr-eb&l9z*H6i1e!nKh@^VsVlFAdB#|rDGp**2Mt|(9Fm{&QE z#w$sID3{UfZo4I&;wt+mMBbHpTtT8rpK%jwLMALb_&YONjhAMt5vlskSZ zHn#DTC-r(4YE7s$;?cOPymM{!(#jWV%`kO_qqCVrYlC=`8P0?eS^TWYYZ5)z-2ID< zZGpYx5|}!%u^rNmS6H*$UteLIINPT0v!f0@r7Y*GP;2&-ltXk3XXeea!-xar5RE?J zu~8CgO{g`Y*5X>Jqx?dx@hn5|+Vk8Xb=JCPK=osLt>Za-{=}32Ewy`f9F~q=Nukz+ zTD$KpX+Lw1P-|mRQK8nZ-Q8Ha-;b|78C6S2q1J?26B}E~6+xSZ{x_l4gj$R7-cUts_x6H+eH;WN;vh`7`4 zA>WM!KkT^7n)Mk~T4tWO)5M(?IJU}YP25LvCJBYcoze9D(+y-8*^t7yH=)qdcyTSG zghI>LVLd{rjc~fXNxZh_QxXbIC^T=5)R9C+ZRg$h{izf`>-b@u1-VTF3lzOrJ~Fj6 zhDlz!l&Nld9~Wp3`I(;g7??ZMx58_`g=4+tZh-h(p={^Y)B@9sjO zjm2hjc_{9*A)Hh?f8%R!-ql*O)q*>8mT6jkmuSUZ!4_haw2gDqJpFcUi)1`>pMbaW z#!1|1;!YC^O(-;>(8`#ICpk-0i%@7|mQL++EF<0Cct_pO^XxbHp{{Jvu*%ua-GjK(Ql`TT_*|a$kyY-i?4%YWs+6qs-_g#nEJYXlJzIMT9`q%xJ=-9oqHI zA-$QWJw$5AAwpk-=SQfu<2mdS`tFI~oqqQc@1=a6#Ow-_CQO>Qmg=}7W4OYk4etu3 zBBO*!6Ej*o=Txt?fI1T>kmuawxlgWv z2j~|*WwRph@Y+Z0)@vuP`#Ea1-rx5qU2mkk`c{~WmVH;4w0wt|W4yRt`9$s6((kds zJ8$$;l#X|8eLv!WjenVUn^r#Tbi7h|e9*hvW-_Jti;3+?d*|Jyp0g1xHC}f7+ni55 zdJz0lWqxX5(o)Y%*mb9~-69y2e#T7Tjd4B?+w&n>WY%=*3U{-3?KI5adGBo}bm@=! zw0&mZDVOH(PSXSVTiu-+>LuFpsatT3dmiHfYs(4wSfd#{QOu#(a$4xvxtdDufbD*) zJ_(an#zdx$v@mJHq?wPHwib8KLzyeNGa%ypvcVFqJ=rCWPt0hvS;UMcOxm07FF@UW zzbOt>lr$!-bO=Nx+&Z1k?@9(5qTFSd{jxz4cebQ||yHB$- zcKu%K)J$2zsT~swuV;;LYFszMsl`ZC>UAvlWWuQlr)K+d+G?e>7JQnezePATMnaCw zoyqK@$9d_*oi@!<5l$_S=G7J=b*1@OELK7P`SJFqxYMEp4YG3@ipcYkPOFX2l#!Tq zzYk?upCz@9J6fD~hP{IE7&D&bwX?1zjo?o&O&dlywcM9-+zb1AHg65*yN>*wxYNX)MoZ%uJtCZ%xYKGYE0-_AsS#mo*1m9R z!l|X6onSQzrzY++ai@tpO*pkOCgSaEN^iJuYSX;3Wz5nW?;J59?leQfkwNaVkKudc zSI*b3;o)d!Kr2hPm#n?b<&)>i^EsgFdg!4MPVEUWNy4cKr^faFxHz@baAT)o))*}% zT4@Pv9@l()Cu~|R8EXkEY#Qx{XV7?diqO-R^_b@8sKlW*9EGaKt)7d*rU{#tBNB4I zt@3&@$E2N+pT@2y4mILd#G!TxufMQq<*Bh!gSY#<%H6Lx)M8}GctFh?k>bdB7G^r< zM{Pf(b@H{aX=BJ0p8F?8D)6@!#i2&K zJ1|9g)=cTwYvaG;IT-E>m;zsJ^VYyb<)QF5s>OB%iU)9)6L z=@zYKes@O0$pgun$-lAeKY8xfU0U)R;9rSg4CNW6cs98f)=H*aF{IH?8)oC!j!O(_ zVn{PNAciz!uq`E1lqoSQuuy2VCK3v*^h8h(rR-y;T8L?VLZOiZ)lLXnM4Z`QX`j#r z2`FRF!kLP(5ekj-Sqy1uR4*X@Y5k^rbl%*n5eLzFrtNlz`c}O^-m7WqELJ8@F{H)a zK|K$NauGvX*gXk_7UxQeCyTE=`4q2YyqD64r+>tdR%5B^wI~!?8w*74;}AnyJjWsw znoww|y&CkI7}CU$CWbUIq_v+GEq#8T-B)^2g+hy#bU8M(^LWaA>XXkp*x>r+Zb;nBp37Ol;eIU_t;Jo&;iYr>;N|8$6P4kKi^2Vn+#p0sY^ z707+H`3WH5(S%2{{h;t@!>dhrv>|VHt>J`66CRCtFweWhSfO#uP>)fIJsiRBmg_V| zyoE;_%0QSRq=;Km#!j)K36CZ`THLGF7#QKv($hS`qs6(BBFo}yPvgfcg-3gWoqK9e z=R5s+Eeek&JX&0Tc}&?`ceY0p9!+?(RN{oVhVW>@qX~~DJeu%m%Gl{y61m;6>(7%g zH;C|P7Bi^5;WcNCSkZ=1bz(&mE7}vpvH#kA-bW5*;Kuq1OlOoxYoG$IJF%iY>E3of zcOUWh19G&!?%s7zftL8HAEVnnSKOz?qj^ZN^WxIBh$;z}7V;#9{acI95iU*HI#XYE z%bXD|O}I4fil?7&5iTvT=}p~F&3iu(WceLh$eC9Yy4++JK@rp3*@fPoJKt467RebZ;fh-Cv669US;c4 zwobF7a^!ISjx2z!r)rd~GxaRg$fX)Z=t;E0I>alPBFy6JDW$}dCS2MON~V+#Tf{!o z&%8O7Uc1AtmYnjKkC6db%nk39d^{@v|hV*Ch^bQKeaMQMpoVYJ|Qoq*UogdbDv=R$Ctfr?3K;u zVSBbi^EZ_lGpCL3dGD=koyykPK7W<1Q`tJpY@*86Ieyln_7sy2NjF~5eLafQ;%`!YQjReMSQ$rBO!(zT50dT1xnW)V-Cc+$j^#`XVcacLe>?Ee9u C`OzW( literal 0 HcmV?d00001 diff --git a/Win64/proj/actor/Debug/actor.tlog/CL.read.1.tlog b/Win64/proj/actor/Debug/actor.tlog/CL.read.1.tlog new file mode 100644 index 0000000000000000000000000000000000000000..d6d1c1b09e077086bbf70aa93efe00ec17dcdd11 GIT binary patch literal 251234 zcmeI5*>W5?vZnL8&H5d5*?n-o zr`2cs{b29kZG8OJK5=XR{<-=`k#GO9_ctG}zSusl?H@aSGAQHcZ|&Lsu%8%C?>gLp zy>x}o_Fn()9P3@Ztn_(xZjYW;>GL^Oh|m4X&i}h%@W`-tYLAarf7t)f#nhFK?VCOu zjosUKu!sA}-*jbv|6rKESUq-l=$}o6jk|EadN!!I9Y^;4mwUh`N;~N=#~lja&d#Bi z&vtexq__6^jjevyz4vByW_ttg_p3Lnf7vd7U;VcFw|&zOd;Qwz>c$@N-dB76V2_?w z?^o~aH}8VyZ}u5zgje5oKOa^f>^nZ#D?ER)PaNB75B5k<@t5b0pgOiaf-6Be7F*nk zi|%i3Y+pBq#|OjGcYE#LcFd{1>GlhLF6{j$!^k`P`CyM&@yh;vGfaThpZ3~!d-cg4 z-`GDWg73e7dG-D3li}-={q5V;NBjSi{r+g5$j^Z9xa+?4!QSK69`bJPJ1idZ4mf9S z$u~O{D2&HH?Np(TL*5tMnp=Nndl|cr^4ul8$Il)8BU|na=iZ@2$N6be!4p1DJF2}l z435R#Vemw-ESc_E4n22r*CU)@4~^r(w3o4zQRDW*Wzn&Y9Ycvl^x5ti8oeJ}>V(DN z{XmuTcl6TTDbXX3;x3_0qF<-@9&bsfmI~H)u&n3##tXai;hXle^Hb|Jw`S+E_g`CO zf2%yTilHm4D6~7Q=76iYJR+X0kddbU@33qSruz}SA& zm3l*R>Pp|8i`LR_eQixq-hR8>gu^jdp2wfI4+M2FAibdX5piqhqJ-&K8HQ?qE;SvZ za36Q&VEBxXMtCRi`Fykcp1#)ei}iQQty*fWbZ_yqse9Sot2bUx=y9KV-#yEh`E{G% zC*9_SZJyHHf17IHDRpngmPd`dc}npV`|(^iPwA3znDibuPwBpKt>!6RHjbFnuRK9S zX?=Ngr}(Fur&O`x{EVBY6diwDoIS@~^OO=#4>?C<>EMYX9!pk2`aIQY$JshBS;r04eaokz1$g9kyWC+ zBC^u>bh)*+!8Uc(Bijc#FjN12JjTe$AXAKN88BP}gZb$}@At+Tl-o0%>i5S&eMrcL zf}>sjI+^8Rf+}?PepWn_I#6JfKHBb23m34S)vF@jrZ#?R73x1#M=h)Vm zdh54;cmJ+-(yv=)y(`P+DY>6}I}7v&G?}?}Bw5c{Ty%Gi%uVtWKN}5%SHv%oHsn4Y z*>7Uk*OO0e%$hkA`QJ=E!TfvhQz8p`49xe<`5vAOcQ=OLW6Sd41m|6O&V1z@vLUKC zvRxb%rh*h-XgU|B4?%m#hviO+73HfdyDB=sz2TLd;gY*cZ*+dzORoIQ&Jn&Mj-tG% z<<`d*<1XIW>2h21tg-QyV2;C~8IpMaY?M-+I^+=fZRN=u;kh& zwk}c={4BYys-M_1x&BM8j5VlRg|2Y1_|B20)O}F_fpv9lP%Mi9>VQtV%xdudY;_Y~ zi}F*gC+mwCn{4&>2E+DqKdksEnmW2toS$-7JNRi9KQ}VZxIENdJe$N)9aGA^4{JY< zUAEv)+shZbImc^vb@OhPh?@|ZI5ACkeD&I4lyv-xg%JR2g_p^o)X>Fd;d$V4J< zjml&T9_mi8;IZeQyZb_xJK1B0x|?Hz9i3KM#i8#)cmGg#p_9-a#&Y2Dk{e0AYaOje zF1nua{cN{5=SpMo?s12wCbh@HU!HD)HzH_!imMSrCSt?0v9Nl?H8Skp?64okIS-ZJ z1m4eH#_XXy%>)iOzT-rBm~uJ}xs+gSECnwQWsgbu1r@VAY`>N0HDq~@p;(WcgNVOs z)9;+zx*i_C^bCyH*S>EZPzL+JGcL)ZQ^&Ks$KGbkczGU12Rh$8mO5SV==rR5qS)T_ zrtl0Yo&kIveqg*eTVIs}WTASxD*>{=ZN{IhN0}IQfo*U$QXBQSk0Bc~-`iN~_PD>t z?tUJ+FEZ}7bhujNnR#VyI<7Qk59OtI56>Y}I9*}-UR+}^>+zl{nt!O!KXz12OpP4# zL#C!j%cKYyt;m5xJ&|XNc7$%k&vq*E<)s-%X^-~Jc7(_K^7l9;v?tC+wHgWh0B9_k*_8${jAgPlyEJ8AESe1p>c(E~BiVxU4zNKic={3G}!v8&SuY2D0gIQm;S5Gvf&A*u}&yq+VW|G%sD9*=qRf&du^B z$6tAoa3$_<$#Z6RA=*lx8ezT1M9H<4H325^5iNb%U%Hrn&}+bcsAXP8#~NDy-p+o> z)2F}M5FAUwfNpzhl#jexa@{YscV?1k<&t!+S&-O-)H^P@$8_bm>qW`^a*`)jRex4k zYG|FSMOHbpb1Q56^gXoH@#e-j(xt80cPc4)W>Dp0*Y}1RkCH3NHv+$*6X zXVqrVjpIJW&@S0=p?4A4v3cjc!?IrKV?fn0obT^qgNHc|bkUI4C$&ru>xAO-(T@7a z+F|X49+p_{@L%}gn0=Jbn!7idv|A3j$NU*(BV$uB-wzqXY?*QOEgtuidet`V4lf(p z8+ywj-*LPzoEZJt#@q^zCkCHFo9pX&4|OMxFEUY{kwe`@euF}9k#pk@Sf_NGI`n%3 zt*JJinWjUX_76=$iVqxi&MkIc$Q?e^+e04H7vsq2#l#p=%lNRUD&+*}zWzQL#GII_ z*ADykP`|2ujJZ4I_2U4|A>V*Uv*T}GWW_kU!=r}vXx1#AD>A9Z(1y=F=p=$CsfXu~c@lMQyYZy*n2jMiWZbIS=Fq*G_{t97 zH!Gjt7|!8YUTMP5q3(hlJ1k3CX0cZgj}6sb-27Xc0L5>jHuz_WQS~z$^C-^HTnnwB z&f$5lhIvJ6feNn0-+ZFq&EM>#TRaKg2*Di@!WgiinC+B9pQfmoZ-x{uo6KsZ}1d|^Qw|7Q|&-p^w=<}{zJN@!Jh}09^zRg zVY)R~p6uSz|E}lYW#y69e6YSHORxE7g*9{BmaW_y#_bYo=D1yAO?Hdi`EyN!I;_~K zyjO?sg_CrKpPfgsqj@cwp2CMuzQk(K_P(p7RyrCD^&-l~0_H#M8Cd|E-)kRFUJbGi0>>Iyj}(hcap?4;Rxl28?u_D{m8~SHfYNFo&Gdmu6lK05tm-=tkYug zTI1P|p9R0i`-1l}uQo~{$j_$a8OJ+Mp$K?bb{_a-@- z5O5Mlq?Wz4Jq(-RS(X}y;pyYV%VG!4g-`U(bU0a2$1gn%mZTZ^24$Npxh|cKn8yB> zQL3!gk{a6|w#IdrYr*uduVyR6`!2b1-^l^%Op$0hmXz;a(bKj30iPD-fLJBqdP$n% zT)%eqE;%1ags(6(|G#*z^HFg|`~{6;ct z6Hdy~$GKquUPtE@xL565~7_1Uo3|Y(Z8RMN9hAI42Ic$U#hT%#v6o0lHM4NC?mMd&p6{;YAhTDm( zoHK7V#qMS*VCPH0KtkElz6-X)M^YZX)hG5ejEr%Q8plEBM=h!f2mWK-yd4VaFXHpq{%J2TZ|AA$$;}5dQatxN=oXPJM;#&eRvaDPt_(Cq zdFItG#zB&M$ZBH(jNBVfo74InhlyUw_FQIZY+xS}HP|15G!ACUIH7f! zP=ZUcqxF^MwYq!UmF2nYWoaJPR|Z{lbO%2Nj=3o!=M1_>wN@8j%5TXsdtPSM{(c8f ztaPQhC*kOB49lI;JH-|X-S@firPm{uJ&wREvnDodZ*l3~z_V2kTz=0(>*sd0ypEj3 zynZB6S8w4gy>HzjG)&dpub)I6{4@V%iF-}%vHEC)NBMr=tv=2!D>kh)H-GNyga7P& z8zr=ce2vn3$mMJq4Lsi!-qj_rH}AAQahIXJEQ7_qf-gk6?=4~gk0Y0eTvQ-rt`8Oa z7iQtm=bKqZb5qfDNZu9D759N=er~iG8a(DppVT+Yy~}wp)nD?~(|L$Yy8II*EU#&h zl;9GZAR)_?YD=_2I!5OrZYG}{ku-Vn zxQ|G7bt#Cm9p>)k@Rqopyd+s3&PF;+r)dA@nJ68rghsn{(qf)OTp+8~!hD8hxJDse-<;^tB(#|Cr;u=f*P{o+{{+5z5Zw z!|Sty`)JCxJKtBlPVkxKE{nv z_5-hRlQ@O+{aB82$M7Z-&pMhc%jbk>Gqh9BY)SZ|cUg#Hy77aj{G99Jh&zQ`kWM8|RTmcII-p?|}!IR--GhEEBzv(*D)`jcFaP<&j zt1d9Uf4hD-wNu%#iZ14*ve2s2RX();H` z$lt(UR|gmCt5PS4#(vjvlJ)m%(aKlD5fg%-;W|+D(pnkIeP&XBx7I&{twkRlZX{mz zxw~tD3!)s4-EaE4ufs6(nh&^6>@4N&fnO3CS%=;Sr17or3S-}ek&1U{&I_dImU!@} z01Ekhz$S^rqxchbPCSO7kIDt8J-~#v+s}*k1ljOCjxp*1fA~3}G^mbTNqCM&+RJ&3 zH$0|siLw~XJ>Hxj6(UIA{_#}JZQQp{uNWNn{V6_6>;)S@5yY}M8(OFQ?yz*wSkbP~ zu>yt6g~`9VZ>Q%@EX9UiU4F$f*d5xNBd~y-^)tFzIp1V zw*j*;(A~B@R>Q~*>ou8yzT5d?Ru5d&ugEU6DO~& z6*zd@r7MMZPTY(+p+4hjoucN%%)YQJjh7T&ECDd3E|r?b;^R(jgKSQm_1!MRzEgg) z{rx#9Y5Pj#3W*;Ey;0useLdyu7MquD+4A_@cY01b<%0X2e`ZbzjJ`!TlOc}39WQgz z03nUf~wfoM(~g%}N82(Vw|Q+Qo&Py4$$aXAfwrx#m?lh|d)bK;zv ziN^+SEItK!^e)Wed7oKlC2Sk|b3OjjLIvj$@H7&_L>C04_}9*Sy|T>GKZjggfK$n`{PC*MBTRHyrMro+Tpm4T_Bg@w+^u9=I)c~YxHM1LMFq5tlo zb^dqZbxzEyb8g0ES{etWKo&b7)Prfn*M#UzsOcuu+5f2;C=$RUBJ-I{KB8?8Clj?iWC`zSX?HR@kG zAN|nlbyh8t{kUo8!U5hGGP2{?5Pp4Z8zLE{F`>v5*{(>}`Bn?L@yIXrt|Tudx1v~8 z5!Lu}b3t)so<1T$SGIEhxWu;;4ZbiNt?VlOx8v)W-rGEvHU0OZ3FJE|x7Mj)tj>D# z(SRy)p)Wm}>zjLyK!y`{Q=LV`FT@+-DU_Q(rB0N`FTR91Wk@L)=cMiVU`+ecslL!B zHisbfiPLY!ZRj`e1&?_i_jJp09Nm5CWaF|t1BpoeFm)|Q_7C1N-@fxMW%7vyZ3Ybh zO^12{^dIm`9d@5dKPM&Z3(K5$=5<&?MpeKS6TrXErjfn2{+;RkKVD8oT|WM_b6N5< zh9Ow;44}i1J#=PVsTN&sgJVg2D2quIS~>lME`Rj;AnSZC9+t0@^N(F%nvbj98sAcl zi|h&IxDhcOdVS7YL%sqTP@>EudrWVo{I#jrS1qu(Fq~L@o5)w;89(VaA68BP-7)YN zQzvs9MOF`M7ms$sIBzo0uMd6~$`3w`_Ay<@A{+Wo`$_Mle2aPBOYl6UpH8WJIwW*7 zqneMXw0J|`{~!MjS+V473by#u;a(G6=HBt?pR>x{c(plTn^OXfh3%}9#psUT440f! zeCBiV+ub1I^wR27FOc=PN-6Q@jJO+H6%l(n*DECUIlXxx*oUIWLU8*+waNg!vuE;q zGR5I+ulqg^1WVumNYP!0W7fdHw)OYfza}K8UlM)ARiCYjoU4wfQ==$OKUL!7YbaJh z1u8v1(|6}ugM6ox1-~2F$^DoLf699mZP->b_2uPE&=rs>)MbjJ%j)1&@%MSE$fm=m zEN;K>Q4>rOj&_CKSJ;|^rz@87N`n%`@9&X)_?$qdqf?k4^<^wiq zhj`ik>ZB6f_0kD!!`#aU-r%On#+BEk?~>{RKAuMxxw9x8JK#|%Nt<^WCr^hta9DrfQaOBJG1a&6=O5cY`u75>G^q4%=e^z2 zA@vCrc=HR{!>=3d8Akje=vwrri>cNN<#Bi6Gd`jFVYgRyBDYt)hJ8Z%#W2Xfa%Zgm zeJ4gqidKdWY-q=5R6K_Z(-Cc|7b#!k(Z1`lv(j0$#0o%<-wWNf#v1r;re~Ap_&Ty( zFc+CP))G6y_J-!loD8`QSDgm6KV?CgXc9s9?|Vh&?@XoL{CgD7kJp^U9-Q* zB_#j))^;`Y?o>)lPd%=~39I!rG#~chpX2sNO~}0a8@H}3ZF(PKp^<|UYz`orirYEX zp5E1K-0EZrAyw3SgIa|-sVjvcWTym)fUggJhh&}y$Kl(a_Ws`dUZl@ULLPhp+_p5v z8g@4~uHqH@=v(R4h(#~EKUQ2~f5y!5cTF;xrejC?K z9Se^;gwKxt7EdNgd9Am3hPY7rnW>n3eQkN@(C?R9kth}zp$kgQy<>gLyCxgFCM@!r zDt8EbLS8rd0&BuW1^`jeC1GHK-&NS)QhB?pr@$K?wQd}i}IW#JJVP@SlM9p?Gg&;6BP zCQQ?S_QI4}U>N%B5|G3(0N|T%&2`LfK6A88Fn}kn9t?4OpD5F<(XirkwXj0>h#Qk* z=mXc2&xUS6Sin%+vwa`Dj(bTQD8@T`r4RD@YqjiTPvN#L%kvC;AL_c@mZLJf|0BNDgW? z;W{3Gh|g28$z3MTdV25C{mvwYg}X$Q4Bfi)S$#3yz0@kpa47BQ)G8(LTT3@uYKQr% zOYV4BDl9`k!)w>yeSRJ_v5~{FBz9`@UfsuS5G;*}<#~ROgY~s*?S6SFvq{D+g8{sh zz5S5i#?qW&`|8VJKz?m}BzKmlQhLX+g}m&_>1s=#bh`RBzE}DL)*)HvKJ{Q&lK+HW zcIi-bQO>y?aK0}5j6`IrKT8fu+g|L43KksWwgq`lDs;-6a0ukBh%fK^?mnBXF z%DlC^32%TWhgy-cYwLb|=_V1u8L;2fZyR`~u1%JN&P+3PsK2A`f;?8O7@kjEA%;>> zFLf8f6M&VbsXBe822=i%kk&Dlhk?DN zIt*BllqZiY$enqpEniK~@w_dy(vVCov$tTmzzajZAa+;johr9UlmjOzzasV|^^;4j zB#f#@Noi~CTZgMl7Mk6TxfgbrC{}e zYr3Mmv2&9Zik9%E+b!5(zfXpbclPta9ba~OY*MNG35T`)%V?$ z<4^XtZ%v#1WdAs!5T|cJg&8I*L&Hy9Y4EU?g=Jrw%}#QJLd<=l=l!b!9pTV zx%(;s*}w>z2l6NoES!-ruX= z2H`EXi@ab@kO^yKtt0t=c5(K)9x%Zr&OommO|9~CmZ2smc;(1~AOeTfo&*&&wAFQEo8!Jo`m|KDbAmnc(SUm3N4I$Ajt#vY5*7eW>Fg)yjB4e!jr! ziMtFzER1@BlDU6aSbn%m3{idGk+jPnhNT~tr~b(yohipHRBWQhc{)vKU0Kak1pMr1 zjn_QE7&J|FJivzb1YKO=Le9T>+TR%G3tZ2KOv|+bzmVoM$!Xsjm8!FmI?8j8eBf2O z6&;RMry<((AwyChta8I-@vc{@i$0dEB_fY0;O(#Oe0|+*VeH&AXD@cGAo|w%cIw}N zl)fHJE2X1G{n$g$3a~A%yV$P}UV)v6?HFj@mmKSJ#y#<{_$(y@e4M3jVvtJ8(eM)2 z5>#XXQ$OvA%7!5GVnqzW_R)!!A!^$#m$p=nh;F1{!7EJ-l&3q1Mpi$^RalaC$W6@q z)YQ_qL`mdCJ($g$_Z?mys#J&g(Mjz3^prw%++{#fZR3N^m67EMmMfDqUf`kssuxLo zx%$g)8nZ9dEz1Xv=vWZ@ExbX6B))P&Pgf@0m|N(_1Iy_V-Dif7U#Prjb()q=uZGa= z(Hqu$Y3LqpQ(_L9LrtHSude9++I;38yIwhU^UP9>g)W}nv?#%JVsPdCq-txOF=Sq{ z-UJgpx$65KhiEHgLDbiYhoJl1={IDL_|R>Dkt&pso96>6*@Eh$Tfeq3_Vk4cc29Vs zBNu+Y`u^>d;*X5Vy+Ecju?hOo6;-@H=d$?!hF@Vh*yxKOPy_fKUx-P9s(Gz9G=jQ`YF|GT6NFFP^@BXNqS{}jW16SWn>Rp2J8_n>X{6Ulu3UAzseUF* zYA>i)86BSKjqNKdMqT=S&=vO7qZ5w;neATU@yfEN!#Wa$I{f;%9w~*>7xqI3S$&^+ z3K^CMDe*8*IU?FY=hh$>SbbK(c5V=&J zli?H6v>4*|ni@k6yg$g+{mc7J38IF0+eE>6W(B>rN}Q80o)Wof+@JIA?%`dae_ncK zB0c8N{S*deaZJ1IYjPgtr ziS#t@W(dmASzD8RJwY4ipS0;b z9EPz?=hV|#;_|7w^_4?Mge%w(weM~Y8_xr5^>eeg zLD#19Y?l-%?qpee>N_*(YU-UI`sZHm>BIaDi+RofhWhJG&t+o~}3Du_ajFshW zI?wKL;GXuwB*1tINt@2|nvX$uG|oTrC9T8-+jO3NyyrUO_+Eq>eoywZpp0kX_>f;Q zMD=|~!cv>gGbLLPS&>gd3EpT=T(3>%xnJ$i@1zm;S^@rPDtP?O5z1*2T5QvKsBPL+ zA51-pp(7X>?QJ^GcE5U%EAj`l={&=6>Xg3Pbe?Uw`SKdJ={&pgu=pmbD#wQ&EN&`@ zLXJlL+$&*AP_^kiyZH=hWt+}3#*UD^>~T5| z9V^--oH1vJwDN*0`8?VroXrw3_U5%oIIm{{4)OMD7u`jJf3Ho#8Drt6=h!CUjI}Xx zyb+IXlW@k!Mf^oz&qF6zJb~)s?!_z8CgJQ-O%P892^n&=Em+B)c#?`Q$l4^FF zKOYno)4C6c}u1dY|Jhd+VXcOqn#_H)>$dk~e?^YbmA!XupC^O+ z$^MdAPt0OM)1cz!%6{wB_bYmgeX_rPyZUJVf3n{n?Gt%tf;RhtsYD)obu&u~ec;UC ztFO-v-{Us>fDLgDmw6>mW83PLJ|*X!gZ^wpTpk@~G45 zz8a-z-ey1jGJfZ+(IC~~|6KjU9{tB82j@R-re|z>O<7qs*?v1#d{NhKAd8wB2j?gSFdqv}L_f zLps_%dJ-BxlhChC%epjeD}A2IxM`Xgw~KGZuSSnue0xC)-2C1=D{r5tJxyDRwaoaj z=jra?SrdgGJ5OH!Y$~2x`~Z6P8$W1%$L4n=D`Z{M? z7%6>kK6{To%@)0F(c2ckIXA28vq_Oxnu`j^))^~D%EPoNhUXi~ z9+S_e#o{q$9*QR$RNA(u7;=8n{vhO3y=NmfZ$k4X{C&L%HKb$T-85L*^(%>$SwIf* ziFuCHOGa}e&N}V!!XgAet4r}AD8uaA&n6AY2SwNQ0d3qLM0p_fb5&CeGRgg`{qTFY ze#9Q_{Zq@1B!g&tmjI8ukfujQUVZH@r514oyrpN(H~}~Q`h{zGgzw&{67O@Y@A=~e zLooIc1AOPTt+a9i|iCsk57`oDk)qc)b~+BMa7G9`{?`iby%(x$!)rksi6;ZI=lh zv~=q3;@q3sm}71lIp@SgX(q z_gosbf>(}QS|S=qui7_4xJx1Q0TUY0kx|+C3*LM{_02dery27OACM^{oE)n_X+Gdm zC3p{=GH``I9}q(QM;$jK?}!d}KHv%ym+9nvVL!gkRs7Z?=lJr1DNkofj)Fg)ac}aQ z3N~)1AG(J_JaqR_75MlVPFz8l>KYG*KTQ}sF^ky~COKawmymN3=+6glyRtK-_67~o z6UNXR)vpT=swc=|D#Q0dZzN?r+w_V@CFr< z_{t5gj?Mb>q^WayOfNWg4V4$I?$$Wd=PuHOZOR?=c9y<;9v*E|Vh+R#fsK4xPbYY7 z@tKb{F{CyRO*NLg&SUBkrV~3sZ*>B~mLT(z^(L5@hqIOEsnOA9m}!_}Ej(f}EzZ)d#l<5TQBL*Jg&WwOa?pQhw|d zvY5g`7L1Sc6t5shmpa?}ezqKMMCR_zCjrm*;^7j`$QV*CqK}g##{%rt*B~UP6(98C zsZlp#Uw2QQ$N-Zk4FX@*SNkDi65#Vegc5IOWRkZuSl&I^{suVp@R(yUw z@D$U!4~Ud4M;@;~DksxeaQVO$6R0jtKkyR+m)!G&BjxjbH+_ZrTR(N)_ZGYK6WdL1 zoe$~`IacI7dgw=tEibup)$ykKnJ}rnpgcn+*wSa%S5}PXxci_h?5Rg59tASny~N{{ zWly(iBnox-^>aN^3TMj9hYm7t{S2|xsY3GLt4eY9r=4Ygj{D8a&F9WM7_Hn|@3|0D z7@j`^C6Uue?ar<7P<~TyiDcHi3uQV!83x0=pM16*)eJ*x#T`h-uQNPDcl_UPgEPfN z44-7|vUMPMjvfr>$OdXHJjl@i6S9;nPCXwh8$5P^ZBuwSL-@>%MLQpCa>;k2wR`gj zppCrgsE@fW(BG4B@OSp}A=0L>LRBTH8ED*gc^B{PQ)JYE;iuJmt3!QjKls%?+W(*I z_eXnO6%3cQ9(Pz;8j-R#p|{3_Ud@8@&27{rS1@{=&mo@ed#*aOCb;A3*fExemx?=W z?xc#YLG%?3#t)P_VR%-3eRebM!hPP25 z=nDGIQg`b^W;^&lA9e!N9xD#q?SY~l%kfyiRj~1t% z14a53Kl3!DWeCd9bGglw>8+s6{4>R1n<;}%;LC!QX4q!RV9k%E<2F+UZwc7iMVHEX z0lwLM?oBV_+f12#G3;|rOHKuCrcCZr+{}eyYb4}SkJa&)_k^^WGW+nykPp~q%E;5c z`BtPHC7nHj7r$;~EQgMmWUwK;!3L}WHg7g!daiAz%r5$>ENeW|^|RK~`_N{}gh=98 z{uZBQn}Fl*ek%Tw^0wMqxFBmYWyZ?#Hd6*Ew2S98ru{I#E}osyX3D(gV-N=0 zOqpGLmBgK6DhqYoZKli{tNK-L(C$8dQDQv7#fSWgA*$~?5|-LbnW^-Juc*zG!S_BL zgX(tJX38+viR|!wd0tMF_;lJ#nJE;S`d~vJD|%zMnKIk`>Oro^A3#>W59zBjY%^uX zpI)0OGtTBAKP=>o$FT=bbWeSsuPSsw6mm2?)BuE@0#w6>eg}SL7z$r0WL~U@A=o~; z;`?o;%;x%yKKs4Rl-X3{(&MPjl-aI9q?&V^DZ{;6ubG0L+Dw^kx2?^T86P9=C*2^4 zz4Wl5w@;fXBk$NYO3x?Vc+u+GOd0xCjK76#rp#{mYBOav=SrnoR6Mz*wpU>@Wc9nS z%l8;}hWCiAHdAI7t_r=inKIjLuGr@udY;v${1_(cdD~2xF=yCj%50X2F-5hRGMn*~ zO6YjvM{S;vLKft-hd!O_nnQhUW(Zqtrpzw7gJQmIrp)d*YcplG$4lBwna%P?yi}gZ zP@}E5cy0M3$l^I00X`p)#WP8KLDpub4CkA)nKHXngr;|oZ1zK#DRaE~ zPnTIVcFId%zfV2C=E2-|-I~d1rsF`KO@jQ}eS%CprG<$`-|d@^EVh1XkB?S=*#GO@ z49Bm8f8(=BTsS0MXY*|0@!u4~nNQeBpQqaN_!a07qI~g3!*~2_>NnCai!(d#I{%|l zU+#f{7$PQs=w#NbUZ(Dtd4yAU8lMi8#+w|`5Y^R`>yZJry!;8mRK)D^5{u5 zyxP1Ir06cN)C8&FwcHbH7iFN1(f-4pbdHbH8M$%1Wy6tuRzz97&h zGPKvuxaV};;I*Hlb%W()kDzQ5q!dfPGEe!uvpL%YscW-&=jy(qY@=Yc*RSG9J(z+{ zc^GYi)PB9igv&rVV{NNa{4+i0HbKgx4bH^xHbH8;wvy6un;^A+-zu^=+XSh9n~t1v z?0q_|rBvD`NX^r^PUk~qTy1IECP+=yjnbR()i}?c*(=oU^?a!I>83D-?87!e>NQV7 zinnyqP@5pN%?Gm$bKY#k^jzBnsa^C{Po4i#nrjoJUZ0zgVk|z(HbLrj?5VCsSZfoc z#&?WKr>wLIQm<(tqBB0#CP|NQt+Xvgn0gXC2B2NC;tjb5oq2Mts}$Q1gY^JO;MNX!rBC>vGEzBl%`!2j@-{(gGoDhJ(owLM7%fZSpul>i+?)Eq(m} literal 0 HcmV?d00001 diff --git a/Win64/proj/actor/Debug/actor.tlog/CL.write.1.tlog b/Win64/proj/actor/Debug/actor.tlog/CL.write.1.tlog new file mode 100644 index 0000000000000000000000000000000000000000..aff6d07ed0c8ded35cc31c3d837f73dd1111f93f GIT binary patch literal 7428 zcmdT|%Tj|d6uoO_{1sM?3wKb^TKiz2j}4dgB00v)=ro8ff{)0-SVCTV=!G+T3%xAl1rnP|E53~O zn7@`cSRxzg0DW_iHfI~lWni_Ql-zIlOHREi0dE zaj3|{UK3XqZ68TWNc;r(+fU!TZsi7yFN?t^c}7gSmpja**X_n*6~zlVz_#r78Em=4 z`)iTv-iB7roH}EKuv#EBL@YNdWRU4!;`zCNjXvzLbFU!mv+PxwT*gN7BQzf`UhA;2 z_$dDnq5J#(ZY2L8#P?Rj6)sDIblrwuWPf<5N24qTuiqDWn-ycL{|{mIqS1z zshQ}`%B~#QxWDyxTo_iV7n{x0?9kXq%$*)q zJhGXX9%dX9R~NCJmy{T}w(K)2Y!Ei`af&O4>0oS+R-ts_E$}?s>716r-u#Y5#{E$#J>Cj}>lbmYxmze8Syr`nuRHgtX<{`pua+Gk-rn zUX|!UJEh9>%vGq?iniS|Rcg3r+;`e2r+u%xFdFNTXT<83xoiI08)9`@{OF%CYIEOR zIEj|nQ1LU%r({L!H)Y@Eo5qcEn#K`)>^a#%v*i;Y+^M!fDHxf(E zT+8|NrIbT#BTjVY&Z^12h)gM9^%>L0*>{iMNzkDtZ+=rgYg;9sGqYojscyxy36=f}auCr9 literal 0 HcmV?d00001 diff --git a/Win64/proj/actor/Debug/actor.tlog/Lib-link.write.1.tlog b/Win64/proj/actor/Debug/actor.tlog/Lib-link.write.1.tlog new file mode 100644 index 0000000000000000000000000000000000000000..dd80495393d7aa9e4fd7c71e89579943715a7616 GIT binary patch literal 1594 zcmc(fyAFad6o&uV#8+`L4sHdisO1tavJia{pI!Y53_57yPz>QfIi=sZKkgUB+NxI~ zt24J#p^~+iR=H}VMfU1+V7<|L&_+7)H2mGLx8mKO5UJJv?fVL?-+K$fiIrkQ&gCti zlV$KX!EYa%Ixu+$CDV0^q#a@&!7g+{Q~jB4h`hrlM<#qMd_=-#BBkaU>N6}Qn{sQY zXd9eW(0ztZaj?dY8S@<0$5+yP6;%&io8V^`IIcB}c<7QQFsXr4(xdYcTjtLv;!+Fj R`F*ZCW_Lj*D6#O)4V?MRwvid2ePs z^XB9IMTwSbmCERek*U;%wVjO$Rm_ID)lT=UZ*<-5#(Ll$@psL)Tb?aKtVXME@2}Xk z-@XOmNwmg>g3DSyC0B&MDSq47RDqfAV9E8mkEH2h9>ZPgk)7>7vqwZe!={Xru(7Za z340Q2a;_#n!?NW2vyI4T6P&B0`XVYNgUeNnJLj-I9y3jsQB_y9DSqw($F+hZ>8hj- z%v8g(p+=`;Y|x)mjF-C50^b|zWT`p6w~WJ_q2=*_X1o2lW}p<{*sic**mX{xTHUqX zz<~a&Te`yR2;DKc+&a}G79EP~9bY+atv=Xz9!h@)_&ZX+zWd;wtKK27hqT#;@2B$m jVD#&%AJUj=`k;V+45QX0wsdqpE}aXq@cp0G<*cr39Z*4Nk-w%;SxMsxH3 zfz>hd-+_=4EjY!R&!2u=w1}8fV)G2S;Mg;8R{DhP81A!%dCzR2H%8UJ<45qHbE=&C z@O*eyLf^-N?5oMg&^W6m8b@Svtng?B)fjQlIcVqi9UA!@Ys}noO%eD*AQ(K|zY`3noeTLM)`VZBx_3o;?w#Q|?SdYFex1K|}`3s|ZL_h!l literal 0 HcmV?d00001 diff --git a/Win64/proj/actor/Debug/actor.tlog/bscmake.read.1.tlog b/Win64/proj/actor/Debug/actor.tlog/bscmake.read.1.tlog new file mode 100644 index 0000000000000000000000000000000000000000..72e8c734c7a4c2750177239e89b4d526e2f4d165 GIT binary patch literal 3134 zcmc(g-A=+l5Jtai6JLc3HC}kvKLKfJ(_JJOqA$X;180hfsFiv%B~3T8ZMSD;c4xlB z{#}`#v{kM`uiT|-HOy@+v{Ya$7`Iw$&iqji*o|7gc)?0oAF*3(`$wvkrr(}VSe^2I z=S0dh!;2-Cc|R^KA?BReEJMMa{S2ql2iZ=^ebHs!GFxlGti3uvA^#;_mF$P*!?NPN zA2Uv0~jh2e80WP=d3Z$R_LlYC)Txlb_0~GtC{G|ijW#= zc1-4qp7a;LIT~ZN0>X42c0l4Dk??X#e~SGLiWS@(B-g8n65mE^IZgR@$Uct literal 0 HcmV?d00001 diff --git a/Win64/proj/actor/Debug/actor.vcxproj.FileListAbsolute.txt b/Win64/proj/actor/Debug/actor.vcxproj.FileListAbsolute.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Win64/proj/actor/actor.vcxproj b/Win64/proj/actor/actor.vcxproj index fed81d6829..addadd0f1f 100644 --- a/Win64/proj/actor/actor.vcxproj +++ b/Win64/proj/actor/actor.vcxproj @@ -1,18 +1,34 @@  + + Debug.DLL + Win32 + Debug.DLL x64 + + Debug + Win32 + Debug x64 + + Release.DLL + Win32 + Release.DLL x64 + + Release + Win32 + Release x64 @@ -30,36 +46,68 @@ MultiByte v143 + + StaticLibrary + MultiByte + v143 + StaticLibrary MultiByte v142 + + StaticLibrary + MultiByte + v142 + StaticLibrary MultiByte v142 + + StaticLibrary + MultiByte + v142 + StaticLibrary MultiByte v143 + + StaticLibrary + MultiByte + v143 + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 @@ -101,6 +149,35 @@ .\..\..\obj\actor\release\$(MSBuildProjectName).log + + + OnlyExplicitInline + ..\..\..\src\material\section\repres\section;..\..\..\src\element\surfaceLoad;..\..\..\src\damping;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\backbone;..\..\..\src\material\section\integration;..\..\..\SRC\element\RockingBC;..\..\..\SRC\element\PFEMElement;..\..\..\src\material\uniaxial\limitState;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\material\nD\stressDensityModel;..\..\..\src\element\twoNodeLink;..\..\..\src\element\elastomericBearing;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\element\triangle;..\..\..\SRC\domain\pattern\drm;..\..\..\src\material\uniaxial\snap;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\api;..\..\..\SRC\element\upU;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\SRC\tcl;..\..\..\SRC\element\UP-ucsd;..\..\..\src\actor\machineBroker;..\..\..\SRC\actor\shadow;..\..\..\src\package;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\shell;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\section\fiber;..\..\..\src\element\fourNodeQuad;..\..\..\src\material\backbone;..\..\..\src\material\state;..\..\..\src\material\state\stiffness;..\..\..\src\material\state\deformation;..\..\..\src\material\state\strength;..\..\..\src\material\nD;..\..\..\src\coordTransformation;..\..\..\src\domain\groundMotion;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\analysis\integrator;..\..\..\src\analysis\fe_ele;..\..\..\src\analysis\dof_grp;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\symSparse;..\..\..\src\analysis\model\simple;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\analysis\algorithm\domaindecompAlgo;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\domain\domain\single;..\..\..\src\convergenceTest;..\..\..\src\analysis\analysis;..\..\..\src\recorder;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\analysis\algorithm;..\..\..\src\system_of_eqn;..\..\..\src\graph\graph;..\..\..\src\graph\numberer;..\..\..\src\analysis\numberer;..\..\..\src\analysis\fe_ele\transformation;..\..\..\src\analysis\fe_ele\lagrange;..\..\..\src\analysis\fe_ele\penalty;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\domain\subdomain;..\..\..\src\domain\constraints;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src\domain\node;..\..\..\src\element;..\..\..\src\matrix;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src;..\..\..\src\actor\actor;..\..\..\src\analysis\handler;..\..\..\src\material\section;..\..\..\src\modelbuilder;..\..\..\src\renderer;..\..\..\src\modelbuilder\tcl;..\..\..\src\tagged\storage;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\patch;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfBar;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfLayer;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\cell;..\..\..\src\element\nonlinearBeamColumn;..\..\..\src\element\nonlinearBEamCOlumn\quadrule;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\nonlinearBeamColumn\fiber;..\..\..\src\material;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\domain\load;..\..\..\src\domain\pattern;..\..\..\src\element\zeroLength;..\..\..\src\element\feap;..\..\..\src\element\truss;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material\uniaxial;..\..\..\src\actor\address;..\..\..\src\actor\message;..\..\..\src\nDarray;..\..\..\src\material\uniaxial\fedeas;..\..\..\src\material\uniaxial\drain;..\..\..\src\element\8nbrick;..\..\..\src\element\brick;..\..\..\src\material\uniaxial\py;..\..\..\src\material\nd\soil;..\..\..\src\element\joint;..\..\..\src\material\nd\feap;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\..\..\obj\actor\release/actor.pch + .\..\..\obj\actor\release/ + .\..\..\obj\actor\release/ + .\..\..\obj\actor\release/ + Level3 + true + Cdecl + Default + + + .\..\..\lib\release\actor.lib + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + .\..\..\obj\actor\release\$(MSBuildProjectName).log + + OnlyExplicitInline @@ -130,6 +207,35 @@ .\..\..\obj\actor\release\$(MSBuildProjectName).log + + + OnlyExplicitInline + ..\..\..\src\material\section\repres\section;..\..\..\src\element\surfaceLoad;..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\backbone;..\..\..\src\material\section\integration;..\..\..\SRC\element\RockingBC;..\..\..\SRC\element\PFEMElement;..\..\..\src\material\uniaxial\limitState;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\material\nD\stressDensityModel;..\..\..\src\element\twoNodeLink;..\..\..\src\element\elastomericBearing;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\element\triangle;..\..\..\SRC\domain\pattern\drm;..\..\..\src\material\uniaxial\snap;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\api;..\..\..\SRC\element\upU;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\SRC\tcl;..\..\..\SRC\element\UP-ucsd;..\..\..\src\actor\machineBroker;..\..\..\SRC\actor\shadow;..\..\..\src\package;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\shell;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\beamWithHinges;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\section\fiber;..\..\..\src\element\fourNodeQuad;..\..\..\src\material\backbone;..\..\..\src\material\state;..\..\..\src\material\state\stiffness;..\..\..\src\material\state\deformation;..\..\..\src\material\state\strength;..\..\..\src\material\nD;..\..\..\src\coordTransformation;..\..\..\src\domain\groundMotion;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\analysis\integrator;..\..\..\src\analysis\fe_ele;..\..\..\src\analysis\dof_grp;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\symSparse;..\..\..\src\analysis\model\simple;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\analysis\algorithm\domaindecompAlgo;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\domain\domain\single;..\..\..\src\convergenceTest;..\..\..\src\analysis\analysis;..\..\..\src\recorder;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\analysis\algorithm;..\..\..\src\system_of_eqn;..\..\..\src\graph\graph;..\..\..\src\graph\numberer;..\..\..\src\analysis\numberer;..\..\..\src\analysis\fe_ele\transformation;..\..\..\src\analysis\fe_ele\lagrange;..\..\..\src\analysis\fe_ele\penalty;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\domain\subdomain;..\..\..\src\domain\constraints;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src\domain\node;..\..\..\src\element;..\..\..\src\matrix;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src;..\..\..\src\actor\actor;..\..\..\src\analysis\handler;..\..\..\src\material\section;..\..\..\src\modelbuilder;..\..\..\src\renderer;..\..\..\src\modelbuilder\tcl;..\..\..\src\tagged\storage;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\patch;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfBar;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfLayer;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\cell;..\..\..\src\element\nonlinearBeamColumn;..\..\..\src\element\nonlinearBEamCOlumn\quadrule;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\nonlinearBeamColumn\fiber;..\..\..\src\material;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\domain\load;..\..\..\src\domain\pattern;..\..\..\src\element\zeroLength;..\..\..\src\element\feap;..\..\..\src\element\truss;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material\uniaxial;..\..\..\src\actor\address;..\..\..\src\actor\message;..\..\..\src\nDarray;..\..\..\src\material\uniaxial\fedeas;..\..\..\src\material\uniaxial\drain;..\..\..\src\element\8nbrick;..\..\..\src\element\brick;..\..\..\src\material\uniaxial\py;..\..\..\src\material\nd\soil;..\..\..\src\element\joint;..\..\..\src\material\nd\feap;c:\Program Files\tcl;c:\Program Files\tcl\include;..\..\..\src\damping;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + .\..\..\obj\actor\release/actor.pch + .\..\..\obj\actor\release/ + .\..\..\obj\actor\release/ + .\..\..\obj\actor\release/ + Level3 + true + Cdecl + Default + + + .\..\..\lib\release\actor.lib + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + .\..\..\obj\actor\release\$(MSBuildProjectName).log + + Disabled @@ -159,6 +265,35 @@ .\..\..\obj\actor\debug\$(MSBuildProjectName).log + + + Disabled + ..\..\..\src\material\section\repres\section;..\..\..\src\element\surfaceLoad;..\..\..\src\damping;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\backbone;..\..\..\src\material\section\integration;..\..\..\SRC\element\RockingBC;..\..\..\SRC\element\PFEMElement;..\..\..\src\material\uniaxial\limitState;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\material\nD\stressDensityModel;..\..\..\src\element\twoNodeLink;..\..\..\src\element\elastomericBearing;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\element\triangle;..\..\..\SRC\domain\pattern\drm;..\..\..\src\material\uniaxial\snap;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\api;..\..\..\SRC\element\upU;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\SRC\tcl;..\..\..\SRC\element\UP-ucsd;..\..\..\src\actor\machineBroker;..\..\..\SRC\actor\shadow;..\..\..\src\package;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\shell;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\section\fiber;..\..\..\src\element\fourNodeQuad;..\..\..\src\material\backbone;..\..\..\src\material\state;..\..\..\src\material\state\stiffness;..\..\..\src\material\state\deformation;..\..\..\src\material\state\strength;..\..\..\src\material\nD;..\..\..\src\coordTransformation;..\..\..\src\domain\groundMotion;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\analysis\integrator;..\..\..\src\analysis\fe_ele;..\..\..\src\analysis\dof_grp;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\symSparse;..\..\..\src\analysis\model\simple;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\analysis\algorithm\domaindecompAlgo;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\domain\domain\single;..\..\..\src\convergenceTest;..\..\..\src\analysis\analysis;..\..\..\src\recorder;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\analysis\algorithm;..\..\..\src\system_of_eqn;..\..\..\src\graph\graph;..\..\..\src\graph\numberer;..\..\..\src\analysis\numberer;..\..\..\src\analysis\fe_ele\transformation;..\..\..\src\analysis\fe_ele\lagrange;..\..\..\src\analysis\fe_ele\penalty;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\domain\subdomain;..\..\..\src\domain\constraints;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src\domain\node;..\..\..\src\element;..\..\..\src\matrix;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src;..\..\..\src\actor\actor;..\..\..\src\analysis\handler;..\..\..\src\material\section;..\..\..\src\modelbuilder;..\..\..\src\renderer;..\..\..\src\modelbuilder\tcl;..\..\..\src\tagged\storage;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\patch;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfBar;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfLayer;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\cell;..\..\..\src\element\nonlinearBeamColumn;..\..\..\src\element\nonlinearBEamCOlumn\quadrule;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\nonlinearBeamColumn\fiber;..\..\..\src\material;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\domain\load;..\..\..\src\domain\pattern;..\..\..\src\element\zeroLength;..\..\..\src\element\feap;..\..\..\src\element\truss;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material\uniaxial;..\..\..\src\actor\address;..\..\..\src\actor\message;..\..\..\src\nDarray;..\..\..\src\material\uniaxial\fedeas;..\..\..\src\material\uniaxial\drain;..\..\..\src\element\8nbrick;..\..\..\src\element\brick;..\..\..\src\material\uniaxial\py;..\..\..\src\material\nd\soil;..\..\..\src\element\joint;..\..\..\src\material\nd\feap;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) + _DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebug + .\..\..\obj\actor\debug/actor.pch + .\..\..\obj\actor\debug/ + .\..\..\obj\actor\debug/ + .\..\..\obj\actor\debug/ + true + Level3 + true + ProgramDatabase + Default + EnableFastChecks + + + .\..\..\lib\debug\actor.lib + true + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + .\..\..\obj\actor\debug\$(MSBuildProjectName).log + + Disabled @@ -188,6 +323,35 @@ .\..\..\obj\actor\debug\$(MSBuildProjectName).log + + + Disabled + ..\..\..\src\material\section\repres\section;..\..\..\src\element\surfaceLoad;..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\backbone;..\..\..\src\material\section\integration;..\..\..\SRC\element\RockingBC;..\..\..\SRC\element\PFEMElement;..\..\..\src\material\uniaxial\limitState;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\material\nD\stressDensityModel;..\..\..\src\element\twoNodeLink;..\..\..\src\element\elastomericBearing;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\element\triangle;..\..\..\SRC\domain\pattern\drm;..\..\..\src\material\uniaxial\snap;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\api;..\..\..\SRC\element\upU;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\SRC\tcl;..\..\..\SRC\element\UP-ucsd;..\..\..\src\actor\machineBroker;..\..\..\SRC\actor\shadow;..\..\..\src\package;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\shell;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\beamWithHinges;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\section\fiber;..\..\..\src\element\fourNodeQuad;..\..\..\src\material\backbone;..\..\..\src\material\state;..\..\..\src\material\state\stiffness;..\..\..\src\material\state\deformation;..\..\..\src\material\state\strength;..\..\..\src\material\nD;..\..\..\src\coordTransformation;..\..\..\src\domain\groundMotion;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\analysis\integrator;..\..\..\src\analysis\fe_ele;..\..\..\src\analysis\dof_grp;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\symSparse;..\..\..\src\analysis\model\simple;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\analysis\algorithm\domaindecompAlgo;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\domain\domain\single;..\..\..\src\convergenceTest;..\..\..\src\analysis\analysis;..\..\..\src\recorder;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\analysis\algorithm;..\..\..\src\system_of_eqn;..\..\..\src\graph\graph;..\..\..\src\graph\numberer;..\..\..\src\analysis\numberer;..\..\..\src\analysis\fe_ele\transformation;..\..\..\src\analysis\fe_ele\lagrange;..\..\..\src\analysis\fe_ele\penalty;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\domain\subdomain;..\..\..\src\domain\constraints;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src\domain\node;..\..\..\src\element;..\..\..\src\matrix;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src;..\..\..\src\actor\actor;..\..\..\src\analysis\handler;..\..\..\src\material\section;..\..\..\src\modelbuilder;..\..\..\src\renderer;..\..\..\src\modelbuilder\tcl;..\..\..\src\tagged\storage;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\patch;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfBar;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfLayer;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\cell;..\..\..\src\element\nonlinearBeamColumn;..\..\..\src\element\nonlinearBEamCOlumn\quadrule;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\nonlinearBeamColumn\fiber;..\..\..\src\material;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\domain\load;..\..\..\src\domain\pattern;..\..\..\src\element\zeroLength;..\..\..\src\element\feap;..\..\..\src\element\truss;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material\uniaxial;..\..\..\src\actor\address;..\..\..\src\actor\message;..\..\..\src\nDarray;..\..\..\src\material\uniaxial\fedeas;..\..\..\src\material\uniaxial\drain;..\..\..\src\element\8nbrick;..\..\..\src\element\brick;..\..\..\src\material\uniaxial\py;..\..\..\src\material\nd\soil;..\..\..\src\element\joint;..\..\..\src\material\nd\feap;c:\Program Files\tcl;c:\Program Files\tcl\include;..\..\..\src\damping;%(AdditionalIncludeDirectories) + _DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + .\..\..\obj\actor\debug/actor.pch + .\..\..\obj\actor\debug/ + .\..\..\obj\actor\debug/ + .\..\..\obj\actor\debug/ + true + Level3 + true + ProgramDatabase + Default + EnableFastChecks + + + .\..\..\lib\debug\actor.lib + true + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + .\..\..\obj\actor\debug\$(MSBuildProjectName).log + + diff --git a/Win64/proj/openSeesPy/OpenSeesPy.vcxproj b/Win64/proj/openSeesPy/OpenSeesPy.vcxproj index 20742a8ab4..b566b5a4c7 100644 --- a/Win64/proj/openSeesPy/OpenSeesPy.vcxproj +++ b/Win64/proj/openSeesPy/OpenSeesPy.vcxproj @@ -198,7 +198,7 @@ actor.lib;analysis.lib;arpack.lib;blas.lib;cblas.lib;convergence.lib;cssparse.lib;damage.lib;database.lib;DoddRestrepo.lib;domain.lib;drain.lib;element.lib;feap.lib;fedeas.lib;glu32.lib;graph.lib;handler.lib;ifconsol.lib;lapack.lib;libifcoremt.lib;libmmt.lib;material.lib;matrix.lib;modelbuilder.lib;opengl32.lib;optimization.lib;PML.lib;python39.lib;recorder.lib;reliability.lib;renderer.lib;sdmuc.lib;superLU.lib;system.lib;tagged.lib;tcl.lib;tcl86t.lib;tk86t.lib;umfpackC.lib;utility.lib;wsock32.lib;%(AdditionalDependencies) $(OutDir)opensees.pyd true - C:\Program Files\Tcl\lib;C:\ProgramData\Anaconda3\libs;..\..\lib;..\..\lib\debug;%(AdditionalLibraryDirectories) + C:\Program Files\Tcl\lib;C:\ProgramData\Anaconda3\libs;..\..\lib;C:\Develop\OpenSees\Win64\lib\debug;..\..\lib\debug;%(AdditionalLibraryDirectories) libcmt.lib;%(IgnoreSpecificDefaultLibraries) true $(OutDir)$(ProjectName).pdb From b58e0795d985a04e77796955ef28a65c237d01ec Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Wed, 8 Jan 2025 16:19:59 +0100 Subject: [PATCH 008/261] done rotation, todo: in section --- SRC/element/shell/ASDShellQ4.cpp | 10 +++++----- SRC/element/shell/ASDShellT3.cpp | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/SRC/element/shell/ASDShellQ4.cpp b/SRC/element/shell/ASDShellQ4.cpp index 5797617d50..b5ed028493 100644 --- a/SRC/element/shell/ASDShellQ4.cpp +++ b/SRC/element/shell/ASDShellQ4.cpp @@ -678,8 +678,8 @@ namespace T(4, 3) = s * s; T(4, 4) = c * c; T(4, 5) = s * c; T(5, 3) = 2.0 * s * c; T(5, 4) = -2.0 * s * c; T(5, 5) = c * c - s * s; - T(6, 6) = c; T(6, 7) = s; - T(7, 6) = -s; T(7, 7) = c; + T(6, 6) = c; T(6, 7) = -s; + T(7, 6) = s; T(7, 7) = c; } // computes the transformation matrix for generalized stresses @@ -698,8 +698,8 @@ namespace T(4, 3) = s * s; T(4, 4) = c * c; T(4, 5) = 2.0 * s * c; T(5, 3) = s * c; T(5, 4) = -s * c; T(5, 5) = c * c - s * s; - T(6, 6) = c; T(6, 7) = s; - T(7, 6) = -s; T(7, 7) = c; + T(6, 6) = c; T(6, 7) = -s; + T(7, 6) = s; T(7, 7) = c; } } @@ -863,7 +863,7 @@ void ASDShellQ4::setDomain(Domain* theDomain) Vector3Type P2(m_transformation->getNodes()[1]->getCrds()); Vector3Type P3(m_transformation->getNodes()[2]->getCrds()); Vector3Type P4(m_transformation->getNodes()[3]->getCrds()); - Vector3Type e1 = (P2 + P3) / 2.0 - (P1 + P4) / 2.0; + e1 = (P2 + P3) / 2.0 - (P1 + P4) / 2.0; e1.normalize(); } m_angle = std::acos(std::max(-1.0, std::min(1.0, e1.dot(e1_local)))); diff --git a/SRC/element/shell/ASDShellT3.cpp b/SRC/element/shell/ASDShellT3.cpp index 6c4802ed9d..5262cc4a7b 100644 --- a/SRC/element/shell/ASDShellT3.cpp +++ b/SRC/element/shell/ASDShellT3.cpp @@ -514,8 +514,8 @@ namespace T(4, 3) = s * s; T(4, 4) = c * c; T(4, 5) = s * c; T(5, 3) = 2.0 * s * c; T(5, 4) = -2.0 * s * c; T(5, 5) = c * c - s * s; - T(6, 6) = c; T(6, 7) = s; - T(7, 6) = -s; T(7, 7) = c; + T(6, 6) = c; T(6, 7) = -s; + T(7, 6) = s; T(7, 7) = c; } // computes the transformation matrix for generalized stresses @@ -534,8 +534,8 @@ namespace T(4, 3) = s * s; T(4, 4) = c * c; T(4, 5) = 2.0 * s * c; T(5, 3) = s * c; T(5, 4) = -s * c; T(5, 5) = c * c - s * s; - T(6, 6) = c; T(6, 7) = s; - T(7, 6) = -s; T(7, 7) = c; + T(6, 6) = c; T(6, 7) = -s; + T(7, 6) = s; T(7, 7) = c; } } @@ -678,7 +678,7 @@ void ASDShellT3::setDomain(Domain* theDomain) // default one Vector3Type P1(m_transformation->getNodes()[0]->getCrds()); Vector3Type P2(m_transformation->getNodes()[1]->getCrds()); - Vector3Type e1 = (P2 - P1) / 2.0; + e1 = (P2 - P1) / 2.0; e1.normalize(); } m_angle = std::acos(std::max(-1.0, std::min(1.0, e1.dot(e1_local)))); From 5d0a05dd7164a146bfa5309c91873e923a72efb3 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Wed, 15 Jan 2025 17:51:49 +0100 Subject: [PATCH 009/261] implex error control --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 267 ++++++++++++++++--- SRC/material/uniaxial/ASDSteel1DMaterial.h | 27 +- Win64/proj/quickMain/quickMain.vcxproj | 4 +- 3 files changed, 255 insertions(+), 43 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index 0b6dfaf7d8..8ccef39dbc 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -44,7 +44,9 @@ // anonymous namespace for utilities namespace { - + enum ErrorCodes { + EC_IMPLEX_Error_Control = -10 + }; /** Converts a string into a vector of doubles using whitespace as delimiter */ @@ -71,7 +73,7 @@ void* OPS_ASDSteel1DMaterial() opserr << "Using ASDSteel1D - Developed by: Alessia Casalucci, Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; first_done = true; } - static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu"; + static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu <-implex> <-implexControl $implexErrorTolerance $implexTimeReductionLimit> "; // check arguments int numArgs = OPS_GetNumRemainingInputArgs(); @@ -90,6 +92,10 @@ void* OPS_ASDSteel1DMaterial() double sy; double su; double eu; + bool implex = false; + bool implex_control = false; + double implex_error_tolerance = 0.05; //to set + double implex_time_redution_limit = 0.01; //to set // get tag if (OPS_GetInt(&numData, &tag) != 0) { @@ -109,6 +115,19 @@ void* OPS_ASDSteel1DMaterial() } return true; }; + auto lam_optional_double = [&numData](const char* variable, double& value) -> bool { + if (OPS_GetNumRemainingInputArgs() > 0) { + if (OPS_GetDouble(&numData, &value) < 0) { + opserr << "nDMaterial ASDSteel1D Error: failed to get '" << variable << "'.\n"; + return false; + } + } + else { + opserr << "nDMaterial ASDSteel1D Error: '" << variable << "' requested but not provided.\n"; + return false; + } + return true; + }; if (!lam_get_dparam(&E, "E")) return nullptr; if (!lam_get_dparam(&sy, "sy")) return nullptr; if (!lam_get_dparam(&su, "su")) return nullptr; @@ -118,6 +137,25 @@ void* OPS_ASDSteel1DMaterial() return nullptr; } + // parse optional arguments + while (OPS_GetNumRemainingInputArgs() > 0) { + const char* value = OPS_GetString(); + if (strcmp(value, "-implex") == 0) { + implex = true; + } + else if (strcmp(value, "-implexControl") == 0) { + implex_control = true; + if (OPS_GetNumRemainingInputArgs() < 2) { + opserr << "nDMaterial ASDSteel1D Error: '-implexControl' given without the next 2 arguments $implexErrorTolerance $implexTimeReductionLimit.\n"; + return nullptr; + } + if (!lam_optional_double("implexErrorTolerance", implex_error_tolerance)) + return nullptr; + if (!lam_optional_double("implexTimeReductionLimit", implex_time_redution_limit)) + return nullptr; + } + } + // obtain chaboche params from E, sy, su, eu // we want to use 2 hardening functions as per chaboche model. // so that the initial slope is close to E and the the stress apporaches su at eu @@ -134,6 +172,10 @@ void* OPS_ASDSteel1DMaterial() params.gamma1 = gamma1; params.H2 = H2 * (1.0 - alpha); params.gamma2 = gamma2; + params.implex = implex; + params.implex_control = implex_control; + params.implex_error_tolerance = implex_error_tolerance; + params.implex_time_redution_limit = implex_time_redution_limit; // create the material UniaxialMaterial* instance = new ASDSteel1DMaterial( @@ -152,6 +194,8 @@ void* OPS_ASDSteel1DMaterial() void ASDSteel1DMaterial::StateVariablesSteel::commit(const ASDSteel1DMaterial::InputParameters& params) { + // store the previously committed variables for next move from n to n - 1 + lambda_commit_old = lambda_commit; // state variables alpha1_commit = alpha1; alpha2_commit = alpha2; @@ -179,6 +223,8 @@ void ASDSteel1DMaterial::StateVariablesSteel::revertToStart(const ASDSteel1DMat alpha2_commit = 0.0; lambda = 0.0; lambda_commit = 0.0; + lambda_commit_old = 0.0; + sg_commit = 0.0; // strain, stress and tangent strain = 0.0; @@ -194,6 +240,8 @@ void ASDSteel1DMaterial::StateVariablesSteel::sendSelf(int& counter, Vector& dda ddata(counter++) = alpha2_commit; ddata(counter++) = lambda; ddata(counter++) = lambda_commit; + ddata(counter++) = lambda_commit_old; + ddata(counter++) = sg_commit; } void ASDSteel1DMaterial::StateVariablesSteel::recvSelf(int& counter, Vector& ddata) { alpha1 = ddata(counter++); @@ -202,6 +250,8 @@ void ASDSteel1DMaterial::StateVariablesSteel::recvSelf(int& counter, Vector& dda alpha2_commit = ddata(counter++); lambda = ddata(counter++); lambda_commit = ddata(counter++); + lambda_commit_old = ddata(counter++); + sg_commit = ddata(counter++); } ASDSteel1DMaterial::ASDSteel1DMaterial( @@ -228,10 +278,46 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) // retval int retval = 0; + // save dT + if (!params.dtime_is_user_defined) { + dtime_n = ops_Dt; + if (!commit_done) { + dtime_0 = dtime_n; + dtime_n_commit = dtime_n; + } + } + // compute real response steel.strain = v; - retval = computeBaseSteel(steel); - if (retval < 0) return retval; + //retval = computeBaseSteel(steel, params.implex); + //if (retval < 0) return retval; + if (params.implex) { + if (params.implex_control) { + // initial state + double stress_implicit = 0.0; + retval = computeBaseSteel(steel, false); // implicit solution + if (retval < 0) return retval; + stress_implicit = steel.stress; + + // explicit solution + retval = computeBaseSteel(steel, params.implex); // Implex solution + if (retval < 0) return retval; + + // Implex error + params.implex_error = std::abs(stress_implicit - steel.stress)/params.sy; + if (params.implex_error > params.implex_error_tolerance) { + if (dtime_n >= params.implex_time_redution_limit * dtime_0) { + return EC_IMPLEX_Error_Control; + } + } + } else { + retval = computeBaseSteel(steel, true); // Implex solution + if (retval < 0) return retval; + } + } + else { + retval = computeBaseSteel(steel, false); + } // todo: homogenize strain = steel.strain; @@ -265,6 +351,23 @@ double ASDSteel1DMaterial::getStrain(void) int ASDSteel1DMaterial::commitState(void) { + // implicit stage + if (params.implex) { + int retval; + retval = computeBaseSteel(steel, false); + if (retval < 0) return retval; + // todo: homogenize + strain = steel.strain; + stress = steel.stress; + C = steel.C; + /* + // IMPL-EX error + params.implex_error = std::abs(steel.stress - stress); + if (params.implex_control && params.implex_error > params.implex_error_tolerance) { + return -1; // avevamo detto quello implicito? + }*/ + } + // compute energy energy += 0.5 * (stress_commit + stress) * (strain - strain_commit); @@ -275,6 +378,10 @@ int ASDSteel1DMaterial::commitState(void) strain_commit = strain; stress_commit = stress; + // implex + dtime_n_commit = dtime_n; + commit_done = true; + // done return 0; } @@ -288,6 +395,9 @@ int ASDSteel1DMaterial::revertToLastCommit(void) strain = strain_commit; stress = stress_commit; + // implex + dtime_n = dtime_n_commit; + // done return 0; } @@ -304,6 +414,14 @@ int ASDSteel1DMaterial::revertToStart(void) stress_commit = 0.0; C = getInitialTangent(); + // implex + dtime_n = 0.0; + dtime_n_commit = 0.0; + dtime_0 = 0.0; + + + commit_done = false; + // output variables energy = 0.0; @@ -328,7 +446,7 @@ int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) int counter; // send DBL data - Vector ddata(InputParameters::NDATA + 1*StateVariablesSteel::NDATA + 7); + Vector ddata(InputParameters::NDATA + 1*StateVariablesSteel::NDATA + 10); counter = 0; ddata(counter++) = static_cast(getTag()); ddata(counter++) = params.E; @@ -337,7 +455,17 @@ int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) ddata(counter++) = params.H2; ddata(counter++) = params.gamma1; ddata(counter++) = params.gamma2; + ddata(counter++) = static_cast(params.implex); + ddata(counter++) = params.implex_error_tolerance; + ddata(counter++) = params.implex_time_redution_limit; + ddata(counter++) = static_cast(params.implex_control); + ddata(counter++) = static_cast(params.dtime_is_user_defined); + ddata(counter++) = params.implex_error; steel.sendSelf(counter, ddata); + ddata(counter++) = dtime_n; + ddata(counter++) = dtime_n_commit; + ddata(counter++) = dtime_0; + ddata(counter++) = static_cast(commit_done); ddata(counter++) = strain; ddata(counter++) = strain_commit; ddata(counter++) = stress; @@ -359,7 +487,7 @@ int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectB int counter; // recv DBL data - Vector ddata(InputParameters::NDATA + 1 * StateVariablesSteel::NDATA + 7); + Vector ddata(InputParameters::NDATA + 1 * StateVariablesSteel::NDATA + 10); if (theChannel.recvVector(getDbTag(), commitTag, ddata) < 0) { opserr << "ASDSteel1DMaterial::recvSelf() - failed to receive DBL data\n"; return -1; @@ -372,7 +500,17 @@ int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectB params.H2 = ddata(counter++); params.gamma1 = ddata(counter++); params.gamma2 = ddata(counter++); + params.implex = static_cast(ddata(counter++)); + params.implex_error_tolerance = ddata(counter++); + params.implex_time_redution_limit = ddata(counter++); + params.implex_control = static_cast(ddata(counter++)); + params.dtime_is_user_defined = static_cast(ddata(counter++)); + params.implex_error = ddata(counter++); steel.recvSelf(counter, ddata); + dtime_n = ddata(counter++); + dtime_n_commit = ddata(counter++); + dtime_0 = ddata(counter++); + commit_done = static_cast(ddata(counter++)); strain = ddata(counter++); strain_commit = ddata(counter++); stress = ddata(counter++); @@ -394,6 +532,19 @@ int ASDSteel1DMaterial::updateParameter(int parameterID, Information& info) { switch (parameterID) { // default + case 2000: + dtime_n = info.theDouble; + params.dtime_is_user_defined = true; + return 0; + case 2001: + dtime_n_commit = info.theDouble; + params.dtime_is_user_defined = true; + return 0; + case 2002: + dtime_0 = info.theDouble; + params.dtime_is_user_defined = true; + return 0; + default: return -1; } @@ -417,6 +568,7 @@ Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Strea // labels static std::vector lb_eqpl_strain = { "PLE" }; + static std::vector lb_implex_error = { "Error" }; // all outputs are 1D static Vector out1(1); @@ -428,6 +580,10 @@ Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Strea out1(0) = steel.lambda; return make_resp(1001, out1, &lb_eqpl_strain); } + // 3000 - implex error + //if (strcmp(argv[0], "implexError") == 0 || strcmp(argv[0], "ImplexError") == 0) { + //return make_resp(3000, getImplexError(), &lb_implex_error); + //} } // otherwise return base-class response @@ -444,6 +600,7 @@ int ASDSteel1DMaterial::getResponse(int responseID, Information& matInformation) case 1001: out1(0) = steel.lambda; return matInformation.setVector(out1); + //case 3000: return matInformation.setVector(getImplexError()); default: break; } @@ -455,11 +612,16 @@ double ASDSteel1DMaterial::getEnergy(void) return energy; } -int ASDSteel1DMaterial::computeBaseSteel(ASDSteel1DMaterial::StateVariablesSteel& sv) +int ASDSteel1DMaterial::computeBaseSteel(ASDSteel1DMaterial::StateVariablesSteel& sv, bool do_implex) { // return value int retval = 0; + // time factor for explicit extrapolation + double time_factor = 1.0; + if (params.implex && do_implex && (dtime_n_commit > 0.0)) + time_factor = dtime_n / dtime_n_commit; + // settings constexpr int MAX_ITER = 100; constexpr double F_REL_TOL = 1.0e-6; @@ -473,6 +635,7 @@ int ASDSteel1DMaterial::computeBaseSteel(ASDSteel1DMaterial::StateVariablesSteel double sigma = sv.stress_commit + params.E * dstrain; double tangent = params.E; // plastic utilities + double sg = 0.0; // plastic flow direction auto lam_rel_stress = [&sv, &sigma]() -> double { return sigma - sv.alpha1 - sv.alpha2; }; @@ -499,44 +662,72 @@ int ASDSteel1DMaterial::computeBaseSteel(ASDSteel1DMaterial::StateVariablesSteel sv.alpha2 = sg * params.H2 / params.gamma2 - (sg * params.H2 / params.gamma2 - sv.alpha2_commit) * std::exp(-params.gamma2 * delta_lambda); }; // plastic corrector - double F = lam_yield_function(); - if (F > 0.0) { - double delta_lambda = 0.0; - double dlambda = 0.0; - bool converged = false; - for (int niter = 0; niter < MAX_ITER; ++niter) { - // form tangent - double dF = lam_yield_derivative(dlambda); - if (dF == 0.0) break; - // solve for dlambda - dlambda = -F / dF; - delta_lambda += dlambda; - // update plastic multiplier increment and sigma - lam_yield_update(dlambda, delta_lambda); - // update residual - F = lam_yield_function(); - // check convergence - if (std::abs(F) < F_REL_TOL * params.sy && std::abs(dlambda) < L_ABS_TOL) { - converged = true; - // update plastic multiplier - sv.lambda += delta_lambda; - // compute tangent - double sg = sign(lam_rel_stress()); - double PE = - params.gamma1 * (params.H1 / params.gamma1 - sg * sv.alpha1) + - params.gamma2 * (params.H2 / params.gamma2 - sg * sv.alpha2); - tangent = (params.E * PE) / (params.E + PE); - break; + if (params.implex && do_implex) { + // extrapolate lambda + // xn + time_factor * (xn - xnn); + double delta_lambda = time_factor * (sv.lambda_commit - sv.lambda_commit_old); + sv.lambda = sv.lambda_commit + delta_lambda; + // extrapolate plastic flow direction + sg = sv.sg_commit; + // update stress + sigma -= sg * delta_lambda * params.E; + // update backstress + sv.alpha1 = sg * params.H1 / params.gamma1 - (sg * params.H1 / params.gamma1 - sv.alpha1_commit) * std::exp(-params.gamma1 * delta_lambda); + sv.alpha2 = sg * params.H2 / params.gamma2 - (sg * params.H2 / params.gamma2 - sv.alpha2_commit) * std::exp(-params.gamma2 * delta_lambda); + } + else { + // standard implicit evaluation of lambda + double F = lam_yield_function(); + if (F > 0.0) { + double delta_lambda = 0.0; + double dlambda = 0.0; + bool converged = false; + for (int niter = 0; niter < MAX_ITER; ++niter) { + // form tangent + double dF = lam_yield_derivative(dlambda); + if (dF == 0.0) break; + // solve for dlambda + dlambda = -F / dF; + delta_lambda += dlambda; + // update plastic multiplier increment and sigma + lam_yield_update(dlambda, delta_lambda); + // update residual + F = lam_yield_function(); + // check convergence + if (std::abs(F) < F_REL_TOL * params.sy && std::abs(dlambda) < L_ABS_TOL) { + converged = true; + // update plastic multiplier + sv.lambda += delta_lambda; + // compute tangent + sg = sign(lam_rel_stress()); + double PE = + params.gamma1 * (params.H1 / params.gamma1 - sg * sv.alpha1) + + params.gamma2 * (params.H2 / params.gamma2 - sg * sv.alpha2); + tangent = (params.E * PE) / (params.E + PE); + break; + } } + if (!converged) + retval = -1; } - if (!converged) - retval = -1; } // accept solution sv.stress = sigma; sv.C = tangent; + // save real plastic flow direction, if mp.implex and !do_implex -> called from commit + if (params.implex && !do_implex) { + // save it in implex mode during implicit phase + sv.sg_commit = sg; + } + // done return retval; } - +/* +const Vector& ASDSteel1DMaterial::getImplexError() const +{ + static Vector d(1); + d(0) = params.implex_error; + return d; +}*/ \ No newline at end of file diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index 0390034c9b..fa081804ae 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -52,7 +52,16 @@ class ASDSteel1DMaterial : public UniaxialMaterial double H2 = 0.0; double gamma1 = 0.0; double gamma2 = 0.0; - static constexpr int NDATA = 6; + // misc + bool implex = false; + double implex_error = 0.0; + double implex_time_redution_limit = 0.01; + double implex_error_tolerance = 0.05; + bool dtime_is_user_defined = false; + // True = keep IMPL-EX error under control + bool implex_control = false; + // counter + static constexpr int NDATA = 12; }; class StateVariablesSteel { public: @@ -64,6 +73,8 @@ class ASDSteel1DMaterial : public UniaxialMaterial // state variables - plastic multiplier double lambda = 0.0; double lambda_commit = 0.0; + double lambda_commit_old = 0.0; // for implex + double sg_commit = 0.0; // plastic flow dir for implex // strain, stress and tangent double strain = 0.0; double strain_commit = 0.0; @@ -71,12 +82,13 @@ class ASDSteel1DMaterial : public UniaxialMaterial double stress_commit = 0.0; double C = 0.0; // methods - static constexpr int NDATA = 11; + static constexpr int NDATA = 13; void commit(const InputParameters& params); void revertToLastCommit(const InputParameters& params); void revertToStart(const InputParameters& params); void sendSelf(int &counter, Vector& ddata); void recvSelf(int& counterg, Vector& ddata); + }; public: @@ -99,6 +111,9 @@ class ASDSteel1DMaterial : public UniaxialMaterial double getTangent(void); double getInitialTangent(void); + // get IMPL-EX error + const Vector& getImplexError() const; + // handle state int commitState(void); int revertToLastCommit(void); @@ -120,13 +135,19 @@ class ASDSteel1DMaterial : public UniaxialMaterial double getEnergy(void); private: - int computeBaseSteel(StateVariablesSteel& sv); + int computeBaseSteel(StateVariablesSteel& sv, bool do_implex); private: // common input parameters InputParameters params; // state variables - steel StateVariablesSteel steel; + // state variables - implex + double dtime_n = 0.0; + double dtime_n_commit = 0.0; + double dtime_0 = 0.0; + bool commit_done = false; + // strain, stress and tangent (homogenized) double strain = 0.0; double strain_commit = 0.0; diff --git a/Win64/proj/quickMain/quickMain.vcxproj b/Win64/proj/quickMain/quickMain.vcxproj index 9d382c783c..e1fb528a0d 100644 --- a/Win64/proj/quickMain/quickMain.vcxproj +++ b/Win64/proj/quickMain/quickMain.vcxproj @@ -32,7 +32,7 @@ Application MultiByte - v142 + v143 Application @@ -42,7 +42,7 @@ Application MultiByte - v142 + v143 From b1ac7b0f3975b015fd0eadc44ee5266a8abb70f2 Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Mon, 20 Jan 2025 12:22:37 -0800 Subject: [PATCH 010/261] adding new VTKHDF recorder --- SRC/Makefile | 3 +- .../FEM_ObjectBrokerAllClasses.cpp | 4 + SRC/classTags.h | 1 + SRC/interpreter/OpenSeesOutputCommands.cpp | 2 + SRC/recorder/CMakeLists.txt | 2 + SRC/recorder/Makefile | 2 +- SRC/recorder/TclRecorderCommands.cpp | 5 + SRC/recorder/VTKHDF_Recorder.cpp | 3609 +++++++++++++++++ SRC/recorder/VTKHDF_Recorder.h | 279 ++ SRC/runtime/commands/domain/recorder.cpp | 9 + SRC/runtime/runtime/TclPackageClassBroker.cpp | 12 + Win32/proj/recorder/recorder.vcxproj | 2 + Win32/proj/recorder/recorder.vcxproj.filters | 6 + Win64/proj/recorder/recorder.vcxproj | 2 + Win64/proj/recorder/recorder.vcxproj.filters | 6 + 15 files changed, 3942 insertions(+), 2 deletions(-) create mode 100644 SRC/recorder/VTKHDF_Recorder.cpp create mode 100644 SRC/recorder/VTKHDF_Recorder.h diff --git a/SRC/Makefile b/SRC/Makefile index fee49cb0dc..0724c3c222 100644 --- a/SRC/Makefile +++ b/SRC/Makefile @@ -432,7 +432,8 @@ RECORDER_LIBS = $(FE)/recorder/Recorder.o \ $(FE)/recorder/ElementRecorderRMS.o \ $(FE)/recorder/NodeRecorderRMS.o \ $(FE)/recorder/MPCORecorder.o \ - $(FE)/recorder/VTK_Recorder.o + $(FE)/recorder/VTK_Recorder.o \ + $(FE)/recorder/VTKHDF_Recorder.o \ DATABASE_LIBS = $(FE)/database/FileDatastore.o \ diff --git a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp index 3f68d3b046..02a7685a14 100644 --- a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp +++ b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp @@ -560,6 +560,7 @@ #include "DriftRecorder.h" #ifdef _HDF5 #include "MPCORecorder.h" +#include "VTKHDF_Recorder.h" #endif // _HDF5 #include "VTK_Recorder.h" #include "GmshRecorder.h" @@ -2735,6 +2736,9 @@ FEM_ObjectBrokerAllClasses::getPtrNewRecorder(int classTag) #ifdef _HDF5 case RECORDER_TAGS_MPCORecorder: return new MPCORecorder(); + + case RECORDER_TAGS_VTKHDF_Recorder: + return new VTKHDF_Recorder(); #endif // _HDF5 default: opserr << "FEM_ObjectBrokerAllClasses::getNewRecordr - "; diff --git a/SRC/classTags.h b/SRC/classTags.h index 46ec11f767..8b67fca0c6 100644 --- a/SRC/classTags.h +++ b/SRC/classTags.h @@ -1190,6 +1190,7 @@ #define RECORDER_TAGS_VTK_Recorder 22 #define RECORDER_TAGS_NodeRecorderRMS 23 #define RECORDER_TAGS_ElementRecorderRMS 24 +#define RECORDER_TAGS_VTKHDF_Recorder 25 #define OPS_STREAM_TAGS_FileStream 1 #define OPS_STREAM_TAGS_StandardStream 2 diff --git a/SRC/interpreter/OpenSeesOutputCommands.cpp b/SRC/interpreter/OpenSeesOutputCommands.cpp index a6a164e14d..ebbb95d435 100644 --- a/SRC/interpreter/OpenSeesOutputCommands.cpp +++ b/SRC/interpreter/OpenSeesOutputCommands.cpp @@ -86,6 +86,7 @@ void* OPS_AlgorithmRecorder(); void* OPS_RemoveRecorder(); #ifdef _HDF5 void* OPS_MPCORecorder(); +void* OPS_VTKHDF_Recorder(); #endif BackgroundMesh& OPS_getBgMesh(); @@ -125,6 +126,7 @@ namespace { recordersMap.insert(std::make_pair("EnvelopeDrift", &OPS_EnvelopeDriftRecorder)); #ifdef _HDF5 recordersMap.insert(std::make_pair("mpco", &OPS_MPCORecorder)); + recordersMap.insert(std::make_pair("VTKHDF", &OPS_VTKHDF_Recorder)); #endif //recordersMap.insert(std::make_pair("Drift", &OPS_DriftRecorder)); //recordersMap.insert(std::make_pair("Pattern", &OPS_PatternRecorder)); diff --git a/SRC/recorder/CMakeLists.txt b/SRC/recorder/CMakeLists.txt index 1d5410c1da..6234f73649 100644 --- a/SRC/recorder/CMakeLists.txt +++ b/SRC/recorder/CMakeLists.txt @@ -56,8 +56,10 @@ if(HDF5_FOUND) target_sources(OPS_Recorder PRIVATE MPCORecorder.cpp + VTKHDF_Recorder.cpp PUBLIC MPCORecorder.h + VTKHDF_Recorder.h ) endif() endif() diff --git a/SRC/recorder/Makefile b/SRC/recorder/Makefile index 714baae4e6..675a7516f8 100644 --- a/SRC/recorder/Makefile +++ b/SRC/recorder/Makefile @@ -23,7 +23,7 @@ OBJS = Recorder.o \ RemoveRecorder.o \ DamageRecorder.o $(GRAPHIC_OBJECTS) \ PVDRecorder.o MPCORecorder.o GmshRecorder.o \ - VTK_Recorder.o + VTK_Recorder.o VTKHDF_Recorder.o # Compilation control diff --git a/SRC/recorder/TclRecorderCommands.cpp b/SRC/recorder/TclRecorderCommands.cpp index 8f4375f623..e8cf1fb11a 100644 --- a/SRC/recorder/TclRecorderCommands.cpp +++ b/SRC/recorder/TclRecorderCommands.cpp @@ -66,6 +66,7 @@ extern void* OPS_PVDRecorder(); extern void* OPS_GmshRecorder(); #ifdef _HDF5 extern void* OPS_MPCORecorder(); +extern void* OPS_VTKHDF_Recorder(); #endif // _HDF5 extern void* OPS_VTK_Recorder(); extern void* OPS_ElementRecorderRMS(); @@ -1934,6 +1935,10 @@ enum outputMode {STANDARD_STREAM, DATA_STREAM, XML_STREAM, DATABASE_STREAM, BIN OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, &theDomain); (*theRecorder) = (Recorder*)OPS_MPCORecorder(); } + else if (strcmp(argv[1], "vtkhdf") == 0 || strcmp(argv[1], "VTKHDF") == 0) { + OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, &theDomain); + (*theRecorder) = (Recorder*)OPS_VTKHDF_Recorder(); + } #endif // _HDF5 else if (strcmp(argv[1],"gmsh") == 0 || strcmp(argv[1],"GMSH") == 0) { OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, &theDomain); diff --git a/SRC/recorder/VTKHDF_Recorder.cpp b/SRC/recorder/VTKHDF_Recorder.cpp new file mode 100644 index 0000000000..d243b75f44 --- /dev/null +++ b/SRC/recorder/VTKHDF_Recorder.cpp @@ -0,0 +1,3609 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +#include "VTKHDF_Recorder.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hdf5.h" + +#ifdef _WIN32 +#include +#else +#include +#endif + + +// Static variable initialization +std::map VTKHDF_Recorder::vtktypes; + + + +// Constructor +SilentStream::SilentStream() : OPS_Stream(0) {} + +// Destructor +SilentStream::~SilentStream() {} + + + + +OutputDataHDF::OutputDataHDF() +{ + disp = false; vel = false; accel = false; + reaction = false; mass = false; unbalancedLoad = false; + stress3D6 = false; strain3D6 = false; + stress2D3 = false; strain2D3 = false; +} + +OutputDataHDF &OutputDataHDF::operator=(const OutputDataHDF &other) +{ + // Guard against self-assignment + if (this == &other) { + return *this; + } + // Copy all members + disp = other.disp; + vel = other.vel; + accel = other.accel; + reaction = other.reaction; + mass = other.mass; + unbalancedLoad = other.unbalancedLoad; + stress3D6 = other.stress3D6; + strain3D6 = other.strain3D6; + stress2D3 = other.stress2D3; + strain2D3 = other.strain2D3; + + + return *this; +} + + + +void* OPS_VTKHDF_Recorder() +{ + // Check minimum arguments + int numdata = OPS_GetNumRemainingInputArgs(); + if(numdata < 1) { + opserr << "WARNING: insufficient number of arguments\n"; + return 0; + } + + // Get filename + const char* name = OPS_GetString(); + + // Initialize default values + OutputDataHDF outputData; + std::vector eledata; + double dT = 0.0; + double rTolDt = 0.00001; + + // Parse remaining arguments + numdata = OPS_GetNumRemainingInputArgs(); + while(numdata > 0) { + const char* type = OPS_GetString(); + + // Displacement options + if(strcmp(type, "disp") == 0) { + outputData.disp = true; + } + // Velocity options + else if(strcmp(type, "vel") == 0) { + outputData.vel = true; + } + // Acceleration options + else if(strcmp(type, "accel") == 0) { + outputData.accel = true; + } + // Reaction options + else if(strcmp(type, "reaction") == 0) { + outputData.reaction = true; + } + // Other response options + else if(strcmp(type, "mass") == 0) { + outputData.mass = true; + } else if(strcmp(type, "unbalancedLoad") == 0) { + outputData.unbalancedLoad = true; + } + + else if (strcmp(type, "stress3D6") == 0) { + outputData.stress3D6 = true; + } else if (strcmp(type, "strain3D6") == 0) { + outputData.strain3D6 = true; + } + else if (strcmp(type, "stress2D3") == 0) { + outputData.stress2D3 = true; + } else if(strcmp(type, "strain2D3") == 0) { + outputData.strain2D3 = true; + } + // Time step options + else if(strcmp(type, "-dT") == 0) { + if(OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING: needs dT\n"; + return 0; + } + numdata = 1; + if(OPS_GetDoubleInput(&numdata, &dT) < 0) { + opserr << "WARNING: failed to read dT\n"; + return 0; + } + dT = (dT < 0) ? 0 : dT; + } + else if(strcmp(type, "-rTolDt") == 0) { + if(OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING: needs rTolDt\n"; + return 0; + } + numdata = 1; + if(OPS_GetDoubleInput(&numdata, &rTolDt) < 0) { + opserr << "WARNING: failed to read rTolDt\n"; + return 0; + } + rTolDt = (rTolDt < 0) ? 0 : rTolDt; + } + + numdata = OPS_GetNumRemainingInputArgs(); + } + // print summary of parmeters for the user + opserr << "VTKHDF_Recorder: " << name << " -dT " << dT << " -rTolDt " << rTolDt << endln; + opserr << "disp " << (outputData.disp ? "true" : "false") << endln; + opserr << "vel " << (outputData.vel ? "true" : "false") << endln; + opserr << "accel " << (outputData.accel ? "true" : "false") << endln; + opserr << "reaction " << (outputData.reaction ? "true" : "false") << endln; + opserr << "mass " << (outputData.mass ? "true" : "false") << endln; + opserr << "unbalancedLoad " << (outputData.unbalancedLoad ? "true" : "false") << endln; + opserr << "stress3D6 " << (outputData.stress3D6 ? "true" : "false") << endln; + opserr << "strain3D6 " << (outputData.strain3D6 ? "true" : "false") << endln; + opserr << "stress2D3 " << (outputData.stress2D3 ? "true" : "false") << endln; + opserr << "strain2D3 " << (outputData.strain2D3 ? "true" : "false") << endln; + + // Create the recorder + return new VTKHDF_Recorder(name, outputData, eledata, dT, rTolDt); +} + +VTKHDF_Recorder::VTKHDF_Recorder(const char *inputName, + const OutputDataHDF& outData, + const std::vector& edata, + double dt, double rTolDt) + :Recorder(RECORDER_TAGS_VTKHDF_Recorder), + // Initialize member variables + name(nullptr), + outputData(outData), + theDomain(0), + nextTimeStampToRecord(0.0), + deltaT(dt), + relDeltaTTol(rTolDt), + counter(0), + initializationDone(false), + initDone(false) +{ + + + name = new char[strlen(inputName) + 1]; + strcpy(name, inputName); + + + VTKHDF_Recorder::setVTKType(); + + // ----------------------- + // 1) Create (or overwrite) the HDF5 file using the C API + // ----------------------- + file_id = H5Fcreate(name, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + if (file_id < 0) { + opserr << "Error: Could not create HDF5 file " << name << endln; + return; // Handle the error as needed, or throw an exception + } + + // 4) Create the group "/VTKHDF" + group_id = H5Gcreate(file_id, "/VTKHDF", + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (group_id < 0) { + opserr << "Error: Could not create group '/VTKHDF' in HDF5 file " << name << endln; + H5Fclose(file_id); + return; + } + + // ----------------------- + // 2) Write the "Version" attribute (two integers [2, 3]) + // ----------------------- + // Create a simple 1D dataspace for two integers + hsize_t dims[1] = {2}; + hid_t version_dataspace_id = H5Screate_simple(1, dims, nullptr); + if (version_dataspace_id < 0) { + opserr << "Error: Could not create dataspace for 'Version' attribute in " + << name << endln; + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + + hid_t version_attr_id = H5Acreate(group_id, + "Version", + H5T_NATIVE_INT, + version_dataspace_id, + H5P_DEFAULT, + H5P_DEFAULT); + if (version_attr_id < 0) { + opserr << "Error: Could not create attribute 'Version' in group '/VTKHDF' in file " + << name << endln; + H5Sclose(version_dataspace_id); + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + + int version_data[2] = {2, 3}; + herr_t status = H5Awrite(version_attr_id, H5T_NATIVE_INT, version_data); + if (status < 0) { + opserr << "Error: Could not write 'Version' attribute in file " << name << endln; + H5Aclose(version_attr_id); + H5Sclose(version_dataspace_id); + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + + // Close version attribute and dataspace + H5Aclose(version_attr_id); + H5Sclose(version_dataspace_id); + + // ----------------------- + // 3) Write the "Type" attribute: "UnstructuredGrid" + // ----------------------- + // Create a dataspace for a single (scalar) string + hid_t type_dataspace_id = H5Screate(H5S_SCALAR); + if (type_dataspace_id < 0) { + opserr << "Error: Could not create dataspace for 'Type' attribute in file " + << name << endln; + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + + // Create a string datatype (fixed-length or variable-length). + // Here we use a fixed-length approach with the length of the string. + const char *typeStr = "UnstructuredGrid"; + size_t typeLen = strlen(typeStr); + + hid_t str_type_id = H5Tcopy(H5T_C_S1); + if (str_type_id < 0) { + opserr << "Error: Could not copy H5T_C_S1 for attribute 'Type' in file " + << name << endln; + H5Sclose(type_dataspace_id); + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + // Set the size of the string type (including space for '\0', if desired) + status = H5Tset_size(str_type_id, typeLen); + if (status < 0) { + opserr << "Error: Could not set size for 'Type' string in file " << name << endln; + H5Tclose(str_type_id); + H5Sclose(type_dataspace_id); + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + // Decide how to handle strings shorter than typeLen (null-pad, etc.) + // For example: + H5Tset_strpad(str_type_id, H5T_STR_NULLTERM); + + // Create the attribute + hid_t type_attr_id = H5Acreate(group_id, + "Type", + str_type_id, + type_dataspace_id, + H5P_DEFAULT, + H5P_DEFAULT); + if (type_attr_id < 0) { + opserr << "Error: Could not create attribute 'Type' in group '/VTKHDF' in file " + << name << endln; + H5Tclose(str_type_id); + H5Sclose(type_dataspace_id); + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + + // Write the string + status = H5Awrite(type_attr_id, str_type_id, typeStr); + if (status < 0) { + opserr << "Error: Could not write attribute 'Type' in file " << name << endln; + H5Aclose(type_attr_id); + H5Tclose(str_type_id); + H5Sclose(type_dataspace_id); + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + + // Close all resources + H5Aclose(type_attr_id); + H5Tclose(str_type_id); + H5Sclose(type_dataspace_id); + + // ----------------------- + // 4) create pointData group "/VTKHDF/pointData" + // ----------------------- + + point_data_group = H5Gcreate(group_id, "/VTKHDF/PointData", + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (point_data_group < 0) { + opserr << "Error: Could not create group '/VTKHDF/pointData' in HDF5 file " << name << endln; + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + + // ----------------------- + // 5) create Cells group "/VTKHDF/CellData" + // ----------------------- + cell_data_group = H5Gcreate(group_id, "/VTKHDF/CellData", + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (cell_data_group < 0) { + opserr << "Error: Could not create group '/VTKHDF/CellData' in HDF5 file " << name << endln; + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + + // ----------------------- + // 6) create Points dataset "/VTKHDF/Points" with shape (0,3) and resizable (unlimited,3) + // ----------------------- + { + hsize_t dims[2] = {0, 3}; + hsize_t maxdims[2] = {H5S_UNLIMITED, 3}; + hid_t space_id = H5Screate_simple(2, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'Points'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[2] = {100, 3}; + H5Pset_chunk(plist_id, 2, chunk_dims); + + hid_t dset_id = H5Dcreate( + group_id, "Points", + H5T_NATIVE_DOUBLE, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'Points'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + + } + + // ----------------------- + // 7) create Connectivity dataset "/VTKHDF/Connectivity" with shape (0,) and resizable (unlimited) + // ----------------------- + { + hsize_t dims[1] = {0}; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + hid_t space_id = H5Screate_simple(1, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'Connectivity'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[1] = {100}; + H5Pset_chunk(plist_id, 1, chunk_dims); + + hid_t dset_id = H5Dcreate( + group_id, "Connectivity", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'Connectivity'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + + } + + + // ----------------------- + // 8) create Offset dataset "/VTKHDF/Offsets" with shape (0,) and resizable (unlimited) + // ----------------------- + { + hsize_t dims[1] = {0}; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + hid_t space_id = H5Screate_simple(1, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'Offset'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[1] = {100}; + H5Pset_chunk(plist_id, 1, chunk_dims); + + hid_t dset_id = H5Dcreate( + group_id, "Offsets", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'Offset'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + + } + + // -------------------------------- + // 9) create the dataset VTKHDF/Types with shape (0,) and resizable (unlimited) + // -------------------------------- + { + hsize_t dims[1] = {0}; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + hid_t space_id = H5Screate_simple(1, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'Types'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[1] = {100}; + H5Pset_chunk(plist_id, 1, chunk_dims); + + hid_t dset_id = H5Dcreate( + group_id, "Types", + H5T_NATIVE_UCHAR, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'Types'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + + } + + + // -------------------------------- + // 10) create a steps group "/VTKHDF/steps" + // -------------------------------- + steps_group = H5Gcreate(group_id, "/VTKHDF/Steps", + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (steps_group < 0) { + opserr << "Error: Could not create group '/VTKHDF/steps' in HDF5 file " << name << endln; + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + + // -------------------------------- + // 11) create NSteps attribute for steps group and set it zero + // -------------------------------- + // Create a dataspace for a single integer + { + // Create NSteps attribute + const char* attr_name = "NSteps"; + hsize_t dims[1] = {1}; + hid_t nsteps_dataspace_id = H5Screate_simple(1, dims, nullptr); + hid_t nsteps_attr_id = H5Acreate(steps_group, + attr_name, + H5T_NATIVE_INT, + nsteps_dataspace_id, + H5P_DEFAULT, + H5P_DEFAULT); + + int nsteps_data = 0; + herr_t status = H5Awrite(nsteps_attr_id, H5T_NATIVE_INT, &nsteps_data); + + // Check overall success and cleanup + if (nsteps_dataspace_id < 0 || nsteps_attr_id < 0 || status < 0) { + opserr << "Error: Failed to initialize 'NSteps' attribute in file " << name << endln; + if (nsteps_attr_id >= 0) H5Aclose(nsteps_attr_id); + if (nsteps_dataspace_id >= 0) H5Sclose(nsteps_dataspace_id); + if (steps_group >= 0) H5Gclose(steps_group); + if (group_id >= 0) H5Gclose(group_id); + if (file_id >= 0) H5Fclose(file_id); + return; + } + + // Clean up handles + H5Aclose(nsteps_attr_id); + H5Sclose(nsteps_dataspace_id); + } + + // -------------------------------- + // 12) + // create groups NumberOfPoints and NumberOfCells + // and NumberOfConnectivityIds with + // resizable length zero shape + // Create NumberOfPoints dataset + // -------------------------------- + { + hsize_t dims[1] = {0}; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + hid_t space_id = H5Screate_simple(1, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'NumberOfPoints'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[1] = {1}; + H5Pset_chunk(plist_id, 1, chunk_dims); + + hid_t dset_id = H5Dcreate( + group_id, "NumberOfPoints", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'NumberOfPoints'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + } + + // Create NumberOfCells dataset + { + hsize_t dims[1] = {0}; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + hid_t space_id = H5Screate_simple(1, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'NumberOfCells'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[1] = {1}; + H5Pset_chunk(plist_id, 1, chunk_dims); + + hid_t dset_id = H5Dcreate( + group_id, "NumberOfCells", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'NumberOfCells'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + } + + // Create NumberOfConnectivityIds dataset + { + hsize_t dims[1] = {0}; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + hid_t space_id = H5Screate_simple(1, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'NumberOfConnectivityIds'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[1] = {1}; + H5Pset_chunk(plist_id, 1, chunk_dims); + + hid_t dset_id = H5Dcreate( + group_id, "NumberOfConnectivityIds", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'NumberOfConnectivityIds'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + } + + + // ----------------------- + // 13) + // create the dataset VTKHDF/Steps/PointOffsets with shape (0) and resizable + // create the dataset VTKHDF/Steps/Values with shape (0) and resizable + // create the dataset VTKHDF/Steps/PartOffsets with shape (0) and resizable + // create the dataset VTKHDF/Steps/NumberOfParts with shape (0) and resizable + // ----------------------- + // Create PointOffsets dataset + { + hsize_t dims[1] = {0}; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + hid_t space_id = H5Screate_simple(1, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'PointOffsets'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[1] = {1}; + H5Pset_chunk(plist_id, 1, chunk_dims); + + hid_t dset_id = H5Dcreate( + steps_group, "PointOffsets", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'PointOffsets'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + } + + // Create Values dataset + { + hsize_t dims[1] = {0}; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + hid_t space_id = H5Screate_simple(1, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'Values'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[1] = {1}; + H5Pset_chunk(plist_id, 1, chunk_dims); + + hid_t dset_id = H5Dcreate( + steps_group, "Values", + H5T_NATIVE_DOUBLE, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'Values'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + } + + // Create PartOffsets dataset + { + hsize_t dims[1] = {0}; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + hid_t space_id = H5Screate_simple(1, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'PartOffsets'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[1] = {1}; + H5Pset_chunk(plist_id, 1, chunk_dims); + + hid_t dset_id = H5Dcreate( + steps_group, "PartOffsets", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'PartOffsets'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + } + + // Create NumberOfParts dataset + { + hsize_t dims[1] = {0}; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + hid_t space_id = H5Screate_simple(1, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'NumberOfParts'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[1] = {100}; + H5Pset_chunk(plist_id, 1, chunk_dims); + + hid_t dset_id = H5Dcreate( + steps_group, "NumberOfParts", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'NumberOfParts'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + } + + // -------------------------------- + // 14) + // create dataset VTKHDF/Steps/CellOffsets with shape (0,1) and resizable (unlimited,1) + // create dataset VTKHDF/Steps/ConnectivityIdOffsets with shape (0,1) and resizable (unlimited,1) + // -------------------------------- + // Create CellOffsets dataset + { + hsize_t dims[2] = {0, 1}; + hsize_t maxdims[2] = {H5S_UNLIMITED, 1}; + hid_t space_id = H5Screate_simple(2, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'CellOffsets'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[2] = {1, 1}; + H5Pset_chunk(plist_id, 2, chunk_dims); + + hid_t dset_id = H5Dcreate( + steps_group, "CellOffsets", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'CellOffsets'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + } + + + // Create ConnectivityIdOffsets dataset + { + hsize_t dims[2] = {0, 1}; + hsize_t maxdims[2] = {H5S_UNLIMITED, 1}; + hid_t space_id = H5Screate_simple(2, dims, maxdims); + if (space_id < 0) { + opserr << "Error creating dataspace for 'ConnectivityIdOffsets'\n"; + return; + } + + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + hsize_t chunk_dims[2] = {1, 1}; + H5Pset_chunk(plist_id, 2, chunk_dims); + + hid_t dset_id = H5Dcreate( + steps_group, "ConnectivityIdOffsets", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + if (dset_id < 0) { + opserr << "Error creating dataset 'ConnectivityIdOffsets'\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + H5Pclose(plist_id); + H5Dclose(dset_id); + } + + // -------------------------------- + // 15) + // create group VTKHDF/Steps/PointDataOffsets + // create group VTKHDF/Steps/CellDataOffsets + // create group VTKHDF/Steps/FieldDataOffsets + // create group VTKHDF/Steps/FieldDataSizes + // -------------------------------- + // Create PointDataOffsets group + { + point_data_offsets_group = H5Gcreate(steps_group, "PointDataOffsets", + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (point_data_offsets_group < 0) { + opserr << "Error: Could not create group '/VTKHDF/Steps/PointDataOffsets' in HDF5 file " << name << endln; + H5Gclose(steps_group); + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + } + + // Create CellDataOffsets group + { + cell_data_offsets_group = H5Gcreate(steps_group, "CellDataOffsets", + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (cell_data_offsets_group < 0) { + opserr << "Error: Could not create group '/VTKHDF/Steps/CellDataOffsets' in HDF5 file " << name << endln; + H5Gclose(steps_group); + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + } + + // Create FieldDataOffsets group + { + hid_t field_data_offsets_group = H5Gcreate(steps_group, "FieldDataOffsets", + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (field_data_offsets_group < 0) { + opserr << "Error: Could not create group '/VTKHDF/Steps/FieldDataOffsets' in HDF5 file " << name << endln; + H5Gclose(steps_group); + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + } + + // Create FieldDataSizes group + { + hid_t field_data_sizes_group = H5Gcreate(steps_group, "FieldDataSizes", + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (field_data_sizes_group < 0) { + opserr << "Error: Could not create group '/VTKHDF/Steps/FieldDataSizes' in HDF5 file " << name << endln; + H5Gclose(steps_group); + H5Gclose(group_id); + H5Fclose(file_id); + return; + } + } + + // -------------------------------- + // 16) + // check if displacement is requested create displacement dataset under PointDataOffsets + // Create dataset for displacement if requested + // -------------------------------- + if (outputData.disp) { + // Define initial dimensions as 0 since we don't know the number of nodes yet + hsize_t dims[1] = {0}; // Initial size (0 rows) + hsize_t max_dims[1] = {H5S_UNLIMITED}; // Maximum size (unlimited rows) + + // Create a dataspace with these dimensions + hid_t space_id = H5Screate_simple(1, dims, max_dims); + if (space_id < 0) { + opserr << "Error creating dataspace for displacement data\n"; + return; + } + + // Create a property list for chunked storage + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + if (plist_id < 0) { + opserr << "Error creating property list for displacement dataset\n"; + H5Sclose(space_id); + return; + } + + // Define the chunk size (e.g., 100 rows per chunk) + hsize_t chunk_dims[1] = {100}; + if (H5Pset_chunk(plist_id, 1, chunk_dims) < 0) { + opserr << "Error setting chunk size for displacement dataset\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + // Create the dataset with chunked storage + hid_t dset_id = H5Dcreate( + point_data_offsets_group, "displacement", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + + if (dset_id < 0) { + opserr << "Error creating dataset for displacement\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + // Clean up + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + } + + // check if displacement is requested create pointData group for displacement + // Create group for displacement if requested + if (outputData.disp) { + + // Define initial dimensions as 0 since we don't know the number of nodes yet + hsize_t dims[2] = {0, 3}; // Initial size (0 rows, 3 columns) + hsize_t max_dims[2] = {H5S_UNLIMITED, 3}; // Maximum size (unlimited rows, fixed 3 columns) + + // Create a dataspace with these dimensions + hid_t space_id = H5Screate_simple(2, dims, max_dims); + if (space_id < 0) { + opserr << "Error creating dataspace for displacement data\n"; + return; + } + + // Create a property list for chunked storage + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + if (plist_id < 0) { + opserr << "Error creating property list for displacement dataset\n"; + H5Sclose(space_id); + return; + } + + // Define the chunk size (e.g., 100 rows per chunk) + hsize_t chunk_dims[2] = {100, 3}; + if (H5Pset_chunk(plist_id, 2, chunk_dims) < 0) { + opserr << "Error setting chunk size for displacement dataset\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + // Create the dataset with chunked storage + hid_t dset_id = H5Dcreate( + point_data_group, "displacement", + H5T_NATIVE_DOUBLE, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + + if (dset_id < 0) { + opserr << "Error creating dataset for displacement\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + // Clean up + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + } + + // check if the acceleration is requested create offset dataset under PointDataOffsets + // Create dataset for acceleration if requested + if (outputData.accel) { + // Define initial dimensions as 0 since we don't know the number of nodes yet + hsize_t dims[1] = {0}; // Initial size (0 rows) + hsize_t max_dims[1] = {H5S_UNLIMITED}; // Maximum size (unlimited rows) + + // Create a dataspace with these dimensions + hid_t space_id = H5Screate_simple(1, dims, max_dims); + if (space_id < 0) { + opserr << "Error creating dataspace for acceleration data\n"; + return; + } + + // Create a property list for chunked storage + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + if (plist_id < 0) { + opserr << "Error creating property list for acceleration dataset\n"; + H5Sclose(space_id); + return; + } + + // Define the chunk size (e.g., 100 rows per chunk) + hsize_t chunk_dims[1] = {100}; + if (H5Pset_chunk(plist_id, 1, chunk_dims) < 0) { + opserr << "Error setting chunk size for acceleration dataset\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + // Create the dataset with chunked storage + hid_t dset_id = H5Dcreate( + point_data_offsets_group, "acceleration", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + + if (dset_id < 0) { + opserr << "Error creating dataset for acceleration\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + // Clean up + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + } + + // check if the acceleration is requested create pointData group for acceleration + // Create group for acceleration if requested + if (outputData.accel) { + + // Define initial dimensions as 0 since we don't know the number of nodes yet + hsize_t dims[2] = {0, 3}; // Initial size (0 rows, 3 columns) + hsize_t max_dims[2] = {H5S_UNLIMITED, 3}; // Maximum size (unlimited rows, fixed 3 columns) + + // Create a dataspace with these dimensions + hid_t space_id = H5Screate_simple(2, dims, max_dims); + if (space_id < 0) { + opserr << "Error creating dataspace for acceleration data\n"; + return; + } + + // Create a property list for chunked storage + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + if (plist_id < 0) { + opserr << "Error creating property list for acceleration dataset\n"; + H5Sclose(space_id); + return; + } + + // Define the chunk size (e.g., 100 rows per chunk) + hsize_t chunk_dims[2] = {100, 3}; + if (H5Pset_chunk(plist_id, 2, chunk_dims) < 0) { + opserr << "Error setting chunk size for acceleration dataset\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + // Create the dataset with chunked storage + hid_t dset_id = H5Dcreate( + point_data_group, "acceleration", + H5T_NATIVE_DOUBLE, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + + if (dset_id < 0) { + opserr << "Error creating dataset for acceleration\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + // Clean up + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + } + + // check if the velocity is requested create offset dataset under PointDataOffsets + // Create dataset for velocity if requested + if (outputData.vel) { + // Define initial dimensions as 0 since we don't know the number of nodes yet + hsize_t dims[1] = {0}; // Initial size (0 rows) + hsize_t max_dims[1] = {H5S_UNLIMITED}; // Maximum size (unlimited rows) + + // Create a dataspace with these dimensions + hid_t space_id = H5Screate_simple(1, dims, max_dims); + if (space_id < 0) { + opserr << "Error creating dataspace for velocity data\n"; + return; + } + + // Create a property list for chunked storage + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + if (plist_id < 0) { + opserr << "Error creating property list for velocity dataset\n"; + H5Sclose(space_id); + return; + } + + // Define the chunk size (e.g., 100 rows per chunk) + hsize_t chunk_dims[1] = {100}; + if (H5Pset_chunk(plist_id, 1, chunk_dims) < 0) { + opserr << "Error setting chunk size for velocity dataset\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + // Create the dataset with chunked storage + hid_t dset_id = H5Dcreate( + point_data_offsets_group, "velocity", + H5T_NATIVE_INT, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + + if (dset_id < 0) { + opserr << "Error creating dataset for velocity\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + // Clean up + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + } + + // check if the velocity is requested create pointData group for velocity + // Create group for velocity if requested + if (outputData.vel) { + + // Define initial dimensions as 0 since we don't know the number of nodes yet + hsize_t dims[2] = {0, 3}; // Initial size (0 rows, 3 columns) + hsize_t max_dims[2] = {H5S_UNLIMITED, 3}; // Maximum size (unlimited rows, fixed 3 columns) + + // Create a dataspace with these dimensions + hid_t space_id = H5Screate_simple(2, dims, max_dims); + if (space_id < 0) { + opserr << "Error creating dataspace for velocity data\n"; + return; + } + + // Create a property list for chunked storage + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + if (plist_id < 0) { + opserr << "Error creating property list for velocity dataset\n"; + H5Sclose(space_id); + return; + } + + // Define the chunk size (e.g., 100 rows per chunk) + hsize_t chunk_dims[2] = {100, 3}; + if (H5Pset_chunk(plist_id, 2, chunk_dims) < 0) { + opserr << "Error setting chunk size for velocity dataset\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + // Create the dataset with chunked storage + hid_t dset_id = H5Dcreate( + point_data_group, "velocity", + H5T_NATIVE_DOUBLE, + space_id, + H5P_DEFAULT, plist_id, H5P_DEFAULT + ); + + if (dset_id < 0) { + opserr << "Error creating dataset for velocity\n"; + H5Pclose(plist_id); + H5Sclose(space_id); + return; + } + + // Clean up + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id); + } + + + + if (outputData.stress3D6) { + int res = 0; + // Create 3DStress6 dataset + const char* dataset_name = "stress3D6"; + hsize_t ncols = 6; + hsize_t chunk_rows = 500; + hid_t type_id = H5T_NATIVE_DOUBLE; + hsize_t max_rows = H5S_UNLIMITED; + res = this->createDataset(cell_data_group, dataset_name, ncols, chunk_rows, type_id, max_rows); + + + // Create 3DStress6 offset dataset + dataset_name = "stress3D6"; + ncols = 1; + chunk_rows = 500; + type_id = H5T_NATIVE_INT; + max_rows = H5S_UNLIMITED; + // res += this->createDataset(cell_data_offsets_group, dataset_name, ncols, chunk_rows, type_id, max_rows); + res += this->createOffsetDataset(cell_data_offsets_group, dataset_name, chunk_rows, type_id, max_rows); + + current_Stress3D6Offset = 0; + if (res < 0) { + opserr << "Error creating 3DStress6 datasets\n"; + return; + } + } + + + if (outputData.strain3D6) { + int res = 0; + // Create 3DStrain6 dataset + const char* dataset_name = "strain3D6"; + hsize_t ncols = 6; + hsize_t chunk_rows = 500; + hid_t type_id = H5T_NATIVE_DOUBLE; + hsize_t max_rows = H5S_UNLIMITED; + res = this->createDataset(cell_data_group, dataset_name, ncols, chunk_rows, type_id, max_rows); + + // Create 3DStrain6 offset dataset + dataset_name = "strain3D6"; + ncols = 1; + chunk_rows = 500; + type_id = H5T_NATIVE_INT; + max_rows = H5S_UNLIMITED; + // res += this->createDataset(cell_data_offsets_group, dataset_name, ncols, chunk_rows, type_id, max_rows); + res += this->createOffsetDataset(cell_data_offsets_group, dataset_name, chunk_rows, type_id, max_rows); + + current_Strain3D6Offset = 0; + if (res < 0) { + opserr << "Error creating 3DStrain6 datasets\n"; + return; + } + } + if (outputData.stress2D3) { + int res = 0; + // Create 2DStress3 dataset + const char* dataset_name = "stress2D3"; + hsize_t ncols = 3; + hsize_t chunk_rows = 500; + hid_t type_id = H5T_NATIVE_DOUBLE; + hsize_t max_rows = H5S_UNLIMITED; + res = this->createDataset(cell_data_group, dataset_name, ncols, chunk_rows, type_id, max_rows); + + // Create 2DStress3 offset dataset + dataset_name = "stress2D3"; + ncols = 1; + chunk_rows = 500; + type_id = H5T_NATIVE_INT; + max_rows = H5S_UNLIMITED; + res += this->createOffsetDataset(cell_data_offsets_group, dataset_name, chunk_rows, type_id, max_rows); + + + current_Stress2D3Offset = 0; + if (res < 0) { + opserr << "Error creating 2DStress3 datasets\n"; + return; + } + } + + if (outputData.strain2D3) { + int res = 0; + // Create 2DStrain3 dataset + const char* dataset_name = "strain2D3"; + hsize_t ncols = 3; + hsize_t chunk_rows = 500; + hid_t type_id = H5T_NATIVE_DOUBLE; + hsize_t max_rows = H5S_UNLIMITED; + res = this->createDataset(cell_data_group, dataset_name, ncols, chunk_rows, type_id, max_rows); + + // Create 2DStrain3 offset dataset + dataset_name = "strain2D3"; + ncols = 1; + chunk_rows = 500; + type_id = H5T_NATIVE_INT; + max_rows = H5S_UNLIMITED; + res += this->createOffsetDataset(cell_data_offsets_group, dataset_name, chunk_rows, type_id, max_rows); + + current_Strain2D3Offset = 0; + if (res < 0) { + opserr << "Error creating 2DStrain3 datasets\n"; + return; + } + } + + + + + + current_PointOffset = 0; + current_CellOffset = 0; + current_ConnectivityIdOffset = 0; + current_PartOffset = 0; + + next_PointOffset = 0; + next_CellOffset = 0; + next_ConnectivityIdOffset = 0; + next_PartOffset = 0; + + + initDone = false; + numSteps = 0; + + // opserr << "initilization done\n"; + CurrentDispOffset = 0; + CurrentVelOffset = 0; + CurrentAccelOffset = 0; + +} + + + + + +VTKHDF_Recorder::VTKHDF_Recorder() + :Recorder(RECORDER_TAGS_VTKHDF_Recorder), + theDomain(0), + nextTimeStampToRecord(0.0), + deltaT(0.0), + relDeltaTTol(0.00001), + counter(0), + initializationDone(false) +{ + name = NULL; + VTKHDF_Recorder::setVTKType(); + initDone = false; + +} + + +int VTKHDF_Recorder::writeMesh() { + // 1) Check domain + if (theDomain == nullptr) { + opserr << "WARNING: No domain found -- VTKHDF_Recorder::writeMesh\n"; + return -1; + } + + // Clear old data structures (if you store them as class members) + theNodeMapping.clear(); + theEleMapping.clear(); + theNodeTags.clear(); + theEleTags.clear(); + theEleClassTags.clear(); + theEleVtkTags.clear(); + theEleVtkOffsets.clear(); + + // 2) Gather node info + NodeIter &theNodes = theDomain->getNodes(); + Node *theNode; + numNode = 0; + maxNDM = 0; // max spatial dimension + maxNDF = 0; // max degrees of freedom + + while ((theNode = theNodes()) != nullptr) { + int nodeTag = theNode->getTag(); + + const Vector &crd = theNode->getCrds(); + if (crd.Size() > maxNDM) { + maxNDM = crd.Size(); + } + + const Vector &disp = theNode->getTrialDisp(); + if (disp.Size() > maxNDF) { + maxNDF = disp.Size(); + } + + // Build mapping (nodeTag -> index) + theNodeMapping[nodeTag] = numNode; + theNodeTags.push_back(nodeTag); + numNode++; + } + + // 3) Gather element info + ElementIter &theElements = theDomain->getElements(); + Element *theElement; + numElement = 0; + numConnectivityIds = 0; + + theEleVtkOffsets.push_back(numConnectivityIds); + while ((theElement = theElements()) != nullptr) { + int eleTag = theElement->getTag(); + int classTag = theElement->getClassTag(); + + // Check if recognized by our VTK type map + auto it = vtktypes.find(classTag); + if (it != vtktypes.end()) { + int vtkType = it->second; + + theEleMapping[eleTag] = numElement; + theEleTags.push_back(eleTag); + theEleClassTags.push_back(classTag); + theEleVtkTags.push_back(vtkType); + + const ID &extNodes = theElement->getExternalNodes(); + int nN = extNodes.Size(); + + // Offsets array is cumulative + numConnectivityIds += nN; + theEleVtkOffsets.push_back(numConnectivityIds); + + numElement++; + } else { + // Possibly skip subdomains or warn for unrecognized element + if (classTag != ELE_TAG_Subdomain) { + opserr << "VTKHDF_Recorder::writeMesh - unknown vtk type for element " + << eleTag << " (classTag=" << classTag << ")" << endln; + } + } + } + + // ------------------------------------------------------------- + // 4) Build arrays for HDF5 + // ------------------------------------------------------------- + + // (A) Points => shape (numNode,3) + std::vector pointsData(numNode * 3, 0.0); + { + NodeIter &theNodes2 = theDomain->getNodes(); + while ((theNode = theNodes2()) != nullptr) { + int nodeTag = theNode->getTag(); + int mappedIndex = theNodeMapping[nodeTag]; + const Vector &crd = theNode->getCrds(); + + pointsData[3 * mappedIndex + 0] = (crd.Size() > 0) ? crd(0) : 0.0; + pointsData[3 * mappedIndex + 1] = (crd.Size() > 1) ? crd(1) : 0.0; + pointsData[3 * mappedIndex + 2] = (crd.Size() > 2) ? crd(2) : 0.0; + } + } + + // (B) Connectivity => shape (numConnectivityIds) + std::vector connectivity(numConnectivityIds); + { + ElementIter &theElements2 = theDomain->getElements(); + int idx = 0; + while ((theElement = theElements2()) != nullptr) { + int classTag = theElement->getClassTag(); + if (vtktypes.find(classTag) != vtktypes.end()) { + const ID &extNodes = theElement->getExternalNodes(); + for (int i = 0; i < extNodes.Size(); i++) { + int nodeTag = extNodes(i); + connectivity[idx++] = static_cast(theNodeMapping[nodeTag]); + } + } + } + } + + // (C) Offsets => shape (numElement+1,1) so that ParaView can read it + std::vector offsets(theEleVtkOffsets.begin(), theEleVtkOffsets.end()); + + + // (D) Types => shape (numElement) + std::vector types(theEleVtkTags.begin(), theEleVtkTags.end()); + + // opserr << " Gathering data done\n"; + // ------------------------------------------------------------- + // 5) Open group "/VTKHDF" from the already opened file_id + // ------------------------------------------------------------- + // Make sure file_id is still valid (i.e., not closed in constructor). + hid_t vtkhdfGroup = H5Gopen(file_id, "/VTKHDF", H5P_DEFAULT); + if (vtkhdfGroup < 0) { + opserr << "Error: Could not open group '/VTKHDF' in file to write mesh.\n"; + return -1; + } + + // ------------------------------------------------------------- + // 6) resize the Point and add the points data + // ------------------------------------------------------------- + { + // Open the existing dataset + hid_t dset_id = H5Dopen(vtkhdfGroup, "Points", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error opening dataset 'Points'\n"; + H5Gclose(vtkhdfGroup); + return -1; + } + + // Get the current dataspace and dimensions + hid_t space_id = H5Dget_space(dset_id); + if (space_id < 0) { + opserr << "Error getting dataspace for 'Points'\n"; + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Get the current dimensions + hsize_t current_dims[2]; + if (H5Sget_simple_extent_dims(space_id, current_dims, NULL) < 0) { + opserr << "Error getting current dimensions\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Calculate new dimensions (current rows + new rows, same columns) + hsize_t new_dims[2] = {current_dims[0] + static_cast(numNode), 3}; + + // Extend the dataset + if (H5Dset_extent(dset_id, new_dims) < 0) { + opserr << "Error setting new extent for 'Points'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Get the new dataspace + hid_t new_space_id = H5Dget_space(dset_id); + if (new_space_id < 0) { + opserr << "Error getting new dataspace for 'Points'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Select the hyperslab where we want to write new data + hsize_t offset[2] = {current_dims[0], 0}; // Start from the end of existing data + hsize_t count[2] = {static_cast(numNode), 3}; // Size of new data + if (H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0) { + opserr << "Error selecting hyperslab\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Create memory space for new data + hid_t mem_space_id = H5Screate_simple(2, count, NULL); + if (mem_space_id < 0) { + opserr << "Error creating memory space for 'Points'\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Write only the new data + if (H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, mem_space_id, new_space_id, H5P_DEFAULT, pointsData.data()) < 0) { + opserr << "Error writing data to 'Points'\n"; + } + + // Close all resources + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + + } + // opserr << "Points done\n"; + + + // ------------------------------------------------------------- + // 7) resize the Connectivity and add the connectivity data + // ------------------------------------------------------------- + { + // Open the existing dataset + hid_t dset_id = H5Dopen(vtkhdfGroup, "Connectivity", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error opening dataset 'Connectivity'\n"; + H5Gclose(vtkhdfGroup); + return -1; + } + + // Get the current dataspace and dimensions + hid_t space_id = H5Dget_space(dset_id); + if (space_id < 0) { + opserr << "Error getting dataspace for 'Connectivity'\n"; + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Get the current dimensions + hsize_t current_dims[1]; + if (H5Sget_simple_extent_dims(space_id, current_dims, NULL) < 0) { + opserr << "Error getting current dimensions\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Calculate new dimensions (current rows + new rows, same columns) + hsize_t new_dims[1] = {current_dims[0] + static_cast(numConnectivityIds)}; + + // Extend the dataset + if (H5Dset_extent(dset_id, new_dims) < 0) { + opserr << "Error setting new extent for 'Connectivity'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Get the new dataspace + hid_t new_space_id = H5Dget_space(dset_id); + if (new_space_id < 0) { + opserr << "Error getting new dataspace for 'Connectivity'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Select the hyperslab where we want to write new data + hsize_t offset[1] = {current_dims[0]}; // Start from the end of existing data + hsize_t count[1] = {static_cast(numConnectivityIds)}; // Size of new data + if (H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0) { + opserr << "Error selecting hyperslab\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Create memory space for new data + hid_t mem_space_id = H5Screate_simple(1, count, NULL); + if (mem_space_id < 0) { + opserr << "Error creating memory space for 'Connectivity'\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Write only the new data + if (H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space_id, new_space_id, H5P_DEFAULT, connectivity.data()) < 0) { + opserr << "Error writing data to 'Connectivity'\n"; + } + + // Close all resources + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + } + // opserr << "Connectivity done\n"; + + // ------------------------------------------------------------- + // 8) resize the Offsets and add the offsets data + // ------------------------------------------------------------- + { + // Open the existing dataset + hid_t dset_id = H5Dopen(vtkhdfGroup, "Offsets", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error opening dataset 'Offsets'\n"; + H5Gclose(vtkhdfGroup); + return -1; + } + + // Get the current dataspace and dimensions + hid_t space_id = H5Dget_space(dset_id); + if (space_id < 0) { + opserr << "Error getting dataspace for 'Offsets'\n"; + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Get the current dimensions + hsize_t current_dims[1]; + if (H5Sget_simple_extent_dims(space_id, current_dims, NULL) < 0) { + opserr << "Error getting current dimensions\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Calculate new dimensions (current rows + new rows, same columns) + hsize_t new_dims[1] = {current_dims[0] + static_cast(numElement+1)}; + + // Extend the dataset + if (H5Dset_extent(dset_id, new_dims) < 0) { + opserr << "Error setting new extent for 'Offsets'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Get the new dataspace + hid_t new_space_id = H5Dget_space(dset_id); + if (new_space_id < 0) { + opserr << "Error getting new dataspace for 'Offsets'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Select the hyperslab where we want to write new data + hsize_t offset[1] = {current_dims[0]}; // Start from the end of existing data + hsize_t count[1] = {static_cast(numElement+1)}; // Size of new data + + if (H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0) { + opserr << "Error selecting hyperslab\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Create memory space for new data + hid_t mem_space_id = H5Screate_simple(1, count, NULL); + if (mem_space_id < 0) { + opserr << "Error creating memory space for 'Offsets'\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Write only the new data + if (H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space_id, new_space_id, H5P_DEFAULT, offsets.data()) < 0) { + opserr << "Error writing data to 'Offsets'\n"; + } + + // Close all resources + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + } + // opserr << "Offsets done\n"; + + + // ------------------------------------------------------------- + // 9) resize the Types and add the types data + // ------------------------------------------------------------- + { + // Open the existing dataset + hid_t dset_id = H5Dopen(vtkhdfGroup, "Types", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error opening dataset 'Types'\n"; + H5Gclose(vtkhdfGroup); + return -1; + } + + // Get the current dataspace and dimensions + hid_t space_id = H5Dget_space(dset_id); + if (space_id < 0) { + opserr << "Error getting dataspace for 'Types'\n"; + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Get the current dimensions + hsize_t current_dims[1]; + if (H5Sget_simple_extent_dims(space_id, current_dims, NULL) < 0) { + opserr << "Error getting current dimensions\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Calculate new dimensions (current rows + new rows, same columns) + hsize_t new_dims[1] = {current_dims[0] + static_cast(numElement)}; + + // Extend the dataset + if (H5Dset_extent(dset_id, new_dims) < 0) { + opserr << "Error setting new extent for 'Types'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Get the new dataspace + hid_t new_space_id = H5Dget_space(dset_id); + if (new_space_id < 0) { + opserr << "Error getting new dataspace for 'Types'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Select the hyperslab where we want to write new data + hsize_t offset[1] = {current_dims[0]}; // Start from the end of existing data + hsize_t count[1] = {static_cast(numElement)}; // Size of new data + if (H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0) { + opserr << "Error selecting hyperslab\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Create memory space for new data + hid_t mem_space_id = H5Screate_simple(1, count, NULL); + if (mem_space_id < 0) { + opserr << "Error creating memory space for 'Types'\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + H5Gclose(vtkhdfGroup); + return -1; + } + + // Write only the new data + if (H5Dwrite(dset_id, H5T_NATIVE_UCHAR, mem_space_id, new_space_id, H5P_DEFAULT, types.data()) < 0) { + opserr << "Error writing data to 'Types'\n"; + } + + // Close all resources + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + } + // opserr << "Types done\n"; + H5Gclose(vtkhdfGroup); + + // ------------------------------------------------------------- + // 10 ) update the current offsets + // ------------------------------------------------------------- + // for having a changing mesh you may need to adjust this ofsset + // espically current_ConnectivityIdOffset and current_CellOffset + // right now we are assuming that the mesh is not changing + + + current_PointOffset = next_PointOffset; + current_CellOffset = next_CellOffset; + current_ConnectivityIdOffset = next_ConnectivityIdOffset; + current_PartOffset = next_PartOffset; + + next_PointOffset = current_PointOffset + numNode; + next_CellOffset = current_CellOffset + 0; + next_ConnectivityIdOffset = current_ConnectivityIdOffset + 0; + next_PartOffset = current_PartOffset + 0; + + + // ------------------------------------------------------------- + // 11 ) Edit specific recorders information + // ------------------------------------------------------------- + // 3DStress6 + + if (outputData.stress3D6) { + opserr << "Setting up stress3D6 responses\n"; + stress3D6Responses.clear(); + stress3D6Responses.reserve(numElement); + for (auto i: theEleTags) { + Element *theElement = theDomain->getElement(i); + SilentStream theOutputHandler; + const char* args[] = {"stress3D6"}; + Response *theResponse = theElement->setResponse(args, 1, theOutputHandler); + stress3D6Responses.push_back(theResponse); + } + } + + // 3DStrain6 + if (outputData.strain3D6) { + opserr << "Setting up strain3D6 responses\n"; + strain3D6Responses.clear(); + strain3D6Responses.reserve(numElement); + for (auto i: theEleTags) { + Element *theElement = theDomain->getElement(i); + SilentStream theOutputHandler; + const char* args[] = {"strain3D6"}; + Response *theResponse = theElement->setResponse(args, 1, theOutputHandler); + strain3D6Responses.push_back(theResponse); + } + } + + // 2DStress3 + if (outputData.stress2D3) { + opserr << "Setting up stress2D3 responses\n"; + stress2D3Responses.clear(); + stress2D3Responses.reserve(numElement); + for (auto i: theEleTags) { + // const char* istring = std::to_string(i).c_str(); + // opserr << istring << endln; + Element *theElement = theDomain->getElement(i); + SilentStream theOutputHandler; + const char* args[] = {"stress2D3"}; + Response *theResponse = theElement->setResponse(args, 1, theOutputHandler); + stress2D3Responses.push_back(theResponse); + } + } + + // 2DStrain3 + if (outputData.strain2D3) { + opserr << "Setting up strain2D3 responses\n"; + strain2D3Responses.clear(); + strain2D3Responses.reserve(numElement); + for (auto i: theEleTags) { + Element *theElement = theDomain->getElement(i); + SilentStream theOutputHandler; + const char* args[] = {"strain2D3"}; + Response *theResponse = theElement->setResponse(args, 1, theOutputHandler); + strain2D3Responses.push_back(theResponse); + } + } + + + + // ------------------------------------------------------------- + // Mark that we've(re)written the mesh + // ------------------------------------------------------------- + initDone = true; + return 0; +} + + +int VTKHDF_Recorder::record(int commitTag, double timeStamp) +{ + if (!initDone) { + this->writeMesh(); + } + + if (deltaT == 0.0 || timeStamp - nextTimeStampToRecord >= -deltaT * relDeltaTTol) { + if (this->writeStep(timeStamp) < 0) { + opserr << "VTKHDF_Recorder::record() - writeStep() failed\n"; + return -1; + } + + // // displacment + if (outputData.disp) { + // opserr<<"writeDisp"<writeDisp() < 0) { + opserr << "VTKHDF_Recorder::record() - writeDisp() failed\n"; + return -1; + } + } + + // // velocity + if (outputData.vel) { + // opserr<<"writeVel"<writeVel() < 0) { + opserr << "VTKHDF_Recorder::record() - writeVel() failed\n"; + return -1; + } + } + + // // acceleration + if (outputData.accel) { + // opserr<<"writeAccel"<writeAccel() < 0) { + opserr << "VTKHDF_Recorder::record() - writeAccel() failed\n"; + return -1; + } + } + + if (outputData.stress3D6) { + // opserr<<"writeStress3D"<writeStrees3D6() < 0) { + opserr << "VTKHDF_Recorder::record() - writeStress3D() failed\n"; + return -1; + } + } + + if (outputData.strain3D6) { + // opserr<<"writeStrain3D"<writeStrain3D6() < 0) { + opserr << "VTKHDF_Recorder::record() - writeStrain3D() failed\n"; + return -1; + } + } + + if (outputData.stress2D3) { + // opserr<<"writeStress2D"<writeStress2D3() < 0) { + opserr << "VTKHDF_Recorder::record() - writeStress2D() failed\n"; + return -1; + } + } + + if (outputData.strain2D3) { + // opserr<<"writeStrain2D"<writeStrain2D3() < 0) { + opserr << "VTKHDF_Recorder::record() - writeStrain2D() failed\n"; + return -1; + } + } + + if (deltaT != 0.0) { + nextTimeStampToRecord = timeStamp + deltaT; + } + } + return 0; +} + + +int VTKHDF_Recorder::writeStress2D3(void) { + + std::vector stressData(numElement * 3, 0.0); + for (auto i: theEleTags) { + Element *theEle = theDomain->getElement(i); + int MappedIndex = theEleMapping[i]; + if (stress2D3Responses[MappedIndex] == 0) { + continue; + } + stress2D3Responses[MappedIndex]->getResponse(); + Information &info = stress2D3Responses[MappedIndex]->getInformation(); + const Vector &stress = info.getData(); + for (int j = 0; j < 3; j++) { + stressData[3 * MappedIndex + j] = stress(j); + } + } + + int res = 0; + res += this->extendDataset(cell_data_group, "stress2D3", stressData.data(), H5T_NATIVE_DOUBLE, numElement, 3); + res += this->extendOffsetDataset(cell_data_offsets_group, "stress2D3", ¤t_Stress2D3Offset, H5T_NATIVE_INT, 1); + current_Stress2D3Offset += numElement; + return res; +} + +int VTKHDF_Recorder::writeStrain2D3(void) { + + std::vector strainData(numElement * 3, 0.0); + for (auto i: theEleTags) { + Element *theEle = theDomain->getElement(i); + int MappedIndex = theEleMapping[i]; + if (strain2D3Responses[MappedIndex] == 0) { + continue; + } + strain2D3Responses[MappedIndex]->getResponse(); + Information &info = strain2D3Responses[MappedIndex]->getInformation(); + const Vector &strain = info.getData(); + for (int j = 0; j < 3; j++) { + strainData[3 * MappedIndex + j] = strain(j); + } + } + + int res = 0; + res += this->extendDataset(cell_data_group, "strain2D3", strainData.data(), H5T_NATIVE_DOUBLE, numElement, 3); + res += this->extendOffsetDataset(cell_data_offsets_group, "strain2D3", ¤t_Strain2D3Offset, H5T_NATIVE_INT, 1); + current_Strain2D3Offset += numElement; + return res; +} + +int VTKHDF_Recorder::writeStrees3D6(void) { + + std::vector stressData(numElement * 6, 0.0); + for (auto i: theEleTags) { + Element *theEle = theDomain->getElement(i); + int MappedIndex = theEleMapping[i]; + if (stress3D6Responses[MappedIndex]==0) { + continue; + } + stress3D6Responses[MappedIndex]->getResponse(); + Information &info = stress3D6Responses[MappedIndex]->getInformation(); + const Vector &stress = info.getData(); + for (int j = 0; j < 6; j++) { + stressData[6 * MappedIndex + j] = stress(j); + } + } + + int res = 0; + res += this->extendDataset(cell_data_group, "stress3D6", stressData.data(), H5T_NATIVE_DOUBLE, numElement, 6); + res += this->extendOffsetDataset(cell_data_offsets_group, "stress3D6", ¤t_Stress3D6Offset, H5T_NATIVE_INT, 1); + current_Stress3D6Offset += numElement; + return res; +} + + +int VTKHDF_Recorder::writeStrain3D6(void) { + + std::vector strainData(numElement * 6, 0.0); + for (auto i: theEleTags) { + Element *theEle = theDomain->getElement(i); + int MappedIndex = theEleMapping[i]; + if (strain3D6Responses[MappedIndex] == 0) { + continue; + } + strain3D6Responses[MappedIndex]->getResponse(); + Information &info = strain3D6Responses[MappedIndex]->getInformation(); + const Vector &strain = info.getData(); + for (int j = 0; j < 6; j++) { + strainData[6 * MappedIndex + j] = strain(j); + } + } + + int res = 0; + res += this->extendDataset(cell_data_group, "strain3D6", strainData.data(), H5T_NATIVE_DOUBLE, numElement, 6); + res += this->extendOffsetDataset(cell_data_offsets_group, "strain3D6", ¤t_Strain3D6Offset, H5T_NATIVE_INT, 1); + current_Strain3D6Offset += numElement; + return res; +} + +int VTKHDF_Recorder::writeVel(void) +{ + // write vel + std::vector velData(numNode * 3, 0.0); + for (auto i : theNodeTags) { + Node *theNode=theDomain->getNode(i); + const Vector &vel=theNode->getVel(); + int mappedIndex = theNodeMapping[i]; + int size = theNode->getCrds().Size(); + + velData[3 * mappedIndex + 0] = (size > 0) ? vel(0) : 0.0; + velData[3 * mappedIndex + 1] = (size > 1) ? vel(1) : 0.0; + velData[3 * mappedIndex + 2] = (size > 2) ? vel(2) : 0.0; + } + + { + // Open dataset in point_data_group and resize it to the new number of steps + hid_t dset_id = H5Dopen(point_data_group, "velocity", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error opening dataset 'velocity'\n"; + return -1; + } + + // Get the current dataspace and dimensions + hid_t space_id = H5Dget_space(dset_id); + if (space_id < 0) { + opserr << "Error getting dataspace for 'velocity'\n"; + H5Dclose(dset_id); + return -1; + } + + // Get the current dimensions + hsize_t current_dims[2]; + if (H5Sget_simple_extent_dims(space_id, current_dims, NULL) < 0) { + opserr << "Error getting current dimensions\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Calculate new dimensions (current rows + new rows, same columns) + hsize_t new_dims[2] = {current_dims[0] + static_cast(numNode), 3}; + + // Extend the dataset + if (H5Dset_extent(dset_id, new_dims) < 0) { + opserr << "Error setting new extent for 'velocity'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Get the new dataspace + hid_t new_space_id = H5Dget_space(dset_id); + if (new_space_id < 0) { + opserr << "Error getting new dataspace for 'velocity'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Select the hyperslab where we want to write new data + hsize_t offset[2] = {current_dims[0], 0}; // Start from the end of existing data + hsize_t count[2] = {static_cast(numNode), 3}; // Size of new data + if (H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0) { + opserr << "Error selecting hyperslab\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Create memory space for new data + hid_t mem_space_id = H5Screate_simple(2, count, NULL); + if (mem_space_id < 0) { + opserr << "Error creating memory space for 'velocity'\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Write only the new data + if (H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, mem_space_id, new_space_id, H5P_DEFAULT, velData.data()) < 0) { + opserr << "Error writing data to 'velocity'\n"; + } + + // Close all resources + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + } + + { + // Open dataset in point_data_offsets_group and resize it to the new number of steps + hid_t dset_id = H5Dopen(point_data_offsets_group, "velocity", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error opening dataset 'velocity'\n"; + return -1; + } + + // Get the current dataspace and dimensions + hid_t space_id = H5Dget_space(dset_id); + if (space_id < 0) { + opserr << "Error getting dataspace for 'velocity'\n"; + H5Dclose(dset_id); + return -1; + } + + // Get the current dimensions + hsize_t current_dims[1]; + if (H5Sget_simple_extent_dims(space_id, current_dims, NULL) < 0) { + opserr << "Error getting current dimensions\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Calculate new dimensions (current rows + new rows, same columns) + hsize_t new_dims[1] = {current_dims[0] + 1}; + + // Extend the dataset + if (H5Dset_extent(dset_id, new_dims) < 0) { + opserr << "Error setting new extent for 'velocity'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Get the new dataspace + hid_t new_space_id = H5Dget_space(dset_id); + if (new_space_id < 0) { + opserr << "Error getting new dataspace for 'velocity'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Select the hyperslab where we want to write new data + hsize_t offset[1] = {current_dims[0]}; // Start from the end of existing data + hsize_t count[1] = {1}; // Size of new data + if (H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0) { + opserr << "Error selecting hyperslab\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Create memory space for new data + hid_t mem_space_id = H5Screate_simple(1, count, NULL); + if (mem_space_id < 0) { + opserr << "Error creating memory space for 'velocity'\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Write only the new data + if (H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space_id, new_space_id, H5P_DEFAULT, &CurrentVelOffset) < 0) { + opserr << "Error writing data to 'velocity'\n"; + } + + // Close all resources + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + } + + CurrentVelOffset += numNode; + return 0; +} + + +int VTKHDF_Recorder::writeAccel(void) +{ + // write accel + std::vector accelData(numNode * 3, 0.0); + for (auto i : theNodeTags) { + Node *theNode=theDomain->getNode(i); + const Vector &accel=theNode->getAccel(); + int mappedIndex = theNodeMapping[i]; + int size = theNode->getCrds().Size(); + + accelData[3 * mappedIndex + 0] = (size > 0) ? accel(0) : 0.0; + accelData[3 * mappedIndex + 1] = (size > 1) ? accel(1) : 0.0; + accelData[3 * mappedIndex + 2] = (size > 2) ? accel(2) : 0.0; + } + + { + // Open dataset in point_data_group and resize it to the new number of steps + hid_t dset_id = H5Dopen(point_data_group, "acceleration", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error opening dataset 'acceleration'\n"; + return -1; + } + + // Get the current dataspace and dimensions + hid_t space_id = H5Dget_space(dset_id); + if (space_id < 0) { + opserr << "Error getting dataspace for 'acceleration'\n"; + H5Dclose(dset_id); + return -1; + } + + // Get the current dimensions + hsize_t current_dims[2]; + if (H5Sget_simple_extent_dims(space_id, current_dims, NULL) < 0) { + opserr << "Error getting current dimensions\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Calculate new dimensions (current rows + new rows, same columns) + hsize_t new_dims[2] = {current_dims[0] + static_cast(numNode), 3}; + + // Extend the dataset + if (H5Dset_extent(dset_id, new_dims) < 0) { + opserr << "Error setting new extent for 'acceleration'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Get the new dataspace + hid_t new_space_id = H5Dget_space(dset_id); + if (new_space_id < 0) { + opserr << "Error getting new dataspace for 'acceleration'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Select the hyperslab where we want to write new data + hsize_t offset[2] = {current_dims[0], 0}; // Start from the end of existing data + hsize_t count[2] = {static_cast(numNode), 3}; // Size of new data + if (H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0) { + opserr << "Error selecting hyperslab\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Create memory space for new data + hid_t mem_space_id = H5Screate_simple(2, count, NULL); + if (mem_space_id < 0) { + opserr << "Error creating memory space for 'acceleration'\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Write only the new data + if (H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, mem_space_id, new_space_id, H5P_DEFAULT, accelData.data()) < 0) { + opserr << "Error writing data to 'acceleration'\n"; + } + + // Close all resources + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + } + + { + // Open dataset in point_data_offsets_group and resize it to the new number of steps + hid_t dset_id = H5Dopen(point_data_offsets_group, "acceleration", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error opening dataset 'acceleration'\n"; + return -1; + } + + // Get the current dataspace and dimensions + hid_t space_id = H5Dget_space(dset_id); + if (space_id < 0) { + opserr << "Error getting dataspace for 'acceleration'\n"; + H5Dclose(dset_id); + return -1; + } + + // Get the current dimensions + hsize_t current_dims[1]; + if (H5Sget_simple_extent_dims(space_id, current_dims, NULL) < 0) { + opserr << "Error getting current dimensions\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Calculate new dimensions (current rows + new rows, same columns) + hsize_t new_dims[1] = {current_dims[0] + 1}; + + // Extend the dataset + if (H5Dset_extent(dset_id, new_dims) < 0) { + opserr << "Error setting new extent for 'acceleration'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Get the new dataspace + hid_t new_space_id = H5Dget_space(dset_id); + if (new_space_id < 0) { + opserr << "Error getting new dataspace for 'acceleration'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Select the hyperslab where we want to write new data + hsize_t offset[1] = {current_dims[0]}; // Start from the end of existing data + hsize_t count[1] = {1}; // Size of new data + if (H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0) { + opserr << "Error selecting hyperslab\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Create memory space for new data + hid_t mem_space_id = H5Screate_simple(1, count, NULL); + if (mem_space_id < 0) { + opserr << "Error creating memory space for 'acceleration'\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Write only the new data + if (H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space_id, new_space_id, H5P_DEFAULT, &CurrentAccelOffset) < 0) { + opserr << "Error writing data to 'acceleration'\n"; + } + + // Close all resources + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + } + + CurrentAccelOffset += numNode; + return 0; + +} + + +int VTKHDF_Recorder::writeDisp(void) +{ + // write disp + std::vector dispData(numNode * 3, 0.0); + for (auto i : theNodeTags) { + Node *theNode=theDomain->getNode(i); + const Vector &disp=theNode->getDisp(); + int mappedIndex = theNodeMapping[i]; + int size = theNode->getCrds().Size(); + + dispData[3 * mappedIndex + 0] = (size > 0) ? disp(0) : 0.0; + dispData[3 * mappedIndex + 1] = (size > 1) ? disp(1) : 0.0; + dispData[3 * mappedIndex + 2] = (size > 2) ? disp(2) : 0.0; + + } + + { + // Open dataset in point_data_group and resize it to the new number of steps + hid_t dset_id = H5Dopen(point_data_group, "displacement", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error opening dataset 'displacement'\n"; + return -1; + } + + // Get the current dataspace and dimensions + hid_t space_id = H5Dget_space(dset_id); + if (space_id < 0) { + opserr << "Error getting dataspace for 'displacement'\n"; + H5Dclose(dset_id); + return -1; + } + + // Get the current dimensions + hsize_t current_dims[2]; + if (H5Sget_simple_extent_dims(space_id, current_dims, NULL) < 0) { + opserr << "Error getting current dimensions\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Calculate new dimensions (current rows + new rows, same columns) + hsize_t new_dims[2] = {current_dims[0] + static_cast(numNode), 3}; + + // Extend the dataset + if (H5Dset_extent(dset_id, new_dims) < 0) { + opserr << "Error setting new extent for 'displacement'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Get the new dataspace + hid_t new_space_id = H5Dget_space(dset_id); + if (new_space_id < 0) { + opserr << "Error getting new dataspace for 'displacement'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Select the hyperslab where we want to write new data + hsize_t offset[2] = {current_dims[0], 0}; // Start from the end of existing data + hsize_t count[2] = {static_cast(numNode), 3}; // Size of new data + if (H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0) { + opserr << "Error selecting hyperslab\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Create memory space for new data + hid_t mem_space_id = H5Screate_simple(2, count, NULL); + if (mem_space_id < 0) { + opserr << "Error creating memory space for 'displacement'\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Write only the new data + if (H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, mem_space_id, new_space_id, H5P_DEFAULT, dispData.data()) < 0) { + opserr << "Error writing data to 'displacement'\n"; + } + + // Close all resources + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + } + + + // write dispofsset into + { + // Open dataset in point_data_offsets_group and resize it to the new number of steps + hid_t dset_id = H5Dopen(point_data_offsets_group, "displacement", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error opening dataset 'displacement'\n"; + return -1; + } + + // Get the current dataspace and dimensions + hid_t space_id = H5Dget_space(dset_id); + if (space_id < 0) { + opserr << "Error getting dataspace for 'displacement'\n"; + H5Dclose(dset_id); + return -1; + } + + // Get the current dimensions + hsize_t current_dims[1]; + if (H5Sget_simple_extent_dims(space_id, current_dims, NULL) < 0) { + opserr << "Error getting current dimensions\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Calculate new dimensions (current rows + new rows, same columns) + hsize_t new_dims[1] = {current_dims[0] + 1}; + + // Extend the dataset + if (H5Dset_extent(dset_id, new_dims) < 0) { + opserr << "Error setting new extent for 'displacement'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Get the new dataspace + hid_t new_space_id = H5Dget_space(dset_id); + if (new_space_id < 0) { + opserr << "Error getting new dataspace for 'displacement'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Select the hyperslab where we want to write new data + hsize_t offset[1] = {current_dims[0]}; // Start from the end of existing data + hsize_t count[1] = {1}; // Size of new data + if (H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0) { + opserr << "Error selecting hyperslab\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Create memory space for new data + hid_t mem_space_id = H5Screate_simple(1, count, NULL); + if (mem_space_id < 0) { + opserr << "Error creating memory space for 'displacement'\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + + // Write only the new data + if (H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space_id, new_space_id, H5P_DEFAULT, &CurrentDispOffset) < 0) { + opserr << "Error writing data to 'displacement'\n"; + } + + // Close all resources + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + } + + // update the current offset + CurrentDispOffset += numNode; + return 0; +} + + + +int VTKHDF_Recorder::writeStep(double timeStamp) +{ + // Update numSteps and attribute + numSteps++; + const char* attr_name = "NSteps"; + + // Open and update NSteps attribute + hid_t attr_id = H5Aopen(steps_group, attr_name, H5P_DEFAULT); + if (attr_id < 0) { + opserr << "Error: Failed to open 'NSteps' attribute\n"; + return -1; + } + + H5Awrite(attr_id, H5T_NATIVE_INT, &numSteps); + H5Aclose(attr_id); + + // Values for each dataset + const int newNumberOfParts = 1; // Always one rank per recorder + const int newPointOffsets = current_PointOffset; + const int newCellOffsets = current_CellOffset; + const int newPartOffsets = current_PartOffset; + const int newConnectivityIdOffsets = current_ConnectivityIdOffset; + const double value = timeStamp; + const int newNumPoints = numNode; + const int newNumCells = numElement; + const int newNumberOfConnectivityIds = numConnectivityIds; + + + // Debug output (can be removed for production) + // opserr << " Number of parts: " << newNumberOfParts << endln; + // opserr << " Point offsets: " << newPointOffsets << endln; + // opserr << " Cell offsets: " << newCellOffsets << endln; + // opserr << " Part offsets: " << newPartOffsets << endln; + // opserr << " Value: " << value << endln; + // opserr << " Number of points: " << newNumPoints << endln; + // opserr << " Number of cells: " << newNumCells << endln; + // opserr << " Number of connectivity ids: " << newNumberOfConnectivityIds << endln; + + // Set up dimensions for dataset operations + hsize_t newSize[1] = {static_cast(numSteps)}; + hsize_t start[1] = {static_cast(numSteps - 1)}; + hsize_t count[1] = {1}; + + // NumberOfParts + { + hid_t dset_id = H5Dopen(steps_group, "NumberOfParts", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error: Failed to open 'NumberOfParts' dataset\n"; + return -1; + } + + H5Dset_extent(dset_id, newSize); + hid_t file_space = H5Dget_space(dset_id); + H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start, NULL, count, NULL); + + // Create memory space and write data + hid_t mem_space = H5Screate_simple(1, count, NULL); + H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space, file_space, H5P_DEFAULT, &newNumberOfParts); + + // Clean up resources + H5Sclose(mem_space); + H5Sclose(file_space); + H5Dclose(dset_id); + } + // PointOffsets + { + hid_t dset_id = H5Dopen(steps_group, "PointOffsets", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error: Failed to open 'PointOffsets' dataset\n"; + return -1; + } + + H5Dset_extent(dset_id, newSize); + hid_t file_space = H5Dget_space(dset_id); + H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start, NULL, count, NULL); + + // Create memory space and write data + hid_t mem_space = H5Screate_simple(1, count, NULL); + H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space, file_space, H5P_DEFAULT, &newPointOffsets); + + // Clean up resources + H5Sclose(mem_space); + H5Sclose(file_space); + H5Dclose(dset_id); + } + + // PartOffsets + { + hid_t dset_id = H5Dopen(steps_group, "PartOffsets", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error: Failed to open 'PartOffsets' dataset\n"; + return -1; + } + + H5Dset_extent(dset_id, newSize); + hid_t file_space = H5Dget_space(dset_id); + H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start, NULL, count, NULL); + + // Create memory space and write data + hid_t mem_space = H5Screate_simple(1, count, NULL); + H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space, file_space, H5P_DEFAULT, &newPartOffsets); + + // Clean up resources + H5Sclose(mem_space); + H5Sclose(file_space); + H5Dclose(dset_id); + } + + // Values + { + hid_t dset_id = H5Dopen(steps_group, "Values", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error: Failed to open 'Values' dataset\n"; + return -1; + } + + H5Dset_extent(dset_id, newSize); + hid_t file_space = H5Dget_space(dset_id); + H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start, NULL, count, NULL); + + // Create memory space and write data + hid_t mem_space = H5Screate_simple(1, count, NULL); + H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, mem_space, file_space, H5P_DEFAULT, &value); + + // Clean up resources + H5Sclose(mem_space); + H5Sclose(file_space); + H5Dclose(dset_id); + } + + // NumberOfPoints + { + hid_t dset_id = H5Dopen(group_id, "NumberOfPoints", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error: Failed to open 'NumberOfPoints' dataset\n"; + return -1; + } + + H5Dset_extent(dset_id, newSize); + hid_t file_space = H5Dget_space(dset_id); + H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start, NULL, count, NULL); + + // Create memory space and write data + hid_t mem_space = H5Screate_simple(1, count, NULL); + H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space, file_space, H5P_DEFAULT, &newNumPoints); + + // Clean up resources + H5Sclose(mem_space); + H5Sclose(file_space); + H5Dclose(dset_id); + } + // NumberOfCells + { + hid_t dset_id = H5Dopen(group_id, "NumberOfCells", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error: Failed to open 'NumberOfCells' dataset\n"; + return -1; + } + + H5Dset_extent(dset_id, newSize); + hid_t file_space = H5Dget_space(dset_id); + H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start, NULL, count, NULL); + + // Create memory space and write data + hid_t mem_space = H5Screate_simple(1, count, NULL); + H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space, file_space, H5P_DEFAULT, &newNumCells); + + // Clean up resources + H5Sclose(mem_space); + H5Sclose(file_space); + H5Dclose(dset_id); + } + + // NumberOfConnectivityIds + { + hid_t dset_id = H5Dopen(group_id, "NumberOfConnectivityIds", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error: Failed to open 'NumberOfConnectivityIds' dataset\n"; + return -1; + } + + H5Dset_extent(dset_id, newSize); + hid_t file_space = H5Dget_space(dset_id); + H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start, NULL, count, NULL); + + // Create memory space and write data + hid_t mem_space = H5Screate_simple(1, count, NULL); + H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space, file_space, H5P_DEFAULT, &newNumberOfConnectivityIds); + + // Clean up resources + H5Sclose(mem_space); + H5Sclose(file_space); + H5Dclose(dset_id); + } + + // Handle CellOffsets dataset + { + // Set new dimensions for the current step + hsize_t newSize2[2] = {static_cast(numSteps), 1}; + hsize_t start2[2] = {static_cast(numSteps - 1), 0}; + hsize_t count2[2] = {1, 1}; + + // Open existing dataset + hid_t dset_id = H5Dopen(steps_group, "CellOffsets", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error: Failed to open 'CellOffsets' dataset\n"; + return -1; + } + + // Extend the dataset + H5Dset_extent(dset_id, newSize2); + + // Get the file space and select the hyperslab + hid_t file_space = H5Dget_space(dset_id); + H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start2, NULL, count2, NULL); + + // Create memory space for single value + hid_t mem_space = H5Screate_simple(2, count2, NULL); + + // Write the cell offset value + H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space, file_space, H5P_DEFAULT, &newCellOffsets); + + // Clean up + H5Sclose(mem_space); + H5Sclose(file_space); + H5Dclose(dset_id); + } + // Handle ConnectivityIdOffsets + { + // Set new dimensions for the current step + hsize_t newSize2[2] = {static_cast(numSteps), 1}; + hsize_t start2[2] = {static_cast(numSteps - 1), 0}; + hsize_t count2[2] = {1, 1}; + + // Open existing dataset + hid_t dset_id = H5Dopen(steps_group, "ConnectivityIdOffsets", H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error: Failed to open 'ConnectivityIdOffsets' dataset\n"; + return -1; + } + + // Extend the dataset + H5Dset_extent(dset_id, newSize2); + + // Get the file space and select the hyperslab + hid_t file_space = H5Dget_space(dset_id); + H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start2, NULL, count2, NULL); + + // Create memory space for single value + hid_t mem_space = H5Screate_simple(2, count2, NULL); + + // Write the connectivity id offset value + H5Dwrite(dset_id, H5T_NATIVE_INT, mem_space, file_space, H5P_DEFAULT, &newConnectivityIdOffsets); + + // Clean up + H5Sclose(mem_space); + H5Sclose(file_space); + H5Dclose(dset_id); + } + + + return 0; +} + + +int VTKHDF_Recorder::restart(void) +{ + return 0; +} + +int VTKHDF_Recorder::domainChanged(void) +{ + opserr << "Warning: VTKHDF_Recorder::domainChanged() - This recorder does not support domain changes yet.\n"; + opserr << "if you changed the domain, you need to create a new recorder.\n"; + opserr << "if you just used the domainChanged() mesthod without changing the domain, you can ignore this warning.\n"; + this->writeMesh(); + return -1; +} + +int VTKHDF_Recorder::setDomain(Domain &domain) +{ + theDomain = &domain; + return 0; +} + +int VTKHDF_Recorder::sendSelf(int commitTag, Channel &theChannel) +{ + // Implementation for sending data + return 0; +} + +int VTKHDF_Recorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +{ + // Implementation for receiving data + return 0; +} + + + + + +// int VTKHDF_Recorder::writeStep_stress3D6() { +// /* +// This function is used to write the 3D stress data to the HDF5 file. The function writes the following: + +// 1) collect the 3D stress data from the elements +// 2) Write the 3D stress data to the dataset "3DStress6" under group "/VTKHDF/CellData" in the HDF5 file +// 3) Write the offset to the dataset "3DStress6" under group "/VTKHDF/Steps/CellDataOffsets" in the HDF5 file +// */ + +// // 1) Collect the 3D stress data from the elements +// std::vector stress(numElement * 6, 0.0); + +// // std::vector velData(numNode * 3, 0.0); +// { +// for (auto i : theEleTags) { +// Element *theElement = theDomain->getElement(i); +// int mappedIndex = theEleMapping[i]; + +// int classTag = theElement->getClassTag(); + +// if (classTag == ELE_TAG_STDQUADUP) { +// // stdQuadUP +// Vector stressVec(6); +// Information &eleInfo = +// theElement->getResponse(1, stressVec); +// theElement->getResponse(1,) + +// } + +// } + +// } + + + + + + +VTKHDF_Recorder::~VTKHDF_Recorder() +{ + // close the HDF5 file + if (name) { + delete [] name; + name = nullptr; + } + + if (file_id >= 0) { H5Fclose(file_id);} + + if (group_id >= 0) {H5Gclose(group_id);} + + if (point_data_group >= 0) {H5Gclose(point_data_group);} + + if (cell_data_group >= 0) {H5Gclose(cell_data_group);} + + if (steps_group >= 0) {H5Gclose(steps_group);} + + if (point_data_offsets_group >= 0) {H5Gclose(point_data_offsets_group);} + + if (cell_data_offsets_group >= 0) {H5Gclose(cell_data_offsets_group);} + +} + + + + + +void VTKHDF_Recorder::setVTKType() +{ + if (!vtktypes.empty()) { + return; + } + // vtktypes[ELE_TAG_Subdomain] = VTK_POLY_VERTEX; + vtktypes[ELEMENT_TAGS_WrapperElement] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ElasticBeam2d] = VTK_LINE; + vtktypes[ELE_TAG_ModElasticBeam2d] = VTK_LINE; + vtktypes[ELE_TAG_ElasticBeam3d] = VTK_LINE; + vtktypes[ELE_TAG_Beam2d] = VTK_LINE; + vtktypes[ELE_TAG_beam2d02] = VTK_LINE; + vtktypes[ELE_TAG_beam2d03] = VTK_LINE; + vtktypes[ELE_TAG_beam2d04] = VTK_LINE; + vtktypes[ELE_TAG_beam3d01] = VTK_LINE; + vtktypes[ELE_TAG_beam3d02] = VTK_LINE; + vtktypes[ELE_TAG_Truss] = VTK_LINE; + vtktypes[ELE_TAG_TrussSection] = VTK_LINE; + vtktypes[ELE_TAG_CorotTruss] = VTK_LINE; + vtktypes[ELE_TAG_CorotTrussSection] = VTK_LINE; + vtktypes[ELE_TAG_fElmt05] = VTK_LINE; + vtktypes[ELE_TAG_fElmt02] = VTK_LINE; + vtktypes[ELE_TAG_MyTruss] = VTK_LINE; + vtktypes[ELE_TAG_ZeroLength] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ZeroLengthSection] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ZeroLengthND] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ZeroLengthContact2D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ZeroLengthContact3D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ZeroLengthContactASDimplex] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ZeroLengthContactNTS2D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ZeroLengthInterface2D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_CoupledZeroLength] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ZeroLengthRocking] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_NLBeamColumn2d] = VTK_LINE; + vtktypes[ELE_TAG_NLBeamColumn3d] = VTK_LINE; + vtktypes[ELE_TAG_LargeDispBeamColumn3d] = VTK_LINE; + vtktypes[ELE_TAG_FourNodeQuad] = VTK_QUAD; + vtktypes[ELE_TAG_FourNodeQuad3d] = VTK_QUAD; + vtktypes[ELE_TAG_Tri31] = VTK_TRIANGLE; + vtktypes[ELE_TAG_SixNodeTri] = VTK_TRIANGLE; + vtktypes[ELE_TAG_BeamWithHinges2d] = VTK_LINE; + vtktypes[ELE_TAG_BeamWithHinges3d] = VTK_LINE; + vtktypes[ELE_TAG_EightNodeBrick] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_TwentyNodeBrick] = VTK_QUADRATIC_HEXAHEDRON; + vtktypes[ELE_TAG_EightNodeBrick_u_p_U] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_TwentyNodeBrick_u_p_U] = VTK_QUADRATIC_HEXAHEDRON; + vtktypes[ELE_TAG_FourNodeQuadUP] = VTK_QUAD; + vtktypes[ELE_TAG_TotalLagrangianFD20NodeBrick] = VTK_QUADRATIC_HEXAHEDRON; + vtktypes[ELE_TAG_TotalLagrangianFD8NodeBrick] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_EightNode_LDBrick_u_p] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_EightNode_Brick_u_p] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_TwentySevenNodeBrick] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_BrickUP] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_Nine_Four_Node_QuadUP] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_Twenty_Eight_Node_BrickUP] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_Twenty_Node_Brick] = VTK_QUADRATIC_HEXAHEDRON; + vtktypes[ELE_TAG_BBarFourNodeQuadUP] = VTK_QUAD; + vtktypes[ELE_TAG_BBarBrickUP] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_PlateMITC4] = VTK_QUAD; + vtktypes[ELE_TAG_ShellMITC4] = VTK_QUAD; + vtktypes[ELE_TAG_ShellMITC9] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ASDShellQ4] = VTK_QUAD; + vtktypes[ELE_TAG_ASDShellT3] = VTK_TRIANGLE; + vtktypes[ELE_TAG_Plate1] = VTK_QUAD; + vtktypes[ELE_TAG_Brick] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_BbarBrick] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_FLBrick] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_EnhancedQuad] = VTK_QUAD; + vtktypes[ELE_TAG_ConstantPressureVolumeQuad] = VTK_QUAD; + vtktypes[ELE_TAG_NineNodeMixedQuad] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_NineNodeQuad] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_EightNodeQuad] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_DispBeamColumn2d] = VTK_LINE; + vtktypes[ELE_TAG_TimoshenkoBeamColumn2d] = VTK_LINE; + vtktypes[ELE_TAG_DispBeamColumn3d] = VTK_LINE; + vtktypes[ELE_TAG_DispBeamColumnWarping3d] = VTK_LINE; + vtktypes[ELE_TAG_HingedBeam2d] = VTK_LINE; + vtktypes[ELE_TAG_HingedBeam3d] = VTK_LINE; + vtktypes[ELE_TAG_TwoPointHingedBeam2d] = VTK_LINE; + vtktypes[ELE_TAG_TwoPointHingedBeam3d] = VTK_LINE; + vtktypes[ELE_TAG_OnePointHingedBeam2d] = VTK_LINE; + vtktypes[ELE_TAG_OnePointHingedBeam3d] = VTK_LINE; + vtktypes[ELE_TAG_BeamColumnJoint2d] = VTK_QUAD; + vtktypes[ELE_TAG_BeamColumnJoint3d] = VTK_QUAD; + vtktypes[ELE_TAG_ForceBeamColumn2d] = VTK_LINE; + vtktypes[ELE_TAG_ForceBeamColumnWarping2d] = VTK_LINE; + vtktypes[ELE_TAG_ForceBeamColumn3d] = VTK_LINE; + vtktypes[ELE_TAG_ElasticForceBeamColumn2d] = VTK_LINE; + vtktypes[ELE_TAG_ElasticForceBeamColumnWarping2d] = VTK_LINE; + vtktypes[ELE_TAG_ElasticForceBeamColumn3d] = VTK_LINE; + vtktypes[ELE_TAG_ForceBeamColumnCBDI2d] = VTK_LINE; + vtktypes[ELE_TAG_ForceBeamColumnCBDI3d] = VTK_LINE; + vtktypes[ELE_TAG_DispBeamColumn2dInt] = VTK_LINE; + vtktypes[ELE_TAG_InternalSpring] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_SimpleJoint2D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_Joint2D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_Joint3D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ElastomericBearingPlasticity3d] = VTK_LINE; + vtktypes[ELE_TAG_ElastomericBearingPlasticity2d] = VTK_LINE; + vtktypes[ELE_TAG_TwoNodeLink] = VTK_LINE; + vtktypes[ELE_TAG_ActuatorCorot] = VTK_LINE; + vtktypes[ELE_TAG_Actuator] = VTK_LINE; + vtktypes[ELE_TAG_Adapter] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ElastomericBearingBoucWen2d] = VTK_LINE; + vtktypes[ELE_TAG_ElastomericBearingBoucWen3d] = VTK_LINE; + vtktypes[ELE_TAG_FlatSliderSimple2d] = VTK_LINE; + vtktypes[ELE_TAG_FlatSliderSimple3d] = VTK_LINE; + vtktypes[ELE_TAG_FlatSlider2d] = VTK_LINE; + vtktypes[ELE_TAG_FlatSlider3d] = VTK_LINE; + vtktypes[ELE_TAG_SingleFPSimple2d] = VTK_LINE; + vtktypes[ELE_TAG_SingleFPSimple3d] = VTK_LINE; + vtktypes[ELE_TAG_SingleFP2d] = VTK_LINE; + vtktypes[ELE_TAG_SingleFP3d] = VTK_LINE; + vtktypes[ELE_TAG_DoubleFPSimple2d] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_DoubleFPSimple3d] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_DoubleFP2d] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_DoubleFP3d] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_TripleFPSimple2d] = VTK_LINE; + vtktypes[ELE_TAG_TripleFPSimple3d] = VTK_LINE; + vtktypes[ELE_TAG_TripleFP2d] = VTK_LINE; + vtktypes[ELE_TAG_TripleFP3d] = VTK_LINE; + vtktypes[ELE_TAG_MultiFP2d] = VTK_LINE; + vtktypes[ELE_TAG_MultiFP3d] = VTK_LINE; + vtktypes[ELE_TAG_GenericClient] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_GenericCopy] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_PY_MACRO2D] = VTK_LINE; + vtktypes[ELE_TAG_SimpleContact2D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_SimpleContact3D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_BeamContact3D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_SurfaceLoad] = VTK_QUAD; + vtktypes[ELE_TAG_BeamContact2D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_BeamEndContact3D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_SSPquad] = VTK_QUAD; + vtktypes[ELE_TAG_SSPquadUP] = VTK_QUAD; + vtktypes[ELE_TAG_SSPbrick] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_SSPbrickUP] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_BeamContact2Dp] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_BeamContact3Dp] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_BeamEndContact3Dp] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_Quad4FiberOverlay] = VTK_QUAD; + vtktypes[ELE_TAG_Brick8FiberOverlay] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_QuadBeamEmbedContact] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_DispBeamColumn2dThermal] = VTK_LINE; + vtktypes[ELE_TAG_TPB1D] = VTK_LINE; + vtktypes[ELE_TAG_TFP_Bearing] = VTK_LINE; + vtktypes[ELE_TAG_TFP_Bearing2d] = VTK_LINE; + vtktypes[ELE_TAG_TripleFrictionPendulum] = VTK_LINE; + vtktypes[ELE_TAG_TripleFrictionPendulumX] = VTK_LINE; + vtktypes[ELE_TAG_PFEMElement2D] = VTK_TRIANGLE; + vtktypes[ELE_TAG_FourNodeQuad02] = VTK_QUAD; + vtktypes[ELE_TAG_cont2d01] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_cont2d02] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_CST] = VTK_TRIANGLE; + vtktypes[ELE_TAG_Truss2] = VTK_LINE; + vtktypes[ELE_TAG_CorotTruss2] = VTK_LINE; + vtktypes[ELE_Tag_ZeroLengthImpact3D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_PFEMElement3D] = VTK_TETRA; + vtktypes[ELE_TAG_PFEMElement2DCompressible] = VTK_TRIANGLE; + vtktypes[ELE_TAG_PFEMElement2DBubble] = VTK_TRIANGLE; + vtktypes[ELE_TAG_PFEMElement2Dmini] = VTK_TRIANGLE; + vtktypes[ELE_TAG_ElasticTimoshenkoBeam2d] = VTK_LINE; + vtktypes[ELE_TAG_ElasticTimoshenkoBeam3d] = VTK_LINE; + vtktypes[ELE_TAG_ElastomericBearingUFRP2d] = VTK_LINE; + vtktypes[ELE_TAG_ElastomericBearingUFRP3d] = VTK_LINE; + vtktypes[ELE_TAG_RJWatsonEQS2d] = VTK_LINE; + vtktypes[ELE_TAG_RJWatsonEQS3d] = VTK_LINE; + vtktypes[ELE_TAG_HDR] = VTK_LINE; + vtktypes[ELE_TAG_ElastomericX] = VTK_LINE; + vtktypes[ELE_TAG_LeadRubberX] = VTK_LINE; + vtktypes[ELE_TAG_PileToe3D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_N4BiaxialTruss] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ShellDKGQ] = VTK_QUAD; + vtktypes[ELE_TAG_ShellNLDKGQ] = VTK_QUAD; + vtktypes[ELE_TAG_MultipleShearSpring] = VTK_LINE; + vtktypes[ELE_TAG_MultipleNormalSpring] = VTK_LINE; + vtktypes[ELE_TAG_KikuchiBearing] = VTK_LINE; + vtktypes[ELE_TAG_ComponentElement2d] = VTK_LINE; + vtktypes[ELE_TAG_YamamotoBiaxialHDR] = VTK_LINE; + vtktypes[ELE_TAG_MVLEM] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_SFI_MVLEM] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_MVLEM_3D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_SFI_MVLEM_3D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_E_SFI_MVLEM_3D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_E_SFI] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_MEFI] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_PFEMElement2DFIC] = VTK_TRIANGLE; + vtktypes[ELE_TAG_TaylorHood2D] = VTK_QUADRATIC_TRIANGLE; + vtktypes[ELE_TAG_PFEMElement2DQuasi] = VTK_TRIANGLE; + vtktypes[ELE_TAG_MINI] = VTK_TRIANGLE; + vtktypes[ELE_TAG_CatenaryCable] = VTK_LINE; + vtktypes[ELE_TAG_FourNodeTetrahedron] = VTK_TETRA; + vtktypes[ELE_TAG_PFEMElement3DBubble] = VTK_TETRA; + vtktypes[ELE_TAG_TriSurfaceLoad] = VTK_TRIANGLE; + vtktypes[ELE_TAG_ShellDKGT] = VTK_TRIANGLE; + vtktypes[ELE_TAG_ShellNLDKGT] = VTK_TRIANGLE; + vtktypes[ELE_TAG_InertiaTruss] = VTK_LINE; + vtktypes[ELE_TAG_ASDAbsorbingBoundary2D] = VTK_QUAD; + vtktypes[ELE_TAG_ASDAbsorbingBoundary3D] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_FSIFluidElement2D] = VTK_QUAD; + vtktypes[ELE_TAG_FSIInterfaceElement2D] = VTK_LINE; + vtktypes[ELE_TAG_FSIFluidBoundaryElement2D] = VTK_LINE; +} + + + +/** + * Creates an HDF5 dataset with automatic dimension detection based on columns + * + * param group_id Parent group ID where dataset will be created + * param dataset_name Name of the dataset to create + * param ncols Number of columns (0 for 1D dataset, >0 for 2D dataset) + * param chunk_rows Number of rows per chunk (default 100) + * param type_id HDF5 datatype for the dataset (default H5T_NATIVE_DOUBLE) + * param max_rows Maximum number of rows (H5S_UNLIMITED for unlimited, 0 for fixed size) + * return hid_t Dataset ID if successful, negative value if failed + */ +int VTKHDF_Recorder::createDataset( + hid_t group_id, + const char* dataset_name, + hsize_t ncols, + hsize_t chunk_rows, + hid_t type_id, + hsize_t max_rows +) { + + // Determine if it's 1D or 2D based on ncols + int ndims = (ncols == 0) ? 1 : 2; + + // Declare fixed-size arrays + hsize_t dims[2]; + hsize_t max_dims[2]; + hsize_t chunk_dims[2]; + + // Set dimensions based on whether it's 1D or 2D + if (ndims == 1) { + dims[0] = 0; + max_dims[0] = max_rows; + chunk_dims[0] = chunk_rows; + } else { + dims[0] = 0; + dims[1] = ncols; + max_dims[0] = max_rows; + max_dims[1] = ncols; + chunk_dims[0] = chunk_rows; + chunk_dims[1] = ncols; + } + + // Create dataspace + hid_t space_id = H5Screate_simple(ndims, dims, max_dims); + if (space_id < 0) { + fprintf(stderr, "Error creating dataspace for %s\n", dataset_name); + return -1; + } + + // Create property list for chunked storage + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + if (plist_id < 0) { + fprintf(stderr, "Error creating property list for %s\n", dataset_name); + H5Sclose(space_id); + return -1; + } + + // Set chunk size + if (H5Pset_chunk(plist_id, ndims, chunk_dims) < 0) { + fprintf(stderr, "Error setting chunk size for %s\n", dataset_name); + H5Pclose(plist_id); + H5Sclose(space_id); + return -1; + } + + // Create the dataset + hid_t dset_id = H5Dcreate( + group_id, + dataset_name, + type_id, + space_id, + H5P_DEFAULT, + plist_id, + H5P_DEFAULT + ); + + // Check if dataset was created successfully + if (dset_id < 0) { + fprintf(stderr, "Error creating dataset %s\n", dataset_name); + H5Pclose(plist_id); + H5Sclose(space_id); + return -1; + } + + // Clean up + H5Pclose(plist_id); + H5Sclose(space_id); + H5Dclose(dset_id); + + return 0; +} + + + +int VTKHDF_Recorder::extendDataset(hid_t dataGroup, + const char* datasetName, + const void* newData, + hid_t datatype, + size_t numNewElements, + size_t numColumns) { + // Open dataset + hid_t dset_id = H5Dopen(dataGroup, datasetName, H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error opening dataset '" << datasetName << "'\n"; + return -1; + } + + // Get the current dataspace + hid_t space_id = H5Dget_space(dset_id); + if (space_id < 0) { + opserr << "Error getting dataspace for '" << datasetName << "'\n"; + H5Dclose(dset_id); + return -1; + } + + // Get rank and dimensions + int rank = H5Sget_simple_extent_ndims(space_id); + std::vector current_dims(rank); + if (H5Sget_simple_extent_dims(space_id, current_dims.data(), NULL) < 0) { + opserr << "Error getting current dimensions\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Prepare new dimensions + std::vector new_dims = current_dims; + new_dims[0] += static_cast(numNewElements); // Extend first dimension + + // Extend the dataset + if (H5Dset_extent(dset_id, new_dims.data()) < 0) { + opserr << "Error setting new extent for '" << datasetName << "'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Get the new dataspace + hid_t new_space_id = H5Dget_space(dset_id); + if (new_space_id < 0) { + opserr << "Error getting new dataspace for '" << datasetName << "'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Prepare hyperslab selection + std::vector offset(rank, 0); + std::vector count(rank); + + offset[0] = current_dims[0]; // Start from end of existing data + count[0] = numNewElements; // Number of new elements + + if (rank == 2) { + count[1] = numColumns; // Use specified number of columns for 2D + } + + // Select hyperslab for writing + if (H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, offset.data(), + NULL, count.data(), NULL) < 0) { + opserr << "Error selecting hyperslab\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Create memory space + hid_t mem_space_id = H5Screate_simple(rank, count.data(), NULL); + if (mem_space_id < 0) { + opserr << "Error creating memory space for '" << datasetName << "'\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Write data with the specified datatype + if (H5Dwrite(dset_id, datatype, mem_space_id, new_space_id, + H5P_DEFAULT, newData) < 0) { + opserr << "Error writing data to '" << datasetName << "'\n"; + } + + // Clean up + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + + return 0; +} + + + + +int VTKHDF_Recorder::createOffsetDataset(hid_t group_id, + const char* dataset_name, + hsize_t chunk_rows, + hid_t type_id, + hsize_t max_rows) { + // Define initial dimensions as 0 since we don't know the number of nodes yet + hsize_t dims[1] = {0}; // Initial size (0 rows) + hsize_t max_dims[1] = {max_rows}; // Maximum size (unlimited rows) + + // Create a dataspace with these dimensions + hid_t space_id = H5Screate_simple(1, dims, max_dims); + if (space_id < 0) { + fprintf(stderr, "Error creating dataspace for %s\n", dataset_name); + return -1; + } + + // Create a property list for chunked storage + hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE); + if (plist_id < 0) { + fprintf(stderr, "Error creating property list for %s\n", dataset_name); + H5Sclose(space_id); + return -1; + } + + // Define the chunk size (e.g., 100 rows per chunk) + hsize_t chunk_dims[1] = {chunk_rows}; + if (H5Pset_chunk(plist_id, 1, chunk_dims) < 0) { + fprintf(stderr, "Error setting chunk size for %s\n", dataset_name); + H5Pclose(plist_id); + H5Sclose(space_id); + return -1; + } + + // Create the dataset with chunked storage + hid_t dset_id = H5Dcreate( + group_id, + dataset_name, + type_id, + space_id, + H5P_DEFAULT, + plist_id, + H5P_DEFAULT + ); + + if (dset_id < 0) { + fprintf(stderr, "Error creating dataset for %s\n", dataset_name); + H5Pclose(plist_id); + H5Sclose(space_id); + return -1; + } + + // Clean up + H5Pclose(plist_id); + H5Dclose(dset_id); + H5Sclose(space_id);// Create dataset with 1 column + + return 0; +} + +int VTKHDF_Recorder::extendOffsetDataset(hid_t group_id, + const char* dataset_name, + const void* new_value, + hid_t datatype, + size_t extra_rows) { + // Open dataset + hid_t dset_id = H5Dopen(group_id, dataset_name, H5P_DEFAULT); + if (dset_id < 0) { + opserr << "Error opening dataset '" << dataset_name << "'\n"; + return -1; + } + + // Get current dataspace and dimensions + hid_t space_id = H5Dget_space(dset_id); + if (space_id < 0) { + opserr << "Error getting dataspace for '" << dataset_name << "'\n"; + H5Dclose(dset_id); + return -1; + } + + // Get current dimensions + hsize_t current_dims[1]; + if (H5Sget_simple_extent_dims(space_id, current_dims, NULL) < 0) { + opserr << "Error getting current dimensions\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Calculate new dimensions + hsize_t new_dims[1] = {current_dims[0] + static_cast(extra_rows)}; + + // Extend dataset + if (H5Dset_extent(dset_id, new_dims) < 0) { + opserr << "Error setting new extent for '" << dataset_name << "'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Get new dataspace + hid_t new_space_id = H5Dget_space(dset_id); + if (new_space_id < 0) { + opserr << "Error getting new dataspace for '" << dataset_name << "'\n"; + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Select hyperslab for new data + hsize_t offset[1] = {current_dims[0]}; + hsize_t count[1] = {1}; + if (H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0) { + opserr << "Error selecting hyperslab\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Create memory space for new data + hid_t mem_space_id = H5Screate_simple(1, count, NULL); + if (mem_space_id < 0) { + opserr << "Error creating memory space for '" << dataset_name << "'\n"; + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Write new data using the provided datatype + if (H5Dwrite(dset_id, datatype, mem_space_id, new_space_id, H5P_DEFAULT, new_value) < 0) { + opserr << "Error writing data to '" << dataset_name << "'\n"; + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + return -1; + } + + // Clean up + H5Sclose(mem_space_id); + H5Sclose(new_space_id); + H5Sclose(space_id); + H5Dclose(dset_id); + + return 0; +} \ No newline at end of file diff --git a/SRC/recorder/VTKHDF_Recorder.h b/SRC/recorder/VTKHDF_Recorder.h new file mode 100644 index 0000000000..8972e77573 --- /dev/null +++ b/SRC/recorder/VTKHDF_Recorder.h @@ -0,0 +1,279 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in the main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +#ifndef VTKHDF_RECORDER_H +#define VTKHDF_RECORDER_H + +// Written: Amin Pakzad, 2025 +// Purpose: Class definition for VTKHDF_Recorder to store responses in HDF5 format. + +// Include existing headers plus HDF5 +#include +#include +#include +#include +#include +#include "Response.h" +#include +#include "hdf5.h" + + + +// Define the OutputData class +class OutputDataHDF { +public: + OutputDataHDF(); + OutputDataHDF &operator=(const OutputDataHDF &other); + + bool disp; + bool vel; + bool accel; + bool reaction; + bool mass, unbalancedLoad; + bool stress3D6, strain3D6; + bool stress2D3, strain2D3; +}; + + +class SilentStream : public OPS_Stream { +public: + SilentStream(); + ~SilentStream() override; + + // Implement all pure virtual methods with no-op behavior + int tag(const char* tagName) override { return 0; } + int tag(const char* tagName, const char* value) override { return 0; } + int endTag() override { return 0; } + int attr(const char* name, int value) override { return 0; } + int attr(const char* name, double value) override { return 0; } + int attr(const char* name, const char* value) override { return 0; } + int write(Vector& data) override { return 0; } + int flush() override { return 0; } + int open() override { return 0; } + int close(openMode nextOpen = APPEND) override { return 0; } + + // Implement the write methods with no-op behavior + OPS_Stream& write(const char* s, int n) override { return *this; } + OPS_Stream& write(const unsigned char* s, int n) override { return *this; } + OPS_Stream& write(const signed char* s, int n) override { return *this; } + OPS_Stream& write(const void* s, int n) override { return *this; } + OPS_Stream& write(const double* s, int n) override { return *this; } + + // Implement output operators with no-op behavior + OPS_Stream& operator<<(char c) override { return *this; } + OPS_Stream& operator<<(unsigned char c) override { return *this; } + OPS_Stream& operator<<(signed char c) override { return *this; } + OPS_Stream& operator<<(const char* s) override { return *this; } + OPS_Stream& operator<<(const unsigned char* s) override { return *this; } + OPS_Stream& operator<<(const signed char* s) override { return *this; } + OPS_Stream& operator<<(const void* p) override { return *this; } + OPS_Stream& operator<<(int n) override { return *this; } + OPS_Stream& operator<<(unsigned int n) override { return *this; } + OPS_Stream& operator<<(long n) override { return *this; } + OPS_Stream& operator<<(unsigned long n) override { return *this; } + OPS_Stream& operator<<(short n) override { return *this; } + OPS_Stream& operator<<(unsigned short n) override { return *this; } + OPS_Stream& operator<<(bool b) override { return *this; } + OPS_Stream& operator<<(double n) override { return *this; } + OPS_Stream& operator<<(float n) override { return *this; } + + // Implement parallel methods with no-op behavior + void setAddCommon(int flag) override {} + int setOrder(const ID& order) override { return 0; } + int sendSelf(int commitTag, Channel& theChannel) override { return 0; } + int recvSelf(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker) override { return 0; } +}; + +// Define the VTKHDF_Recorder class +class VTKHDF_Recorder : public Recorder { +public: + typedef std::vector EleData; + + VTKHDF_Recorder(const char *filename, const OutputDataHDF &ndata, + const std::vector &edata, double dt = 0, double rTolDt = 0.00001); + VTKHDF_Recorder(); + ~VTKHDF_Recorder(); + + int record(int commitTag, double timeStamp) override; + int restart() override; + int domainChanged() override; + int setDomain(Domain &domain) override; + int sendSelf(int commitTag, Channel &theChannel) override; + int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) override; + +private: + int createDataset(hid_t group_id, const char* dataset_name, + hsize_t ncols, hsize_t chunk_rows = 100, + hid_t type_id = H5T_NATIVE_DOUBLE, + hsize_t max_rows = H5S_UNLIMITED); + + int createOffsetDataset(hid_t group_id, const char* dataset_name, + hsize_t chunk_rows = 100, + hid_t type_id = H5T_NATIVE_DOUBLE, + hsize_t max_rows = H5S_UNLIMITED); + + int extendDataset(hid_t dataGroup, + const char* datasetName, + const void* newData, + hid_t datatype, + size_t numNewElements, + size_t numColumns = 0); + + + int extendOffsetDataset(hid_t group_id, + const char* dataset_name, + const void* new_value, + hid_t datatype, + size_t extra_rows = 1); + + + OutputDataHDF outputData; + +protected: + bool initDone; + virtual void addEleData(const EleData &edata) { eledata.push_back(edata); } + std::vector eledata; + +private: + int writeMesh(); + int writeStep(double timeStamp); + int writeDisp(); + int writeVel(); + int writeAccel(); + int writeStrees3D6(); + int writeStrain3D6(); + int writeStress2D3(); + int writeStrain2D3(); + + + + Domain *theDomain; + + double nextTimeStampToRecord; + double deltaT; + double relDeltaTTol; + + char *name; + int counter; + + int ndm; + int ndf; + + int numNode; + int numElement; + int numConnectivityIds; + int maxNDM; + int maxNDF; + + hid_t group_id; + hid_t file_id; + + bool initializationDone; + + hid_t dispOffsetDataset; + hid_t dispDataset; + + + int current_PointOffset; + int current_CellOffset; + int current_ConnectivityIdOffset; + int current_PartOffset; + int next_PointOffset; + int next_CellOffset; + int next_ConnectivityIdOffset; + int next_PartOffset; + + + + // data specif offsets + int CurrentDispOffset; + int CurrentVelOffset; + int CurrentAccelOffset; + + // 3Dstrees6 + int current_Stress3D6Offset; + std::vector stress3D6Responses; // specific to 3DStress6 responses + + // 3DStrain6 + int current_Strain3D6Offset; + std::vector strain3D6Responses; // specific to 3DStrain6 responses + + // 2Dstrees3 + int current_Stress2D3Offset; + std::vector stress2D3Responses; // specific to 2DStress3 responses + + // 2DStrain3 + int current_Strain2D3Offset; + std::vector strain2D3Responses; // specific to 2DStrain3 responses + + + + + + u_int numSteps; + + + + std::map theNodeMapping; + std::map theEleMapping; + + std::vector theNodeTags; + std::vector theEleTags; + std::vector theEleClassTags; + std::vector theEleVtkTags; + std::vector theEleVtkOffsets; + + // Create groups for temporal data + hid_t steps_group; + hid_t point_data_group; + hid_t cell_data_group; + hid_t point_data_offsets_group; + hid_t cell_data_offsets_group; + + hid_t nsteps_attr_id; + + + + // Keep VtkType enum and related static members + enum VtkType { + VTK_VERTEX = 1, + VTK_POLY_VERTEX = 2, + VTK_LINE = 3, + VTK_POLY_LINE = 4, + VTK_TRIANGLE = 5, + VTK_TRIANGLE_STRIP = 6, + VTK_POLYGON = 7, + VTK_PIXEL = 8, + VTK_QUAD = 9, + VTK_TETRA = 10, + VTK_VOXEL = 11, + VTK_HEXAHEDRON = 12, + VTK_WEDGE = 12, + VTK_PYRAMID = 14, + VTK_QUADRATIC_EDGE = 21, + VTK_QUADRATIC_TRIANGLE = 22, + VTK_QUADRATIC_QUAD = 23, + VTK_QUADRATIC_TETRA = 24, + VTK_QUADRATIC_HEXAHEDRON = 25 + }; + + static std::map vtktypes; + static void setVTKType(); +}; + +#endif diff --git a/SRC/runtime/commands/domain/recorder.cpp b/SRC/runtime/commands/domain/recorder.cpp index 3fa09dcc11..ffdc898918 100644 --- a/SRC/runtime/commands/domain/recorder.cpp +++ b/SRC/runtime/commands/domain/recorder.cpp @@ -67,6 +67,7 @@ extern FEM_ObjectBroker theBroker; OPS_Routine OPS_PVDRecorder; OPS_Routine OPS_GmshRecorder; OPS_Routine OPS_MPCORecorder; +OPS_Routine OPS_VTKHDF_Recorder; OPS_Routine OPS_VTK_Recorder; OPS_Routine OPS_ElementRecorderRMS; @@ -1306,6 +1307,14 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } } + + else if (strcmp(argv[1], "vtkhdf") == 0 || strcmp(argv[1], "VTKHDF") == 0) { + OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, &theDomain); + (*theRecorder) = (Recorder *)OPS_VTKHDF_Recorder(rt, argc, argv); + if (theRecorder == 0) { + return TCL_ERROR; + } + } #endif #if 0 diff --git a/SRC/runtime/runtime/TclPackageClassBroker.cpp b/SRC/runtime/runtime/TclPackageClassBroker.cpp index 06ce284ba4..96fbf1770d 100644 --- a/SRC/runtime/runtime/TclPackageClassBroker.cpp +++ b/SRC/runtime/runtime/TclPackageClassBroker.cpp @@ -348,6 +348,11 @@ using namespace OpenSees::Hash::literals; #include "VTK_Recorder.h" #include "GmshRecorder.h" +#ifdef _H5DRM +#include "VTKHDF_Recorder.h" +#endif + + // mp_constraint header files #include "MP_Constraint.h" #include "Joint/MP_Joint2D.h" @@ -1660,6 +1665,13 @@ TclPackageClassBroker::getPtrNewRecorder(int classTag) case RECORDER_TAGS_GmshRecorder: return new GmshRecorder(); +#ifdef _H5DRM + case RECORDER_TAGS_VTKHDF_Recorder(): + return new VTKHDF_Recorder(); +#endif + + + // case RECORDER_TAGS_MPCORecorder: // return new MPCORecorder(); diff --git a/Win32/proj/recorder/recorder.vcxproj b/Win32/proj/recorder/recorder.vcxproj index 95dd6d244c..cfac6b5c85 100644 --- a/Win32/proj/recorder/recorder.vcxproj +++ b/Win32/proj/recorder/recorder.vcxproj @@ -131,6 +131,7 @@ + @@ -161,6 +162,7 @@ + diff --git a/Win32/proj/recorder/recorder.vcxproj.filters b/Win32/proj/recorder/recorder.vcxproj.filters index 2c1d755b37..db3aaba4f9 100644 --- a/Win32/proj/recorder/recorder.vcxproj.filters +++ b/Win32/proj/recorder/recorder.vcxproj.filters @@ -95,6 +95,9 @@ Source Files + + Source Files + Source Files @@ -181,6 +184,9 @@ Header Files + + Header Files + Header Files diff --git a/Win64/proj/recorder/recorder.vcxproj b/Win64/proj/recorder/recorder.vcxproj index 1bed981d4d..2846fd1f7f 100644 --- a/Win64/proj/recorder/recorder.vcxproj +++ b/Win64/proj/recorder/recorder.vcxproj @@ -217,6 +217,7 @@ + @@ -248,6 +249,7 @@ + diff --git a/Win64/proj/recorder/recorder.vcxproj.filters b/Win64/proj/recorder/recorder.vcxproj.filters index e524034c08..03e6cfba09 100644 --- a/Win64/proj/recorder/recorder.vcxproj.filters +++ b/Win64/proj/recorder/recorder.vcxproj.filters @@ -95,6 +95,9 @@ Source Files + + Source Files + Source Files @@ -184,6 +187,9 @@ Header Files + + Header Files + Header Files From c6669e651c92b54742b9c43f7f149a5df3212638 Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Mon, 20 Jan 2025 12:25:03 -0800 Subject: [PATCH 011/261] Add stress3D6 response support for vtkhdf recorder in Brick element --- SRC/element/brick/Brick.cpp | 79 +++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/SRC/element/brick/Brick.cpp b/SRC/element/brick/Brick.cpp index dd92b27908..4f2b4144a3 100644 --- a/SRC/element/brick/Brick.cpp +++ b/SRC/element/brick/Brick.cpp @@ -1777,9 +1777,47 @@ Brick::setResponse(const char **argv, int argc, OPS_Stream &output) } theResponse = new ElementResponse(this, 5, Vector(48)); + } else if (strcmp(argv[0],"stress3D6") == 0) { + // this response if for vtkhdf recorder which averages the stresses + // over the 8 gauss points and returns the 6 values + output.tag("GaussPoint"); + output.attr("number",1); + output.tag("NdMaterialOutput"); + output.attr("classType", materialPointers[0]->getClassTag()); + output.attr("tag", materialPointers[0]->getTag()); + + output.tag("ResponseType","sigma11"); + output.tag("ResponseType","sigma22"); + output.tag("ResponseType","sigma33"); + output.tag("ResponseType","sigma12"); + output.tag("ResponseType","sigma23"); + output.tag("ResponseType","sigma13"); + + output.endTag(); // NdMaterialOutput + output.endTag(); // GaussPoint + theResponse = new ElementResponse(this, 6, Vector(6)); + + } else if (strcmp(argv[0],"strain3D6") == 0) { + // this response if for vtkhdf recorder which averages the strains + // over the 8 gauss points and returns the 6 values + output.tag("GaussPoint"); + output.attr("number",1); + output.tag("NdMaterialOutput"); + output.attr("classType", materialPointers[0]->getClassTag()); + output.attr("tag", materialPointers[0]->getTag()); + + output.tag("ResponseType","eps11"); + output.tag("ResponseType","eps22"); + output.tag("ResponseType","eps33"); + output.tag("ResponseType","eps12"); + output.tag("ResponseType","eps23"); + output.tag("ResponseType","eps13"); + + output.endTag(); // NdMaterialOutput + output.endTag(); // GaussPoint + + theResponse = new ElementResponse(this, 7, Vector(6)); } - - output.endTag(); // ElementOutput return theResponse; } @@ -1846,8 +1884,43 @@ Brick::getResponse(int responseID, Information &eleInfo) } return eleInfo.setVector(stresses); - } + } else if (responseID == 6) { + + // Loop over the integration points + Vector tmpStress(6); + for (int i = 0; i < 8; i++) { + + // Get material stress + const Vector &sigma = materialPointers[i]->getStress(); + tmpStress(0) += sigma(0)*0.125; + tmpStress(1) += sigma(1)*0.125; + tmpStress(2) += sigma(2)*0.125; + tmpStress(3) += sigma(3)*0.125; + tmpStress(4) += sigma(4)*0.125; + tmpStress(5) += sigma(5)*0.125; + } + + return eleInfo.setVector(tmpStress); + } else if (responseID == 7) { + + // Loop over the integration points + int cnt = 0; + Vector tmpStrain(6); + for (int i = 0; i < 8; i++) { + + // Get material strain + const Vector &sigma = materialPointers[i]->getStrain(); + tmpStrain(0) += sigma(0); + tmpStrain(1) += sigma(1); + tmpStrain(2) += sigma(2); + tmpStrain(3) += sigma(3); + tmpStrain(4) += sigma(4); + tmpStrain(5) += sigma(5); + } + tmpStrain /= 8.0; + return eleInfo.setVector(tmpStrain); + } else return -1; } From 3129e9305fda0f999e345e4dc7ead7dc63068049 Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Mon, 20 Jan 2025 12:25:43 -0800 Subject: [PATCH 012/261] Add stress3D6 response support for vtkhdf recorder in BBarBrick element --- SRC/element/brick/BbarBrick.cpp | 62 +++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/SRC/element/brick/BbarBrick.cpp b/SRC/element/brick/BbarBrick.cpp index eb2c00b422..5b124b6057 100644 --- a/SRC/element/brick/BbarBrick.cpp +++ b/SRC/element/brick/BbarBrick.cpp @@ -1464,7 +1464,43 @@ BbarBrick::setResponse(const char **argv, int argc, OPS_Stream &output) output.endTag(); // GaussPoint } theResponse = new ElementResponse(this, 4, Vector(48)); + } else if (strcmp(argv[0],"stress3D6") == 0) { + + output.tag("GaussPoint"); + output.attr("number",1); + output.tag("NdMaterialOutput"); + output.attr("classType", materialPointers[0]->getClassTag()); + output.attr("tag", materialPointers[0]->getTag()); + + output.tag("ResponseType","sigma11"); + output.tag("ResponseType","sigma22"); + output.tag("ResponseType","sigma33"); + output.tag("ResponseType","sigma12"); + output.tag("ResponseType","sigma23"); + output.tag("ResponseType","sigma13"); + + output.endTag(); // NdMaterialOutput + output.endTag(); // GaussPoint + theResponse = new ElementResponse(this, 5, Vector(6)); + } else if (strcmp(argv[0],"strain3D6") == 0) { + output.tag("GaussPoint"); + output.attr("number",1); + output.tag("NdMaterialOutput"); + output.attr("classType", materialPointers[0]->getClassTag()); + output.attr("tag", materialPointers[0]->getTag()); + + output.tag("ResponseType","eps11"); + output.tag("ResponseType","eps22"); + output.tag("ResponseType","eps33"); + output.tag("ResponseType","eps12"); + output.tag("ResponseType","eps23"); + output.tag("ResponseType","eps13"); + + output.endTag(); // NdMaterialOutput + output.endTag(); // GaussPoint + theResponse = new ElementResponse(this, 6, Vector(6)); } + output.endTag(); // ElementOutput return theResponse; @@ -1513,7 +1549,33 @@ BbarBrick::getResponse(int responseID, Information &eleInfo) stresses(cnt++) = sigma(5); } return eleInfo.setVector(stresses); + } else if (responseID == 5) { + + Vector tmpStress(6); + for (int i = 0; i < 8; i++) { + const Vector &sigma = materialPointers[i]->getStress(); + tmpStress(0) += sigma(0) * 0.125; + tmpStress(1) += sigma(1) * 0.125; + tmpStress(2) += sigma(2) * 0.125; + tmpStress(3) += sigma(3) * 0.125; + tmpStress(4) += sigma(4) * 0.125; + tmpStress(5) += sigma(5) * 0.125; + } + return eleInfo.setVector(tmpStress); + } else if (responseID == 6) { + Vector tmpStrain(6); + for (int i = 0; i < 8; i++) { + const Vector &sigma = materialPointers[i]->getStrain(); + tmpStrain(0) += sigma(0) * 0.125; + tmpStrain(1) += sigma(1) * 0.125; + tmpStrain(2) += sigma(2) * 0.125; + tmpStrain(3) += sigma(3) * 0.125; + tmpStrain(4) += sigma(4) * 0.125; + tmpStrain(5) += sigma(5) * 0.125; + } + return eleInfo.setVector(tmpStrain); } + // Get) else return -1; From f94725ec2f1cf9a0a68165876332b35359856fbc Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Mon, 20 Jan 2025 12:26:29 -0800 Subject: [PATCH 013/261] Add stress3D6 response support for vtkhdf recorder in BBarBrickUP element --- SRC/element/UP-ucsd/BBarBrickUP.cpp | 65 +++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/SRC/element/UP-ucsd/BBarBrickUP.cpp b/SRC/element/UP-ucsd/BBarBrickUP.cpp index 60a8bcb4cd..f8d12755a3 100644 --- a/SRC/element/UP-ucsd/BBarBrickUP.cpp +++ b/SRC/element/UP-ucsd/BBarBrickUP.cpp @@ -1584,8 +1584,45 @@ BBarBrickUP::setResponse(const char **argv, int argc, OPS_Stream &output) output.endTag(); // GaussPoint } theResponse = new ElementResponse(this, 5, Vector(48)); + } else if (strcmp(argv[0],"stress3D6") ==0) { + output.tag("GaussPoint"); + output.attr("number",1); + output.tag("NdMaterialOutput"); + output.attr("classType", materialPointers[0]->getClassTag()); + output.attr("tag", materialPointers[0]->getTag()); + + output.tag("ResponseType","sigma11"); + output.tag("ResponseType","sigma22"); + output.tag("ResponseType","sigma33"); + output.tag("ResponseType","sigma12"); + output.tag("ResponseType","sigma23"); + output.tag("ResponseType","sigma13"); + + output.endTag(); // NdMaterialOutput + output.endTag(); // GaussPoint + theResponse = new ElementResponse(this, 6, Vector(6)); + } else if (strcmp(argv[0],"strain3D6")==0) { + output.tag("GaussPoint"); + output.attr("number",1); + output.tag("NdMaterialOutput"); + output.attr("classType", materialPointers[0]->getClassTag()); + output.attr("tag", materialPointers[0]->getTag()); + + output.tag("ResponseType","eps11"); + output.tag("ResponseType","eps22"); + output.tag("ResponseType","eps33"); + output.tag("ResponseType","eps12"); + output.tag("ResponseType","eps23"); + output.tag("ResponseType","eps13"); + + output.endTag(); // NdMaterialOutput + output.endTag(); // GaussPoint + theResponse = new ElementResponse(this, 7, Vector(6)); } + + + output.endTag(); // ElementOutput return theResponse; @@ -1626,6 +1663,34 @@ BBarBrickUP::getResponse(int responseID, Information &eleInfo) return eleInfo.setVector(stresses); } + else if (responseID == 6) { + + Vector tmpStress(6); + for (int i = 0; i < 8; i++) { + // Get material stress response + const Vector &sigma = materialPointers[i]->getStress(); + tmpStress(0) = sigma(0) * 0.125; + tmpStress(1) = sigma(1) * 0.125; + tmpStress(2) = sigma(2) * 0.125; + tmpStress(3) = sigma(3) * 0.125; + tmpStress(4) = sigma(4) * 0.125; + tmpStress(5) = sigma(5) * 0.125; + } + return eleInfo.setVector(tmpStress); + } else if (responseID == 7) { + Vector tmpStrain(6); + for (int i = 0; i < 8; i++) { + // Get material strain response + const Vector &eps = materialPointers[i]->getStrain(); + tmpStrain(0) = eps(0) * 0.125; + tmpStrain(1) = eps(1) * 0.125; + tmpStrain(2) = eps(2) * 0.125; + tmpStrain(3) = eps(3) * 0.125; + tmpStrain(4) = eps(4) * 0.125; + tmpStrain(5) = eps(5) * 0.125; + } + return eleInfo.setVector(tmpStrain); + } else return -1; From 0bca381c6866f68007d27fc6b37639ca89f44040 Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Mon, 20 Jan 2025 12:27:07 -0800 Subject: [PATCH 014/261] Add stress3D6 response support for vtkhdf recorder in BrickUP element --- SRC/element/UP-ucsd/BrickUP.cpp | 63 ++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/SRC/element/UP-ucsd/BrickUP.cpp b/SRC/element/UP-ucsd/BrickUP.cpp index 8617cd6555..350efbeede 100644 --- a/SRC/element/UP-ucsd/BrickUP.cpp +++ b/SRC/element/UP-ucsd/BrickUP.cpp @@ -1567,6 +1567,40 @@ BrickUP::setResponse(const char **argv, int argc, OPS_Stream &output) output.endTag(); // GaussPoint } theResponse = new ElementResponse(this, 5, Vector(48)); + } else if (strcmp(argv[0],"stress3D6")==0) { + output.tag("GaussPoint"); + output.attr("number",1); + output.tag("NdMaterialOutput"); + output.attr("classType", materialPointers[0]->getClassTag()); + output.attr("tag", materialPointers[0]->getTag()); + + output.tag("ResponseType","sigma11"); + output.tag("ResponseType","sigma22"); + output.tag("ResponseType","sigma33"); + output.tag("ResponseType","sigma12"); + output.tag("ResponseType","sigma23"); + output.tag("ResponseType","sigma13"); + + output.endTag(); // NdMaterialOutput + output.endTag(); // GaussPoint + theResponse = new ElementResponse(this, 6, Vector(6)); + } else if (strcmp(argv[0],"strain3D6")==0) { + output.tag("GaussPoint"); + output.attr("number",1); + output.tag("NdMaterialOutput"); + output.attr("classType", materialPointers[0]->getClassTag()); + output.attr("tag", materialPointers[0]->getTag()); + + output.tag("ResponseType","eps11"); + output.tag("ResponseType","eps22"); + output.tag("ResponseType","eps33"); + output.tag("ResponseType","eps12"); + output.tag("ResponseType","eps23"); + output.tag("ResponseType","eps13"); + + output.endTag(); // NdMaterialOutput + output.endTag(); // GaussPoint + theResponse = new ElementResponse(this, 7, Vector(6)); } output.endTag(); // ElementOutput @@ -1608,7 +1642,34 @@ BrickUP::getResponse(int responseID, Information &eleInfo) } return eleInfo.setVector(stresses); - } + } else if (responseID == 6) { + + Vector tmpStress(6); + for (int i = 0; i < 8; i++) { + // Get material stress response + const Vector &sigma = materialPointers[i]->getStress(); + tmpStress(0) = sigma(0) * 0.125; + tmpStress(1) = sigma(1) * 0.125; + tmpStress(2) = sigma(2) * 0.125; + tmpStress(3) = sigma(3) * 0.125; + tmpStress(4) = sigma(4) * 0.125; + tmpStress(5) = sigma(5) * 0.125; + } + return eleInfo.setVector(tmpStress); + } else if (responseID == 7) { + Vector tmpStrain(6); + for (int i = 0; i < 8; i++) { + // Get material strain response + const Vector &eps = materialPointers[i]->getStrain(); + tmpStrain(0) = eps(0) * 0.125; + tmpStrain(1) = eps(1) * 0.125; + tmpStrain(2) = eps(2) * 0.125; + tmpStrain(3) = eps(3) * 0.125; + tmpStrain(4) = eps(4) * 0.125; + tmpStrain(5) = eps(5) * 0.125; + } + return eleInfo.setVector(tmpStrain); + } else return -1; From 6de02abbec4330c9a8ed9fdc5e33633f24cd4781 Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Mon, 20 Jan 2025 12:27:31 -0800 Subject: [PATCH 015/261] Add stress3D6 response support for vtkhdf recorder in SSPBrick element --- SRC/element/UWelements/SSPbrick.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/SRC/element/UWelements/SSPbrick.cpp b/SRC/element/UWelements/SSPbrick.cpp index 9e0e14acc8..3ef1951e46 100644 --- a/SRC/element/UWelements/SSPbrick.cpp +++ b/SRC/element/UWelements/SSPbrick.cpp @@ -983,15 +983,33 @@ SSPbrick::Print(OPS_Stream &s, int flag) Response* SSPbrick::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) { - // no special recorders for this element, call the method in the material class - return theMaterial->setResponse(argv, argc, eleInfo); + if (strcmp(argv[0],"stress3D6") == 0) { + return new ElementResponse(this, 1234432100, Vector(6)); + } + if (strcmp(argv[0],"strain3D6") == 0) { + return new ElementResponse(this, 1234432101, Vector(6)); + } else { + // no special recorders for this element, call the method in the material class + return theMaterial->setResponse(argv, argc, eleInfo); + } } int SSPbrick::getResponse(int responseID, Information &eleInfo) { - // no special recorders for this element, call the method in the material class - return theMaterial->getResponse(responseID, eleInfo); + if (responseID == 1234432100) { + // get stress from the material + const Vector &mStress = theMaterial->getStress(); + return eleInfo.setVector(mStress); + } else if (responseID == 1234432101) { + // get strain from the material + + const Vector &mStrain = theMaterial->getStrain(); + return eleInfo.setVector(mStrain); + } else { + // no special recorders for this element, call the method in the material class + return theMaterial->getResponse(responseID, eleInfo); + } } int From 986239da8bcc72197abf4bcd9edfd6e229848bca Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Mon, 20 Jan 2025 12:28:00 -0800 Subject: [PATCH 016/261] Add stress3D6 response support for vtkhdf recorder in SSPBrickUP element --- SRC/element/UWelements/SSPbrickUP.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/SRC/element/UWelements/SSPbrickUP.cpp b/SRC/element/UWelements/SSPbrickUP.cpp index 68a6bb507b..25cbd7210c 100644 --- a/SRC/element/UWelements/SSPbrickUP.cpp +++ b/SRC/element/UWelements/SSPbrickUP.cpp @@ -1132,15 +1132,35 @@ SSPbrickUP::Print(OPS_Stream &s, int flag) Response* SSPbrickUP::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) { - // no special recorders for this element, call the method in the material class - return theMaterial->setResponse(argv, argc, eleInfo); + + if (strcmp(argv[0],"stress3D6") == 0) { + return new ElementResponse(this, 1, Vector(6)); + } + if (strcmp(argv[0],"strain3D6") == 0) { + return new ElementResponse(this, 2, Vector(6)); + } else { + // no special recorders for this element, call the method in the material class + return theMaterial->setResponse(argv, argc, eleInfo); + } } int SSPbrickUP::getResponse(int responseID, Information &eleInfo) { // no special recorders for this element, call the method in the material class - return theMaterial->getResponse(responseID, eleInfo); + if (responseID == 1) { + // get stress from the material + const Vector &mStress = theMaterial->getStress(); + return eleInfo.setVector(mStress); + } else if (responseID == 2) { + // get strain from the material + + const Vector &mStrain = theMaterial->getStrain(); + return eleInfo.setVector(mStrain); + } else { + // no special recorders for this element, call the method in the material class + return theMaterial->getResponse(responseID, eleInfo); + } } int From e7f0f522c86a7c0d51a3256e434a13389bc457e1 Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Mon, 20 Jan 2025 12:29:09 -0800 Subject: [PATCH 017/261] Add stress3D6 response support for vtkhdf recorder in SSPquadUP element --- SRC/element/UWelements/SSPquadUP.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/SRC/element/UWelements/SSPquadUP.cpp b/SRC/element/UWelements/SSPquadUP.cpp index 105cbabd5c..ecf6bff71a 100644 --- a/SRC/element/UWelements/SSPquadUP.cpp +++ b/SRC/element/UWelements/SSPquadUP.cpp @@ -978,15 +978,34 @@ SSPquadUP::Print(OPS_Stream &s, int flag) Response* SSPquadUP::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) { - // no special recorders for this element, call the method in the material class - return theMaterial->setResponse(argv, argc, eleInfo); + if (strcmp(argv[0],"stress2D3")==0) { + return new ElementResponse(this, 1234432100, Vector(3)); + } else if (strcmp(argv[0],"strain2D3")==0) { + return new ElementResponse(this, 1234432101, Vector(3)); + } else { + return theMaterial->setResponse(argv, argc, eleInfo); + } } int SSPquadUP::getResponse(int responseID, Information &eleInfo) { - // no special recorders for this element, call the method in the material class - return theMaterial->getResponse(responseID, eleInfo); + if (responseID == 1234432100) { + // return the stress vector + Vector stress(3); + stress = theMaterial->getStress(); + eleInfo.setVector(stress); + return 0; + } else if (responseID == 1234432101) { + // return the strain vector + Vector strain(3); + strain = theMaterial->getStrain(); + eleInfo.setVector(strain); + return 0; + } else { + // default is to call getResponse in the material + return theMaterial->getResponse(responseID, eleInfo); + } } int From 851fd91868a7bf3fa9eb537b760e8c5c6918212f Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Mon, 20 Jan 2025 12:48:48 -0800 Subject: [PATCH 018/261] Add stress2D3 response support for vtkhdf recorder in SSPquad element. --- SRC/element/UWelements/SSPquad.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/SRC/element/UWelements/SSPquad.cpp b/SRC/element/UWelements/SSPquad.cpp index a7e4df4145..4db3296ab9 100644 --- a/SRC/element/UWelements/SSPquad.cpp +++ b/SRC/element/UWelements/SSPquad.cpp @@ -839,15 +839,34 @@ SSPquad::Print(OPS_Stream &s, int flag) Response* SSPquad::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) { - // no special recorders for this element, call the method in the material class - return theMaterial->setResponse(argv, argc, eleInfo); + if (strcmp(argv[0],"stress2D3")==0) { + return new ElementResponse(this, 1234432101, Vector(3)); + } else if (strcmp(argv[0],"strain2D3")==0) { + return new ElementResponse(this, 1234432102, Vector(3)); + } else { + return theMaterial->setResponse(argv, argc, eleInfo); + } } int SSPquad::getResponse(int responseID, Information &eleInfo) { - // no special recorders for this element, call the method in the material class - return theMaterial->getResponse(responseID, eleInfo); + if (responseID == 1234432101) { + // return the stress vector + Vector stress(3); + stress = theMaterial->getStress(); + eleInfo.setVector(stress); + return 0; + } else if (responseID == 1234432102) { + // return the strain vector + Vector strain(3); + strain = theMaterial->getStrain(); + eleInfo.setVector(strain); + return 0; + } else { + // default is to call getResponse in the material + return theMaterial->getResponse(responseID, eleInfo); + } } int From 279d45f7ce65f4fda995c6706ba7d2c9b89638f4 Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Mon, 20 Jan 2025 12:52:26 -0800 Subject: [PATCH 019/261] remove printing information for vtkhdf recorder --- SRC/recorder/VTKHDF_Recorder.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/SRC/recorder/VTKHDF_Recorder.cpp b/SRC/recorder/VTKHDF_Recorder.cpp index d243b75f44..cefa922c1c 100644 --- a/SRC/recorder/VTKHDF_Recorder.cpp +++ b/SRC/recorder/VTKHDF_Recorder.cpp @@ -173,18 +173,18 @@ void* OPS_VTKHDF_Recorder() numdata = OPS_GetNumRemainingInputArgs(); } - // print summary of parmeters for the user - opserr << "VTKHDF_Recorder: " << name << " -dT " << dT << " -rTolDt " << rTolDt << endln; - opserr << "disp " << (outputData.disp ? "true" : "false") << endln; - opserr << "vel " << (outputData.vel ? "true" : "false") << endln; - opserr << "accel " << (outputData.accel ? "true" : "false") << endln; - opserr << "reaction " << (outputData.reaction ? "true" : "false") << endln; - opserr << "mass " << (outputData.mass ? "true" : "false") << endln; - opserr << "unbalancedLoad " << (outputData.unbalancedLoad ? "true" : "false") << endln; - opserr << "stress3D6 " << (outputData.stress3D6 ? "true" : "false") << endln; - opserr << "strain3D6 " << (outputData.strain3D6 ? "true" : "false") << endln; - opserr << "stress2D3 " << (outputData.stress2D3 ? "true" : "false") << endln; - opserr << "strain2D3 " << (outputData.strain2D3 ? "true" : "false") << endln; + // // print summary of parmeters for the user + // opserr << "VTKHDF_Recorder: " << name << " -dT " << dT << " -rTolDt " << rTolDt << endln; + // opserr << "disp " << (outputData.disp ? "true" : "false") << endln; + // opserr << "vel " << (outputData.vel ? "true" : "false") << endln; + // opserr << "accel " << (outputData.accel ? "true" : "false") << endln; + // opserr << "reaction " << (outputData.reaction ? "true" : "false") << endln; + // opserr << "mass " << (outputData.mass ? "true" : "false") << endln; + // opserr << "unbalancedLoad " << (outputData.unbalancedLoad ? "true" : "false") << endln; + // opserr << "stress3D6 " << (outputData.stress3D6 ? "true" : "false") << endln; + // opserr << "strain3D6 " << (outputData.strain3D6 ? "true" : "false") << endln; + // opserr << "stress2D3 " << (outputData.stress2D3 ? "true" : "false") << endln; + // opserr << "strain2D3 " << (outputData.strain2D3 ? "true" : "false") << endln; // Create the recorder return new VTKHDF_Recorder(name, outputData, eledata, dT, rTolDt); From 618d434a49ad1af8bcd49c23fdbbb43592a58f4e Mon Sep 17 00:00:00 2001 From: amnp95 Date: Mon, 20 Jan 2025 21:13:57 -0800 Subject: [PATCH 020/261] fixing VTKHDF types for windows compiler --- SRC/recorder/VTKHDF_Recorder.cpp | 2 +- SRC/recorder/VTKHDF_Recorder.h | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/SRC/recorder/VTKHDF_Recorder.cpp b/SRC/recorder/VTKHDF_Recorder.cpp index cefa922c1c..566dbb317d 100644 --- a/SRC/recorder/VTKHDF_Recorder.cpp +++ b/SRC/recorder/VTKHDF_Recorder.cpp @@ -1517,7 +1517,7 @@ int VTKHDF_Recorder::writeMesh() { // (D) Types => shape (numElement) - std::vector types(theEleVtkTags.begin(), theEleVtkTags.end()); + std::vector types(theEleVtkTags.begin(), theEleVtkTags.end()); // opserr << " Gathering data done\n"; // ------------------------------------------------------------- diff --git a/SRC/recorder/VTKHDF_Recorder.h b/SRC/recorder/VTKHDF_Recorder.h index 8972e77573..f37166379f 100644 --- a/SRC/recorder/VTKHDF_Recorder.h +++ b/SRC/recorder/VTKHDF_Recorder.h @@ -30,10 +30,11 @@ #include #include "Response.h" #include +#include +#include #include "hdf5.h" - // Define the OutputData class class OutputDataHDF { public: @@ -225,7 +226,7 @@ class VTKHDF_Recorder : public Recorder { - u_int numSteps; + unsigned int numSteps; @@ -235,7 +236,7 @@ class VTKHDF_Recorder : public Recorder { std::vector theNodeTags; std::vector theEleTags; std::vector theEleClassTags; - std::vector theEleVtkTags; + std::vector theEleVtkTags; std::vector theEleVtkOffsets; // Create groups for temporal data From 99d4d826bc1d60f707cd369aa75bfe96d09bb32a Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Tue, 21 Jan 2025 12:12:21 -0800 Subject: [PATCH 021/261] add PML elements to vtk types --- SRC/recorder/VTKHDF_Recorder.cpp | 6 ++++++ SRC/recorder/VTK_Recorder.cpp | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/SRC/recorder/VTKHDF_Recorder.cpp b/SRC/recorder/VTKHDF_Recorder.cpp index 566dbb317d..6fc34d3421 100644 --- a/SRC/recorder/VTKHDF_Recorder.cpp +++ b/SRC/recorder/VTKHDF_Recorder.cpp @@ -3261,6 +3261,12 @@ void VTKHDF_Recorder::setVTKType() vtktypes[ELE_TAG_FSIFluidElement2D] = VTK_QUAD; vtktypes[ELE_TAG_FSIInterfaceElement2D] = VTK_LINE; vtktypes[ELE_TAG_FSIFluidBoundaryElement2D] = VTK_LINE; + vtktypes[ELE_TAG_PML2D_3] = VTK_QUAD; + vtktypes[ELE_TAG_PML2D_5] = VTK_QUAD; + vtktypes[ELE_TAG_PML2D_12] = VTK_QUAD; + vtktypes[ELE_TAG_PML2DVISCOUS] = VTK_QUAD; + vtktypes[ELE_TAG_PML2D] = VTK_QUAD; + vtktypes[ELE_TAG_PML3D] = VTK_HEXAHEDRON; } diff --git a/SRC/recorder/VTK_Recorder.cpp b/SRC/recorder/VTK_Recorder.cpp index 16dc4b456b..ae3754e1db 100644 --- a/SRC/recorder/VTK_Recorder.cpp +++ b/SRC/recorder/VTK_Recorder.cpp @@ -1199,6 +1199,12 @@ VTK_Recorder::setVTKType() vtktypes[ELE_TAG_FSIFluidElement2D] = VTK_QUAD; vtktypes[ELE_TAG_FSIInterfaceElement2D] = VTK_LINE; vtktypes[ELE_TAG_FSIFluidBoundaryElement2D] = VTK_LINE; + vtktypes[ELE_TAG_PML2D_3] = VTK_QUAD; + vtktypes[ELE_TAG_PML2D_5] = VTK_QUAD; + vtktypes[ELE_TAG_PML2D_12] = VTK_QUAD; + vtktypes[ELE_TAG_PML2DVISCOUS] = VTK_QUAD; + vtktypes[ELE_TAG_PML2D] = VTK_QUAD; + vtktypes[ELE_TAG_PML3D] = VTK_HEXAHEDRON; } From d8e46ad73d4852a324bae33cdbcfba827f7e097d Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Wed, 22 Jan 2025 16:58:25 -0800 Subject: [PATCH 022/261] adding Flush to save the data if the simulation crashes for vtkhdf recorder --- SRC/recorder/VTKHDF_Recorder.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SRC/recorder/VTKHDF_Recorder.cpp b/SRC/recorder/VTKHDF_Recorder.cpp index 6fc34d3421..6851231354 100644 --- a/SRC/recorder/VTKHDF_Recorder.cpp +++ b/SRC/recorder/VTKHDF_Recorder.cpp @@ -1984,6 +1984,7 @@ int VTKHDF_Recorder::writeMesh() { int VTKHDF_Recorder::record(int commitTag, double timeStamp) { + H5Fflush(file_id, H5F_SCOPE_GLOBAL); if (!initDone) { this->writeMesh(); } @@ -2057,6 +2058,7 @@ int VTKHDF_Recorder::record(int commitTag, double timeStamp) nextTimeStampToRecord = timeStamp + deltaT; } } + H5Fflush(file_id, H5F_SCOPE_GLOBAL); return 0; } From a0a9ae8ce499a5b68c04d5fccb26c38acfef7bbd Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Fri, 7 Feb 2025 10:50:51 +0100 Subject: [PATCH 023/261] add E_SFI_MVLEM_3D --- SRC/recorder/MPCORecorder.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SRC/recorder/MPCORecorder.cpp b/SRC/recorder/MPCORecorder.cpp index 1d9bf4ebda..ed678f5835 100755 --- a/SRC/recorder/MPCORecorder.cpp +++ b/SRC/recorder/MPCORecorder.cpp @@ -3995,7 +3995,8 @@ namespace mpco { else if ( // ./mvlem elem_class_tag == ELE_TAG_MVLEM_3D || - elem_class_tag == ELE_TAG_SFI_MVLEM_3D + elem_class_tag == ELE_TAG_SFI_MVLEM_3D || + elem_class_tag == ELE_TAG_E_SFI_MVLEM_3D ) { geom_type = ElementGeometryType::Quadrilateral_CohesiveBand_4N; int_type = ElementIntegrationRuleType::CustomIntegrationRule; @@ -4173,7 +4174,8 @@ namespace mpco { bool done = false; std::string request1 = "section"; if (elem->getClassTag() == ELE_TAG_MVLEM_3D || - elem->getClassTag() == ELE_TAG_SFI_MVLEM_3D) { + elem->getClassTag() == ELE_TAG_SFI_MVLEM_3D || + elem->getClassTag() == ELE_TAG_E_SFI_MVLEM_3D) { request1 = "material"; } std::string request3 = "dummy"; From 71b179b00516b52bd9d9694538f42a390eaabcac Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Thu, 13 Feb 2025 12:08:15 +0100 Subject: [PATCH 024/261] add global penalty value as automation --- .../handler/AutoConstraintHandler.cpp | 95 ++++++++++++++++--- 1 file changed, 80 insertions(+), 15 deletions(-) diff --git a/SRC/analysis/handler/AutoConstraintHandler.cpp b/SRC/analysis/handler/AutoConstraintHandler.cpp index 14bf7cdca7..dd86793a3b 100644 --- a/SRC/analysis/handler/AutoConstraintHandler.cpp +++ b/SRC/analysis/handler/AutoConstraintHandler.cpp @@ -64,6 +64,15 @@ #include #include +// for parallel +#ifdef _PARALLEL_PROCESSING +extern bool OPS_PARTITIONED; +#include +#endif // _PARALLEL_PROCESSING +#ifdef _PARALLEL_INTERPRETERS +#include +#endif // _PARALLEL_INTERPRETERS + void* OPS_AutoConstraintHandler() { // default parameters @@ -152,41 +161,49 @@ namespace { */ PenaltyEvaluator(Domain* domain, const std::vector mps, double penalty_oom) { - // store nodes involved in the input mps and init penalty to 0 + // store nodes involved in the input mps and init their local penalty to 0 for (auto* mp : mps) { if (mp) { m_node_penalty[mp->getNodeRetained()] = 0.0; m_node_penalty[mp->getNodeConstrained()] = 0.0; } } - // eval elements connected to those nodes + // evaluate global and local stiffness info + m_gp_min = 0.0; + m_gp_max = 0.0; + m_gp_avg = 0.0; + m_gp_cnt = 0.0; Element* elePtr; ElementIter& theEles = domain->getElements(); while ((elePtr = theEles()) != 0) { if (!elePtr->isSubdomain()) { - // element nodes. process only if at least one node is involved - const ID& elenodes = elePtr->getExternalNodes(); - bool found = false; - for (int i = 0; i < elenodes.Size(); ++i) { - if (m_node_penalty.count(elenodes(i)) > 0) { - found = true; - break; - } - } - if (!found) continue; - // eval max diagonal entry for this element + // eval max diagonal entry for this element ... const Matrix& K = elePtr->getInitialStiff(); double kmax = 0.0; for (int i = 0; i < K.noRows(); ++i) { double ki = std::abs(K(i, i)); kmax = std::max(kmax, ki); } - // and accumulte the same to each node (it's just an approximation) + // ... and accumulte the same kmax to each node (it's just an approximation) + // (process only if at least one node is involved) + const ID& elenodes = elePtr->getExternalNodes(); for (int i = 0; i < elenodes.Size(); ++i) { auto iter = m_node_penalty.find(elenodes(i)); if (iter != m_node_penalty.end()) iter->second += kmax; } + // now eval the global min/max/avg stiffness + m_gp_max = std::max(m_gp_max, kmax); + m_gp_min = m_gp_max; + double k_tol = 1.0e-12 * kmax; + for (int i = 0; i < K.noRows(); ++i) { + double ki = std::abs(K(i, i)); + if (ki > k_tol) { + m_gp_min = std::min(m_gp_min, ki); + m_gp_avg += ki; + m_gp_cnt += 1.0; + } + } } } // now m_node_penalty contains the accumulated max diagonal stiffness entry @@ -200,6 +217,42 @@ namespace { // compute the penalty value item.second = std::pow(10.0, koom + penalty_oom); } + // finalize the global stiffness info for global penalty +#if defined(_PARALLEL_PROCESSING) || defined(_PARALLEL_INTERPRETERS) + int pid = 0; + int np = 1; + MPI_Comm_rank(MPI_COMM_WORLD, &pid); + MPI_Comm_size(MPI_COMM_WORLD, &np); + // quick return for 1 process or for non-partitioned cases (should not happen) + bool do_allreduce = true; + if (np == 1) do_allreduce = false; +#if defined(_PARALLEL_PROCESSING) + if (pid == 0 && !OPS_PARTITIONED) do_allreduce = false; +#endif // defined(_PARALLEL_PROCESSING) + if (do_allreduce) { + double local_min = m_gp_min; + double local_max = m_gp_max; + double local_avg = m_gp_avg; + double local_cnt = m_gp_cnt; + if (MPI_Allreduce(&local_min, &m_gp_min, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD) != MPI_SUCCESS) { + opserr << "AutoConstraintHandler Warning: MPI_Allreduce failed to get MIN\n"; + } + if (MPI_Allreduce(&local_max, &m_gp_max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD) != MPI_SUCCESS) { + opserr << "AutoConstraintHandler Warning: MPI_Allreduce failed to get MAX\n"; + } + if (MPI_Allreduce(&local_avg, &m_gp_avg, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD) != MPI_SUCCESS) { + opserr << "AutoConstraintHandler Warning: MPI_Allreduce failed to get SUM\n"; + } + if (MPI_Allreduce(&local_cnt, &m_gp_cnt, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD) != MPI_SUCCESS) { + opserr << "AutoConstraintHandler Warning: MPI_Allreduce failed to get CNT\n"; + } + } +#endif // defined(_PARALLEL_PROCESSING) || defined(_PARALLEL_INTERPRETERS) + // finalize the average + if (m_gp_cnt > 0.0) m_gp_avg /= m_gp_cnt; + // compute the global penalty as function of the average + double gp_koom = std::round(std::log10(m_gp_avg)); + m_global_penalty = std::pow(10.0, gp_koom + penalty_oom); } /** returns the penalty value for the input mp constraint @@ -212,12 +265,19 @@ namespace { if (itr != m_node_penalty.end()) value = std::max(value, itr->second); auto itc = m_node_penalty.find(mp->getNodeConstrained()); if (itc != m_node_penalty.end()) value = std::max(value, itc->second); + if (value == 0.0) value = m_global_penalty; return value; } public: // maps a node id to the penalty value at that node std::unordered_map m_node_penalty; + // global penalty data + double m_gp_min = 0.0; + double m_gp_max = 0.0; + double m_gp_avg = 0.0; + double m_gp_cnt = 0.0; + double m_global_penalty = 0.0; }; } @@ -390,7 +450,6 @@ AutoConstraintHandler::handle(const ID* nodesLast) MP_Constraint* mpPtr; while ((mpPtr = theMPs()) != 0) mps_penalty.push_back(mpPtr); - } std::shared_ptr peval; if (auto_penalty) @@ -440,6 +499,12 @@ AutoConstraintHandler::handle(const ID* nodesLast) ss << "+ MP Constraints:\n"; ss << " + " << mps_penalty.size() << " constraints handled with the Penalty method\n"; if (auto_penalty) { + ss << " + Global Penalty values:\n"; + ss << " + KMIN = " << std::scientific << peval->m_gp_min << "\n"; + ss << " + KMAX = " << std::scientific << peval->m_gp_max << "\n"; + ss << " + KAVG = " << std::scientific << peval->m_gp_avg << "\n"; + ss << " + PVAL = " << std::scientific << peval->m_global_penalty + << std::defaultfloat << " ( Selected penalty value = 10^(round(log10(KAVG))+" << auto_penalty_oom << ") )\n"; ss << " + Automatic Penalty values for each MP Constraint:\n"; for (MP_Constraint* mp : mps_penalty) ss << " + MP(tag = " << mp->getTag() << ") = " << std::scientific << peval->getPenaltyValue(mp) << "\n"; From a3f76751c01e90fa2fdef5aec277141d67162a9a Mon Sep 17 00:00:00 2001 From: amnp95 Date: Thu, 27 Feb 2025 18:39:36 -0800 Subject: [PATCH 025/261] Refactor PML3D update logic and streamline domain time step handling --- SRC/element/PML/PML3D.cpp | 82 ++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 45 deletions(-) diff --git a/SRC/element/PML/PML3D.cpp b/SRC/element/PML/PML3D.cpp index eb69d27701..5512dc0d0a 100644 --- a/SRC/element/PML/PML3D.cpp +++ b/SRC/element/PML/PML3D.cpp @@ -198,6 +198,15 @@ void PML3D::setDomain(Domain* theDomain) int MCRD = 3; int NNODE = 8; pml3d_(M, C, K, G, &NDOFEL, props, &NPROPS, coords, &MCRD, &NNODE); + dt = theDomain->getDT(); + + // // make C zero + for (int i = 0; i < PML3D_NUM_DOF*PML3D_NUM_DOF; i++) { + // C[i] = 0.0; + // K[i] = 0.0; + // M[i] = 0.0; + // G[i] = 0.0; + } } // ======================================================================= @@ -205,33 +214,26 @@ void PML3D::setDomain(Domain* theDomain) // ======================================================================= int PML3D::update(void) { - // check if the dt has changed - if (fabs(Domainptr->getDT() - dt) > 1e-10) { - update_dt = 1; - dt = Domainptr->getDT(); - } else { - update_dt = 0; - } - - if (updateflag == 1) { - // get u, v, a from nodes and calculate the ubar vector - int loc = 0; - double c1 = dt; - double c2 = dt * dt * 0.5; - double c3 = dt*dt*dt*((1.0/6.0)-eta); - double c4 = dt*dt*dt*eta; - for (int i = 0; i < PML3D_NUM_NODES; i++) { - const Vector& uNode = nodePointers[i]->getDisp(); - const Vector& vNode = nodePointers[i]->getVel(); - const Vector& aNode = nodePointers[i]->getAccel(); - const Vector& atpdt = nodePointers[i]->getTrialAccel(); - for (int j = 0; j < 9; j++) { - ubar(loc) = ubart(loc) + uNode(j)*c1 + vNode(j)*c2 + aNode(j)*c3 + atpdt(j)*c4; - loc++; - } + dt = Domainptr->getDT(); + // opserr << "dt = " << dt << "\n"; + // get u, v, a from nodes and calculate the ubar vector + int loc = 0; + double c1 = dt; + double c2 = dt * dt * 0.5; + double c3 = dt*dt*dt*((1.0/6.0)-eta); + double c4 = dt*dt*dt*eta; + for (int i = 0; i < PML3D_NUM_NODES; i++) { + const Vector& uNode = nodePointers[i]->getDisp(); + const Vector& vNode = nodePointers[i]->getVel(); + const Vector& aNode = nodePointers[i]->getAccel(); + const Vector& atpdt = nodePointers[i]->getTrialAccel(); + for (int j = 0; j < 9; j++) { + ubar(loc) = ubart(loc) + uNode(j)*c1 + vNode(j)*c2 + aNode(j)*c3 + atpdt(j)*c4; + loc++; } } - updateflag = 1; + + return 0; } @@ -241,16 +243,10 @@ int PML3D::update(void) const Matrix& PML3D::getTangentStiff() { // check if the dt is changed to update the tangent stiffness matrix - if (update_dt == 1) { - double cg = eta*dt/beta; - //keff = k + cg*g( k and g are symmetric matrices) - for (int i = 0; i < PML3D_NUM_DOF; i++) { - for (int j = i; j < PML3D_NUM_DOF; j++) { // Loop over the upper triangular part of the matrices. - double sum = K[i*PML3D_NUM_DOF + j] + cg * G[i*PML3D_NUM_DOF + j]; - Keff[i*PML3D_NUM_DOF + j] = sum; - Keff[j*PML3D_NUM_DOF + i] = sum; // Since K and G are symmetric, set the corresponding lower triangular element. - } - } + double cg = eta*dt/beta; + //keff = k + cg*g( k and g are symmetric matrices) + for (int i = 0; i < PML3D_NUM_DOF*PML3D_NUM_DOF; i++) { + Keff[i] = K[i] + cg*G[i]; } tangent.setData(Keff, PML3D_NUM_DOF, PML3D_NUM_DOF); return tangent; @@ -354,14 +350,12 @@ PML3D::getResistingForceIncInertia() theVector(loc++) = vel[j]; } } - - resid.addMatrixVector(1.0, this->getDamp(), theVector, 1.0); // R += G*ubar - mass.setData(G, PML3D_NUM_DOF, PML3D_NUM_DOF); - resid.addMatrixVector(1.0, mass, ubar, 1.0); + tangent.setData(G, PML3D_NUM_DOF, PML3D_NUM_DOF); + resid.addMatrixVector(1.0, tangent, ubar, 1.0); return resid; @@ -441,12 +435,10 @@ int PML3D::revertToStart() int success = 0; // set ubar and ubart to zero - // for (int i = 0; i < PML3D_NUM_DOF; i++) { - // ubar[i] = 0.0; - // ubart[i] = 0.0; - // } - ubar.Zero(); - ubart.Zero(); + for (int i = 0; i < PML3D_NUM_DOF; i++) { + ubar(i) = 0.0; + ubart(i) = 0.0; + } return success; } From 52c8815fb4eca89da1a82fe5f81cc2715138ff3c Mon Sep 17 00:00:00 2001 From: amnp95 Date: Thu, 27 Feb 2025 19:56:05 -0800 Subject: [PATCH 026/261] Add hMatrix parameter and LFLAGS to pml3d_ function call in PML3D --- SRC/element/PML/PML3D.cpp | 7 +- SRC/element/PML/PML3D.h | 5 +- SRC/element/PML/pml_3d.f | 1061 ++++++++++++++++++++++++------------- 3 files changed, 709 insertions(+), 364 deletions(-) diff --git a/SRC/element/PML/PML3D.cpp b/SRC/element/PML/PML3D.cpp index 5512dc0d0a..c114fe8dc5 100644 --- a/SRC/element/PML/PML3D.cpp +++ b/SRC/element/PML/PML3D.cpp @@ -197,7 +197,12 @@ void PML3D::setDomain(Domain* theDomain) int NPROPS = 13; int MCRD = 3; int NNODE = 8; - pml3d_(M, C, K, G, &NDOFEL, props, &NPROPS, coords, &MCRD, &NNODE); + int LFLAGS = 12; + // make props[10] and props[11] zero + props[10] = 0.0; + props[11] = 0.0; + double H[PML3D_NUM_DOF*PML3D_NUM_DOF]; + pml3d_(M, C, K, G, H, &NDOFEL, props, coords, &MCRD, &NNODE, &LFLAGS); dt = theDomain->getDT(); // // make C zero diff --git a/SRC/element/PML/PML3D.h b/SRC/element/PML/PML3D.h index 1d3faab729..45bc116390 100644 --- a/SRC/element/PML/PML3D.h +++ b/SRC/element/PML/PML3D.h @@ -67,12 +67,13 @@ extern "C" void pml3d_(double* mMatrix, double* cMatrix, double* kMatrix, double* gMatrix, + double* hMatrix, int* NDOFEL, double* PROPS, - int* NPROPS, double* COORDS, int* MCRD, - int* NNODE); + int* NNODE, + int* LFLAGS); #endif diff --git a/SRC/element/PML/pml_3d.f b/SRC/element/PML/pml_3d.f index 31475ad05f..28977d3c70 100644 --- a/SRC/element/PML/pml_3d.f +++ b/SRC/element/PML/pml_3d.f @@ -1,58 +1,36 @@ -c------------------------------------------------------------------------------ -c Complete UEL file for Perfectly-Matched-Layer (PML) (3D) -c------------------------------------------------------------------------------ -c Note: 1) Please do not distribute the material model routines, and if -c anyone asks, please refer them to Prof. Ertugrul Taciroglu -c (etacir@ucla.edu) -c 2) Please properly acknowledge our related publications when you -c publish your results -c Ref: Zhang W, Esmaeilzadeh Seylabi E, Taciroglu E. An ABAQUS toolbox for -c soil-structure interaction analysis. Computers and Geotechnics. 114 -c (2019): 103143. -c------------------------------------------------------------------------------ -c Authors: Wenyang Zhang (zwyll@ucla.edu) -c University of California, Los Angeles -c------------------------------------------------------------------------------ -c Function inputs given by the user: -c -c E = PROPS(1) --- Young's modulus -c xnu = PROPS(2) --- Poisson's Ratio -c rho = PROPS(3) --- Density -c EleType_pos = floor(PROPS(4)) --- Element type, See line -c PML_L = PROPS(5) --- Thickness of the PML -c afp = PROPS(6) --- Coefficient m, typically m = 2 -c PML_Rcoef = PROPS(7) --- Coefficient R, typically R = 1e-8 -c RD_half_width_x = PROPS(8) --- Halfwidth of the regular domain in x-direction -c RD_half_width_y = PROPS(9) --- Halfwidth of the regular domain in y-direction -c RD_depth = PROPS(10) --- Depth of the regular domain -c Damp_alpha = PROPS(11) --- Rayleigh damping coefficient alpha -c Damp_beta = PROPS(12) --- Rayleigh damping coefficient beta +! Modify material properties +! Modify cp_ref for PML + +! +! ABAQUS format UEL subroutine +! +! This file is compatible with ABAQUS/Standard +! +! The example implements a standard fully integrated 3D linear elastic continuum element +! +! The file also contains the following subrouines: +! abq_UEL_3D_integrationpoints - defines integration ponits for 3D continuum elements +! abq_UEL_3D_shapefunctions - defines shape functions for 3D continuum elements +! abq_UEL_invert3D - computes the inverse and determinant of a 3x3 matrix +! abq_facenodes_3D - returns list of nodes on the face of a 3D element +! !=========================== ABAQUS format user element subroutine =================== -c SUBROUTINE UEL(RHS,AMATRX,SVARS,ENERGY,NDOFEL,NRHS,NSVARS, -c 1 PROPS,NPROPS,COORDS,MCRD,NNODE,U,DU,V,A,JTYPE,TIME,DTIME, -c 2 KSTEP,KINC,JELEM,PARAMS,NDLOAD,JDLTYP,ADLMAG,PREDEF,NPREDF, -c 3 LFLAGS,MLVARX,DDLMAG,MDLOAD,PNEWDT,JPROPS,NJPROP,PERIOD) -c ! -c INCLUDE 'ABA_PARAM.INC' -c ! -c ! -c DIMENSION MTRX(NDF,NDF),KTRX(NDF,NDF),C(NDF,NDF), NDF, (*), -c 1 SVARS(*),ENERGY(8),COORDS(MCRD,NNODE),U(NDOFEL), -c 2 DU(MLVARX,*),V(NDOFEL),A(NDOFEL),TIME(2),PARAMS(*), -c 3 JDLTYP(MDLOAD,*),ADLMAG(MDLOAD,*),DDLMAG(MDLOAD,*), -c 4 PREDEF(2,NPREDF,NNODE),LFLAGS(*),JPROPS(*) - - SUBROUTINE PML_3D(MMTRX,CMTRX,KMTRX,GMTRX, NDF, - 1 PROPS,NPROPS,COORDS,MCRD,NNODE) - - - REAL *8 MMTRX,CMTRX,KMTRX,GMTRX,PROPS,COORDS,PARAMS - - INTEGER *4 NDF,NRHS,NPROPS,MCRD,NNODE + SUBROUTINE PML_3D(MMATRX,CMATRX,KMATRX,GMATRX,HMATRX, + 1 NDOFEL,PROPS,COORDS,MCRD,NNODE,LFLAGS) + ! + ! INCLUDE 'ABA_PARAM.INC' + ! + ! + REAL *8 PROPS,COORDS,MMATRX, CMATRX, KMATRX, GMATRX, HMATRX + INTEGER *4 NDOFEL,MCRD,NNODE,LFLAGS - DIMENSION MMTRX(NDF,NDF),CMTRX(NDF,NDF),KMTRX(NDF,NDF),PROPS(*), - 1 COORDS(MCRD,NNODE),GMTRX(NDF,NDF) + DIMENSION MMATRX(NDOFEL,NDOFEL), + 1 CMATRX(NDOFEL,NDOFEL), + 2 KMATRX(NDOFEL,NDOFEL), + 3 GMATRX(NDOFEL,NDOFEL), + 4 HMATRX(NDOFEL,NDOFEL), + 5 PROPS(*),COORDS(MCRD,NNODE),LFLAGS(*) ! ! Variables that must be computed in this routine @@ -74,7 +52,7 @@ SUBROUTINE PML_3D(MMTRX,CMTRX,KMTRX,GMTRX, NDF, ! If PNEWDT>1 ABAQUS may increase the time increment by a factor PNEWDT ! ! Variables provided for information - ! NDF Total # DOF for the element + ! NDOFEL Total # DOF for the element ! NRHS Dimension variable ! NSVARS Total # element state variables ! PROPS(1:NPROPS) User-specified properties of the element @@ -93,6 +71,7 @@ SUBROUTINE PML_3D(MMTRX,CMTRX,KMTRX,GMTRX, NDF, ! KSTEP Current step number ! KINC Increment number ! JELEM User assigned element number in ABAQUS (internally assigned) + ! PARAMS(1:3) Time increment parameters alpha, beta, gamma for implicit dynamics ! NDLOAD Number of user-defined distributed loads defined for this element ! JDLTYP(1:NDLOAD) Integers n defining distributed load types defined as Un or (if negative) UnNU in input file ! ADLMAG(1:NDLOAD) Distributed load magnitudes @@ -124,11 +103,12 @@ SUBROUTINE PML_3D(MMTRX,CMTRX,KMTRX,GMTRX, NDF, real*8 ZERO,ONE,HALF PARAMETER ( ZERO = 0.D0, HALF = 0.5D0, ONE = 1.D0 ) - real*8 coef_alpha + real*8 coef_alpha, coef_beta PARAMETER (coef_alpha = 1.d0/12.d0) + PARAMETER (coef_beta = 1.d0/48.d0) - integer :: i,j,n_points,kint, nfacenodes, ipoin - integer :: face_node_list(8) ! List of nodes on an element face + integer :: i,j,n_points,kint + ! integer :: face_node_list(8) ! List of nodes on an element face ! double precision :: xi(3,64) ! Volumetric Integration points double precision :: w(64) ! Integration weights @@ -138,22 +118,27 @@ SUBROUTINE PML_3D(MMTRX,CMTRX,KMTRX,GMTRX, NDF, double precision :: dNdx(20,3) ! Derivative of shape functions wrt spatial coords ! ! Variables below are for computing integrals over element faces - double precision :: face_coords(3,8) ! Coords of nodes on an element face - double precision :: xi2(2,9) ! Area integration points - double precision :: N2(9) ! 2D shape functions - double precision :: dNdxi2(9,2) ! 2D shape function derivatives - double precision :: norm(3) ! Normal to an element face - double precision :: dxdxi2(3,2) ! Derivative of spatial coord wrt normalized areal coord + ! double precision :: face_coords(3,8) ! Coords of nodes on an element face + ! double precision :: xi2(2,9) ! Area integration points + ! double precision :: N2(9) ! 2D shape functions + ! double precision :: dNdxi2(9,2) ! 2D shape function derivatives + ! double precision :: norm(3) ! Normal to an element face + ! double precision :: dxdxi2(3,2) ! Derivative of spatial coord wrt normalized areal coord ! - + double precision :: strain(6) ! Strain vector contains [e11, e22, e33, 2e12, 2e13, 2e23] + double precision :: stress(6) ! Stress vector contains [s11, s22, s33, s12, s13, s23] + double precision :: D(6,6) ! stress = D*(strain) (NOTE FACTOR OF 2 in shear strain) double precision :: B(6,60) ! strain = B*(dof_total) double precision :: dxidx(3,3), determinant ! Jacobian inverse and determinant - double precision :: E, xnu, D44, D11, D12 ! Material properties + double precision :: E, xnu ! Material properties + ! double precision :: ALPHA, BETA, GAMMA ! Newmark Integration properties double precision :: Phi(3,60) ! Matrix consists of shape functions [N1 N2 ... N20] - double precision :: MMATRX(NDF,NDF) ! Element mass matrix - double precision :: KMATRX(NDF,NDF) ! Element stiffness matrix - double precision :: CMATRX(NDF,NDF) ! Element damping matrix - double precision :: GMATRX(NDF,NDF) ! Element G matrix + ! double precision :: MMATRX(NDOFEL,NDOFEL) ! Element mass matrix + ! double precision :: KMATRX(NDOFEL,NDOFEL) ! Element stiffness matrix + ! double precision :: CMATRX(NDOFEL,NDOFEL) ! Element damping matrix + ! double precision :: GMATRX(NDOFEL,NDOFEL) ! Element G matrix + ! double precision :: HMATRX(NDOFEL,NDOFEL) ! Element H matrix + double precision :: rho ! Density of the material double precision :: PML_L,afp,PML_Rcoef ! Parameters of PML @@ -171,21 +156,30 @@ SUBROUTINE PML_3D(MMTRX,CMTRX,KMTRX,GMTRX, NDF, double precision :: Phi_x(8), Phi_y(8), Phi_z(8) ! Derivative of shape functions for displacement fields [N1,i N2,i ... N8,i]^T double precision :: lambda, mu ! Lame' constants double precision :: M_RD(24,24) ! Mass matrix for regular domain + double precision :: C_RD(24,24) ! Damping matrix for regular domain double precision :: M_a(24,24),M_b(24,24),M_c(24,24),M_d(24,24) ! Mass matrices double precision :: N_a(48,48),N_b(48,48),N_c(48,48),N_d(48,48) ! N matrices for PML double precision :: A_eu(24,48), A_wu(24,48), A_pu(24,48) ! A_iu matrices for PML, where i = e, w, p double precision :: A_el(24,48), A_wl(24,48), A_pl(24,48) ! A_il matrices for PML, where i = e, w, p double precision :: K_PML(72,72), M_PML(72,72), C_PML(72,72) ! Stiffnee, mass and damping matrices for PML double precision :: G_PML(72,72) ! G matrices for PML + double precision :: H_PML(72,72) ! H matrices for PML double precision :: d_bar_n(72), d_bar_n1(72) ! d_bar at previous and current step + double precision :: d_bar_dot_n(72), d_bar_dot_n1(72) ! d_bar_dot at previous and current step + double precision :: U_n(72), V_n(72), A_n(72) ! U, V, A at previous step - integer :: NodeDOF ! Number of DOF per node + integer :: NodeDOF,res1, res2, res3, res4, res5 ! Number of DOF per node double precision :: Damp_alpha, Damp_beta ! Damping coefficients for Rayleigh Damping + + ! double precision :: Vs ! Shear wave velocity + + + NodeDOF = NDOFEL/NNODE + - NodeDOF = NDF/NNODE ! ! Example ABAQUS UEL implementing 3D linear elastic elements @@ -198,13 +192,77 @@ SUBROUTINE PML_3D(MMTRX,CMTRX,KMTRX,GMTRX, NDF, if (NNODE == 10) n_points = 4 ! Quadratic tet if (NNODE == 8) n_points = 27 ! Linear Hex if (NNODE == 20) n_points = 27 ! Quadratic hex + ! Local Variables + ! print propertises + ! write(6,*) ' PROPS(1) = ',PROPS(1) + ! write(6,*) ' PROPS(2) = ',PROPS(2) + ! write(6,*) ' PROPS(3) = ',PROPS(3) + ! write(6,*) ' PROPS(4) = ',PROPS(4) + ! write(6,*) ' PROPS(5) = ',PROPS(5) + ! write(6,*) ' PROPS(6) = ',PROPS(6) + ! write(6,*) ' PROPS(7) = ',PROPS(7) + ! write(6,*) ' PROPS(8) = ',PROPS(8) + ! write(6,*) ' PROPS(9) = ',PROPS(9) + ! write(6,*) ' PROPS(10) = ',PROPS(10) + ! write(6,*) ' PROPS(11) = ',PROPS(11) + ! write(6,*) ' PROPS(12) = ',PROPS(12) + + ! ! print coords + ! write(6,*) ' coords(1,1) = ',coords(1,1) + ! write(6,*) ' coords(2,1) = ',coords(2,1) + ! write(6,*) ' coords(3,1) = ',coords(3,1) + ! write(6,*) ' coords(1,2) = ',coords(1,2) + ! write(6,*) ' coords(2,2) = ',coords(2,2) + ! write(6,*) ' coords(3,2) = ',coords(3,2) + ! write(6,*) ' coords(1,3) = ',coords(1,3) + ! write(6,*) ' coords(2,3) = ',coords(2,3) + ! write(6,*) ' coords(3,3) = ',coords(3,3) + ! write(6,*) ' coords(1,4) = ',coords(1,4) + ! write(6,*) ' coords(2,4) = ',coords(2,4) + ! write(6,*) ' coords(3,4) = ',coords(3,4) + ! write(6,*) ' coords(1,5) = ',coords(1,5) + ! write(6,*) ' coords(2,5) = ',coords(2,5) + ! write(6,*) ' coords(3,5) = ',coords(3,5) + ! write(6,*) ' coords(1,6) = ',coords(1,6) + ! write(6,*) ' coords(2,6) = ',coords(2,6) + ! write(6,*) ' coords(3,6) = ',coords(3,6) + ! write(6,*) ' coords(1,7) = ',coords(1,7) + ! write(6,*) ' coords(2,7) = ',coords(2,7) + ! write(6,*) ' coords(3,7) = ',coords(3,7) + ! write(6,*) ' coords(1,8) = ',coords(1,8) + ! write(6,*) ' coords(2,8) = ',coords(2,8) + ! write(6,*) ' coords(3,8) = ',coords(3,8) + + ! ! print MCRD + ! write(6,*) ' MCRD = ',MCRD + + ! ! print NNODE + ! write(6,*) ' NNODE = ',NNODE + + ! ! print NDOFEL + ! write(6,*) ' NDOFEL = ',NDOFEL + + ! ! print LFLAGS + ! write(6,*) ' LFLAGS(1) = ',LFLAGS(1) + call abq_UEL_3D_integrationpoints(n_points, NNODE, xi, w) - MMATRX(1:NDF,1:NDF) = 0.d0 - KMATRX(1:NDF,1:NDF) = 0.d0 - CMATRX(1:NDF,1:NDF) = 0.d0 - GMATRX(1:NDF,1:NDF) = 0.d0 + ! if (MLVARX<3*NNODE) then + ! write(6,*) ' Error in abaqus UEL ' + ! write(6,*) ' Variable MLVARX must exceed 3*NNODE' + ! write(6,*) ' MLVARX = ',MLVARX,' NNODE = ',NNODE + ! stop + ! endif + + ! RHS(1:MLVARX,1) = 0.d0 + ! AMATRX(1:NDOFEL,1:NDOFEL) = 0.d0 + MMATRX(1:NDOFEL,1:NDOFEL) = 0.d0 + KMATRX(1:NDOFEL,1:NDOFEL) = 0.d0 + CMATRX(1:NDOFEL,1:NDOFEL) = 0.d0 + GMATRX(1:NDOFEL,1:NDOFEL) = 0.d0 + HMATRX(1:NDOFEL,1:NDOFEL) = 0.d0 + E = PROPS(1) xnu = PROPS(2) @@ -219,27 +277,16 @@ SUBROUTINE PML_3D(MMTRX,CMTRX,KMTRX,GMTRX, NDF, Damp_alpha = PROPS(11) Damp_beta = PROPS(12) - -c write(6,*) ' E = ',E,' xnu = ',xnu,' rho = ', rho -c write(6,*) ' Etype = ',EleType_pos,' PML_L = ',PML_L -c write(6,*) ' afp = ',afp,' PML_Rcoef = ',PML_Rcoef -c write(6,*) ' RD_halfwidth_x = ',RD_half_width_x -c write(6,*) ' RD_halfwidth_y = ',RD_half_width_y -c write(6,*) ' RD_Depth = ',RD_depth -c do i=1,NNODE -c write(6,*) COORDS(1,i),' ',COORDS(2,i),' ',COORDS(3,i) -c end do - -c write(6,*) IF (afp .LT. 3.d0) THEN n_points = 27 else n_points = 64 endif - + lambda = xnu*E/( (1.d0+xnu)*(1.d0-2.D0*xnu) ) mu = 0.5D0*E/(1.d0+xnu) + M_RD = 0.d0 M_a = 0.d0 M_b = 0.d0 @@ -260,19 +307,24 @@ SUBROUTINE PML_3D(MMTRX,CMTRX,KMTRX,GMTRX, NDF, A_pl = 0.d0 K_RD = 0.d0 + C_RD = 0.d0 K_PML = 0.d0 C_PML = 0.d0 M_PML = 0.d0 G_PML = 0.d0 + H_PML = 0.d0 d_bar_n = 0.d0 d_bar_n1 = 0.d0 + + d_bar_dot_n = 0.d0 + d_bar_dot_n1 = 0.d0 U_n = 0.d0 V_n = 0.d0 A_n = 0.d0 - + ! -- Loop over integration points do kint = 1, n_points call abq_UEL_3D_shapefunctions(xi(1:3,kint),NNODE,N,dNdxi) @@ -290,402 +342,687 @@ SUBROUTINE PML_3D(MMTRX,CMTRX,KMTRX,GMTRX, NDF, B(6,2:3*NNODE-1:3) = dNdx(1:NNODE,3) B(6,3:3*NNODE:3) = dNdx(1:NNODE,2) - Phi = 0.d0 - Phi(1,1:3*NNODE-2:3) = N(1:NNODE) - Phi(2,2:3*NNODE-1:3) = N(1:NNODE) - Phi(3,3:3*NNODE:3) = N(1:NNODE) - - Phi_x = 0.d0 - Phi_y = 0.d0 - Phi_z = 0.d0 - Phi_x(1:NNODE) = dNdx(1:NNODE,1) - Phi_y(1:NNODE) = dNdx(1:NNODE,2) - Phi_z(1:NNODE) = dNdx(1:NNODE,3) - + ! strain = matmul(B(1:6,1:3*NNODE),U(1:3*NNODE)) - x1 = 0.d0 - x2 = 0.d0 - x3 = 0.d0 - - do i = 1,NNODE - x1 = x1 + N(i)*coords(1,i) - x2 = x2 + N(i)*coords(2,i) - x3 = x3 + N(i)*coords(3,i) - end do - - call PML_alpha_beta_function(PROPS,x1,x2,x3,PML_alpha_beta) - - coef_a = PML_alpha_beta(1,1)*PML_alpha_beta(1,2) + stress = matmul(D,strain) + + + ! ALPHA = PARAMS(1) + ! BETA = PARAMS(2) + ! GAMMA = PARAMS(3) + + ! DADU = ONE/(BETA*DTIME**2.d0) + ! DVDU = GAMMA/(BETA*DTIME) + + Phi = 0.d0 + Phi(1,1:3*NNODE-2:3) = N(1:NNODE) + Phi(2,2:3*NNODE-1:3) = N(1:NNODE) + Phi(3,3:3*NNODE:3) = N(1:NNODE) + + Phi_x = 0.d0 + Phi_y = 0.d0 + Phi_z = 0.d0 + Phi_x(1:NNODE) = dNdx(1:NNODE,1) + Phi_y(1:NNODE) = dNdx(1:NNODE,2) + Phi_z(1:NNODE) = dNdx(1:NNODE,3) + + + x1 = 0.d0 + x2 = 0.d0 + x3 = 0.d0 + + do i = 1,NNODE + x1 = x1 + N(i)*coords(1,i) + x2 = x2 + N(i)*coords(2,i) + x3 = x3 + N(i)*coords(3,i) + end do + + ! write(6,*) ' x1 = ',x1 + ! write(6,*) ' x2 = ',x2 + ! write(6,*) ' x3 = ',x3 + + ! mu = rho*Vs**2.d0 + ! E = mu*2.d0*(1.d0+xnu) + ! lambda = xnu*E/((1.d0+xnu)*(1.d0-2.D0*xnu)) + ! PROPS(1) = E + ! write(6,*) ' E = ',E + ! write(6,*) ' xnu = ',xnu + ! write(6,*) ' lambda = ',lambda + ! write(6,*) ' mu = ',mu + + call PML_alpha_beta_function(PROPS,x1,x2,x3,PML_alpha_beta) + + coef_a = PML_alpha_beta(1,1)*PML_alpha_beta(1,2) 1 *PML_alpha_beta(1,3) + ! write(6,*) ' alpha11 :',PML_alpha_beta(1,1) + ! write(6,*) ' alpha12 :',PML_alpha_beta(1,2) + ! write(6,*) ' alpha13 :',PML_alpha_beta(1,3) + + + coef_b = PML_alpha_beta(1,1)*PML_alpha_beta(1,2) + 1 *PML_alpha_beta(2,3) + + 2 PML_alpha_beta(1,1)*PML_alpha_beta(1,3) + 3 *PML_alpha_beta(2,2) + + 4 PML_alpha_beta(1,2)*PML_alpha_beta(1,3) + 5 *PML_alpha_beta(2,1) + + coef_c = PML_alpha_beta(1,1)*PML_alpha_beta(2,2) + 1 *PML_alpha_beta(2,3) + + 2 PML_alpha_beta(1,2)*PML_alpha_beta(2,3) + 3 *PML_alpha_beta(2,1) + + 4 PML_alpha_beta(1,3)*PML_alpha_beta(2,2) + 5 *PML_alpha_beta(2,1) + + coef_d = PML_alpha_beta(2,1)*PML_alpha_beta(2,2) + 1 *PML_alpha_beta(2,3) - coef_b = PML_alpha_beta(1,1)*PML_alpha_beta(1,2) - 1 *PML_alpha_beta(2,3) + - 2 PML_alpha_beta(1,1)*PML_alpha_beta(1,3) - 3 *PML_alpha_beta(2,2) + - 4 PML_alpha_beta(1,2)*PML_alpha_beta(1,3) - 5 *PML_alpha_beta(2,1) - - coef_c = PML_alpha_beta(1,1)*PML_alpha_beta(2,2) - 1 *PML_alpha_beta(2,3) + - 2 PML_alpha_beta(1,2)*PML_alpha_beta(2,3) - 3 *PML_alpha_beta(2,1) + - 4 PML_alpha_beta(1,3)*PML_alpha_beta(2,2) - 5 *PML_alpha_beta(2,1) - - coef_d = PML_alpha_beta(2,1)*PML_alpha_beta(2,2) - 1 *PML_alpha_beta(2,3) - - coef_Le = 0.d0 - coef_Lp = 0.d0 - coef_Lw = 0.d0 - - do i = 1,3 + coef_Le = 0.d0 + coef_Lp = 0.d0 + coef_Lw = 0.d0 + + do i = 1,3 do j = 1,3 - coef_Le(i,j) = PML_alpha_beta(1,i)*PML_alpha_beta(1,j) - coef_Lp(i,j) = PML_alpha_beta(1,i)*PML_alpha_beta(2,j) + - 1 PML_alpha_beta(2,i)*PML_alpha_beta(1,j) - coef_Lw(i,j) = PML_alpha_beta(2,i)*PML_alpha_beta(2,j) + coef_Le(i,j) = PML_alpha_beta(1,i)*PML_alpha_beta(1,j) + coef_Lp(i,j) = PML_alpha_beta(1,i)*PML_alpha_beta(2,j) + + 1 PML_alpha_beta(2,i)*PML_alpha_beta(1,j) + coef_Lw(i,j) = PML_alpha_beta(2,i)*PML_alpha_beta(2,j) end do - end do - - - do i = 1,NNODE + end do + + + do i = 1,NNODE do j = 1,NNODE - Kxx(i,j) = (lambda + 2.d0*mu) * Phi_x(i)*Phi_x(j) + - 1 mu*(Phi_y(i)*Phi_y(j)+Phi_z(i)*Phi_z(j)) - Kyy(i,j) = (lambda + 2.d0*mu) * Phi_y(i)*Phi_y(j) + - 1 mu*(Phi_x(i)*Phi_x(j)+Phi_z(i)*Phi_z(j)) - Kzz(i,j) = (lambda + 2.d0*mu) * Phi_z(i)*Phi_z(j) + - 1 mu*(Phi_x(i)*Phi_x(j)+Phi_y(i)*Phi_y(j)) - - Kxy(i,j) = lambda * Phi_x(i)*Phi_y(j) + - 1 mu * Phi_y(i)*Phi_x(j) - - Kxz(i,j) = lambda * Phi_x(i)*Phi_z(j) + - 1 mu * Phi_z(i)*Phi_x(j) - - Kyz(i,j) = lambda * Phi_y(i)*Phi_z(j) + - 1 mu * Phi_z(i)*Phi_y(j) - - M_RD(i,j) = M_RD(i,j) + rho*N(i)*N(j)*w(kint)*determinant - M_a(i,j) = M_a(i,j) + - 1 coef_a*rho*N(i)*N(j)*w(kint)*determinant - M_b(i,j) = M_b(i,j) + - 1 coef_b*rho*N(i)*N(j)*w(kint)*determinant + Kxx(i,j) = (lambda + 2.d0*mu) * Phi_x(i)*Phi_x(j) + + 1 mu*(Phi_y(i)*Phi_y(j)+Phi_z(i)*Phi_z(j)) + Kyy(i,j) = (lambda + 2.d0*mu) * Phi_y(i)*Phi_y(j) + + 1 mu*(Phi_x(i)*Phi_x(j)+Phi_z(i)*Phi_z(j)) + Kzz(i,j) = (lambda + 2.d0*mu) * Phi_z(i)*Phi_z(j) + + 1 mu*(Phi_x(i)*Phi_x(j)+Phi_y(i)*Phi_y(j)) + + Kxy(i,j) = lambda * Phi_x(i)*Phi_y(j) + + 1 mu * Phi_y(i)*Phi_x(j) + + Kxz(i,j) = lambda * Phi_x(i)*Phi_z(j) + + 1 mu * Phi_z(i)*Phi_x(j) + + Kyz(i,j) = lambda * Phi_y(i)*Phi_z(j) + + 1 mu * Phi_z(i)*Phi_y(j) + + M_RD(i,j) = M_RD(i,j) + rho*N(i)*N(j)*w(kint)*determinant + M_a(i,j) = M_a(i,j) + + 1 coef_a*rho*N(i)*N(j)*w(kint)*determinant + ! if i == 1 and j == 1 then print coef_a, rho, N(i), N(j), w(kint), determinant end if + ! If (i.EQ. 1 .AND. j .EQ. 1 ) THEN + ! write(6,*) ' coef_a = ',coef_a + ! write(6,*) ' rho = ',rho + ! write(6,*) ' N(i) = ',N(i) + ! write(6,*) ' N(j) = ',N(j) + ! write(6,*) ' w(kint) = ',w(kint) + ! write(6,*) ' determinant = ',determinant + ! endif + M_b(i,j) = M_b(i,j) + + 1 coef_b*rho*N(i)*N(j)*w(kint)*determinant M_c(i,j) = M_c(i,j) + - 1 coef_c*rho*N(i)*N(j)*w(kint)*determinant + 1 coef_c*rho*N(i)*N(j)*w(kint)*determinant M_d(i,j) = M_d(i,j) + - 1 coef_d*rho*N(i)*N(j)*w(kint)*determinant - + 1 coef_d*rho*N(i)*N(j)*w(kint)*determinant + A_eu(i,j) = A_eu(i,j) + - 1 Phi_x(i)*N(j)*coef_Le(2,3)*w(kint)*determinant + 1 Phi_x(i)*N(j)*coef_Le(2,3)*w(kint)*determinant A_eu(i,j+NNODE*3) = A_eu(i,j+NNODE*3) + - 1 Phi_y(i)*N(j)*coef_Le(1,3)*w(kint)*determinant + 1 Phi_y(i)*N(j)*coef_Le(1,3)*w(kint)*determinant A_eu(i,j+NNODE*4) = A_eu(i,j+NNODE*4) + - 1 Phi_z(i)*N(j)*coef_Le(1,2)*w(kint)*determinant - + 1 Phi_z(i)*N(j)*coef_Le(1,2)*w(kint)*determinant + A_eu(i+NNODE,j+NNODE) = A_eu(i+NNODE,j+NNODE) + - 1 Phi_y(i)*N(j)*coef_Le(1,3)*w(kint)*determinant + 1 Phi_y(i)*N(j)*coef_Le(1,3)*w(kint)*determinant A_eu(i+NNODE,j+NNODE*3) = A_eu(i+NNODE,j+NNODE*3) + - 1 Phi_x(i)*N(j)*coef_Le(2,3)*w(kint)*determinant + 1 Phi_x(i)*N(j)*coef_Le(2,3)*w(kint)*determinant A_eu(i+NNODE,j+NNODE*5) = A_eu(i+NNODE,j+NNODE*5) + - 1 Phi_z(i)*N(j)*coef_Le(1,2)*w(kint)*determinant - + 1 Phi_z(i)*N(j)*coef_Le(1,2)*w(kint)*determinant + A_eu(i+NNODE*2,j+NNODE*2) = A_eu(i+NNODE*2,j+NNODE*2) + - 1 Phi_z(i)*N(j)*coef_Le(1,2)*w(kint)*determinant + 1 Phi_z(i)*N(j)*coef_Le(1,2)*w(kint)*determinant A_eu(i+NNODE*2,j+NNODE*4) = A_eu(i+NNODE*2,j+NNODE*4) + - 1 Phi_x(i)*N(j)*coef_Le(2,3)*w(kint)*determinant + 1 Phi_x(i)*N(j)*coef_Le(2,3)*w(kint)*determinant A_eu(i+NNODE*2,j+NNODE*5) = A_eu(i+NNODE*2,j+NNODE*5) + - 1 Phi_y(i)*N(j)*coef_Le(1,3)*w(kint)*determinant - + 1 Phi_y(i)*N(j)*coef_Le(1,3)*w(kint)*determinant + A_wu(i,j) = A_wu(i,j) + - 1 Phi_x(i)*N(j)*coef_Lw(2,3)*w(kint)*determinant + 1 Phi_x(i)*N(j)*coef_Lw(2,3)*w(kint)*determinant A_wu(i,j+NNODE*3) = A_wu(i,j+NNODE*3) + - 1 Phi_y(i)*N(j)*coef_Lw(1,3)*w(kint)*determinant + 1 Phi_y(i)*N(j)*coef_Lw(1,3)*w(kint)*determinant A_wu(i,j+NNODE*4) = A_wu(i,j+NNODE*4) + - 1 Phi_z(i)*N(j)*coef_Lw(1,2)*w(kint)*determinant - + 1 Phi_z(i)*N(j)*coef_Lw(1,2)*w(kint)*determinant + A_wu(i+NNODE,j+NNODE) = A_wu(i+NNODE,j+NNODE) + - 1 Phi_y(i)*N(j)*coef_Lw(1,3)*w(kint)*determinant + 1 Phi_y(i)*N(j)*coef_Lw(1,3)*w(kint)*determinant A_wu(i+NNODE,j+NNODE*3) = A_wu(i+NNODE,j+NNODE*3) + - 1 Phi_x(i)*N(j)*coef_Lw(2,3)*w(kint)*determinant + 1 Phi_x(i)*N(j)*coef_Lw(2,3)*w(kint)*determinant A_wu(i+NNODE,j+NNODE*5) = A_wu(i+NNODE,j+NNODE*5) + - 1 Phi_z(i)*N(j)*coef_Lw(1,2)*w(kint)*determinant - + 1 Phi_z(i)*N(j)*coef_Lw(1,2)*w(kint)*determinant + A_wu(i+NNODE*2,j+NNODE*2) = A_wu(i+NNODE*2,j+NNODE*2) + - 1 Phi_z(i)*N(j)*coef_Lw(1,2)*w(kint)*determinant + 1 Phi_z(i)*N(j)*coef_Lw(1,2)*w(kint)*determinant A_wu(i+NNODE*2,j+NNODE*4) = A_wu(i+NNODE*2,j+NNODE*4) + - 1 Phi_x(i)*N(j)*coef_Lw(2,3)*w(kint)*determinant + 1 Phi_x(i)*N(j)*coef_Lw(2,3)*w(kint)*determinant A_wu(i+NNODE*2,j+NNODE*5) = A_wu(i+NNODE*2,j+NNODE*5) + - 1 Phi_y(i)*N(j)*coef_Lw(1,3)*w(kint)*determinant - + 1 Phi_y(i)*N(j)*coef_Lw(1,3)*w(kint)*determinant + A_pu(i,j) = A_pu(i,j) + - 1 Phi_x(i)*N(j)*coef_Lp(2,3)*w(kint)*determinant + 1 Phi_x(i)*N(j)*coef_Lp(2,3)*w(kint)*determinant A_pu(i,j+NNODE*3) = A_pu(i,j+NNODE*3) + - 1 Phi_y(i)*N(j)*coef_Lp(1,3)*w(kint)*determinant + 1 Phi_y(i)*N(j)*coef_Lp(1,3)*w(kint)*determinant A_pu(i,j+NNODE*4) = A_pu(i,j+NNODE*4) + - 1 Phi_z(i)*N(j)*coef_Lp(1,2)*w(kint)*determinant - + 1 Phi_z(i)*N(j)*coef_Lp(1,2)*w(kint)*determinant + A_pu(i+NNODE,j+NNODE) = A_pu(i+NNODE,j+NNODE) + - 1 Phi_y(i)*N(j)*coef_Lp(1,3)*w(kint)*determinant + 1 Phi_y(i)*N(j)*coef_Lp(1,3)*w(kint)*determinant A_pu(i+NNODE,j+NNODE*3) = A_pu(i+NNODE,j+NNODE*3) + - 1 Phi_x(i)*N(j)*coef_Lp(2,3)*w(kint)*determinant + 1 Phi_x(i)*N(j)*coef_Lp(2,3)*w(kint)*determinant A_pu(i+NNODE,j+NNODE*5) = A_pu(i+NNODE,j+NNODE*5) + - 1 Phi_z(i)*N(j)*coef_Lp(1,2)*w(kint)*determinant - + 1 Phi_z(i)*N(j)*coef_Lp(1,2)*w(kint)*determinant + A_pu(i+NNODE*2,j+NNODE*2) = A_pu(i+NNODE*2,j+NNODE*2) + - 1 Phi_z(i)*N(j)*coef_Lp(1,2)*w(kint)*determinant + 1 Phi_z(i)*N(j)*coef_Lp(1,2)*w(kint)*determinant A_pu(i+NNODE*2,j+NNODE*4) = A_pu(i+NNODE*2,j+NNODE*4) + - 1 Phi_x(i)*N(j)*coef_Lp(2,3)*w(kint)*determinant + 1 Phi_x(i)*N(j)*coef_Lp(2,3)*w(kint)*determinant A_pu(i+NNODE*2,j+NNODE*5) = A_pu(i+NNODE*2,j+NNODE*5) + - 1 Phi_y(i)*N(j)*coef_Lp(1,3)*w(kint)*determinant - - end do - end do + 1 Phi_y(i)*N(j)*coef_Lp(1,3)*w(kint)*determinant + + end do + end do + + + Kyx(1:NNODE,1:NNODE) = transpose(Kxy(1:NNODE,1:NNODE)) + Kzx(1:NNODE,1:NNODE) = transpose(Kxz(1:NNODE,1:NNODE)) + Kzy(1:NNODE,1:NNODE) = transpose(Kyz(1:NNODE,1:NNODE)) + + K_RD(1:NNODE,1:NNODE) = K_RD(1:NNODE,1:NNODE) + + 1 Kxx(1:NNODE,1:NNODE)*w(kint)*determinant + K_RD(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = + 1 K_RD(NNODE+1:2*NNODE,NNODE+1:2*NNODE) + + 2 Kyy(1:NNODE,1:NNODE)*w(kint)*determinant + K_RD(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) = + 1 K_RD(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) + + 2 Kzz(1:NNODE,1:NNODE)*w(kint)*determinant + + K_RD(1:NNODE,NNODE+1:2*NNODE) = + 1 K_RD(1:NNODE,NNODE+1:2*NNODE) + + 2 Kxy(1:NNODE,1:NNODE)*w(kint)*determinant + K_RD(1:NNODE,2*NNODE+1:3*NNODE) = + 1 K_RD(1:NNODE,2*NNODE+1:3*NNODE) + + 2 Kxz(1:NNODE,1:NNODE)*w(kint)*determinant + K_RD(NNODE+1:2*NNODE,2*NNODE+1:3*NNODE) = + 1 K_RD(NNODE+1:2*NNODE,2*NNODE+1:3*NNODE) + + 2 Kyz(1:NNODE,1:NNODE)*w(kint)*determinant + + K_RD(NNODE+1:2*NNODE,1:NNODE) = + 1 K_RD(NNODE+1:2*NNODE,1:NNODE) + + 2 Kyx(1:NNODE,1:NNODE)*w(kint)*determinant + K_RD(2*NNODE+1:3*NNODE,1:NNODE) = + 1 K_RD(2*NNODE+1:3*NNODE,1:NNODE) + + 2 Kzx(1:NNODE,1:NNODE)*w(kint)*determinant + K_RD(2*NNODE+1:3*NNODE,NNODE+1:2*NNODE) = + 1 K_RD(2*NNODE+1:3*NNODE,NNODE+1:2*NNODE) + + 2 Kzy(1:NNODE,1:NNODE)*w(kint)*determinant + - - Kyx(1:NNODE,1:NNODE) = transpose(Kxy(1:NNODE,1:NNODE)) - Kzx(1:NNODE,1:NNODE) = transpose(Kxz(1:NNODE,1:NNODE)) - Kzy(1:NNODE,1:NNODE) = transpose(Kyz(1:NNODE,1:NNODE)) - - K_RD(1:NNODE,1:NNODE) = K_RD(1:NNODE,1:NNODE) + - 1 Kxx(1:NNODE,1:NNODE)*w(kint)*determinant - K_RD(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = - 1 K_RD(NNODE+1:2*NNODE,NNODE+1:2*NNODE) + - 2 Kyy(1:NNODE,1:NNODE)*w(kint)*determinant - K_RD(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) = - 1 K_RD(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) + - 2 Kzz(1:NNODE,1:NNODE)*w(kint)*determinant - - K_RD(1:NNODE,NNODE+1:2*NNODE) = - 1 K_RD(1:NNODE,NNODE+1:2*NNODE) + - 2 Kxy(1:NNODE,1:NNODE)*w(kint)*determinant - K_RD(1:NNODE,2*NNODE+1:3*NNODE) = - 1 K_RD(1:NNODE,2*NNODE+1:3*NNODE) + - 2 Kxz(1:NNODE,1:NNODE)*w(kint)*determinant - K_RD(NNODE+1:2*NNODE,2*NNODE+1:3*NNODE) = - 1 K_RD(NNODE+1:2*NNODE,2*NNODE+1:3*NNODE) + - 2 Kyz(1:NNODE,1:NNODE)*w(kint)*determinant - - K_RD(NNODE+1:2*NNODE,1:NNODE) = - 1 K_RD(NNODE+1:2*NNODE,1:NNODE) + - 2 Kyx(1:NNODE,1:NNODE)*w(kint)*determinant - K_RD(2*NNODE+1:3*NNODE,1:NNODE) = - 1 K_RD(2*NNODE+1:3*NNODE,1:NNODE) + - 2 Kzx(1:NNODE,1:NNODE)*w(kint)*determinant - K_RD(2*NNODE+1:3*NNODE,NNODE+1:2*NNODE) = - 1 K_RD(2*NNODE+1:3*NNODE,NNODE+1:2*NNODE) + - 2 Kzy(1:NNODE,1:NNODE)*w(kint)*determinant - - end do - - M_RD(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = M_RD(1:NNODE,1:NNODE) - M_RD(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) - 1 = M_RD(1:NNODE,1:NNODE) - - M_a(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = M_a(1:NNODE,1:NNODE) - M_a(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) - 1 = M_a(1:NNODE,1:NNODE) - - M_b(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = M_b(1:NNODE,1:NNODE) - M_b(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) - 1 = M_b(1:NNODE,1:NNODE) - - M_c(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = M_c(1:NNODE,1:NNODE) - M_c(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) - 1 = M_c(1:NNODE,1:NNODE) - - M_d(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = M_d(1:NNODE,1:NNODE) - M_d(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) - 1 = M_d(1:NNODE,1:NNODE) + - N_a(1:NNODE,1:NNODE) = - 1 M_a(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) - N_a(1:NNODE,NNODE+1:2*NNODE) = + M_RD(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = M_RD(1:NNODE,1:NNODE) + M_RD(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) + 1 = M_RD(1:NNODE,1:NNODE) + + C_RD(1:3*NNODE,1:3*NNODE) = Damp_alpha*M_RD(1:3*NNODE,1:3*NNODE) + 1 + Damp_beta*K_RD(1:3*NNODE,1:3*NNODE) + + M_a(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = M_a(1:NNODE,1:NNODE) + M_a(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) + 1 = M_a(1:NNODE,1:NNODE) + + M_b(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = M_b(1:NNODE,1:NNODE) + M_b(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) + 1 = M_b(1:NNODE,1:NNODE) + + M_c(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = M_c(1:NNODE,1:NNODE) + M_c(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) + 1 = M_c(1:NNODE,1:NNODE) + + M_d(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = M_d(1:NNODE,1:NNODE) + M_d(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) + 1 = M_d(1:NNODE,1:NNODE) + + ! write(6,*) " NNODE: ", NNODE + ! write(6,*) " lambda: ", lambda + ! write(6,*) " mu: ", mu + ! write(6,*) " rho: ", rho + N_a(1:NNODE,1:NNODE) = + 1 M_a(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) + N_a(1:NNODE,NNODE+1:2*NNODE) = 1 -M_a(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_a(1:NNODE,2*NNODE+1:3*NNODE) = + N_a(1:NNODE,2*NNODE+1:3*NNODE) = 1 -M_a(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_a(NNODE+1:2*NNODE,1:NNODE) = + N_a(NNODE+1:2*NNODE,1:NNODE) = 1 -M_a(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_a(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = - 1 M_a(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) - N_a(NNODE+1:2*NNODE,2*NNODE+1:3*NNODE) = + N_a(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = + 1 M_a(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) + N_a(NNODE+1:2*NNODE,2*NNODE+1:3*NNODE) = 1 -M_a(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_a(2*NNODE+1:3*NNODE,1:NNODE) = + N_a(2*NNODE+1:3*NNODE,1:NNODE) = 1 -M_a(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_a(2*NNODE+1:3*NNODE,NNODE+1:2*NNODE) = + N_a(2*NNODE+1:3*NNODE,NNODE+1:2*NNODE) = 1 -M_a(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_a(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) = + N_a(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) = 1 M_a(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) - N_a(3*NNODE+1:4*NNODE,3*NNODE+1:4*NNODE) = + N_a(3*NNODE+1:4*NNODE,3*NNODE+1:4*NNODE) = 1 M_a(1:NNODE,1:NNODE)/rho/mu - N_a(4*NNODE+1:5*NNODE,4*NNODE+1:5*NNODE) = + N_a(4*NNODE+1:5*NNODE,4*NNODE+1:5*NNODE) = 1 M_a(1:NNODE,1:NNODE)/rho/mu - N_a(5*NNODE+1:6*NNODE,5*NNODE+1:6*NNODE) = + N_a(5*NNODE+1:6*NNODE,5*NNODE+1:6*NNODE) = 1 M_a(1:NNODE,1:NNODE)/rho/mu - - N_b(1:NNODE,1:NNODE) = + N_b(1:NNODE,1:NNODE) = 1 M_b(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) - N_b(1:NNODE,NNODE+1:2*NNODE) = + N_b(1:NNODE,NNODE+1:2*NNODE) = 1 -M_b(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_b(1:NNODE,2*NNODE+1:3*NNODE) = + N_b(1:NNODE,2*NNODE+1:3*NNODE) = 1 -M_b(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_b(NNODE+1:2*NNODE,1:NNODE) = + N_b(NNODE+1:2*NNODE,1:NNODE) = 1 -M_b(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_b(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = + N_b(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = 1 M_b(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) - N_b(NNODE+1:2*NNODE,2*NNODE+1:3*NNODE) = + N_b(NNODE+1:2*NNODE,2*NNODE+1:3*NNODE) = 1 -M_b(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_b(2*NNODE+1:3*NNODE,1:NNODE) = + N_b(2*NNODE+1:3*NNODE,1:NNODE) = 1 -M_b(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_b(2*NNODE+1:3*NNODE,NNODE+1:2*NNODE) = + N_b(2*NNODE+1:3*NNODE,NNODE+1:2*NNODE) = 1 -M_b(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_b(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) = + N_b(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) = 1 M_b(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) - N_b(3*NNODE+1:4*NNODE,3*NNODE+1:4*NNODE) = + N_b(3*NNODE+1:4*NNODE,3*NNODE+1:4*NNODE) = 1 M_b(1:NNODE,1:NNODE)/rho/mu - N_b(4*NNODE+1:5*NNODE,4*NNODE+1:5*NNODE) = + N_b(4*NNODE+1:5*NNODE,4*NNODE+1:5*NNODE) = 1 M_b(1:NNODE,1:NNODE)/rho/mu - N_b(5*NNODE+1:6*NNODE,5*NNODE+1:6*NNODE) = + N_b(5*NNODE+1:6*NNODE,5*NNODE+1:6*NNODE) = 1 M_b(1:NNODE,1:NNODE)/rho/mu - N_c(1:NNODE,1:NNODE) = + N_c(1:NNODE,1:NNODE) = 1 M_c(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) - N_c(1:NNODE,NNODE+1:2*NNODE) = + N_c(1:NNODE,NNODE+1:2*NNODE) = 1 -M_c(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_c(1:NNODE,2*NNODE+1:3*NNODE) = + N_c(1:NNODE,2*NNODE+1:3*NNODE) = 1 -M_c(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_c(NNODE+1:2*NNODE,1:NNODE) = + N_c(NNODE+1:2*NNODE,1:NNODE) = 1 -M_c(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_c(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = + N_c(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = 1 M_c(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) - N_c(NNODE+1:2*NNODE,2*NNODE+1:3*NNODE) = + N_c(NNODE+1:2*NNODE,2*NNODE+1:3*NNODE) = 1 -M_c(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_c(2*NNODE+1:3*NNODE,1:NNODE) = + N_c(2*NNODE+1:3*NNODE,1:NNODE) = 1 -M_c(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_c(2*NNODE+1:3*NNODE,NNODE+1:2*NNODE) = + N_c(2*NNODE+1:3*NNODE,NNODE+1:2*NNODE) = 1 -M_c(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_c(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) = + N_c(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) = 1 M_c(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) - N_c(3*NNODE+1:4*NNODE,3*NNODE+1:4*NNODE) = + N_c(3*NNODE+1:4*NNODE,3*NNODE+1:4*NNODE) = 1 M_c(1:NNODE,1:NNODE)/rho/mu - N_c(4*NNODE+1:5*NNODE,4*NNODE+1:5*NNODE) = + N_c(4*NNODE+1:5*NNODE,4*NNODE+1:5*NNODE) = 1 M_c(1:NNODE,1:NNODE)/rho/mu - N_c(5*NNODE+1:6*NNODE,5*NNODE+1:6*NNODE) = + N_c(5*NNODE+1:6*NNODE,5*NNODE+1:6*NNODE) = 1 M_c(1:NNODE,1:NNODE)/rho/mu - N_d(1:NNODE,1:NNODE) = + N_d(1:NNODE,1:NNODE) = 1 M_d(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) - N_d(1:NNODE,NNODE+1:2*NNODE) = + N_d(1:NNODE,NNODE+1:2*NNODE) = 1 -M_d(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_d(1:NNODE,2*NNODE+1:3*NNODE) = + N_d(1:NNODE,2*NNODE+1:3*NNODE) = 1 -M_d(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_d(NNODE+1:2*NNODE,1:NNODE) = + N_d(NNODE+1:2*NNODE,1:NNODE) = 1 -M_d(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_d(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = + N_d(NNODE+1:2*NNODE,NNODE+1:2*NNODE) = 1 M_d(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) - N_d(NNODE+1:2*NNODE,2*NNODE+1:3*NNODE) = + N_d(NNODE+1:2*NNODE,2*NNODE+1:3*NNODE) = 1 -M_d(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_d(2*NNODE+1:3*NNODE,1:NNODE) = + N_d(2*NNODE+1:3*NNODE,1:NNODE) = 1 -M_d(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_d(2*NNODE+1:3*NNODE,NNODE+1:2*NNODE) = + N_d(2*NNODE+1:3*NNODE,NNODE+1:2*NNODE) = 1 -M_d(1:NNODE,1:NNODE)/rho*(lambda)/mu/2.d0/(3.d0*lambda+2.d0*mu) - N_d(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) = + N_d(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) = 1 M_d(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) - N_d(3*NNODE+1:4*NNODE,3*NNODE+1:4*NNODE) = + N_d(3*NNODE+1:4*NNODE,3*NNODE+1:4*NNODE) = 1 M_d(1:NNODE,1:NNODE)/rho/mu - N_d(4*NNODE+1:5*NNODE,4*NNODE+1:5*NNODE) = + N_d(4*NNODE+1:5*NNODE,4*NNODE+1:5*NNODE) = 1 M_d(1:NNODE,1:NNODE)/rho/mu - N_d(5*NNODE+1:6*NNODE,5*NNODE+1:6*NNODE) = + N_d(5*NNODE+1:6*NNODE,5*NNODE+1:6*NNODE) = 1 M_d(1:NNODE,1:NNODE)/rho/mu - - IF (EleType_pos .EQ. 1) THEN - M_PML(1:NNODE*3,1:NNODE*3) = M_RD(1:NNODE*3,1:NNODE*3) + + IF (EleType_pos .EQ. 1 .OR. LFLAGS(1).EQ.1 .OR. + & LFLAGS(1).EQ.2) THEN + + M_PML(1:NNODE*3,1:NNODE*3) = M_RD(1:NNODE*3,1:NNODE*3) + + K_PML(1:NNODE*3,1:NNODE*3) = K_RD(1:NNODE*3,1:NNODE*3) + write(*,*) 'this 2 if statement is working' + + + + else + IF (EleType_pos .EQ. 1) THEN + + M_PML(1:NNODE*3,1:NNODE*3) = M_RD(1:NNODE*3,1:NNODE*3) + 1 M_a(1:NNODE*3,1:NNODE*3) - M_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = + M_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = 1 -N_a(1:NNODE*6,1:NNODE*6) - C_PML(1:NNODE*3,1:NNODE*3) = M_b(1:NNODE*3,1:NNODE*3) - C_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = A_eu(1:NNODE*3,1:NNODE*6) - C_PML(NNODE*3+1:NNODE*9,1:NNODE*3) = - 1 transpose(A_eu(1:NNODE*3,1:NNODE*6)) - C_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = + C_PML(1:NNODE*3,1:NNODE*3) = C_RD(1:NNODE*3,1:NNODE*3) + + 1 M_b(1:NNODE*3,1:NNODE*3) + C_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = A_eu(1:NNODE*3,1:NNODE*6) + C_PML(NNODE*3+1:NNODE*9,1:NNODE*3) = + 1 transpose(A_eu(1:NNODE*3,1:NNODE*6)) + C_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = 1 -N_b(1:NNODE*6,1:NNODE*6) - K_PML(1:NNODE*3,1:NNODE*3) = K_RD(1:NNODE*3,1:NNODE*3) + + K_PML(1:NNODE*3,1:NNODE*3) = K_RD(1:NNODE*3,1:NNODE*3) + 1 M_c(1:NNODE*3,1:NNODE*3) - K_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = A_pu(1:NNODE*3,1:NNODE*6) - K_PML(NNODE*3+1:NNODE*9,1:NNODE*3) = + K_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = A_pu(1:NNODE*3,1:NNODE*6) + K_PML(NNODE*3+1:NNODE*9,1:NNODE*3) = 1 transpose(A_pu(1:NNODE*3,1:NNODE*6)) - K_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = + K_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = 1 -N_c(1:NNODE*6,1:NNODE*6) - G_PML(1:NNODE*3,1:NNODE*3) = M_d(1:NNODE*3,1:NNODE*3) - G_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = A_wu(1:NNODE*3,1:NNODE*6) - G_PML(NNODE*3+1:NNODE*9,1:NNODE*3) = + G_PML(1:NNODE*3,1:NNODE*3) = M_d(1:NNODE*3,1:NNODE*3) + G_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = A_wu(1:NNODE*3,1:NNODE*6) + G_PML(NNODE*3+1:NNODE*9,1:NNODE*3) = 1 transpose(A_wu(1:NNODE*3,1:NNODE*6)) - G_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = - 1 -N_d(1:NNODE*6,1:NNODE*6) + G_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = + 1 -N_d(1:NNODE*6,1:NNODE*6) + ! write(*,*) 'this 1 if statement is working' - else - M_PML(1:NNODE*3,1:NNODE*3) = M_a(1:NNODE*3,1:NNODE*3) - M_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = + else + ! write(*,*) 'this if statement is working' + M_PML(1:NNODE*3,1:NNODE*3) = + 1 M_a(1:NNODE*3,1:NNODE*3) + M_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = + 1 A_eu(1:NNODE*3,1:NNODE*6)*Damp_beta + M_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = 1 -N_a(1:NNODE*6,1:NNODE*6) - C_PML(1:NNODE*3,1:NNODE*3) = M_b(1:NNODE*3,1:NNODE*3) - C_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = A_eu(1:NNODE*3,1:NNODE*6) - C_PML(NNODE*3+1:NNODE*9,1:NNODE*3) = + C_PML(1:NNODE*3,1:NNODE*3) = + 1 M_b(1:NNODE*3,1:NNODE*3) + + 2 M_a(1:NNODE*3,1:NNODE*3)*Damp_alpha + + C_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = + 1 A_pu(1:NNODE*3,1:NNODE*6)*Damp_beta + + 2 A_eu(1:NNODE*3,1:NNODE*6) + C_PML(NNODE*3+1:NNODE*9,1:NNODE*3) = 1 transpose(A_eu(1:NNODE*3,1:NNODE*6)) - C_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = + C_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = 1 -N_b(1:NNODE*6,1:NNODE*6) - K_PML(1:NNODE*3,1:NNODE*3) = M_c(1:NNODE*3,1:NNODE*3) - K_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = A_pu(1:NNODE*3,1:NNODE*6) - K_PML(NNODE*3+1:NNODE*9,1:NNODE*3) = - 1 transpose(A_pu(1:NNODE*3,1:NNODE*6)) - K_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = + K_PML(1:NNODE*3,1:NNODE*3) = + 1 M_c(1:NNODE*3,1:NNODE*3) + M_b(1:NNODE*3,1:NNODE*3)*Damp_alpha + K_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = + 1 A_pu(1:NNODE*3,1:NNODE*6)+A_wu(1:NNODE*3,1:NNODE*6)*Damp_beta + K_PML(NNODE*3+1:NNODE*9,1:NNODE*3) = + 1 transpose(A_pu(1:NNODE*3,1:NNODE*6)) + K_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = 1 -N_c(1:NNODE*6,1:NNODE*6) - G_PML(1:NNODE*3,1:NNODE*3) = M_d(1:NNODE*3,1:NNODE*3) - G_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = A_wu(1:NNODE*3,1:NNODE*6) - G_PML(NNODE*3+1:NNODE*9,1:NNODE*3) = - 1 transpose(A_wu(1:NNODE*3,1:NNODE*6)) + G_PML(1:NNODE*3,1:NNODE*3) = + 1 M_d(1:NNODE*3,1:NNODE*3) + M_c(1:NNODE*3,1:NNODE*3)*Damp_alpha + G_PML(1:NNODE*3,NNODE*3+1:NNODE*9) = A_wu(1:NNODE*3,1:NNODE*6) + G_PML(NNODE*3+1:NNODE*9,1:NNODE*3) = + 1 transpose(A_wu(1:NNODE*3,1:NNODE*6)) G_PML(NNODE*3+1:NNODE*9,NNODE*3+1:NNODE*9) = 1 -N_d(1:NNODE*6,1:NNODE*6) + + H_PML(1:NNODE*3,1:NNODE*3) = + 1 M_d(1:NNODE*3,1:NNODE*3)*Damp_alpha + + + endif + + + endif - endif do i = 1,8 do j = 1,8 - MMTRX((i-1)*9+1:i*9,(j-1)*9+1:j*9) = + MMATRX((i-1)*9+1:i*9,(j-1)*9+1:j*9) = 1 M_PML(i:NDOFEL-8+i:8,j:NDOFEL-8+j:8) - CMTRX((i-1)*9+1:i*9,(j-1)*9+1:j*9) = + CMATRX((i-1)*9+1:i*9,(j-1)*9+1:j*9) = 1 C_PML(i:NDOFEL-8+i:8,j:NDOFEL-8+j:8) - KMTRX((i-1)*9+1:i*9,(j-1)*9+1:j*9) = + KMATRX((i-1)*9+1:i*9,(j-1)*9+1:j*9) = 1 K_PML(i:NDOFEL-8+i:8,j:NDOFEL-8+j:8) - GMTRX((i-1)*9+1:i*9,(j-1)*9+1:j*9) = + GMATRX((i-1)*9+1:i*9,(j-1)*9+1:j*9) = 1 G_PML(i:NDOFEL-8+i:8,j:NDOFEL-8+j:8) + HMATRX((i-1)*9+1:i*9,(j-1)*9+1:j*9) = + 1 H_PML(i:NDOFEL-8+i:8,j:NDOFEL-8+j:8) end do end do - ! ! set MMTRX equal to M_PML - ! MMTRX(1:NNODE*9,1:NNODE*9) = M_PML(1:NNODE*9,1:NNODE*9) - ! CMTRX(1:NNODE*9,1:NNODE*9) = C_PML(1:NNODE*9,1:NNODE*9) - ! KMTRX(1:NNODE*9,1:NNODE*9) = K_PML(1:NNODE*9,1:NNODE*9) - ! GMTRX(1:NNODE*9,1:NNODE*9) = G_PML(1:NNODE*9,1:NNODE*9) + ! print Ele_type pos + ! write(*,*) ' EleType_pos', EleType_pos + ! MMATRX(1:NDOFEL,1:NDOFEL) = GMATRX(1:NDOFEL,1:NDOFEL) + +CMATRX(1:NDOFEL,1:NDOFEL) = CMATRX(1:NDOFEL,1:NDOFEL) + Damp_alpha*MMATRX(1:NDOFEL,1:NDOFEL) + Damp_beta*KMATRX(1:NDOFEL,1:NDOFEL) + + + ! IF (LFLAGS(1).EQ.1 .OR. LFLAGS(1).EQ.2) THEN + ! AMATRX(1:NDOFEL,1:NDOFEL) = KMATRX(1:NDOFEL,1:NDOFEL) + ! RHS(1:NDOFEL,1) = RHS(1:NDOFEL,1) + ! 1 - matmul(KMATRX(1:NDOFEL,1:NDOFEL),U(1:NDOFEL)) + + ! ELSE IF (LFLAGS(1).EQ.11 .OR. LFLAGS(1).EQ.12) THEN + + + ! d_bar_n(1:NDOFEL) = SVARS(1:NDOFEL) + ! U_n(1:NDOFEL) = SVARS(NDOFEL+1:NDOFEL*2) + ! V_n(1:NDOFEL) = SVARS(2*NDOFEL+1:NDOFEL*3) + ! A_n(1:NDOFEL) = SVARS(3*NDOFEL+1:NDOFEL*4) + ! d_bar_dot_n(1:NDOFEL) = SVARS(4*NDOFEL+1:NDOFEL*5) + + + + ! d_bar_n1(1:NDOFEL) = d_bar_n(1:NDOFEL) + + ! 1 DTIME*U_n(1:NDOFEL) + DTIME**2.d0/2.d0*V_n(1:NDOFEL) + + ! 2 DTIME**3.d0*(1.d0/6.d0 - coef_alpha)*A_n(1:NDOFEL) + + ! 3 DTIME**3.d0*coef_alpha*A(1:NDOFEL) + + ! d_bar_dot_n1(1:NDOFEL) = d_bar_dot_n(1:NDOFEL) + + ! 1 DTIME*d_bar_n(1:NDOFEL) + DTIME**2.d0/2.d0*U_n(1:NDOFEL) + + ! 2 DTIME**3.d0/6.d0*V_n(1:NDOFEL) + + ! 3 DTIME**4.d0*(1.d0/24.d0-coef_beta)*A_n(1:NDOFEL) + + ! 4 DTIME**4.d0*coef_beta*A(1:NDOFEL) + + + ! AMATRX(1:NDOFEL,1:NDOFEL) = + ! 1 (1.d0+ALPHA)*HMATRX(1:NDOFEL,1:NDOFEL)*DTIME**2.d0*coef_beta/ + ! 2 BETA + ! 3 + (1.d0+ALPHA)*GMATRX(1:NDOFEL,1:NDOFEL)*DTIME*coef_alpha/BETA + ! 4 + (1.d0+ALPHA)*KMATRX(1:NDOFEL,1:NDOFEL) + ! 5 + (1.d0+ALPHA)*CMATRX(1:NDOFEL,1:NDOFEL)*DVDU + ! 6 + MMATRX(1:NDOFEL,1:NDOFEL)*DADU + + ! RHS(1:NDOFEL,1) = RHS(1:NDOFEL,1) + ! & - matmul(MMATRX(1:NDOFEL,1:NDOFEL),A(1:NDOFEL)) + ! & - (1.d0+ALPHA)*matmul(KMATRX(1:NDOFEL,1:NDOFEL),U(1:NDOFEL)) + ! & - (1.d0+ALPHA)*matmul(CMATRX(1:NDOFEL,1:NDOFEL),V(1:NDOFEL)) + ! & - (1.d0+ALPHA)* + ! & matmul(GMATRX(1:NDOFEL,1:NDOFEL),d_bar_n1(1:NDOFEL)) + ! & - (1.d0+ALPHA)* + ! & matmul(HMATRX(1:NDOFEL,1:NDOFEL),d_bar_dot_n1(1:NDOFEL)) + ! & + ALPHA*matmul(KMATRX(1:NDOFEL,1:NDOFEL),U_n(1:NDOFEL)) + ! & + ALPHA*matmul(CMATRX(1:NDOFEL,1:NDOFEL),V_n(1:NDOFEL)) + ! & + ALPHA*matmul(GMATRX(1:NDOFEL,1:NDOFEL),d_bar_n(1:NDOFEL)) + ! & +ALPHA*matmul(HMATRX(1:NDOFEL,1:NDOFEL),d_bar_dot_n(1:NDOFEL)) + + + ! SVARS(1:NDOFEL) = d_bar_n1(1:NDOFEL) + ! SVARS(NDOFEL+1:NDOFEL*2) = U(1:NDOFEL) + ! SVARS(2*NDOFEL+1:NDOFEL*3) = V(1:NDOFEL) + ! SVARS(3*NDOFEL+1:NDOFEL*4) = A(1:NDOFEL) + ! SVARS(4*NDOFEL+1:NDOFEL*5) = d_bar_dot_n1(1:NDOFEL) + + ! ELSE + ! write(6,*) ' Error in abaqus UEL ' + ! write(6,*) ' Analsis types not supported' + ! stop + ! END IF + + + + ! ! PNEWDT = 1.d0 ! This leaves the timestep unchanged (ABAQUS will use its own algorithm to determine DTIME) + ! ! + ! ! Apply distributed loads + ! ! + ! ! Distributed loads are specified in the input file using the Un option in the input file. + ! ! n specifies the face number, following the ABAQUS convention + ! ! + ! ! + ! do j = 1,NDLOAD + + ! call abq_facenodes_3D(NNODE,iabs(JDLTYP(j,1)), + ! 1 face_node_list,nfacenodes) + + ! do i = 1,nfacenodes + ! face_coords(1:3,i) = coords(1:3,face_node_list(i)) + ! end do + + ! if (nfacenodes == 3) n_points = 3 + ! if (nfacenodes == 6) n_points = 4 + ! if (nfacenodes == 4) n_points = 4 + ! if (nfacenodes == 8) n_points = 9 + + ! call abq_UEL_2D_integrationpoints(n_points, nfacenodes, xi2, w) + + ! do kint = 1,n_points + ! call abq_UEL_2D_shapefunctions(xi2(1:2,kint), + ! 1 nfacenodes,N2,dNdxi2) + ! dxdxi2 = matmul(face_coords(1:3,1:nfacenodes), + ! 1 dNdxi2(1:nfacenodes,1:2)) + ! norm(1)=(dxdxi2(2,1)*dxdxi2(3,2))-(dxdxi2(2,2)*dxdxi2(3,1)) + ! norm(2)=(dxdxi2(1,1)*dxdxi2(3,2))-(dxdxi2(1,2)*dxdxi2(3,1)) + ! norm(3)=(dxdxi2(1,1)*dxdxi2(2,2))-(dxdxi2(1,2)*dxdxi2(2,1)) + + ! do i = 1,nfacenodes + ! ipoin = face_node_list(i) + ! RHS(ipoin:ipoin+2*9:9,1) = RHS(ipoin:ipoin+2*9:9,1) + ! 1 - N2(i)*adlmag(j,1)*norm(1:3)*w(kint) ! Note determinant is already in normal + ! end do + ! end do + ! end do + + ! check symmetry of matrices with tolerance + + ! insert MMatrix in to M_PMl + ! M_PML(1:NDOFEL,1:NDOFEL) = MMATRX(1:NDOFEL,1:NDOFEL) + ! C_PML(1:NDOFEL,1:NDOFEL) = CMATRX(1:NDOFEL,1:NDOFEL) + ! K_PML(1:NDOFEL,1:NDOFEL) = KMATRX(1:NDOFEL,1:NDOFEL) + ! G_PML(1:NDOFEL,1:NDOFEL) = GMATRX(1:NDOFEL,1:NDOFEL) + ! H_PML(1:NDOFEL,1:NDOFEL) = HMATRX(1:NDOFEL,1:NDOFEL) + + + ! call check_symmetry(M_PML,1.d-10,res1,"M") + ! if (res1 == 1) then + ! write(6,*) 'M_PML is symmetric ', res1 + ! end if + ! call check_symmetry(G_PML,1.d-10,res4,"G") + ! if (res4 == 1) then + ! write(6,*) 'G_PML is symmetric ', res4 + ! end if + ! call check_symmetry(H_PML,1.d-10,res5,"H") + ! if (res5 == 1) then + ! write(6,*) 'H_PML is symmetric ', res5 + ! end if + ! call check_symmetry(K_PML,1.d-10,res3,"K") + ! if (res3 == 1) then + ! write(6,*) 'K_PML is symmetric ', res3 + ! end if + ! call check_symmetry(C_PML,1.d-10,res2,"C") + ! if (res2 == 1) then + ! write(6,*) 'C_PML is symmetric ', res2 + ! end if + + ! call check_zero(M_PML,1.d-10,res1,"M") + ! if (res1 == 1) write(6,*) 'M_PML is zero ', res1 + ! call check_zero(G_PML,1.d-10,res1,"G") + ! if (res1 == 1) write(6,*) 'G_PML is zero ', res1 + ! call check_zero(H_PML,1.d-10,res1,"H") + ! if (res1 == 1) write(6,*) 'H_PML is zero ', res1 + ! call check_zero(K_PML,1.d-10,res1,"K") + ! if (res1 == 1) write(6,*) 'K_PML is zero ', res1 + ! call check_zero(C_PML,1.d-10,res1,"C") + ! if (res1 == 1) write(6,*) 'C_PML is zero ', res1 + + return END SUBROUTINE PML_3D + + ! check symmetry of matrices with tolerance + subroutine check_symmetry(AMATRX,RTOL,a,char) + + implicit none + double precision, intent(in) :: AMATRX(72,72) + double precision, intent(in) :: RTOL + character(len=1), intent(in) :: char + integer , intent(out) :: a + integer :: i,j + + a = 1 + + do i = 1, 72 + do j = 1, 72 + if (abs(AMATRX(i,j)-AMATRX(j,i)) > RTOL) then + write(6,*) 'Matrix ',char,' is not symmetric' + write(6,*) '(i,j) = ',AMATRX(i,j) + write(6,*) '(j,i) = ',AMATRX(j,i) + a = 0 + exit + endif + end do + if (a == 0) exit + end do + + return + end subroutine check_symmetry + + + subroutine check_zero(AMATRX,RTOL,a,char) + + implicit none + double precision, intent(in) :: AMATRX(72,72) + double precision, intent(in) :: RTOL + character(len=1), intent(in) :: char + integer , intent(out) :: a + integer :: i,j + + a = 1 + + do i = 1, 72 + do j = 1, 72 + if (abs(AMATRX(i,j)) > RTOL) then + write(6,*) 'Matrix ',char,' is not zero' + write(6,*) '(i,j) = ',AMATRX(i,j) + a = 0 + exit + endif + end do + if (a == 0) exit + end do + + return + end subroutine check_zero subroutine abq_UEL_3D_integrationpoints(n_points, n_nodes, xi, w) @@ -1123,7 +1460,7 @@ subroutine abq_UEL_2D_integrationpoints(n_points, n_nodes, xi, w) double precision, intent(out) :: xi(2,*) double precision, intent(out) :: w(*) - integer :: i,j,k,n + ! integer :: i,j,k,n double precision :: cn,w1,w2,w11,w12,w22 @@ -1440,7 +1777,6 @@ subroutine PML_alpha_beta_function(PROPS,x1,x2,x3,PML_alpha_beta) cp_ref = SQRT(E *(1.d0-xnu)/rho/(1.d0+xnu)/(1.d0-2.d0*xnu)) - IF(x2 < -RD_half_width_y) then IF(x1 < -RD_half_width_x) then IF(x3 < -RD_depth) then @@ -1547,7 +1883,7 @@ subroutine PML_alpha_beta_function(PROPS,x1,x2,x3,PML_alpha_beta) endif endif - + ! write(6,*) "EleType_arg ",EleType_arg select case (EleType_arg) case(1) !Regular domain (do nothing) n1 = 0.d0 @@ -1696,9 +2032,12 @@ subroutine PML_alpha_beta_function(PROPS,x1,x2,x3,PML_alpha_beta) end select PML_b = PML_L / 1.d0 !characteristic length (average element size in the PML domain) - - alpha_0 = ((afp+1)*PML_b) / (2.d0*PML_L )*LOG(1.d0 / PML_Rcoef) - beta_0 = ((afp+1)*cp_ref) / (2.d0*PML_L )*LOG(1.d0 / PML_Rcoef) + + alpha_0 = ((afp+1)*PML_b) / (2.d0*PML_L )*LOG10(1.d0 / PML_Rcoef) + beta_0 = ((afp+1)*cp_ref) / (2.d0*PML_L )*LOG10(1.d0 / PML_Rcoef) + +! alpha_0 = 5.d0 +! beta_0 = 800.d0 PML_alpha_beta(1,1) = 1.d0 + alpha_0*((x1 -x1_0) * n1 /PML_L)**afp PML_alpha_beta(1,2) = 1.d0 + alpha_0*((x2 -x2_0) * n2 /PML_L)**afp From d6813eaba9e13fe15f8653fe7a77555839404685 Mon Sep 17 00:00:00 2001 From: amnp95 Date: Thu, 27 Feb 2025 19:57:34 -0800 Subject: [PATCH 027/261] Add PML3DVISCOUS element implementation and update project files --- SRC/Makefile | 2 + .../FEM_ObjectBrokerAllClasses.cpp | 50 +- SRC/classTags.h | 1 + SRC/element/PML/CMakeLists.txt | 2 + SRC/element/PML/Makefile | 3 +- SRC/element/PML/PML3DVISCOUS.cpp | 785 ++++++++++++++++++ SRC/element/PML/PML3DVISCOUS.h | 146 ++++ SRC/element/TclElementCommands.cpp | 29 +- SRC/interpreter/OpenSeesElementCommands.cpp | 6 +- Win32/proj/element/element.vcxproj | 6 +- Win32/proj/element/element.vcxproj.filters | 14 +- Win64/proj/element/element.vcxproj | 2 + Win64/proj/element/element.vcxproj.filters | 2 + 13 files changed, 1002 insertions(+), 46 deletions(-) create mode 100644 SRC/element/PML/PML3DVISCOUS.cpp create mode 100644 SRC/element/PML/PML3DVISCOUS.h diff --git a/SRC/Makefile b/SRC/Makefile index fee49cb0dc..fb8a6075ae 100644 --- a/SRC/Makefile +++ b/SRC/Makefile @@ -683,6 +683,7 @@ ELE_LIBS = $(FE)/element/Element.o \ $(FE)/element/UWelements/Tcl_generateInterfacePoints.o \ $(FE)/element/PML/pml_3d.o \ $(FE)/element/PML/PML3D.o \ + $(FE)/element/PML/PML3DVISCOUS.o \ $(FE)/element/PML/pml_2d.o \ $(FE)/element/PML/PML2D.o \ $(FE)/element/PML/PML2D_3.o \ @@ -971,6 +972,7 @@ MATERIAL_LIBS = $(FE)/material/Material.o \ $(FE)/material/nD/PlasticDamageConcretePlaneStress.o \ $(FE)/element/PML/pml_3d.o \ $(FE)/element/PML/PML3D.o \ + $(FE)/element/PML/PML3DVISCOUS.o \ $(FE)/element/PML/pml_2d.o \ $(FE)/element/PML/PML2D.o \ $(FE)/element/PML/PML2D_3.o \ diff --git a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp index 3f68d3b046..d3250b6cd6 100644 --- a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp +++ b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp @@ -420,6 +420,7 @@ #include "PML/PML2D_5.h" #include "PML/PML2D_12.h" #include "PML/PML2DVISCOUS.h" +#include "PML/PML3DVISCOUS.h" #include "UP-ucsd/Nine_Four_Node_QuadUP.h" @@ -880,7 +881,7 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) return new InertiaTruss(); case ELE_TAG_ZeroLength: - return new ZeroLength(); + return new ZeroLength(); case ELE_TAG_CoupledZeroLength: return new CoupledZeroLength(); @@ -910,13 +911,13 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) return new FourNodeQuadUP(); case ELE_TAG_FourNodeQuad: - return new FourNodeQuad(); + return new FourNodeQuad(); case ELE_TAG_FourNodeQuad3d: return new FourNodeQuad3d(); case ELE_TAG_Tri31: - return new Tri31(); + return new Tri31(); case ELE_TAG_SixNodeTri: return new SixNodeTri(); @@ -1029,7 +1030,7 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) case ELE_TAG_TriSurfaceLoad: return new TriSurfaceLoad(); - + case ELE_TAG_Quad4FiberOverlay: return new Quad4FiberOverlay(); //Amin Pakzad @@ -1041,7 +1042,7 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) case ELE_TAG_FourNodeTetrahedron: return new FourNodeTetrahedron(); - + case ELE_TAG_PML2D: return new PML2D(); @@ -1060,6 +1061,9 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) case ELE_TAG_PML2DVISCOUS: return new PML2DVISCOUS(); // Amin Pakzad + case ELE_TAG_PML3DVISCOUS: + return new PML3DVISCOUS(); // Amin Pakzad + case ELE_TAG_BeamContact2D: return new BeamContact2D(); @@ -1086,13 +1090,13 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) case ELE_TAG_ShellMITC9: return new ShellMITC9(); - + case ELE_TAG_ShellDKGQ: //Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu return new ShellDKGQ(); //Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu case ELE_TAG_ShellNLDKGQ: //Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu return new ShellNLDKGQ(); //Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu - + case ELE_TAG_ShellDKGT: return new ShellDKGT(); @@ -1104,7 +1108,7 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) case ELE_TAG_ASDShellT3: // Massimo Petracca return new ASDShellT3(); // Massimo Petracca - + case ELE_TAG_BbarBrick: return new BbarBrick(); @@ -1115,7 +1119,7 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) return new Inno3DPnPJoint(); // Cristian Miculas case ELE_TAG_TwoNodeLink: - return new TwoNodeLink(); + return new TwoNodeLink(); case ELE_TAG_TwoNodeLinkSection: return new TwoNodeLinkSection(); @@ -1522,7 +1526,7 @@ FEM_ObjectBrokerAllClasses::getNewSectionIntegration(int classTag) case SECTION_INTEGRATION_TAG_HSS: return new HSSSectionIntegration(); - + default: opserr << "FEM_ObjectBrokerAllClasses::getSectionIntegration - "; opserr << " - no SectionIntegration type exists for class tag "; @@ -1767,7 +1771,7 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) case MAT_TAG_TDConcreteMC10NL: return new TDConcreteMC10NL(); - + case MAT_TAG_Steel01: return new Steel01(); @@ -1781,7 +1785,7 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) return new Steel2(); case MAT_TAG_Steel4: - return new Steel4(); + return new Steel4(); case MAT_TAG_RambergOsgoodSteel: return new RambergOsgoodSteel(); @@ -1824,7 +1828,7 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) case MAT_TAG_SelfCentering: return new SelfCenteringMaterial(); - + case MAT_TAG_TzLiq1: return new TzLiq1(); @@ -1887,7 +1891,7 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) case MAT_TAG_HookGap: return new HookGap(); - + case MAT_TAG_Viscous: return new ViscousMaterial(); @@ -1928,7 +1932,7 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) return new ENTMaterial(); case MAT_TAG_GNG: - return new GNGMaterial(); + return new GNGMaterial(); case MAT_TAG_Ratchet: return new Ratchet(); @@ -2022,7 +2026,7 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) case MAT_TAG_BarSlip: return new BarSlipMaterial(); - + case MAT_TAG_HystereticPoly: // Salvatore Sessa return new HystereticPoly(); @@ -2043,7 +2047,7 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) case MAT_TAG_Pinching4: return new Pinching4Material(); - + case MAT_TAG_CFSSSWP: return new CFSSSWP(); @@ -2096,14 +2100,14 @@ FEM_ObjectBrokerAllClasses::getNewSection(int classTag) return new ElasticBDShearSection2d(); case SEC_TAG_ElasticShear3d: - return new ElasticShearSection3d(); - + return new ElasticShearSection3d(); + case SEC_TAG_ElasticTube3d: return new ElasticTubeSection3d(); case SEC_TAG_ElasticWarpingShear2d: return new ElasticWarpingShearSection2d(); - + case SEC_TAG_Generic1d: return new GenericSection1d(); @@ -2145,7 +2149,7 @@ FEM_ObjectBrokerAllClasses::getNewSection(int classTag) case SEC_TAG_FiberSectionWarping3d: return new FiberSectionWarping3d(); - + case SEC_TAG_ElasticPlateSection: return new ElasticPlateSection(); @@ -2206,7 +2210,7 @@ FEM_ObjectBrokerAllClasses::getNewNDMaterial(int classTag) return new ElasticIsotropicPlateFiber(); case ND_TAG_ElasticIsotropicBeamFiber: - return new ElasticIsotropicBeamFiber(); + return new ElasticIsotropicBeamFiber(); case ND_TAG_ElasticIsotropicBeamFiber2d: return new ElasticIsotropicBeamFiber2d(); @@ -2768,7 +2772,7 @@ FEM_ObjectBrokerAllClasses::getNewConstraintHandler(int classTag) case HANDLER_TAG_TransformationConstraintHandler: return new TransformationConstraintHandler(); - + case HANDLER_TAG_AutoConstraintHandler: return new AutoConstraintHandler(); diff --git a/SRC/classTags.h b/SRC/classTags.h index 46ec11f767..74e61b6fb8 100644 --- a/SRC/classTags.h +++ b/SRC/classTags.h @@ -895,6 +895,7 @@ #define ELE_TAG_ShellNLDKGTThermal 268 // Giovanni Rinaldin #define ELE_TAG_Pipe 269 #define ELE_TAG_CurvedPipe 270 +#define ELE_TAG_PML3DVISCOUS 271 // Amin Pakzad #define FRN_TAG_Coulomb 1 diff --git a/SRC/element/PML/CMakeLists.txt b/SRC/element/PML/CMakeLists.txt index 017d4a89ea..b33148daf2 100644 --- a/SRC/element/PML/CMakeLists.txt +++ b/SRC/element/PML/CMakeLists.txt @@ -13,6 +13,7 @@ target_sources(OPS_Element PML2D.cpp PML3D.cpp PML2DVISCOUS.cpp + PML3DVISCOUS.cpp PML2D_3.cpp PML2D_5.cpp PML2D_12.cpp @@ -20,6 +21,7 @@ target_sources(OPS_Element PML3D.h PML2D.h PML2DVISCOUS.h + PML3DVISCOUS.h PML2D_3.h PML2D_5.h PML2D_12.h diff --git a/SRC/element/PML/Makefile b/SRC/element/PML/Makefile index 456c81a1f3..4fc5954a40 100644 --- a/SRC/element/PML/Makefile +++ b/SRC/element/PML/Makefile @@ -3,7 +3,8 @@ include ../../../Makefile.def OBJS = PML2D.o PML3D.o \ pml_2d.o pml_3d.o \ PML2D_3.o PML2D_5.o PML2D_12.o \ - PML2DVISCOUS.o + PML2DVISCOUS.o \ + PML3DVISCOUS.o all: $(OBJS) diff --git a/SRC/element/PML/PML3DVISCOUS.cpp b/SRC/element/PML/PML3DVISCOUS.cpp new file mode 100644 index 0000000000..9f31942642 --- /dev/null +++ b/SRC/element/PML/PML3DVISCOUS.cpp @@ -0,0 +1,785 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// Written by: Amin Pakzad, Pedro Arduino (parduino@uw.edu) +// +// Eight node PML3DVISCOUS element .. a c++ wrapper to fortran routine +// provided by Wenyang Zhang (zwyll@ucla.edu), University of California, Los Angeles +// +// University of Washington, UC. Los Angeles, U.C. Berkeley, 12, 2020 + + +#include "PML3DVISCOUS.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +// ======================================================================= +// PML3DVISCOUS element tcl command +// ======================================================================= +void* OPS_PML3DVISCOUS() +{ + // check if the total number of arguments passed is correct + if (OPS_GetNumRemainingInputArgs() < (9 + PML3DVISCOUS_NUM_PROPS + 3)) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element PML3DVISCOUS eleTag? [8 integer nodeTags] [PML3DVISCOUS_NUM_PARAMS material properties]\n"; + return 0; + } + + // reading element tag and node numbers + int idata[9]; + int num = 9; + if (OPS_GetIntInput(&num, idata) < 0) { + opserr << "WARNING: invalid integer data : could be the tag or the node numbers \n"; + return 0; + } + + // reading Newmark parameters + double Newmark[3]; + num = 3; + if (OPS_GetDoubleInput(&num, Newmark) < 0) { + opserr << "WARNING: invalid double data: could be Newmark parameters\n"; + return 0; + } + + // reading material properties + double dData[PML3DVISCOUS_NUM_PROPS]; num = PML3DVISCOUS_NUM_PROPS; + if (OPS_GetDoubleInput(&num, dData) < 0) { + opserr << "WARNING: invalid double data\n"; + return 0; + } + + // create a new PML3DVISCOUS element and add it to the Domain + return new PML3DVISCOUS(idata[0], &idata[1], Newmark, dData); +} + +// ======================================================================= +// static data +// ======================================================================= +Matrix PML3DVISCOUS::tangent(PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); +Matrix PML3DVISCOUS::mass(PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); +Matrix PML3DVISCOUS::damping(PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); +Vector PML3DVISCOUS::resid(PML3DVISCOUS_NUM_DOF); +double PML3DVISCOUS::eta = 0.; +double PML3DVISCOUS::beta = 0.; +double PML3DVISCOUS::gamma = 0.; +double PML3DVISCOUS::dt = 0.; +int PML3DVISCOUS::eleCount = 0; +// int PML3DVISCOUS::numberOfElements = 0; + + +// ======================================================================= +// null constructor +// ======================================================================= +PML3DVISCOUS::PML3DVISCOUS() + :Element(0, ELE_TAG_PML3DVISCOUS), + connectedExternalNodes(PML3DVISCOUS_NUM_NODES), + ubar(PML3DVISCOUS_NUM_DOF), + ubart(PML3DVISCOUS_NUM_DOF), + ubarbar(PML3DVISCOUS_NUM_DOF), + ubarbart(PML3DVISCOUS_NUM_DOF) +{ + for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) { + nodePointers[i] = 0; + } + dt = 0; + ubar.Zero(); + ubart.Zero(); + ubarbar.Zero(); + ubarbart.Zero(); + updateflag = 0; + update_dt = 0; + eta = 0; + beta = 0; + gamma = 0; + +} + +// ======================================================================= +// Full constructor +// ======================================================================= +PML3DVISCOUS::PML3DVISCOUS(int tag, int* nodeTags, double* nemwarks, double* eleData) + :Element(tag, ELE_TAG_PML3DVISCOUS), + connectedExternalNodes(PML3DVISCOUS_NUM_NODES), + ubar(PML3DVISCOUS_NUM_DOF), + ubart(PML3DVISCOUS_NUM_DOF), + ubarbar(PML3DVISCOUS_NUM_DOF), + ubarbart(PML3DVISCOUS_NUM_DOF) +{ + eleCount++; + if (eleCount == 1) { + opserr << "Perfectly Matched Layer 3D (PMLVISCOUS) element - Written: W. Zhang, E. Taciroglu, A. Pakzad, P. Arduino, UCLA, UCLA, U.Washington, U.Washington\n "; + } + // initialize node pointers + for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) { + connectedExternalNodes(i) = nodeTags[i]; + nodePointers[i] = 0; + } + + // initialize Newmark parameters + eta = nemwarks[0]; + beta = nemwarks[1]; + gamma = nemwarks[2]; + + // initialize material properties + for (int i = 0; i < PML3DVISCOUS_NUM_PROPS; i++) + props[i] = eleData[i]; + + // initialize the ubar and ubart vectors to zero + ubart.Zero(); + ubar.Zero(); + ubarbar.Zero(); + ubarbart.Zero(); + updateflag = 0; + update_dt = 0; +} + +// ======================================================================= +// destructor +// ======================================================================= +PML3DVISCOUS::~PML3DVISCOUS() +{ + +} + +// ======================================================================= +// Set Domain +// ======================================================================= +void PML3DVISCOUS::setDomain(Domain* theDomain) +{ + + Domainptr = theDomain; + + // node pointers + for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) + nodePointers[i] = theDomain->getNode(connectedExternalNodes(i)); + + this->DomainComponent::setDomain(theDomain); + + // create the coordinate vectors + double coords[PML3DVISCOUS_NUM_DOF]; + for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) { + const Vector& loc = nodePointers[i]->getCrds(); + coords[i * 3] = loc(0); + coords[i * 3 + 1] = loc(1); + coords[i * 3 + 2] = loc(2); + } + int NDOFEL = PML3DVISCOUS_NUM_DOF; + int NPROPS = 13; + int MCRD = 3; + int NNODE = 8; + int LFLAGS = 12; + for (int i = 0; i < PML3DVISCOUS_NUM_DOF*PML3DVISCOUS_NUM_DOF; i++) { + C[i] = 0.0; + K[i] = 0.0; + M[i] = 0.0; + G[i] = 0.0; + H[i] = 0.0; + } + pml3d_(M, C, K, G, H, &NDOFEL, props, coords, &MCRD, &NNODE, &LFLAGS); + dt = theDomain->getDT(); + + // // make C zero + for (int i = 0; i < PML3DVISCOUS_NUM_DOF*PML3DVISCOUS_NUM_DOF; i++) { + // C[i] = 0.0; + // K[i] = 0.0; + // M[i] = 0.0; + // G[i] = 0.0; + // H[i] = 0.0; + } + + + std::ofstream myfile; + std::string filename; + int tag = this->getTag(); + + // // save M matrix in a file + // filename = "./PML/M" + std::to_string(tag) + ".mat"; + // myfile.open(filename); + // for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { + // for (int j = 0; j < PML3DVISCOUS_NUM_DOF; j++) { + // myfile << M[i*PML3DVISCOUS_NUM_DOF + j] << " "; + // } + // myfile << "\n"; + // } + // myfile.close(); + + // // save C matrix in a file + // filename = "./PML/C" + std::to_string(tag) + ".mat"; + // myfile.open(filename); + // for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { + // for (int j = 0; j < PML3DVISCOUS_NUM_DOF; j++) { + // myfile << C[i*PML3DVISCOUS_NUM_DOF + j] << " "; + // } + // myfile << "\n"; + // } + // myfile.close(); + + // // save K matrix in a file + // filename = "./PML/K" + std::to_string(tag) + ".mat"; + // myfile.open(filename); + // for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { + // for (int j = 0; j < PML3DVISCOUS_NUM_DOF; j++) { + // myfile << K[i*PML3DVISCOUS_NUM_DOF + j] << " "; + // } + // myfile << "\n"; + // } + // myfile.close(); + + // // save G matrix in a file + // filename = "./PML/G" + std::to_string(tag) + ".mat"; + // myfile.open(filename); + // for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { + // for (int j = 0; j < PML3DVISCOUS_NUM_DOF; j++) { + // myfile << G[i*PML3DVISCOUS_NUM_DOF + j] << " "; + // } + // myfile << "\n"; + // } + // myfile.close(); + + // save H matrix in a file + // filename = "./PML/H" + std::to_string(tag) + ".mat"; + // myfile.open(filename); + // for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { + // for (int j = 0; j < PML3DVISCOUS_NUM_DOF; j++) { + // myfile << H[i*PML3DVISCOUS_NUM_DOF + j] << " "; + // } + // myfile << "\n"; + // } + // myfile.close(); + +} + +// ======================================================================= +// update +// ======================================================================= +int PML3DVISCOUS::update(void) +{ + dt = Domainptr->getDT(); + // opserr << "dt = " << dt << "\n"; + // get u, v, a from nodes and calculate the ubar vector + int loc = 0; + double c1 = dt; + double c2 = dt * dt * 0.5; + double c3 = dt*dt*dt*((1.0/6.0)-eta); + double c4 = dt*dt*dt*eta; + for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) { + const Vector& uNode = nodePointers[i]->getDisp(); + const Vector& vNode = nodePointers[i]->getVel(); + const Vector& aNode = nodePointers[i]->getAccel(); + const Vector& atpdt = nodePointers[i]->getTrialAccel(); + for (int j = 0; j < 9; j++) { + ubar(loc) = ubart(loc) + uNode(j)*c1 + vNode(j)*c2 + aNode(j)*c3 + atpdt(j)*c4; + loc++; + } + } + + double keisi = 1.0/48.0; + + loc = 0; + c1 = dt; + c2 = dt * dt * 0.5; + c3 = dt * dt * dt /6.0; + c4 = dt * dt * dt * dt * (1.0/24.0 - keisi); + int c5 = dt * dt * dt * dt * keisi; + for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) { + const Vector& uNode = nodePointers[i]->getDisp(); + const Vector& vNode = nodePointers[i]->getVel(); + const Vector& aNode = nodePointers[i]->getAccel(); + const Vector& atpdt = nodePointers[i]->getTrialAccel(); + for (int j = 0; j < 9; j++) { + ubarbar(loc) = ubarbart(loc) + ubart(loc)*c1 + uNode(j)*c2 + vNode(j)*c3 + aNode(j)*c4 + atpdt(j)*c5; + loc++; + } + } + + return 0; +} + +// ======================================================================= +// return stiffness matrix +// ======================================================================= +const Matrix& PML3DVISCOUS::getTangentStiff() +{ + // check if the dt is changed to update the tangent stiffness matrix + double cg = eta*dt/beta; + double keisi = 1.0/48.0; + double ch = dt * dt * keisi/beta; + //keff = k + cg*g( k and g are symmetric matrices) + for (int i = 0; i < PML3DVISCOUS_NUM_DOF*PML3DVISCOUS_NUM_DOF; i++) { + Keff[i] = K[i] + cg*G[i] + ch*H[i]; + } + tangent.setData(Keff, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); + return tangent; +} + +// ======================================================================= +// return initial stiffness matrix +// ======================================================================= +const Matrix& PML3DVISCOUS::getInitialStiff() +{ + return this->getTangentStiff(); +} + +// ======================================================================= +// return mass matrix +// ======================================================================= +const Matrix& PML3DVISCOUS::getMass() +{ + mass.setData(M, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); + // mass.Zero(); + return mass; +} + +// ======================================================================= +// return damping matrix +// ======================================================================= +const Matrix& PML3DVISCOUS::getDamp() +{ + damping.setData(C, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); + // damping.Zero(); + return damping; +} + +// ======================================================================= +// Ressisting force +// ======================================================================= +//get residual +const Vector& PML3DVISCOUS::getResistingForce() +{ + // if (innertag==14) { + // opserr << "getResistingForce function is called\n"; + // } + int numNodalDOF = 9; + static Vector theVector(PML3DVISCOUS_NUM_DOF); + + // get K into stiff + tangent.setData(K, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); + + // + // perform: R = K * u + // + + int loc = 0; + for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) { + const Vector& uNode = nodePointers[i]->getTrialDisp(); + for (int j = 0; j < numNodalDOF; j++) + theVector(loc++) = uNode(j); + } + resid.addMatrixVector(0.0, tangent, theVector, 1.0); + return resid; +} + + +// ======================================================================= +// +// ======================================================================= +//get residual with inertia terms +const Vector& +PML3DVISCOUS::getResistingForceIncInertia() +{ + // R += K*u + static Vector theVector(PML3DVISCOUS_NUM_DOF); + tangent.setData(K, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); + + int loc = 0; + for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) { + const Vector& uNode = nodePointers[i]->getTrialDisp(); + for (int j = 0; j < 9; j++) + theVector(loc++) = uNode(j); + } + resid.addMatrixVector(0.0, tangent, theVector, 1.0); + + + + // R += M*a + loc = 0; + Node** theNodes = this->getNodePtrs(); + for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) { + const Vector& acc = theNodes[i]->getTrialAccel(); + for (int j = 0; j < 9; j++) { + theVector(loc++) = acc(j); + } + } + resid.addMatrixVector(1.0, this->getMass(), theVector, 1.0); + + // R += C*v + loc = 0; + for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) { + const Vector& vel = theNodes[i]->getTrialVel(); + for (int j = 0; j < 9; j++) { + theVector(loc++) = vel[j]; + } + } + resid.addMatrixVector(1.0, this->getDamp(), theVector, 1.0); + + + // R += G*ubar + tangent.setData(G, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); + resid.addMatrixVector(1.0, tangent, ubar, 1.0); + + // R += H*ubarbar + tangent.setData(H, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); + resid.addMatrixVector(1.0, tangent, ubarbar, 1.0); + + + return resid; +} + +// ======================================================================= +// get the number of external nodes +// ======================================================================= +int PML3DVISCOUS::getNumExternalNodes() const +{ + return PML3DVISCOUS_NUM_NODES; +} + +// ======================================================================= +// return connected external nodes +// ======================================================================= +const ID& PML3DVISCOUS::getExternalNodes() +{ + return connectedExternalNodes; +} + +// ======================================================================= +// return node pointers +// ======================================================================= +Node** PML3DVISCOUS::getNodePtrs(void) +{ + return nodePointers; +} + +// ======================================================================= +// return number of dofs +// ======================================================================= +int PML3DVISCOUS::getNumDOF() +{ + return PML3DVISCOUS_NUM_DOF; +} + +// ======================================================================= +// commit state +// ======================================================================= +int PML3DVISCOUS::commitState() +{ + int success = 0; + if ((success = this->Element::commitState()) != 0) { + opserr << "PML3DVISCOUS::commitState () - failed in base class"; + } + + // set ubart to ubar + for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { + ubart(i) = ubar(i); + } + + updateflag = 0; + return success; +} + +// ======================================================================= +// revert to last commit +// ======================================================================= +int PML3DVISCOUS::revertToLastCommit() +{ + int success = 0; + + // set ubar to ubart + for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { + ubar(i) = ubart(i); + ubarbar(i) = ubarbart(i); + } + + return success; +} + +// ======================================================================= +// revert to start +// ======================================================================= +int PML3DVISCOUS::revertToStart() +{ + int success = 0; + + // set ubar and ubart to zero + for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { + ubar(i) = 0.0; + ubart(i) = 0.0; + ubarbar(i) = 0.0; + ubarbart(i) = 0.0; + } + + return success; +} + +// ======================================================================= +// add load +// ======================================================================= +int PML3DVISCOUS::addLoad(ElementalLoad* theLoad, double loadFactor) +{ + return -1; +} + +// ======================================================================= +// add zero load +// ======================================================================= +void PML3DVISCOUS::zeroLoad() +{ + return; +} + +// ======================================================================= +// senself +// ======================================================================= +int PML3DVISCOUS::sendSelf(int commitTag, + Channel& theChannel) +{ + int res = 0; + + // note: we don't check for dataTag == 0 for Element + // objects as that is taken care of in a commit by the Domain + // object - don't want to have to do the check if sending data + int dataTag = this->getDbTag(); + + // PML3DVISCOUS packs its data into a Vector and sends this to theChannel + // along with its dbTag and the commitTag passed in the arguments + static Vector data(PML3DVISCOUS_NUM_PROPS + 4); + data(0) = this->getTag(); + + for (int ii = 1; ii <= PML3DVISCOUS_NUM_PROPS; ii++) { + data(ii) = props[ii - 1]; + } + data(PML3DVISCOUS_NUM_PROPS+1) = eta; + data(PML3DVISCOUS_NUM_PROPS+2) = beta; + data(PML3DVISCOUS_NUM_PROPS+3) = gamma; + + res += theChannel.sendVector(dataTag, commitTag, data); + if (res < 0) { + opserr << "WARNING PML3DVISCOUS::sendSelf() - " << this->getTag() << " failed to send Vector\n"; + return res; + } + + + // PML3DVISCOUS then sends the tags of its four nodes + res += theChannel.sendID(dataTag, commitTag, connectedExternalNodes); + if (res < 0) { + opserr << "WARNING PML3DVISCOUS::sendSelf() - " << this->getTag() << " failed to send ID\n"; + return res; + } + + return res; +} + +// ======================================================================= +// recvself +// ======================================================================= +int PML3DVISCOUS::recvSelf(int commitTag, + Channel& theChannel, + FEM_ObjectBroker& theBroker) +{ + int res = 0; + + int dataTag = this->getDbTag(); + + // PML3DVISCOUS creates a Vector, receives the Vector and then sets the + // internal data with the data in the Vector + static Vector data(PML3DVISCOUS_NUM_PROPS + 4); + res += theChannel.recvVector(dataTag, commitTag, data); + if (res < 0) { + opserr << "WARNING PML3DVISCOUS::recvSelf() - failed to receive Vector\n"; + return res; + } + + this->setTag((int)data(0)); + + + for (int ii = 1; ii <= PML3DVISCOUS_NUM_PROPS; ii++) { + props[ii - 1] = data(ii); + } + + eta = data(PML3DVISCOUS_NUM_PROPS+1); + beta = data(PML3DVISCOUS_NUM_PROPS+2); + gamma = data(PML3DVISCOUS_NUM_PROPS+3); + + // PML3DVISCOUS now receives the tags of its four external nodes + res += theChannel.recvID(dataTag, commitTag, connectedExternalNodes); + if (res < 0) { + opserr << "WARNING PML3DVISCOUS::recvSelf() - " << this->getTag() << " failed to receive ID\n"; + return res; + } + + return res; +} + + +// ======================================================================= +// display +// ======================================================================= +int PML3DVISCOUS::displaySelf(Renderer& theViewer, int displayMode, float fact, const char** modes, int numMode) +{ + // Get the end point display coords + static Vector v1(3); + static Vector v2(3); + static Vector v3(3); + static Vector v4(3); + static Vector v5(3); + static Vector v6(3); + static Vector v7(3); + static Vector v8(3); + nodePointers[0]->getDisplayCrds(v1, fact, displayMode); + nodePointers[1]->getDisplayCrds(v2, fact, displayMode); + nodePointers[2]->getDisplayCrds(v3, fact, displayMode); + nodePointers[3]->getDisplayCrds(v4, fact, displayMode); + nodePointers[4]->getDisplayCrds(v5, fact, displayMode); + nodePointers[5]->getDisplayCrds(v6, fact, displayMode); + nodePointers[6]->getDisplayCrds(v7, fact, displayMode); + nodePointers[7]->getDisplayCrds(v8, fact, displayMode); + + // place values in coords matrix + static Matrix coords(8, 3); + for (int i = 0; i < 3; i++) { + coords(0, i) = v1(i); + coords(1, i) = v2(i); + coords(2, i) = v3(i); + coords(3, i) = v4(i); + coords(4, i) = v5(i); + coords(5, i) = v6(i); + coords(6, i) = v7(i); + coords(7, i) = v8(i); + } + + // fill RGB vector + static Vector values(8); + for (int i = 0; i < 8; i++) + values(i) = 1.0; + + // draw the cube + return theViewer.drawCube(coords, values, this->getTag()); +} + +// ======================================================================= +// setresponse +// ======================================================================= +Response* PML3DVISCOUS::setResponse(const char** argv, int argc, OPS_Stream& output) +{ + Response* theResponse = 0; + + // char outputData[32]; + + // output.tag("ElementOutput"); + // output.attr("eleType", "PML3DVISCOUS"); + // output.attr("eleTag", this->getTag()); + // for (int i = 1; i <= 8; i++) { + // sprintf(outputData, "node%d", i); + // output.attr(outputData, nodePointers[i - 1]->getTag()); + // } + + // if (strcmp(argv[0], "force") == 0 || strcmp(argv[0], "forces") == 0) { + + // for (int i = 1; i <= 8; i++) { + // sprintf(outputData, "P1_%d", i); + // output.tag("ResponseType", outputData); + // sprintf(outputData, "P2_%d", i); + // output.tag("ResponseType", outputData); + // sprintf(outputData, "P3_%d", i); + // output.tag("ResponseType", outputData); + // } + + // theResponse = new ElementResponse(this, 1, resid); + // } + // output.endTag(); // ElementOutput + return theResponse; +} + +// ======================================================================= +// getresponse +// ======================================================================= +int PML3DVISCOUS::getResponse(int responseID, Information& eleInfo) +{ + // static Vector stresses(48); + + // if (responseID == 1) + // return eleInfo.setVector(this->getResistingForce()); + + return -1; +} + +// ======================================================================= +// set parameter +// ======================================================================= +int PML3DVISCOUS::setParameter(const char** argv, int argc, Parameter& param) +{ + int res = -1; + return res; +} + +// ======================================================================= +// update parameter +// ======================================================================= +int PML3DVISCOUS::updateParameter(int parameterID, Information& info) +{ + int res = -1; + return res; +} + +// ======================================================================= +// print +// ======================================================================= +void PML3DVISCOUS::Print(OPS_Stream &s, int flag) { + + if (flag == OPS_PRINT_CURRENTSTATE) { + s << "Element: " << this->getTag() << endln; + s << "type: PML3DVISCOUS \n"; + s << "Nodes: " << connectedExternalNodes; + s << "eta: " << eta << " beta: " << beta << " gamma: " << gamma << endln; + s << endln; + s << "Resisting Force (no inertia): " << this->getResistingForce(); + } + + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << "\t\t\t{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"PML3DVISCOUS\", "; + s << "\"nodes\": [" << connectedExternalNodes(0) << ", "; + for (int i = 1; i < 7; i++) + s << connectedExternalNodes(i) << ", "; + s << connectedExternalNodes(7) << "], "; + } + return; +} diff --git a/SRC/element/PML/PML3DVISCOUS.h b/SRC/element/PML/PML3DVISCOUS.h new file mode 100644 index 0000000000..7819d56364 --- /dev/null +++ b/SRC/element/PML/PML3DVISCOUS.h @@ -0,0 +1,146 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + + +// Written by: Amin Pakzad, Pedro Arduino (parduino@uw.edu) +// +// Eight node PML3D element .. a c++ wrapper to fortran routine +// provided by Wenyang Zhang (zwyll@ucla.edu), University of California, Los Angeles +// +// University of Washington, UC. Los Angeles, U.C. Berkeley, 12, 2020 + + +#ifndef PML3DVISCOUS_H +#define PML3DVISCOUS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PML3DVISCOUS_NUM_DOF 72 +#define PML3DVISCOUS_NUM_PROPS 12 +#define PML3DVISCOUS_NUM_NODES 8 + +#ifdef _WIN32 + +#define pml3d_ PML_3D + +extern "C" void pml3d_(double* mMatrix, + double* cMatrix, + double* kMatrix, + double* gMatrix, + int* NDOFEL, + double* PROPS, + int* NPROPS, + double* COORDS, + int* MCRD, + int* NNODE); + +#else + +#define pml3d_ pml_3d_ + +extern "C" void pml3d_(double* mMatrix, + double* cMatrix, + double* kMatrix, + double* gMatrix, + double* hMatrix, + int* NDOFEL, + double* PROPS, + double* COORDS, + int* MCRD, + int* NNODE, + int* LFLAGS); + +#endif + +class PML3DVISCOUS : public Element { + +public: + + PML3DVISCOUS(); //null constructor + PML3DVISCOUS(int tag, int* nodeTags, double* newmarks, double* dData); // full constructor + virtual ~PML3DVISCOUS(); //destructor + const char* getClassType(void) const { return "PML3DVISCOUS"; }; //return class type + void setDomain(Domain* theDomain); // set domain + int getNumExternalNodes() const; // get number of external nodes + const ID& getExternalNodes(); // get external nodes + Node** getNodePtrs(void); // get external nodes + int getNumDOF(); // get number of DOF + int commitState(); // commit state + int revertToLastCommit(); // revert to last commit + int revertToStart(); // revert to start + int update(void); // update + void Print(OPS_Stream& s, int flag); // print out element data + const Matrix& getTangentStiff(); // get stiffness matrix + const Matrix& getInitialStiff(); // get initial stiffness matrix + const Matrix& getMass(); // get mass matrix + const Matrix& getDamp(); // get damping matrix + void zeroLoad(); // set residual to 0 + int addLoad(ElementalLoad* theLoad, double loadFactor); // add element loads + const Vector& getResistingForce(); // get residual + const Vector& getResistingForceIncInertia(); // get residual including damping forces + int sendSelf(int commitTag, Channel& theChannel); // send self + int recvSelf(int commitTag, Channel& theChannel, FEM_ObjectBroker & theBroker); // receive self + Response* setResponse(const char** argv, int argc, OPS_Stream& s); // set response + int getResponse(int responseID, Information& eleInformation); // get response + int setParameter(const char** argv, int argc, Parameter& param); + int updateParameter(int parameterID, Information& info); // update parameter + int displaySelf(Renderer&, int mode, float fact, const char** displayModes = 0, int numModes = 0); + +private: + + Domain* Domainptr; // pointer to the domain + double props[PML3DVISCOUS_NUM_PROPS]; // material properties + ID connectedExternalNodes; //eight node numbers + Node* nodePointers[PML3DVISCOUS_NUM_NODES]; //pointers to eight nodes + double K[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // stiffness matrix + double C[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // damping matrix + double M[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // mass matrix + double G[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // G matrix + double H[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // H matrix + double Keff[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // effective stiffness matrix + static double eta; // Newmark parameters: eta + static double beta; // Newmark parameters: beta + static double gamma; // Newmark parameters: gamma + static Matrix tangent; // tangent matrix + static Vector resid; // residual vector + static Matrix mass; // mass matrix + static Matrix damping; // damping matrix + Vector ubart; // ubar at time t + Vector ubarbart; // ubarbar at time t + Vector ubar; // ubar at time t+dt + Vector ubarbar; // ubarbar at time t+dt + static double dt; // time step + int updateflag; // update flag + int update_dt; // flag for updating dt + static int eleCount; // element count + // int innertag; // inner tag + // static int numberOfElements; // number of elements +}; + +#endif + diff --git a/SRC/element/TclElementCommands.cpp b/SRC/element/TclElementCommands.cpp index 944aebb4c6..a614cbc522 100644 --- a/SRC/element/TclElementCommands.cpp +++ b/SRC/element/TclElementCommands.cpp @@ -140,6 +140,7 @@ extern void *OPS_PML2D_3(void); extern void *OPS_PML2D_5(void); extern void *OPS_PML2D_12(void); extern void *OPS_PML2DVISCOUS(void); +extern void *OPS_PML3DVISCOUS(void); extern void *OPS_CorotTruss2(void); extern void *OPS_ZeroLengthImpact3D(void); extern void *OPS_HDR(void); @@ -238,7 +239,7 @@ TclModelBuilder_addJoint2D(ClientData, Tcl_Interp *, int, TCL_Char **, Domain*); extern int TclModelBuilder_addJoint3D(ClientData, Tcl_Interp *, int, TCL_Char **, Domain*, TclModelBuilder *); - + extern int TclModelBuilder_addEnhancedQuad(ClientData, Tcl_Interp *, int, TCL_Char **, Domain*, TclModelBuilder *); @@ -585,8 +586,8 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, ID info; if (OPS_GetNDM() == 2) theEle = (Element *)OPS_PML2DVISCOUS(); - // else - // theEle = (Element *)OPS_PML3DVISCOUS(); + if (OPS_GetNDM() == 3) + theEle = (Element *)OPS_PML3DVISCOUS(); if (theEle != 0) theElement = theEle; else { @@ -598,7 +599,7 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, ID info; if (OPS_GetNDM() == 2) theEle = (Element *)OPS_PML2D(); - else + if (OPS_GetNDM() == 3) theEle = (Element *)OPS_PML3D(); if (theEle != 0) theElement = theEle; @@ -751,7 +752,7 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, else { opserr << "TclElementCommand -- unable to create element of type : " << argv[1] << endln; return TCL_ERROR; - } + } } else if ((strcmp(argv[1],"BeamContact3dp") == 0) || (strcmp(argv[1],"BeamContact3Dp") == 0)) { @@ -937,8 +938,8 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, if (theEle != 0) theElement = (Element *)theEle; else { - opserr << "TclElementCommand -- unable to create element of type : " << argv[1] << endln; - return TCL_ERROR; + opserr << "TclElementCommand -- unable to create element of type : " << argv[1] << endln; + return TCL_ERROR; } } @@ -1026,11 +1027,11 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, void* theEle = OPS_ShellNLDKGTThermal(); if (theEle != 0) theElement = (Element*)theEle; - else { - opserr << "TclElementCommand -- unable to create element of type : " << argv[1] << endln; - return TCL_ERROR; - } - //end of adding thermo-mechanical shell elements by L.Jiang [SIF] + else { + opserr << "TclElementCommand -- unable to create element of type : " << argv[1] << endln; + return TCL_ERROR; + } + //end of adding thermo-mechanical shell elements by L.Jiang [SIF] } else if ((strcmp(argv[1],"shellNL") == 0) || (strcmp(argv[1],"ShellNL") == 0) || (strcmp(argv[1],"shellMITC9") == 0) || (strcmp(argv[1],"ShellMITC9") == 0)) { @@ -1422,7 +1423,7 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, return TCL_ERROR; } } - + else if (strcmp(argv[1], "ASDAbsorbingBoundary2D") == 0) { void *theEle = OPS_ASDAbsorbingBoundary2D(); if (theEle != 0) { @@ -1954,7 +1955,7 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, int result = TclModelBuilder_addJoint3D(clientData, interp, argc, argv, theTclDomain, theTclBuilder); return result; - } + } else if ((strcmp(argv[1],"LehighJoint2D") == 0) || (strcmp(argv[1],"LehighJoint2d") == 0)) { diff --git a/SRC/interpreter/OpenSeesElementCommands.cpp b/SRC/interpreter/OpenSeesElementCommands.cpp index 1956520e0b..689b3ed4b4 100644 --- a/SRC/interpreter/OpenSeesElementCommands.cpp +++ b/SRC/interpreter/OpenSeesElementCommands.cpp @@ -264,6 +264,7 @@ void* OPS_ShellNLDKGQThermal(); void* OPS_ShellNLDKGTThermal(); void* OPS_PipeElement(); void* OPS_CurvedPipeElement(); +void* OPS_PML3DVISCOUS(void); namespace { @@ -382,7 +383,7 @@ namespace { if(ndm == 3) return OPS_E_SFI_MVLEM_3D(); return 0; - } + } static void* OPS_DispBeamColumn() { @@ -466,7 +467,7 @@ namespace { return OPS_BeamColumnJoint3d(); } } - + static void* OPS_FlatSliderBearing() { int ndm = OPS_GetNDM(); @@ -815,6 +816,7 @@ namespace { functionMap.insert(std::make_pair("PML2D_5", &OPS_PML2D_5)); functionMap.insert(std::make_pair("PML2D_12", &OPS_PML2D_12)); functionMap.insert(std::make_pair("PML2DVISCOUS", &OPS_PML2DVISCOUS)); + functionMap.insert(std::make_pair("PML3DVISCOUS", &OPS_PML3DVISCOUS)); functionMap.insert(std::make_pair("ShellNLDKGQThermal", &OPS_ShellNLDKGQThermal)); functionMap.insert(std::make_pair("shellNLDKGQThermal", &OPS_ShellNLDKGQThermal)); functionMap.insert(std::make_pair("ShellNLDKGTThermal", &OPS_ShellNLDKGTThermal)); diff --git a/Win32/proj/element/element.vcxproj b/Win32/proj/element/element.vcxproj index 6564e73d3e..fe65c81d5d 100644 --- a/Win32/proj/element/element.vcxproj +++ b/Win32/proj/element/element.vcxproj @@ -149,7 +149,7 @@ - + @@ -183,6 +183,7 @@ + @@ -438,7 +439,7 @@ - + @@ -472,6 +473,7 @@ + diff --git a/Win32/proj/element/element.vcxproj.filters b/Win32/proj/element/element.vcxproj.filters index 9d5abcfdf8..2a9b740af7 100644 --- a/Win32/proj/element/element.vcxproj.filters +++ b/Win32/proj/element/element.vcxproj.filters @@ -716,7 +716,7 @@ mvlem - + mvlem @@ -966,7 +966,7 @@ PML - PML + PML PML @@ -977,6 +977,9 @@ PML + + PML + mvlem @@ -1501,7 +1504,7 @@ mvlem - + mvlem @@ -1755,13 +1758,16 @@ PML - + PML PML + + PML + mvlem diff --git a/Win64/proj/element/element.vcxproj b/Win64/proj/element/element.vcxproj index f16d7ded2a..08938d509a 100644 --- a/Win64/proj/element/element.vcxproj +++ b/Win64/proj/element/element.vcxproj @@ -294,6 +294,7 @@ + @@ -599,6 +600,7 @@ + diff --git a/Win64/proj/element/element.vcxproj.filters b/Win64/proj/element/element.vcxproj.filters index a5e62fa69e..f88b58fd3e 100644 --- a/Win64/proj/element/element.vcxproj.filters +++ b/Win64/proj/element/element.vcxproj.filters @@ -105,6 +105,7 @@ + @@ -407,6 +408,7 @@ + From 141d078238628f423a8aac6fab4abc174f065bc1 Mon Sep 17 00:00:00 2001 From: amnp95 Date: Wed, 5 Mar 2025 22:08:10 -0600 Subject: [PATCH 028/261] Update element commands to use PML3DVISCOUS for 3D elements --- SRC/element/TclElementCommands.cpp | 2 +- SRC/interpreter/OpenSeesElementCommands.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SRC/element/TclElementCommands.cpp b/SRC/element/TclElementCommands.cpp index a614cbc522..726208c381 100644 --- a/SRC/element/TclElementCommands.cpp +++ b/SRC/element/TclElementCommands.cpp @@ -600,7 +600,7 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, if (OPS_GetNDM() == 2) theEle = (Element *)OPS_PML2D(); if (OPS_GetNDM() == 3) - theEle = (Element *)OPS_PML3D(); + theEle = (Element *)OPS_PML3DVISCOUS(); if (theEle != 0) theElement = theEle; else { diff --git a/SRC/interpreter/OpenSeesElementCommands.cpp b/SRC/interpreter/OpenSeesElementCommands.cpp index 689b3ed4b4..e161c8da70 100644 --- a/SRC/interpreter/OpenSeesElementCommands.cpp +++ b/SRC/interpreter/OpenSeesElementCommands.cpp @@ -595,7 +595,7 @@ namespace { return OPS_PML2D(); } else { - return OPS_PML3D(); + return OPS_PML3DVISCOUS(); } } From 12803ca2e73a573ee4d48e53c476a7bf88760cc1 Mon Sep 17 00:00:00 2001 From: amnp95 Date: Fri, 7 Mar 2025 21:03:00 -0600 Subject: [PATCH 029/261] Add ElasticIsotropicMaterial integration to PML3DVISCOUS and expose material properties --- SRC/element/PML/PML3DVISCOUS.cpp | 936 +++++++++++--- SRC/element/PML/PML3DVISCOUS.h | 49 +- SRC/element/PML/pml_3d.f | 1297 +++++--------------- SRC/material/nD/ElasticIsotropicMaterial.h | 2 + 4 files changed, 1076 insertions(+), 1208 deletions(-) diff --git a/SRC/element/PML/PML3DVISCOUS.cpp b/SRC/element/PML/PML3DVISCOUS.cpp index 9f31942642..7ef4ccf6f8 100644 --- a/SRC/element/PML/PML3DVISCOUS.cpp +++ b/SRC/element/PML/PML3DVISCOUS.cpp @@ -44,11 +44,244 @@ #include #include #include - +#include +#include #include #include #include -#include +#include + + + +void OPS_PML3DVISCOUS_Box(double* boxParams, double* eleCenter, double* Xref, double* Normal) { + // calculate the Xref and Normal for the Box meshType + // boxParams: XC, YC, ZC, L, W, H + // XC, YC, ZC: center of the box at the surface + // L, W, H: length, width, height of the box + Xref[0] = 0.0; + Xref[1] = 0.0; + Xref[2] = 0.0; + Normal[0] = 0.0; + Normal[1] = 0.0; + Normal[2] = 0.0; + double xref, yref, zref, nx, ny, nz; + xref = 0.0; yref = 0.0; zref = 0.0; + nx = 0.0; ny = 0.0; nz = 0.0; + + // calculate the Normal + double widthx = boxParams[3]/2.; + double widthy = boxParams[4]/2.; + double depth = boxParams[5]; + double Xmesh = boxParams[0]; + double Ymesh = boxParams[1]; + double Zmesh = boxParams[2]; + + double x1 = eleCenter[0]; + double x2 = eleCenter[1]; + double x3 = eleCenter[2]; + + int EleType_arg = 0; + + if (x2 < Ymesh - widthy) { + if (x1 < Xmesh - widthx) { + if (x3 < Zmesh - depth) { + EleType_arg = 15; + nx = -1.0; + ny = -1.0; + nz = -1.0; + xref = Xmesh - widthx; + yref = Ymesh - widthy; + zref = Zmesh - depth; + } + else { + EleType_arg = 6; + nx = -1.0; + ny = -1.0; + nz = 0.0; + xref = Xmesh - widthx; + yref = Ymesh - widthy; + zref = Zmesh; + } + } + else if (x1 < Xmesh + widthx) { + if (x3 < Zmesh - depth) { + EleType_arg = 11; + nx = 0.0; + ny = -1.0; + nz = -1.0; + xref = Xmesh; + yref = Ymesh - widthy; + zref = Zmesh - depth; + } + else { + EleType_arg = 2; + nx = 0.0; + ny = -1.0; + nz = 0.0; + xref = Xmesh; + yref = Ymesh - widthy; + zref = Zmesh; + } + } + else { + if (x3 < Zmesh - depth) { + EleType_arg = 16; + nx = 1.0; + ny = -1.0; + nz = -1.0; + xref = Xmesh + widthx; + yref = Ymesh - widthy; + zref = Zmesh - depth; + } + else { + EleType_arg = 7; + nx = 1.0; + ny = -1.0; + nz = 0.0; + xref = Xmesh + widthx; + yref = Ymesh - widthy; + zref = Zmesh; + } + } + } else if (x2 < Ymesh + widthy) { + if (x1 < Xmesh - widthx) { + if (x3 < Zmesh - depth) { + EleType_arg = 14; + nx = -1.0; + ny = 0.0; + nz = -1.0; + xref = Xmesh - widthx; + yref = Ymesh; + zref = Zmesh - depth; + } + else { + EleType_arg = 5; + nx = -1.0; + ny = 0.0; + nz = 0.0; + xref = Xmesh - widthx; + yref = Ymesh; + zref = Zmesh; + } + } + else if (x1 < Xmesh + widthx) { + if (x3 < Zmesh - depth) { + EleType_arg = 10; + nx = 0.0; + ny = 0.0; + nz = -1.0; + xref = Xmesh; + yref = Ymesh; + zref = Zmesh - depth; + } + else { + EleType_arg = 1; + nx = 0.0; + ny = 0.0; + nz = 0.0; + xref = Xmesh; + yref = Ymesh; + zref = Zmesh; + } + } + else { + if (x3 < Zmesh - depth) { + EleType_arg = 12; + nx = 1.0; + ny = 0.0; + nz = -1.0; + xref = Xmesh + widthx; + yref = Ymesh; + zref = Zmesh - depth; + } + else { + EleType_arg = 3; + nx = 1.0; + ny = 0.0; + nz = 0.0; + xref = Xmesh + widthx; + yref = Ymesh; + zref = Zmesh; + } + } + } else { + if (x1 < Xmesh - widthx) { + if (x3 < Zmesh - depth) { + EleType_arg = 18; + nx = -1.0; + ny = 1.0; + nz = -1.0; + xref = Xmesh - widthx; + yref = Ymesh + widthy; + zref = Zmesh - depth; + } + else { + EleType_arg = 9; + nx = -1.0; + ny = 1.0; + nz = 0.0; + xref = Xmesh - widthx; + yref = Ymesh + widthy; + zref = Zmesh; + } + } + else if (x1 < Xmesh + widthx) { + if (x3 < Zmesh - depth) { + EleType_arg = 13; + nx = 0.0; + ny = 1.0; + nz = -1.0; + xref = Xmesh; + yref = Ymesh + widthy; + zref = Zmesh - depth; + } + else { + EleType_arg = 4; + nx = 0.0; + ny = 1.0; + nz = 0.0; + xref = Xmesh; + yref = Ymesh + widthy; + zref = Zmesh; + } + } + else { + if (x3 < Zmesh - depth) { + EleType_arg = 17; + nx = 1.0; + ny = 1.0; + nz = -1.0; + xref = Xmesh + widthx; + yref = Ymesh + widthy; + zref = Zmesh - depth; + } + else { + EleType_arg = 8; + nx = 1.0; + ny = 1.0; + nz = 0.0; + xref = Xmesh + widthx; + yref = Ymesh + widthy; + zref = Zmesh; + } + } + } + + // int tag = 1; + // opserr << "Element Tag: " << tag << "\n"; + // opserr << "Element Type(" << tag << "): " << EleType_arg << "\n"; + // // opserr << "Element Center(" << tag << "): " << elementCenter[0] << " " << elementCenter[1] << " " << elementCenter[2] << "\n"; + // opserr << "Element Reference(" << tag << "): " << xref << " " << yref << " " << zref << "\n"; + // opserr << "Element Normal(" << tag << "): " << nx << " " << ny << " " << nz << "\n"; + + // return the calculated Xref and Normal + Xref[0] = xref; + Xref[1] = yref; + Xref[2] = zref; + Normal[0] = nx; + Normal[1] = ny; + Normal[2] = nz; +} // ======================================================================= @@ -57,9 +290,9 @@ void* OPS_PML3DVISCOUS() { // check if the total number of arguments passed is correct - if (OPS_GetNumRemainingInputArgs() < (9 + PML3DVISCOUS_NUM_PROPS + 3)) { + if (OPS_GetNumRemainingInputArgs() < (11)) { opserr << "WARNING insufficient arguments\n"; - opserr << "Want: element PML3DVISCOUS eleTag? [8 integer nodeTags] [PML3DVISCOUS_NUM_PARAMS material properties]\n"; + opserr << "Want: element PML3DVISCOUS eleTag? Node1? Node2? Node3? Node4? Node5? Node6? Node7? Node 8? matTag? $PMLThickness\n"; return 0; } @@ -70,38 +303,320 @@ void* OPS_PML3DVISCOUS() opserr << "WARNING: invalid integer data : could be the tag or the node numbers \n"; return 0; } + // calculate the number center of the element by averaging the node coordinates + double elementCenter[3] = {0.0, 0.0, 0.0}; + // OPS_GetNodeCrd(int* nodeTag, int* sizeData, double* data); + for (int i = 1; i < 9; i++) { + int nodeTag = idata[i]; + double nodeCoord[3] = {0.0, 0.0, 0.0}; + num = 3; + if (OPS_GetNodeCrd(&nodeTag, &num, nodeCoord) < 0) { + opserr << "WARNING: invalid node tag: " << nodeTag << endln; + return 0; + } + for (int j = 0; j < 3; j++) { + elementCenter[j] += nodeCoord[j]; + } + } + for (int j = 0; j < 3; j++) { + elementCenter[j] /= 8; + } + + + // get the material tag + int matTag; + num = 1; + if (OPS_GetIntInput(&num, &matTag) < 0) { + opserr << "WARNING: invalid integer data: could be the material tag\n"; + return 0; + } + + NDMaterial* mat = OPS_GetNDMaterial(matTag); + if (mat == 0) { + opserr << "WARNING material not found\n"; + opserr << "material tag: " << matTag; + opserr << "\nPML3DVISCOUS element: " << idata[0] << endln; + } + // check if the material is "ElasticIsotropicMaterial" + if (strcmp(mat->getClassType(), "ElasticIsotropicMaterial") != 0) { + opserr << "Error: PML3DVISCOUS element only supports ElasticIsotropicMaterial\n"; + opserr << "\tMaterial provided is of type: " << mat->getClassType() << endln; + return 0; + } + + // cast the material to ElasticIsotropicMaterial + ElasticIsotropicMaterial* Elasmat = (ElasticIsotropicMaterial*)mat; + + double E = Elasmat->getElasticModulus(); + double nu = Elasmat->getPoissonsRatio(); + double rho = Elasmat->getRho(); + + + + // get the PML thickness + double PMLThickness; + num = 1; + if (OPS_GetDoubleInput(&num, &PMLThickness) < 0) { + opserr << "WARNING: invalid double data: could be the PMLThickness\n"; + return 0; + } + + - // reading Newmark parameters - double Newmark[3]; - num = 3; - if (OPS_GetDoubleInput(&num, Newmark) < 0) { - opserr << "WARNING: invalid double data: could be Newmark parameters\n"; + // reading the meshType string and it related parameters + num = 1; + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "Error: need meshType\n"; + opserr << "meshType could be: \"General\", \"Box\", \"Sphere\", \"Cylinder\"\n"; return 0; } + double Xref[3]={0.0, 0.0, 0.0}; // double Normal[] + double Normal[3]={0.0, 0.0, 0.0}; // double Normal[] + + const char* meshType = OPS_GetString(); + if (strcmp(meshType, "General") == 0) { + // reading the meshType string and it related parameters + // this meshType needs to read the following parameters + // Xref, Yref, Zref, N1, N2, N3 + num = 6; + if (OPS_GetNumRemainingInputArgs() < 6) { + opserr << "Error: need meshType parameters\n"; + opserr << "meshType parameters: Xref, Yref, Zref, N1, N2, N3\n"; + return 0; + } + num = 3; + if (OPS_GetDoubleInput(&num, Xref) < 0) { + opserr << "WARNING: invalid double data: could be Xref, Yref, Zref\n"; + return 0; + } - // reading material properties - double dData[PML3DVISCOUS_NUM_PROPS]; num = PML3DVISCOUS_NUM_PROPS; - if (OPS_GetDoubleInput(&num, dData) < 0) { - opserr << "WARNING: invalid double data\n"; + num = 3; + if (OPS_GetDoubleInput(&num, Normal) < 0) { + opserr << "WARNING: invalid double data: could be N1, N2, N3\n"; + return 0; + } + } + else if (strcmp(meshType, "Box") == 0 || strcmp(meshType, "box") == 0) { + // reading the meshType string and it related parameters + // this meshType needs to read the following parameters + // XC, YC, ZC, L, W, H + // XC, YC, ZC: center of the box at the surface + // L, W, H: length, width, height of the box + num = 6; + if (OPS_GetNumRemainingInputArgs() < 6) { + opserr << "Error: need meshType parameters\n"; + opserr << "meshType parameters: XC, YC, ZC, L, W, H\n"; + return 0; + } + double boxParams[6]; + num = 6; + if (OPS_GetDoubleInput(&num, boxParams) < 0) { + opserr << "WARNING: invalid double data: could be XC, YC, ZC, L, W, H\n"; + return 0; + } + // call the helper function to calculate the Xref and Normal + OPS_PML3DVISCOUS_Box(boxParams, elementCenter, Xref, Normal); + } + else if (strcmp(meshType, "Sphere") == 0 || strcmp(meshType, "sphere") == 0) { + // reading the meshType string and it related parameters + // this meshType needs to read the following parameters + // XC, YC, ZC, R + // XC, YC, ZC: center of the sphere at the surface + // R: radius of the sphere + num = 4; + if (OPS_GetNumRemainingInputArgs() < 4) { + opserr << "Error: need meshType parameters\n"; + opserr << "meshType parameters: XC, YC, ZC, R\n"; + return 0; + } + double sphereParams[4]; + num = 4; + if (OPS_GetDoubleInput(&num, sphereParams) < 0) { + opserr << "WARNING: invalid double data: could be XC, YC, ZC, R\n"; + return 0; + } + // call the helper function to calculate the Xref and Normal + // not implemented yet + opserr << "Error: Sphere meshType not implemented yet\n"; return 0; } + else if (strcmp(meshType, "Cylinder") == 0 || strcmp(meshType, "cylinder") == 0) { + // reading the meshType string and it related parameters + // this meshType needs to read the following parameters + // XC, YC, ZC, R, H, dir + // XC, YC, ZC: center of the cylinder at the surface + // R: radius of the cylinder + // H: height of the cylinder + // dir: direction of the cylinder + num = 6; + if (OPS_GetNumRemainingInputArgs() < 6) { + opserr << "Error: need meshType parameters\n"; + opserr << "meshType parameters: XC, YC, ZC, R, H, dir\n"; + return 0; + } + double cylinderParams[6]; + num = 6; + if (OPS_GetDoubleInput(&num, cylinderParams) < 0) { + opserr << "WARNING: invalid double data: could be XC, YC, ZC, R, H, dir\n"; + return 0; + } + // call the helper function to calculate the Xref and Normal + // not implemented yet + opserr << "Error: Cylinder meshType not implemented yet\n"; + return 0; + } + else { + opserr << "Error: meshType not recognized\n"; + opserr << "meshType could be: \"General\", \"Box\", \"Sphere\", \"Cylinder\"\n"; + return 0; + } + // cp_ref = SQRT(E *(1.d0-xnu)/rho/(1.d0+xnu)/(1.d0-2.d0*xnu)) + double Cp = sqrt(E * (1.0 - nu) / rho / (1.0 + nu) / (1.0 - 2.0 * nu)); + double m_coeff = 2.0; + double R = 1.0e-8; + double PML_b = PMLThickness / 1.0; + double alpha_0 = 0.0; + double beta_0 = 0.0; + bool ExplicitAlphaBeta = false; + double gamma = 0.5; + double beta = 0.25; + double eta = 1.0/12.0; + double keisi = 1.0/48.0; + + // now iterate overe the remaining arguments to read optional parameters + while (OPS_GetNumRemainingInputArgs() > 0) { + const char* option = OPS_GetString(); + if (strcmp(option, "-Newmark") == 0 || strcmp(option, "-newmark") == 0) { + // reading Newmark parameters + double Newmark[4]; + num = 4; + if (OPS_GetDoubleInput(&num, Newmark) < 0) { + opserr << "WARNING: invalid double data: could be Newmark parameters\n"; + opserr << "Newmark parameters: gamma, beta, dt, alpha_f\n"; + return 0; + } + gamma = Newmark[0]; + beta = Newmark[1]; + eta = Newmark[2]; + keisi = Newmark[3]; + } + else if (strcmp(option, "-Cp") == 0 || strcmp(option, "-cp") == 0) { + // reading the PML parameters + num = 1; + if (OPS_GetDoubleInput(&num, &Cp) < 0) { + opserr << "WARNING: invalid double data: could be Cp\n"; + return 0; + } + } + else if (strcmp(option, "-m") == 0 || strcmp(option, "-M") == 0) { + // reading the PML parameters + num = 1; + if (OPS_GetDoubleInput(&num, &m_coeff) < 0) { + opserr << "WARNING: invalid double data: could be m\n"; + return 0; + } + } + else if (strcmp(option, "-R") == 0 || strcmp(option, "-r") == 0) { + // reading the PML parameters + num = 1; + if (OPS_GetDoubleInput(&num, &R) < 0) { + opserr << "WARNING: invalid double data: could be R\n"; + return 0; + } + } + else if (strcmp(option, "-alphabeta") == 0) { + // reading the PML parameters + double alphabeta[2]; + num = 2; + if (OPS_GetDoubleInput(&num, alphabeta) < 0) { + opserr << "WARNING: invalid double data: could be alphabeta\n"; + return 0; + } + alpha_0 = alphabeta[0]; + beta_0 = alphabeta[1]; + ExplicitAlphaBeta = true; + } + else { + opserr << "WARNING: unknown option: " << option << endln; + return 0; + } + } + + + if (!ExplicitAlphaBeta) { + + alpha_0 = ((m_coeff + 1) * PML_b) / (2.0 * PML_b)*log10(1.0 / R); + beta_0 = ((m_coeff + 1) * Cp) / (2.0 * PML_b)*log10(1.0 / R); + } else { + opserr << "Warning: PML Element(" << idata[0] << ") is using user defined alpha and beta\n"; + } + + // opserr << "PML3DVISCOUS element, tag: " << idata[0] << endln; + // opserr << "Node 1: " << idata[1] << endln; + // opserr << "Node 2: " << idata[2] << endln; + // opserr << "Node 3: " << idata[3] << endln; + // opserr << "Node 4: " << idata[4] << endln; + // opserr << "Node 5: " << idata[5] << endln; + // opserr << "Node 6: " << idata[6] << endln; + // opserr << "Node 7: " << idata[7] << endln; + // opserr << "Node 8: " << idata[8] << endln; + // opserr << "Element center: " << elementCenter[0] << ", " << elementCenter[1] << ", " << elementCenter[2] << endln; + // opserr << "PML Thickness: " << PMLThickness << endln; + // opserr << "Material tag: " << matTag << endln; + // opserr << "Material type: " << mat->getClassType() << endln; + // opserr << "Material information: " << endln; + // opserr << "\t E: " << E << endln; + // opserr << "\t nu: " << nu << endln; + // opserr << "\t rho: " << rho << endln; + // opserr << "Mesh Type: " << meshType << endln; + // opserr << "Xref: " << Xref[0] << ", " << Xref[1] << ", " << Xref[2] << endln; + // opserr << "Normal: " << Normal[0] << ", " << Normal[1] << ", " << Normal[2] << endln; + // opserr << "Cp: " << Cp << endln; + // opserr << "m: " << m_coeff << endln; + // opserr << "R: " << R << endln; + // opserr << "alpha_0: " << alpha_0 << endln; + // opserr << "beta_0: " << beta_0 << endln; + // opserr << "ExplicitAlphaBeta: " << ExplicitAlphaBeta << endln; + - // create a new PML3DVISCOUS element and add it to the Domain - return new PML3DVISCOUS(idata[0], &idata[1], Newmark, dData); + return new PML3DVISCOUS(idata[0], &idata[1], + Elasmat, PMLThickness, + Xref, Normal, + alpha_0, beta_0, ExplicitAlphaBeta, + Cp, m_coeff, R, + gamma, beta, eta, keisi); } + // ======================================================================= // static data // ======================================================================= -Matrix PML3DVISCOUS::tangent(PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); -Matrix PML3DVISCOUS::mass(PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); -Matrix PML3DVISCOUS::damping(PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); -Vector PML3DVISCOUS::resid(PML3DVISCOUS_NUM_DOF); -double PML3DVISCOUS::eta = 0.; -double PML3DVISCOUS::beta = 0.; double PML3DVISCOUS::gamma = 0.; +double PML3DVISCOUS::beta = 0.; +double PML3DVISCOUS::eta = 0.; +double PML3DVISCOUS::keisi = 0.; double PML3DVISCOUS::dt = 0.; int PML3DVISCOUS::eleCount = 0; +int PML3DVISCOUS::ComputedEleTag = -1; + +double PML3DVISCOUS::M[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF] = {0}; +double PML3DVISCOUS::C[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF] = {0}; +double PML3DVISCOUS::K[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF] = {0}; +double PML3DVISCOUS::G[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF] = {0}; +double PML3DVISCOUS::H[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF] = {0}; +double PML3DVISCOUS::Keff[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF] = {0}; + + +// Matrix PML3DVISCOUS::tangent(PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); +// Matrix PML3DVISCOUS::mass(PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); +// Matrix PML3DVISCOUS::damping(PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); +Matrix PML3DVISCOUS::tangent(K, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); +Matrix PML3DVISCOUS::mass(M, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); +Matrix PML3DVISCOUS::damping(C, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); +Matrix PML3DVISCOUS::Gmat(G, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); +Matrix PML3DVISCOUS::Hmat(H, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); +Matrix PML3DVISCOUS::keffmat(Keff, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); +Vector PML3DVISCOUS::resid(PML3DVISCOUS_NUM_DOF); // int PML3DVISCOUS::numberOfElements = 0; @@ -126,26 +641,57 @@ PML3DVISCOUS::PML3DVISCOUS() ubarbart.Zero(); updateflag = 0; update_dt = 0; - eta = 0; - beta = 0; gamma = 0; - + beta = 0; + eta = 0; + keisi = 0; + tangent.Zero(); + mass.Zero(); + damping.Zero(); + Gmat.Zero(); + Hmat.Zero(); + keffmat.Zero(); + theMaterial = 0; + PML_L = 0; + cp_ref = 0; + m_coeff = 0; + R_coeff = 0; + alpha0 = 0; + beta0 = 0; + ExplicitAlphaBeta = false; + + } // ======================================================================= // Full constructor // ======================================================================= -PML3DVISCOUS::PML3DVISCOUS(int tag, int* nodeTags, double* nemwarks, double* eleData) - :Element(tag, ELE_TAG_PML3DVISCOUS), +PML3DVISCOUS::PML3DVISCOUS(int tag, int* nodeTags, + ElasticIsotropicMaterial* theMat, + double PMLThickness, + double* Xref, double* Normal, + double alpha_0, double beta_0, bool explicitAB, + double Cp, double m_coeff, double R, + double gammaN, double betaN, double etaN, double keisiN + ):Element(tag, ELE_TAG_PML3DVISCOUS), connectedExternalNodes(PML3DVISCOUS_NUM_NODES), ubar(PML3DVISCOUS_NUM_DOF), ubart(PML3DVISCOUS_NUM_DOF), ubarbar(PML3DVISCOUS_NUM_DOF), - ubarbart(PML3DVISCOUS_NUM_DOF) + ubarbart(PML3DVISCOUS_NUM_DOF), + theMaterial(theMat), PML_L(PMLThickness), + cp_ref(Cp), m_coeff(m_coeff), R_coeff(R), + alpha0(alpha_0), beta0(beta_0), ExplicitAlphaBeta(explicitAB) { eleCount++; if (eleCount == 1) { - opserr << "Perfectly Matched Layer 3D (PMLVISCOUS) element - Written: W. Zhang, E. Taciroglu, A. Pakzad, P. Arduino, UCLA, UCLA, U.Washington, U.Washington\n "; + opserr << "Perfectly Matched Layer 3D (PMLVISCOUS) element - Written: W. Zhang, E. Taciroglu, A. Pakzad, P. Arduino, UCLA, U.Washington\n "; + tangent.Zero(); + mass.Zero(); + damping.Zero(); + Gmat.Zero(); + Hmat.Zero(); + keffmat.Zero(); } // initialize node pointers for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) { @@ -154,13 +700,10 @@ PML3DVISCOUS::PML3DVISCOUS(int tag, int* nodeTags, double* nemwarks, double* ele } // initialize Newmark parameters - eta = nemwarks[0]; - beta = nemwarks[1]; - gamma = nemwarks[2]; - - // initialize material properties - for (int i = 0; i < PML3DVISCOUS_NUM_PROPS; i++) - props[i] = eleData[i]; + gamma = gammaN; + beta = betaN; + eta = etaN; + keisi = keisiN; // initialize the ubar and ubart vectors to zero ubart.Zero(); @@ -169,6 +712,56 @@ PML3DVISCOUS::PML3DVISCOUS(int tag, int* nodeTags, double* nemwarks, double* ele ubarbart.Zero(); updateflag = 0; update_dt = 0; + + + xref = Xref[0]; + yref = Xref[1]; + zref = Xref[2]; + + nx = Normal[0]; + ny = Normal[1]; + nz = Normal[2]; + + // print out the information + // opserr << "PML3DVISCOUS element, tag: " << this->getTag() << endln; + // opserr << "Node 1: " << connectedExternalNodes(0) << endln; + // opserr << "Node 2: " << connectedExternalNodes(1) << endln; + // opserr << "Node 3: " << connectedExternalNodes(2) << endln; + // opserr << "Node 4: " << connectedExternalNodes(3) << endln; + // opserr << "Node 5: " << connectedExternalNodes(4) << endln; + // opserr << "Node 6: " << connectedExternalNodes(5) << endln; + // opserr << "Node 7: " << connectedExternalNodes(6) << endln; + // opserr << "Node 8: " << connectedExternalNodes(7) << endln; + // opserr << "PML Thickness: " << PML_L << endln; + // opserr << "Material tag: " << theMaterial->getTag() << endln; + // opserr << "Material type: " << theMaterial->getClassType() << endln; + // opserr << "Material information: " << endln; + // opserr << "\t E: " << theMaterial->getElasticModulus() << endln; + // opserr << "\t nu: " << theMaterial->getPoissonsRatio() << endln; + // opserr << "\t rho: " << theMaterial->getRho() << endln; + // opserr << "Xref: " << xref << ", " << yref << ", " << zref << endln; + // opserr << "Normal: " << nx << ", " << ny << ", " << nz << endln; + // opserr << "Cp: " << cp_ref << endln; + // opserr << "m: " << m_coeff << endln; + // opserr << "R: " << R_coeff << endln; + // opserr << "alpha_0: " << alpha0 << endln; + // opserr << "beta_0: " << beta0 << endln; + // if (ExplicitAlphaBeta) { + // opserr << "ExplicitAlphaBeta: " << "True" << endln; + // } else { + // opserr << "ExplicitAlphaBeta: " << "False" << endln; + // } + // opserr << "Newmark parameters: " << endln; + // opserr << "\t gamma: " << gamma << endln; + // opserr << "\t beta: " << beta << endln; + // opserr << "\t eta: " << eta << endln; + // opserr << "\t keisi: " << keisi << endln; + // opserr << "Rayleigh Damping parameters: " << endln; + // opserr << "\t alphaM: " << alphaM << endln; + // opserr << "\t betaK: " << betaK << endln; + // opserr << "\t betaK0: " << betaK0 << endln; + // opserr << "\t betaKc: " << betaKc << endln; + } // ======================================================================= @@ -192,15 +785,19 @@ void PML3DVISCOUS::setDomain(Domain* theDomain) nodePointers[i] = theDomain->getNode(connectedExternalNodes(i)); this->DomainComponent::setDomain(theDomain); - - // create the coordinate vectors - double coords[PML3DVISCOUS_NUM_DOF]; for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) { const Vector& loc = nodePointers[i]->getCrds(); coords[i * 3] = loc(0); coords[i * 3 + 1] = loc(1); coords[i * 3 + 2] = loc(2); } +} +// ======================================================================= +// Calculate the matricies +// ======================================================================= +void PML3DVISCOUS::calculateMatrices() +{ + // create the coordinate vectors int NDOFEL = PML3DVISCOUS_NUM_DOF; int NPROPS = 13; int MCRD = 3; @@ -213,79 +810,32 @@ void PML3DVISCOUS::setDomain(Domain* theDomain) G[i] = 0.0; H[i] = 0.0; } - pml3d_(M, C, K, G, H, &NDOFEL, props, coords, &MCRD, &NNODE, &LFLAGS); - dt = theDomain->getDT(); - // // make C zero - for (int i = 0; i < PML3DVISCOUS_NUM_DOF*PML3DVISCOUS_NUM_DOF; i++) { - // C[i] = 0.0; - // K[i] = 0.0; - // M[i] = 0.0; - // G[i] = 0.0; - // H[i] = 0.0; - } + double betarayleigh = (betaK0 > betaK) ? betaK0 : betaK; + betarayleigh = (betaKc > betarayleigh) ? betaKc : betarayleigh; + double props[16]; + props[0] = theMaterial->getElasticModulus(); + props[1] = theMaterial->getPoissonsRatio(); + props[2] = theMaterial->getRho(); + props[3] = 6.0; + props[4] = PML_L; + props[5] = xref; + props[6] = yref; + props[7] = zref; + props[8] = nx; + props[9] = ny; + props[10] = nz; + props[11] = alpha0; + props[12] = beta0; + props[13] = alphaM; + props[14] = betarayleigh; + props[15] = m_coeff; + + pml3d_(M, C, K, G, H, &NDOFEL, props, coords, &MCRD, &NNODE, &LFLAGS); + ComputedEleTag = this->getTag(); +} - std::ofstream myfile; - std::string filename; - int tag = this->getTag(); - - // // save M matrix in a file - // filename = "./PML/M" + std::to_string(tag) + ".mat"; - // myfile.open(filename); - // for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { - // for (int j = 0; j < PML3DVISCOUS_NUM_DOF; j++) { - // myfile << M[i*PML3DVISCOUS_NUM_DOF + j] << " "; - // } - // myfile << "\n"; - // } - // myfile.close(); - - // // save C matrix in a file - // filename = "./PML/C" + std::to_string(tag) + ".mat"; - // myfile.open(filename); - // for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { - // for (int j = 0; j < PML3DVISCOUS_NUM_DOF; j++) { - // myfile << C[i*PML3DVISCOUS_NUM_DOF + j] << " "; - // } - // myfile << "\n"; - // } - // myfile.close(); - - // // save K matrix in a file - // filename = "./PML/K" + std::to_string(tag) + ".mat"; - // myfile.open(filename); - // for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { - // for (int j = 0; j < PML3DVISCOUS_NUM_DOF; j++) { - // myfile << K[i*PML3DVISCOUS_NUM_DOF + j] << " "; - // } - // myfile << "\n"; - // } - // myfile.close(); - - // // save G matrix in a file - // filename = "./PML/G" + std::to_string(tag) + ".mat"; - // myfile.open(filename); - // for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { - // for (int j = 0; j < PML3DVISCOUS_NUM_DOF; j++) { - // myfile << G[i*PML3DVISCOUS_NUM_DOF + j] << " "; - // } - // myfile << "\n"; - // } - // myfile.close(); - - // save H matrix in a file - // filename = "./PML/H" + std::to_string(tag) + ".mat"; - // myfile.open(filename); - // for (int i = 0; i < PML3DVISCOUS_NUM_DOF; i++) { - // for (int j = 0; j < PML3DVISCOUS_NUM_DOF; j++) { - // myfile << H[i*PML3DVISCOUS_NUM_DOF + j] << " "; - // } - // myfile << "\n"; - // } - // myfile.close(); - -} // ======================================================================= // update @@ -311,8 +861,6 @@ int PML3DVISCOUS::update(void) } } - double keisi = 1.0/48.0; - loc = 0; c1 = dt; c2 = dt * dt * 0.5; @@ -338,16 +886,18 @@ int PML3DVISCOUS::update(void) // ======================================================================= const Matrix& PML3DVISCOUS::getTangentStiff() { + if (ComputedEleTag != this->getTag()) { + this->calculateMatrices(); + } + // check if the dt is changed to update the tangent stiffness matrix double cg = eta*dt/beta; - double keisi = 1.0/48.0; double ch = dt * dt * keisi/beta; //keff = k + cg*g( k and g are symmetric matrices) for (int i = 0; i < PML3DVISCOUS_NUM_DOF*PML3DVISCOUS_NUM_DOF; i++) { Keff[i] = K[i] + cg*G[i] + ch*H[i]; } - tangent.setData(Keff, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); - return tangent; + return keffmat; } // ======================================================================= @@ -363,8 +913,9 @@ const Matrix& PML3DVISCOUS::getInitialStiff() // ======================================================================= const Matrix& PML3DVISCOUS::getMass() { - mass.setData(M, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); - // mass.Zero(); + if (ComputedEleTag != this->getTag()) { + this->calculateMatrices(); + } return mass; } @@ -373,8 +924,9 @@ const Matrix& PML3DVISCOUS::getMass() // ======================================================================= const Matrix& PML3DVISCOUS::getDamp() { - damping.setData(C, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); - // damping.Zero(); + if (ComputedEleTag != this->getTag()) { + this->calculateMatrices(); + } return damping; } @@ -384,14 +936,12 @@ const Matrix& PML3DVISCOUS::getDamp() //get residual const Vector& PML3DVISCOUS::getResistingForce() { - // if (innertag==14) { - // opserr << "getResistingForce function is called\n"; - // } + if (ComputedEleTag != this->getTag()) { + this->calculateMatrices(); + } int numNodalDOF = 9; static Vector theVector(PML3DVISCOUS_NUM_DOF); - // get K into stiff - tangent.setData(K, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); // // perform: R = K * u @@ -415,9 +965,11 @@ const Vector& PML3DVISCOUS::getResistingForce() const Vector& PML3DVISCOUS::getResistingForceIncInertia() { + if (ComputedEleTag != this->getTag()) { + this->calculateMatrices(); + } // R += K*u static Vector theVector(PML3DVISCOUS_NUM_DOF); - tangent.setData(K, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); int loc = 0; for (int i = 0; i < PML3DVISCOUS_NUM_NODES; i++) { @@ -438,7 +990,7 @@ PML3DVISCOUS::getResistingForceIncInertia() theVector(loc++) = acc(j); } } - resid.addMatrixVector(1.0, this->getMass(), theVector, 1.0); + resid.addMatrixVector(1.0, mass, theVector, 1.0); // R += C*v loc = 0; @@ -448,18 +1000,14 @@ PML3DVISCOUS::getResistingForceIncInertia() theVector(loc++) = vel[j]; } } - resid.addMatrixVector(1.0, this->getDamp(), theVector, 1.0); + resid.addMatrixVector(1.0, damping, theVector, 1.0); // R += G*ubar - tangent.setData(G, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); - resid.addMatrixVector(1.0, tangent, ubar, 1.0); + resid.addMatrixVector(1.0, Gmat, ubar, 1.0); // R += H*ubarbar - tangent.setData(H, PML3DVISCOUS_NUM_DOF, PML3DVISCOUS_NUM_DOF); - resid.addMatrixVector(1.0, tangent, ubarbar, 1.0); - - + resid.addMatrixVector(1.0, Hmat, ubarbar, 1.0); return resid; } @@ -570,40 +1118,41 @@ void PML3DVISCOUS::zeroLoad() int PML3DVISCOUS::sendSelf(int commitTag, Channel& theChannel) { - int res = 0; - - // note: we don't check for dataTag == 0 for Element - // objects as that is taken care of in a commit by the Domain - // object - don't want to have to do the check if sending data - int dataTag = this->getDbTag(); + return 0; + // int res = 0; - // PML3DVISCOUS packs its data into a Vector and sends this to theChannel - // along with its dbTag and the commitTag passed in the arguments - static Vector data(PML3DVISCOUS_NUM_PROPS + 4); - data(0) = this->getTag(); + // // note: we don't check for dataTag == 0 for Element + // // objects as that is taken care of in a commit by the Domain + // // object - don't want to have to do the check if sending data + // int dataTag = this->getDbTag(); - for (int ii = 1; ii <= PML3DVISCOUS_NUM_PROPS; ii++) { - data(ii) = props[ii - 1]; - } - data(PML3DVISCOUS_NUM_PROPS+1) = eta; - data(PML3DVISCOUS_NUM_PROPS+2) = beta; - data(PML3DVISCOUS_NUM_PROPS+3) = gamma; + // // PML3DVISCOUS packs its data into a Vector and sends this to theChannel + // // along with its dbTag and the commitTag passed in the arguments + // static Vector data(PML3DVISCOUS_NUM_PROPS + 4); + // data(0) = this->getTag(); - res += theChannel.sendVector(dataTag, commitTag, data); - if (res < 0) { - opserr << "WARNING PML3DVISCOUS::sendSelf() - " << this->getTag() << " failed to send Vector\n"; - return res; - } + // for (int ii = 1; ii <= PML3DVISCOUS_NUM_PROPS; ii++) { + // data(ii) = props[ii - 1]; + // } + // data(PML3DVISCOUS_NUM_PROPS+1) = eta; + // data(PML3DVISCOUS_NUM_PROPS+2) = beta; + // data(PML3DVISCOUS_NUM_PROPS+3) = gamma; + + // res += theChannel.sendVector(dataTag, commitTag, data); + // if (res < 0) { + // opserr << "WARNING PML3DVISCOUS::sendSelf() - " << this->getTag() << " failed to send Vector\n"; + // return res; + // } - // PML3DVISCOUS then sends the tags of its four nodes - res += theChannel.sendID(dataTag, commitTag, connectedExternalNodes); - if (res < 0) { - opserr << "WARNING PML3DVISCOUS::sendSelf() - " << this->getTag() << " failed to send ID\n"; - return res; - } + // // PML3DVISCOUS then sends the tags of its four nodes + // res += theChannel.sendID(dataTag, commitTag, connectedExternalNodes); + // if (res < 0) { + // opserr << "WARNING PML3DVISCOUS::sendSelf() - " << this->getTag() << " failed to send ID\n"; + // return res; + // } - return res; + // return res; } // ======================================================================= @@ -613,38 +1162,39 @@ int PML3DVISCOUS::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker) { - int res = 0; + return 0; + // int res = 0; - int dataTag = this->getDbTag(); + // int dataTag = this->getDbTag(); - // PML3DVISCOUS creates a Vector, receives the Vector and then sets the - // internal data with the data in the Vector - static Vector data(PML3DVISCOUS_NUM_PROPS + 4); - res += theChannel.recvVector(dataTag, commitTag, data); - if (res < 0) { - opserr << "WARNING PML3DVISCOUS::recvSelf() - failed to receive Vector\n"; - return res; - } + // // PML3DVISCOUS creates a Vector, receives the Vector and then sets the + // // internal data with the data in the Vector + // static Vector data(PML3DVISCOUS_NUM_PROPS + 4); + // res += theChannel.recvVector(dataTag, commitTag, data); + // if (res < 0) { + // opserr << "WARNING PML3DVISCOUS::recvSelf() - failed to receive Vector\n"; + // return res; + // } - this->setTag((int)data(0)); + // this->setTag((int)data(0)); - for (int ii = 1; ii <= PML3DVISCOUS_NUM_PROPS; ii++) { - props[ii - 1] = data(ii); - } + // for (int ii = 1; ii <= PML3DVISCOUS_NUM_PROPS; ii++) { + // props[ii - 1] = data(ii); + // } - eta = data(PML3DVISCOUS_NUM_PROPS+1); - beta = data(PML3DVISCOUS_NUM_PROPS+2); - gamma = data(PML3DVISCOUS_NUM_PROPS+3); + // eta = data(PML3DVISCOUS_NUM_PROPS+1); + // beta = data(PML3DVISCOUS_NUM_PROPS+2); + // gamma = data(PML3DVISCOUS_NUM_PROPS+3); - // PML3DVISCOUS now receives the tags of its four external nodes - res += theChannel.recvID(dataTag, commitTag, connectedExternalNodes); - if (res < 0) { - opserr << "WARNING PML3DVISCOUS::recvSelf() - " << this->getTag() << " failed to receive ID\n"; - return res; - } + // // PML3DVISCOUS now receives the tags of its four external nodes + // res += theChannel.recvID(dataTag, commitTag, connectedExternalNodes); + // if (res < 0) { + // opserr << "WARNING PML3DVISCOUS::recvSelf() - " << this->getTag() << " failed to receive ID\n"; + // return res; + // } - return res; + // return res; } @@ -672,16 +1222,16 @@ int PML3DVISCOUS::displaySelf(Renderer& theViewer, int displayMode, float fact, nodePointers[7]->getDisplayCrds(v8, fact, displayMode); // place values in coords matrix - static Matrix coords(8, 3); + static Matrix Coords(8, 3); for (int i = 0; i < 3; i++) { - coords(0, i) = v1(i); - coords(1, i) = v2(i); - coords(2, i) = v3(i); - coords(3, i) = v4(i); - coords(4, i) = v5(i); - coords(5, i) = v6(i); - coords(6, i) = v7(i); - coords(7, i) = v8(i); + Coords(0, i) = v1(i); + Coords(1, i) = v2(i); + Coords(2, i) = v3(i); + Coords(3, i) = v4(i); + Coords(4, i) = v5(i); + Coords(5, i) = v6(i); + Coords(6, i) = v7(i); + Coords(7, i) = v8(i); } // fill RGB vector @@ -690,7 +1240,7 @@ int PML3DVISCOUS::displaySelf(Renderer& theViewer, int displayMode, float fact, values(i) = 1.0; // draw the cube - return theViewer.drawCube(coords, values, this->getTag()); + return theViewer.drawCube(Coords, values, this->getTag()); } // ======================================================================= diff --git a/SRC/element/PML/PML3DVISCOUS.h b/SRC/element/PML/PML3DVISCOUS.h index 7819d56364..31424008e9 100644 --- a/SRC/element/PML/PML3DVISCOUS.h +++ b/SRC/element/PML/PML3DVISCOUS.h @@ -39,6 +39,7 @@ #include #include #include +#include #define PML3DVISCOUS_NUM_DOF 72 #define PML3DVISCOUS_NUM_PROPS 12 @@ -82,7 +83,14 @@ class PML3DVISCOUS : public Element { public: PML3DVISCOUS(); //null constructor - PML3DVISCOUS(int tag, int* nodeTags, double* newmarks, double* dData); // full constructor + // PML3DVISCOUS(int tag, int* nodeTags, double* newmarks, double* dData); // full constructor + PML3DVISCOUS(int tag, int* nodeTags, + ElasticIsotropicMaterial* theMat, double PMLThickness, + double* Xref, double* Normal, + double alpha_0, double beta_0, bool explicitAB, + double Cp, double m_coeff, double R, + double gammaN, double betaN, double etaN, double keisiN); // full constructor + virtual ~PML3DVISCOUS(); //destructor const char* getClassType(void) const { return "PML3DVISCOUS"; }; //return class type void setDomain(Domain* theDomain); // set domain @@ -112,24 +120,28 @@ class PML3DVISCOUS : public Element { int displaySelf(Renderer&, int mode, float fact, const char** displayModes = 0, int numModes = 0); private: - + void calculateMatrices(); // calculate matrices method Domain* Domainptr; // pointer to the domain - double props[PML3DVISCOUS_NUM_PROPS]; // material properties + // double props[PML3DVISCOUS_NUM_PROPS]; // material properties ID connectedExternalNodes; //eight node numbers Node* nodePointers[PML3DVISCOUS_NUM_NODES]; //pointers to eight nodes - double K[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // stiffness matrix - double C[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // damping matrix - double M[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // mass matrix - double G[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // G matrix - double H[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // H matrix - double Keff[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // effective stiffness matrix - static double eta; // Newmark parameters: eta + static double K[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // stiffness matrix + static double C[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // damping matrix + static double M[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // mass matrix + static double G[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // G matrix + static double H[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // H matrix + static double Keff[PML3DVISCOUS_NUM_DOF * PML3DVISCOUS_NUM_DOF]; // effective stiffness matrix + static double gamma; // Newmark parameters: gamma static double beta; // Newmark parameters: beta - static double gamma; // Newmark parameters: gamma + static double eta; // Newmark parameters: eta + static double keisi; // Newmark parameters: keisi static Matrix tangent; // tangent matrix static Vector resid; // residual vector static Matrix mass; // mass matrix static Matrix damping; // damping matrix + static Matrix Gmat; // G matrix + static Matrix Hmat; // H matrix + static Matrix keffmat; // effective stiffness matrix Vector ubart; // ubar at time t Vector ubarbart; // ubarbar at time t Vector ubar; // ubar at time t+dt @@ -138,8 +150,23 @@ class PML3DVISCOUS : public Element { int updateflag; // update flag int update_dt; // flag for updating dt static int eleCount; // element count + static int ComputedEleTag; // computed element tag + double coords[24]; // int innertag; // inner tag // static int numberOfElements; // number of elements + double alpha0; // alpha0 pml parameter + double beta0; // beta0 pml parameter + double xref, yref, zref; // reference point + double nx, ny, nz; // normal vector + const char* meshtype; // type of mesh + double PML_L; // PML minimum thickness + double m_coeff; // m parameter for PML + double R_coeff; // PML damping ratio + double cp_ref; // reference wave speed + bool ExplicitAlphaBeta; // flag for explicit alpha beta + + ElasticIsotropicMaterial* theMaterial; // pointer to the material + }; #endif diff --git a/SRC/element/PML/pml_3d.f b/SRC/element/PML/pml_3d.f index 28977d3c70..af71152435 100644 --- a/SRC/element/PML/pml_3d.f +++ b/SRC/element/PML/pml_3d.f @@ -32,72 +32,6 @@ SUBROUTINE PML_3D(MMATRX,CMATRX,KMATRX,GMATRX,HMATRX, 4 HMATRX(NDOFEL,NDOFEL), 5 PROPS(*),COORDS(MCRD,NNODE),LFLAGS(*) - ! - ! Variables that must be computed in this routine - ! RHS(i) Right hand side vector. Dimensions are RHS(MLVARX,1) - ! AMATRX(i,j) Stiffness matrix d RHS(i)/ d DU(j) - ! SVARS(1:NSVARS) Element state variables. Must be updated in this routine - ! ENERGY(1:8) - ! Energy(1) Kinetic Energy - ! Energy(2) Elastic Strain Energy - ! Energy(3) Creep Dissipation - ! Energy(4) Plastic Dissipation - ! Energy(5) Viscous Dissipation - ! Energy(6) Artificial strain energy - ! Energy(7) Electrostatic energy - ! Energy(8) Incremental work done by loads applied to the element - ! PNEWDT Allows user to control ABAQUS time increments. - ! If PNEWDT<1 then time step is abandoned and computation is restarted with - ! a time increment equal to PNEWDT*DTIME - ! If PNEWDT>1 ABAQUS may increase the time increment by a factor PNEWDT - ! - ! Variables provided for information - ! NDOFEL Total # DOF for the element - ! NRHS Dimension variable - ! NSVARS Total # element state variables - ! PROPS(1:NPROPS) User-specified properties of the element - ! NPROPS No. properties - ! JPROPS(1:NJPROPS) Integer valued user specified properties for the element - ! NJPROPS No. integer valued properties - ! COORDS(i,N) ith coordinate of Nth node on element - ! MCRD Maximum of (# coords,minimum of (3,#DOF)) on any node - ! U Vector of DOF at the end of the increment - ! DU Vector of DOF increments - ! V Vector of velocities (defined only for implicit dynamics) - ! A Vector of accelerations (defined only for implicit dynamics) - ! TIME(1:2) TIME(1) Current value of step time - ! TIME(2) Total time - ! DTIME Time increment - ! KSTEP Current step number - ! KINC Increment number - ! JELEM User assigned element number in ABAQUS (internally assigned) - ! PARAMS(1:3) Time increment parameters alpha, beta, gamma for implicit dynamics - ! NDLOAD Number of user-defined distributed loads defined for this element - ! JDLTYP(1:NDLOAD) Integers n defining distributed load types defined as Un or (if negative) UnNU in input file - ! ADLMAG(1:NDLOAD) Distributed load magnitudes - ! DDLMAG(1:NDLOAD) Increment in distributed load magnitudes - ! PREDEF(1:2,1:NPREDF,1:NNODE) Predefined fields. - ! PREDEF(1,...) Value of predefined field - ! PREDEF(2,...) Increment in predefined field - ! PREDEF(1:2,1,k) Value of temperature/temperature increment at kth node - ! PREDEF(1:2,2:NPREDF,k) Value of user defined field/field increment at kth node - ! NPREDF Number of predefined fields - ! LFLAGS Control variable - ! LFLAGS(1) Defines procedure type - ! LFLAGS(2) 0 => small displacement analysis 1 => Large displacement (NLGEOM option) - ! LFLAGS(3) 1 => Subroutine must return both RHS and AMATRX - ! 2 => Subroutine must return stiffness AMATRX = -dF/du - ! 3 => Subroutine must return daming matrix AMATRX = -dF/dudot - ! 4 => Subroutine must return mass matrix AMATRX = -dF/duddot - ! 5 => Define the RHS only - ! 6 => Define the mass matrix for the initial acceleration calculation - ! 100 => Define perturbation quantities for output - ! LFLAGS(4) 0 => General step 1 => linear perturbation step - ! LFLAGS(5) 0 => current approximation to solution based on Newton correction; 1 => based on extrapolation - ! MLVARX Dimension variable for RHS - ! PERIOD Time period of the current step - ! - ! ! Local Variables real*8 ZERO,ONE,HALF @@ -108,7 +42,6 @@ SUBROUTINE PML_3D(MMATRX,CMATRX,KMATRX,GMATRX,HMATRX, PARAMETER (coef_beta = 1.d0/48.d0) integer :: i,j,n_points,kint - ! integer :: face_node_list(8) ! List of nodes on an element face ! double precision :: xi(3,64) ! Volumetric Integration points double precision :: w(64) ! Integration weights @@ -116,34 +49,21 @@ SUBROUTINE PML_3D(MMATRX,CMATRX,KMATRX,GMATRX,HMATRX, double precision :: dNdxi(20,3) ! 3D Shape function derivatives double precision :: dxdxi(3,3) ! Derivative of position wrt normalized coords double precision :: dNdx(20,3) ! Derivative of shape functions wrt spatial coords - ! - ! Variables below are for computing integrals over element faces - ! double precision :: face_coords(3,8) ! Coords of nodes on an element face - ! double precision :: xi2(2,9) ! Area integration points - ! double precision :: N2(9) ! 2D shape functions - ! double precision :: dNdxi2(9,2) ! 2D shape function derivatives - ! double precision :: norm(3) ! Normal to an element face - ! double precision :: dxdxi2(3,2) ! Derivative of spatial coord wrt normalized areal coord - ! + double precision :: strain(6) ! Strain vector contains [e11, e22, e33, 2e12, 2e13, 2e23] double precision :: stress(6) ! Stress vector contains [s11, s22, s33, s12, s13, s23] double precision :: D(6,6) ! stress = D*(strain) (NOTE FACTOR OF 2 in shear strain) double precision :: B(6,60) ! strain = B*(dof_total) double precision :: dxidx(3,3), determinant ! Jacobian inverse and determinant double precision :: E, xnu ! Material properties - ! double precision :: ALPHA, BETA, GAMMA ! Newmark Integration properties double precision :: Phi(3,60) ! Matrix consists of shape functions [N1 N2 ... N20] - ! double precision :: MMATRX(NDOFEL,NDOFEL) ! Element mass matrix - ! double precision :: KMATRX(NDOFEL,NDOFEL) ! Element stiffness matrix - ! double precision :: CMATRX(NDOFEL,NDOFEL) ! Element damping matrix - ! double precision :: GMATRX(NDOFEL,NDOFEL) ! Element G matrix - ! double precision :: HMATRX(NDOFEL,NDOFEL) ! Element H matrix double precision :: rho ! Density of the material - double precision :: PML_L,afp,PML_Rcoef ! Parameters of PML - double precision :: RD_half_width_x, RD_half_width_y ! Parameters of PML - double precision :: RD_depth ! Parameters of PML + double precision :: PML_L,afp ! Parameters of PML + double precision :: alpha_0, beta_0 ! Parameters of PML + double precision :: x1_0, x2_0, x3_0 ! Parameters of PML + double precision :: n1, n2, n3 ! Parameters of PML integer :: EleType_pos ! Parameters of PML double precision :: x1,x2,x3,PML_alpha_beta(2,3) ! Coordinates x, y and z, alphas and betas @@ -170,93 +90,25 @@ SUBROUTINE PML_3D(MMATRX,CMATRX,KMATRX,GMATRX,HMATRX, double precision :: U_n(72), V_n(72), A_n(72) ! U, V, A at previous step - integer :: NodeDOF,res1, res2, res3, res4, res5 ! Number of DOF per node + integer :: NodeDOF double precision :: Damp_alpha, Damp_beta ! Damping coefficients for Rayleigh Damping - ! double precision :: Vs ! Shear wave velocity NodeDOF = NDOFEL/NNODE - ! - ! Example ABAQUS UEL implementing 3D linear elastic elements - ! El props are: - - ! PROPS(1) Young's modulus - ! PROPS(2) Poisson's ratio if (NNODE == 4) n_points = 1 ! Linear tet if (NNODE == 10) n_points = 4 ! Quadratic tet if (NNODE == 8) n_points = 27 ! Linear Hex if (NNODE == 20) n_points = 27 ! Quadratic hex ! Local Variables - ! print propertises - ! write(6,*) ' PROPS(1) = ',PROPS(1) - ! write(6,*) ' PROPS(2) = ',PROPS(2) - ! write(6,*) ' PROPS(3) = ',PROPS(3) - ! write(6,*) ' PROPS(4) = ',PROPS(4) - ! write(6,*) ' PROPS(5) = ',PROPS(5) - ! write(6,*) ' PROPS(6) = ',PROPS(6) - ! write(6,*) ' PROPS(7) = ',PROPS(7) - ! write(6,*) ' PROPS(8) = ',PROPS(8) - ! write(6,*) ' PROPS(9) = ',PROPS(9) - ! write(6,*) ' PROPS(10) = ',PROPS(10) - ! write(6,*) ' PROPS(11) = ',PROPS(11) - ! write(6,*) ' PROPS(12) = ',PROPS(12) - - ! ! print coords - ! write(6,*) ' coords(1,1) = ',coords(1,1) - ! write(6,*) ' coords(2,1) = ',coords(2,1) - ! write(6,*) ' coords(3,1) = ',coords(3,1) - ! write(6,*) ' coords(1,2) = ',coords(1,2) - ! write(6,*) ' coords(2,2) = ',coords(2,2) - ! write(6,*) ' coords(3,2) = ',coords(3,2) - ! write(6,*) ' coords(1,3) = ',coords(1,3) - ! write(6,*) ' coords(2,3) = ',coords(2,3) - ! write(6,*) ' coords(3,3) = ',coords(3,3) - ! write(6,*) ' coords(1,4) = ',coords(1,4) - ! write(6,*) ' coords(2,4) = ',coords(2,4) - ! write(6,*) ' coords(3,4) = ',coords(3,4) - ! write(6,*) ' coords(1,5) = ',coords(1,5) - ! write(6,*) ' coords(2,5) = ',coords(2,5) - ! write(6,*) ' coords(3,5) = ',coords(3,5) - ! write(6,*) ' coords(1,6) = ',coords(1,6) - ! write(6,*) ' coords(2,6) = ',coords(2,6) - ! write(6,*) ' coords(3,6) = ',coords(3,6) - ! write(6,*) ' coords(1,7) = ',coords(1,7) - ! write(6,*) ' coords(2,7) = ',coords(2,7) - ! write(6,*) ' coords(3,7) = ',coords(3,7) - ! write(6,*) ' coords(1,8) = ',coords(1,8) - ! write(6,*) ' coords(2,8) = ',coords(2,8) - ! write(6,*) ' coords(3,8) = ',coords(3,8) - - ! ! print MCRD - ! write(6,*) ' MCRD = ',MCRD - - ! ! print NNODE - ! write(6,*) ' NNODE = ',NNODE - - ! ! print NDOFEL - ! write(6,*) ' NDOFEL = ',NDOFEL - - ! ! print LFLAGS - ! write(6,*) ' LFLAGS(1) = ',LFLAGS(1) - - call abq_UEL_3D_integrationpoints(n_points, NNODE, xi, w) - ! if (MLVARX<3*NNODE) then - ! write(6,*) ' Error in abaqus UEL ' - ! write(6,*) ' Variable MLVARX must exceed 3*NNODE' - ! write(6,*) ' MLVARX = ',MLVARX,' NNODE = ',NNODE - ! stop - ! endif - ! RHS(1:MLVARX,1) = 0.d0 - ! AMATRX(1:NDOFEL,1:NDOFEL) = 0.d0 MMATRX(1:NDOFEL,1:NDOFEL) = 0.d0 KMATRX(1:NDOFEL,1:NDOFEL) = 0.d0 CMATRX(1:NDOFEL,1:NDOFEL) = 0.d0 @@ -269,13 +121,18 @@ SUBROUTINE PML_3D(MMATRX,CMATRX,KMATRX,GMATRX,HMATRX, rho = PROPS(3) EleType_pos = floor(PROPS(4)) PML_L = PROPS(5) - afp = PROPS(6) - PML_Rcoef = PROPS(7) - RD_half_width_x = PROPS(8) - RD_half_width_y = PROPS(9) - RD_depth = PROPS(10) - Damp_alpha = PROPS(11) - Damp_beta = PROPS(12) + x1_0 = PROPS(6) + x2_0 = PROPS(7) + x3_0 = PROPS(8) + n1 = PROPS(9) + n2 = PROPS(10) + n3 = PROPS(11) + alpha_0 = PROPS(12) + beta_0 = PROPS(13) + Damp_alpha = PROPS(14) + Damp_beta = PROPS(15) + afp = PROPS(16) + IF (afp .LT. 3.d0) THEN n_points = 27 @@ -377,26 +234,26 @@ SUBROUTINE PML_3D(MMATRX,CMATRX,KMATRX,GMATRX,HMATRX, x3 = x3 + N(i)*coords(3,i) end do - ! write(6,*) ' x1 = ',x1 - ! write(6,*) ' x2 = ',x2 - ! write(6,*) ' x3 = ',x3 - - ! mu = rho*Vs**2.d0 - ! E = mu*2.d0*(1.d0+xnu) - ! lambda = xnu*E/((1.d0+xnu)*(1.d0-2.D0*xnu)) - ! PROPS(1) = E - ! write(6,*) ' E = ',E - ! write(6,*) ' xnu = ',xnu - ! write(6,*) ' lambda = ',lambda - ! write(6,*) ' mu = ',mu - - call PML_alpha_beta_function(PROPS,x1,x2,x3,PML_alpha_beta) + + + ! call PML_alpha_beta_function(PROPS,x1,x2,x3,PML_alpha_beta) + ! PML_alpha_beta(1,1) = 1.d0 + alpha_0*((x1 -x1_0) * n1 /PML_L)**afp + ! PML_alpha_beta(1,2) = 1.d0 + alpha_0*((x2 -x2_0) * n2 /PML_L)**afp + ! PML_alpha_beta(1,3) = 1.d0 + alpha_0*((x3 -x3_0) * n3 /PML_L)**afp + PML_alpha_beta(1,1) = alpha_0*((x1 -x1_0) * n1 /PML_L)**afp + PML_alpha_beta(1,2) = alpha_0*((x2 -x2_0) * n2 /PML_L)**afp + PML_alpha_beta(1,3) = alpha_0*((x3 -x3_0) * n3 /PML_L)**afp + PML_alpha_beta(1,1) = 1.d0 + PML_alpha_beta(1,1) + PML_alpha_beta(1,2) = 1.d0 + PML_alpha_beta(1,2) + PML_alpha_beta(1,3) = 1.d0 + PML_alpha_beta(1,3) + + PML_alpha_beta(2,1) = beta_0*((x1 -x1_0) * n1 /PML_L)**afp + PML_alpha_beta(2,2) = beta_0*((x2 -x2_0) * n2 /PML_L)**afp + PML_alpha_beta(2,3) = beta_0*((x3 -x3_0) * n3 /PML_L)**afp coef_a = PML_alpha_beta(1,1)*PML_alpha_beta(1,2) 1 *PML_alpha_beta(1,3) - ! write(6,*) ' alpha11 :',PML_alpha_beta(1,1) - ! write(6,*) ' alpha12 :',PML_alpha_beta(1,2) - ! write(6,*) ' alpha13 :',PML_alpha_beta(1,3) + coef_b = PML_alpha_beta(1,1)*PML_alpha_beta(1,2) @@ -451,15 +308,10 @@ SUBROUTINE PML_3D(MMATRX,CMATRX,KMATRX,GMATRX,HMATRX, M_RD(i,j) = M_RD(i,j) + rho*N(i)*N(j)*w(kint)*determinant M_a(i,j) = M_a(i,j) + 1 coef_a*rho*N(i)*N(j)*w(kint)*determinant - ! if i == 1 and j == 1 then print coef_a, rho, N(i), N(j), w(kint), determinant end if - ! If (i.EQ. 1 .AND. j .EQ. 1 ) THEN - ! write(6,*) ' coef_a = ',coef_a - ! write(6,*) ' rho = ',rho - ! write(6,*) ' N(i) = ',N(i) - ! write(6,*) ' N(j) = ',N(j) - ! write(6,*) ' w(kint) = ',w(kint) - ! write(6,*) ' determinant = ',determinant - ! endif + + + + M_b(i,j) = M_b(i,j) + 1 coef_b*rho*N(i)*N(j)*w(kint)*determinant M_c(i,j) = M_c(i,j) + @@ -595,10 +447,7 @@ SUBROUTINE PML_3D(MMATRX,CMATRX,KMATRX,GMATRX,HMATRX, M_d(2*NNODE+1:3*NNODE,2*NNODE+1:3*NNODE) 1 = M_d(1:NNODE,1:NNODE) - ! write(6,*) " NNODE: ", NNODE - ! write(6,*) " lambda: ", lambda - ! write(6,*) " mu: ", mu - ! write(6,*) " rho: ", rho + N_a(1:NNODE,1:NNODE) = 1 M_a(1:NNODE,1:NNODE)/rho*(lambda+mu)/mu/(3.d0*lambda+2.d0*mu) N_a(1:NNODE,NNODE+1:2*NNODE) = @@ -808,221 +657,13 @@ SUBROUTINE PML_3D(MMATRX,CMATRX,KMATRX,GMATRX,HMATRX, end do end do - - ! print Ele_type pos - ! write(*,*) ' EleType_pos', EleType_pos - ! MMATRX(1:NDOFEL,1:NDOFEL) = GMATRX(1:NDOFEL,1:NDOFEL) - -CMATRX(1:NDOFEL,1:NDOFEL) = CMATRX(1:NDOFEL,1:NDOFEL) + Damp_alpha*MMATRX(1:NDOFEL,1:NDOFEL) + Damp_beta*KMATRX(1:NDOFEL,1:NDOFEL) - - - ! IF (LFLAGS(1).EQ.1 .OR. LFLAGS(1).EQ.2) THEN - ! AMATRX(1:NDOFEL,1:NDOFEL) = KMATRX(1:NDOFEL,1:NDOFEL) - ! RHS(1:NDOFEL,1) = RHS(1:NDOFEL,1) - ! 1 - matmul(KMATRX(1:NDOFEL,1:NDOFEL),U(1:NDOFEL)) - - ! ELSE IF (LFLAGS(1).EQ.11 .OR. LFLAGS(1).EQ.12) THEN - - - ! d_bar_n(1:NDOFEL) = SVARS(1:NDOFEL) - ! U_n(1:NDOFEL) = SVARS(NDOFEL+1:NDOFEL*2) - ! V_n(1:NDOFEL) = SVARS(2*NDOFEL+1:NDOFEL*3) - ! A_n(1:NDOFEL) = SVARS(3*NDOFEL+1:NDOFEL*4) - ! d_bar_dot_n(1:NDOFEL) = SVARS(4*NDOFEL+1:NDOFEL*5) - - - - ! d_bar_n1(1:NDOFEL) = d_bar_n(1:NDOFEL) + - ! 1 DTIME*U_n(1:NDOFEL) + DTIME**2.d0/2.d0*V_n(1:NDOFEL) + - ! 2 DTIME**3.d0*(1.d0/6.d0 - coef_alpha)*A_n(1:NDOFEL) + - ! 3 DTIME**3.d0*coef_alpha*A(1:NDOFEL) - - ! d_bar_dot_n1(1:NDOFEL) = d_bar_dot_n(1:NDOFEL) + - ! 1 DTIME*d_bar_n(1:NDOFEL) + DTIME**2.d0/2.d0*U_n(1:NDOFEL) + - ! 2 DTIME**3.d0/6.d0*V_n(1:NDOFEL) + - ! 3 DTIME**4.d0*(1.d0/24.d0-coef_beta)*A_n(1:NDOFEL) + - ! 4 DTIME**4.d0*coef_beta*A(1:NDOFEL) - - - ! AMATRX(1:NDOFEL,1:NDOFEL) = - ! 1 (1.d0+ALPHA)*HMATRX(1:NDOFEL,1:NDOFEL)*DTIME**2.d0*coef_beta/ - ! 2 BETA - ! 3 + (1.d0+ALPHA)*GMATRX(1:NDOFEL,1:NDOFEL)*DTIME*coef_alpha/BETA - ! 4 + (1.d0+ALPHA)*KMATRX(1:NDOFEL,1:NDOFEL) - ! 5 + (1.d0+ALPHA)*CMATRX(1:NDOFEL,1:NDOFEL)*DVDU - ! 6 + MMATRX(1:NDOFEL,1:NDOFEL)*DADU - - ! RHS(1:NDOFEL,1) = RHS(1:NDOFEL,1) - ! & - matmul(MMATRX(1:NDOFEL,1:NDOFEL),A(1:NDOFEL)) - ! & - (1.d0+ALPHA)*matmul(KMATRX(1:NDOFEL,1:NDOFEL),U(1:NDOFEL)) - ! & - (1.d0+ALPHA)*matmul(CMATRX(1:NDOFEL,1:NDOFEL),V(1:NDOFEL)) - ! & - (1.d0+ALPHA)* - ! & matmul(GMATRX(1:NDOFEL,1:NDOFEL),d_bar_n1(1:NDOFEL)) - ! & - (1.d0+ALPHA)* - ! & matmul(HMATRX(1:NDOFEL,1:NDOFEL),d_bar_dot_n1(1:NDOFEL)) - ! & + ALPHA*matmul(KMATRX(1:NDOFEL,1:NDOFEL),U_n(1:NDOFEL)) - ! & + ALPHA*matmul(CMATRX(1:NDOFEL,1:NDOFEL),V_n(1:NDOFEL)) - ! & + ALPHA*matmul(GMATRX(1:NDOFEL,1:NDOFEL),d_bar_n(1:NDOFEL)) - ! & +ALPHA*matmul(HMATRX(1:NDOFEL,1:NDOFEL),d_bar_dot_n(1:NDOFEL)) - - - ! SVARS(1:NDOFEL) = d_bar_n1(1:NDOFEL) - ! SVARS(NDOFEL+1:NDOFEL*2) = U(1:NDOFEL) - ! SVARS(2*NDOFEL+1:NDOFEL*3) = V(1:NDOFEL) - ! SVARS(3*NDOFEL+1:NDOFEL*4) = A(1:NDOFEL) - ! SVARS(4*NDOFEL+1:NDOFEL*5) = d_bar_dot_n1(1:NDOFEL) - - ! ELSE - ! write(6,*) ' Error in abaqus UEL ' - ! write(6,*) ' Analsis types not supported' - ! stop - ! END IF - - - - ! ! PNEWDT = 1.d0 ! This leaves the timestep unchanged (ABAQUS will use its own algorithm to determine DTIME) - ! ! - ! ! Apply distributed loads - ! ! - ! ! Distributed loads are specified in the input file using the Un option in the input file. - ! ! n specifies the face number, following the ABAQUS convention - ! ! - ! ! - ! do j = 1,NDLOAD - - ! call abq_facenodes_3D(NNODE,iabs(JDLTYP(j,1)), - ! 1 face_node_list,nfacenodes) - - ! do i = 1,nfacenodes - ! face_coords(1:3,i) = coords(1:3,face_node_list(i)) - ! end do - - ! if (nfacenodes == 3) n_points = 3 - ! if (nfacenodes == 6) n_points = 4 - ! if (nfacenodes == 4) n_points = 4 - ! if (nfacenodes == 8) n_points = 9 - - ! call abq_UEL_2D_integrationpoints(n_points, nfacenodes, xi2, w) - - ! do kint = 1,n_points - ! call abq_UEL_2D_shapefunctions(xi2(1:2,kint), - ! 1 nfacenodes,N2,dNdxi2) - ! dxdxi2 = matmul(face_coords(1:3,1:nfacenodes), - ! 1 dNdxi2(1:nfacenodes,1:2)) - ! norm(1)=(dxdxi2(2,1)*dxdxi2(3,2))-(dxdxi2(2,2)*dxdxi2(3,1)) - ! norm(2)=(dxdxi2(1,1)*dxdxi2(3,2))-(dxdxi2(1,2)*dxdxi2(3,1)) - ! norm(3)=(dxdxi2(1,1)*dxdxi2(2,2))-(dxdxi2(1,2)*dxdxi2(2,1)) - - ! do i = 1,nfacenodes - ! ipoin = face_node_list(i) - ! RHS(ipoin:ipoin+2*9:9,1) = RHS(ipoin:ipoin+2*9:9,1) - ! 1 - N2(i)*adlmag(j,1)*norm(1:3)*w(kint) ! Note determinant is already in normal - ! end do - ! end do - ! end do - - ! check symmetry of matrices with tolerance - - ! insert MMatrix in to M_PMl - ! M_PML(1:NDOFEL,1:NDOFEL) = MMATRX(1:NDOFEL,1:NDOFEL) - ! C_PML(1:NDOFEL,1:NDOFEL) = CMATRX(1:NDOFEL,1:NDOFEL) - ! K_PML(1:NDOFEL,1:NDOFEL) = KMATRX(1:NDOFEL,1:NDOFEL) - ! G_PML(1:NDOFEL,1:NDOFEL) = GMATRX(1:NDOFEL,1:NDOFEL) - ! H_PML(1:NDOFEL,1:NDOFEL) = HMATRX(1:NDOFEL,1:NDOFEL) - - - ! call check_symmetry(M_PML,1.d-10,res1,"M") - ! if (res1 == 1) then - ! write(6,*) 'M_PML is symmetric ', res1 - ! end if - ! call check_symmetry(G_PML,1.d-10,res4,"G") - ! if (res4 == 1) then - ! write(6,*) 'G_PML is symmetric ', res4 - ! end if - ! call check_symmetry(H_PML,1.d-10,res5,"H") - ! if (res5 == 1) then - ! write(6,*) 'H_PML is symmetric ', res5 - ! end if - ! call check_symmetry(K_PML,1.d-10,res3,"K") - ! if (res3 == 1) then - ! write(6,*) 'K_PML is symmetric ', res3 - ! end if - ! call check_symmetry(C_PML,1.d-10,res2,"C") - ! if (res2 == 1) then - ! write(6,*) 'C_PML is symmetric ', res2 - ! end if - - ! call check_zero(M_PML,1.d-10,res1,"M") - ! if (res1 == 1) write(6,*) 'M_PML is zero ', res1 - ! call check_zero(G_PML,1.d-10,res1,"G") - ! if (res1 == 1) write(6,*) 'G_PML is zero ', res1 - ! call check_zero(H_PML,1.d-10,res1,"H") - ! if (res1 == 1) write(6,*) 'H_PML is zero ', res1 - ! call check_zero(K_PML,1.d-10,res1,"K") - ! if (res1 == 1) write(6,*) 'K_PML is zero ', res1 - ! call check_zero(C_PML,1.d-10,res1,"C") - ! if (res1 == 1) write(6,*) 'C_PML is zero ', res1 - - return END SUBROUTINE PML_3D - ! check symmetry of matrices with tolerance - subroutine check_symmetry(AMATRX,RTOL,a,char) - - implicit none - double precision, intent(in) :: AMATRX(72,72) - double precision, intent(in) :: RTOL - character(len=1), intent(in) :: char - integer , intent(out) :: a - integer :: i,j - - a = 1 - - do i = 1, 72 - do j = 1, 72 - if (abs(AMATRX(i,j)-AMATRX(j,i)) > RTOL) then - write(6,*) 'Matrix ',char,' is not symmetric' - write(6,*) '(i,j) = ',AMATRX(i,j) - write(6,*) '(j,i) = ',AMATRX(j,i) - a = 0 - exit - endif - end do - if (a == 0) exit - end do - - return - end subroutine check_symmetry - - - subroutine check_zero(AMATRX,RTOL,a,char) - - implicit none - double precision, intent(in) :: AMATRX(72,72) - double precision, intent(in) :: RTOL - character(len=1), intent(in) :: char - integer , intent(out) :: a - integer :: i,j - - a = 1 - - do i = 1, 72 - do j = 1, 72 - if (abs(AMATRX(i,j)) > RTOL) then - write(6,*) 'Matrix ',char,' is not zero' - write(6,*) '(i,j) = ',AMATRX(i,j) - a = 0 - exit - endif - end do - if (a == 0) exit - end do - - return - end subroutine check_zero + + subroutine abq_UEL_3D_integrationpoints(n_points, n_nodes, xi, w) @@ -1390,665 +1031,313 @@ subroutine abq_UEL_invert3d(A,A_inverse,determinant) end subroutine abq_UEL_invert3d - subroutine abq_facenodes_3D(nelnodes,face,list,nfacenodes) - - implicit none - - integer, intent (in) :: nelnodes - integer, intent (in) :: face - integer, intent (out) :: list(*) - integer, intent (out) :: nfacenodes - - ! - ! Subroutine to return list of nodes on an element face for standard 3D solid elements - ! - - if (nelnodes == 4) then - nfacenodes = 3 - if (face == 1) list(1:3) = [1,2,3] - if (face == 2) list(1:3) = [1,4,2] - if (face == 3) list(1:3) = [2,4,3] - if (face == 4) list(1:3) = [3,4,1] - else if (nelnodes ==6) then - nfacenodes = 3 - if (face==1) list(1:3) = [1,2,3] - if (face==2) list(1:3) = [6,5,4] - if (face==3) list(1:4) = [1,2,5,4] - if (face==4) list(1:4) = [2,3,6,5] - if (face==5) list(1:4) = [4,6,3,1] - if (face>2) nfacenodes = 4 - else if (nelnodes == 10) then - nfacenodes = 6 - if (face == 1) list(1:6) = [1,2,3,5,6,7] - if (face == 2) list(1:6) = [1,4,2,8,9,5] - if (face == 3) list(1:6) = [2,4,3,9,10,6] - if (face == 4) list(1:6) = [3,4,1,10,8,7] - else if (nelnodes == 8) then - nfacenodes = 4 - if (face==1) list(1:4) = [1,2,3,4] - if (face==2) list(1:4) = [5,8,7,6] - if (face==3) list(1:4) = [1,5,6,2] - if (face==4) list(1:4) = [2,6,7,3] - if (face==5) list(1:4) = [3,7,8,4] - if (face==6) list(1:4) = [4,8,5,1] - else if (nelnodes ==15) then - nfacenodes = 6 - if (face==1) list(1:6) = [1,2,3,7,8,9] - if (face==2) list(1:6) = [6,5,4,11,10,12] - if (face==3) list(1:8) = [1,2,5,4,7,14,10,13] - if (face==4) list(1:8) = [2,3,6,5,8,15,11,14] - if (face==5) list(1:8) = [4,6,3,1,12,15,9,13] - if (face>2) nfacenodes = 8 - else if (nelnodes == 20) then - nfacenodes = 8 - if (face == 1) list(1:8) = [1,2,3,4,9,10,11,12] - if (face == 2) list(1:8) = [5,8,7,6,16,15,14,13] - if (face == 3) list(1:8) = [1,5,6,2,17,13,18,9] - if (face == 4) list(1:8) = [2,6,7,3,18,14,19,10] - if (face == 5) list(1:8) = [3,7,8,4,19,15,6,11] - if (face == 6) list(1:8) = [4,8,5,1,20,16,17,12] - endif - - end subroutine abq_facenodes_3D - subroutine abq_UEL_2D_integrationpoints(n_points, n_nodes, xi, w) - - implicit none - integer, intent(in) :: n_points - integer, intent(in) :: n_nodes - - double precision, intent(out) :: xi(2,*) - double precision, intent(out) :: w(*) - - ! integer :: i,j,k,n - - double precision :: cn,w1,w2,w11,w12,w22 - - ! Defines integration points and weights for 2D continuum elements - - if ( n_points==1 ) then - if ( n_nodes==4 .or. n_nodes==9 ) then ! --- 4 or 9 noded quad - xi(1, 1) = 0.D0 - xi(2, 1) = 0.D0 - w(1) = 4.D0 - else if ( n_nodes==3 .or. n_nodes==6 ) then ! --- 3 or 6 noded triangle - xi(1, 1) = 1.D0/3.D0 - xi(2, 1) = 1.D0/3.D0 - w(1) = 1.D0/2.D0 - end if - else if ( n_points==3 ) then - xi(1, 1) = 0.5D0 - xi(2, 1) = 0.5D0 - w(1) = 1.D0/6.D0 - xi(1, 2) = 0.D0 - xi(2, 2) = 0.5D0 - w(2) = w(1) - xi(1, 3) = 0.5D0 - xi(2, 3) = 0.D0 - w(3) = w(1) - else if ( n_points==4 ) then - if ( n_nodes==4 .or. n_nodes==8 .or. n_nodes==9 ) then - ! 2X2 GAUSS INTEGRATION POINTS FOR QUADRILATERAL - ! 43 - ! 12 - cn = 0.5773502691896260D0 - xi(1, 1) = -cn - xi(1, 2) = cn - xi(1, 3) = cn - xi(1, 4) = -cn - xi(2, 1) = -cn - xi(2, 2) = -cn - xi(2, 3) = cn - xi(2, 4) = cn - w(1) = 1.D0 - w(2) = 1.D0 - w(3) = 1.D0 - w(4) = 1.D0 - else if ( n_nodes==3 .or. n_nodes==6 ) then - ! xi integration points for triangle - xi(1, 1) = 1.D0/3.D0 - xi(2, 1) = xi(1, 1) - w(1) = -27.D0/96.D0 - xi(1, 2) = 0.6D0 - xi(2, 2) = 0.2D0 - w(2) = 25.D0/96.D0 - xi(1, 3) = 0.2D0 - xi(2, 3) = 0.6D0 - w(3) = w(2) - xi(1, 4) = 0.2D0 - xi(2, 4) = 0.2D0 - w(4) = w(2) - end if - - else if ( n_points==7 ) then - ! Quintic integration for triangle - xi(1,1) = 1.d0/3.d0 - xi(2,1) = xi(1,1) - w(1) = 0.1125d0 - xi(1,2) = 0.0597158717d0 - xi(2,2) = 0.4701420641d0 - w(2) = 0.0661970763d0 - xi(1,3) = xi(2,2) - xi(2,3) = xi(1,2) - w(3) = w(2) - xi(1,4) = xi(2,2) - xi(2,4) = xi(2,2) - w(4) = w(2) - xi(1,5) = 0.7974269853d0 - xi(2,5) = 0.1012865073d0 - w(5) = 0.0629695902d0 - xi(1,6) = xi(2,5) - xi(2,6) = xi(1,5) - w(6) = w(5) - xi(1,7) = xi(2,5) - xi(2,7) = xi(2,5) - w(7) = w(5) - else if ( n_points==9 ) then - ! 3X3 GAUSS INTEGRATION POINTS - ! 789 - ! 456 - ! 123 - cn = 0.7745966692414830D0 - xi(1, 1) = -cn - xi(1, 2) = 0.D0 - xi(1, 3) = cn - xi(1, 4) = -cn - xi(1, 5) = 0.D0 - xi(1, 6) = cn - xi(1, 7) = -cn - xi(1, 8) = 0.D0 - xi(1, 9) = cn - xi(2, 1) = -cn - xi(2, 2) = -cn - xi(2, 3) = -cn - xi(2, 4) = 0.D0 - xi(2, 5) = 0.D0 - xi(2, 6) = 0.D0 - xi(2, 7) = cn - xi(2, 8) = cn - xi(2, 9) = cn - w1 = 0.5555555555555560D0 - w2 = 0.8888888888888890D0 - w11 = w1*w1 - w12 = w1*w2 - w22 = w2*w2 - w(1) = w11 - w(2) = w12 - w(3) = w11 - w(4) = w12 - w(5) = w22 - w(6) = w12 - w(7) = w11 - w(8) = w12 - w(9) = w11 - end if - - return - end subroutine abq_UEL_2D_integrationpoints +! subroutine PML_alpha_beta_function(PROPS,x1,x2,x3,PML_alpha_beta) +! implicit none - - - subroutine abq_UEL_2D_shapefunctions(xi,n_nodes,f,df) - - implicit none - integer, intent(in) :: n_nodes - - double precision, intent(in) :: xi(2) - double precision, intent(out) :: f(*) - double precision, intent(out) :: df(9,2) - double precision g1, g2, g3, dg1, dg2, dg3 - double precision h1, h2, h3, dh1, dh2, dh3 - double precision z,dzdp, dzdq - - if ( n_nodes==3 ) then ! SHAPE FUNCTIONS FOR 3 NODED TRIANGLE - f(1) = xi(1) - f(2) = xi(2) - f(3) = 1.D0 - xi(1) - xi(2) - df(1, 1) = 1.D0 - df(1, 2) = 0.D0 - df(2, 1) = 0.D0 - df(2, 2) = 1.D0 - df(3, 1) = -1.D0 - df(3, 2) = -1.D0 - else if ( n_nodes==4 ) then - ! SHAPE FUNCTIONS FOR 4 NODED QUADRILATERAL - ! 43 - ! 12 - g1 = 0.5D0*(1.D0 - xi(1)) - g2 = 0.5D0*(1.D0 + xi(1)) - h1 = 0.5D0*(1.D0 - xi(2)) - h2 = 0.5D0*(1.D0 + xi(2)) - f(1) = g1*h1 - f(2) = g2*h1 - f(3) = g2*h2 - f(4) = g1*h2 - dg1 = -0.5D0 - dg2 = 0.5D0 - dh1 = -0.5D0 - dh2 = 0.5D0 - df(1, 1) = dg1*h1 - df(2, 1) = dg2*h1 - df(3, 1) = dg2*h2 - df(4, 1) = dg1*h2 - df(1, 2) = g1*dh1 - df(2, 2) = g2*dh1 - df(3, 2) = g2*dh2 - df(4, 2) = g1*dh2 - - else if ( n_nodes==6 ) then - - ! SHAPE FUNCTIONS FOR 6 NODED TRIANGLE - ! 3 - - ! 6 5 - - ! 1 4 2 - - ! P = L1 - ! Q = L2 - ! Z = 1 - P - Q = L3 - - z = 1.D0 - xi(1) - xi(2) - f(1) = (2.D0*xi(1) - 1.D0)*xi(1) - f(2) = (2.D0*xi(2) - 1.D0)*xi(2) - f(3) = (2.D0*z - 1.D0)*z - f(4) = 4.D0*xi(1)*xi(2) - f(5) = 4.D0*xi(2)*z - f(6) = 4.D0*xi(1)*z - dzdp = -1.D0 - dzdq = -1.D0 - df(1, 1) = 4.D0*xi(1) - 1.D0 - df(2, 1) = 0.D0 - df(3, 1) = 4.D0*z*dzdp - dzdp - df(4, 1) = 4.D0*xi(2) - df(5, 1) = 4.D0*xi(2)*dzdp - df(6, 1) = 4.D0*z + 4.D0*xi(1)*dzdp - df(1, 2) = 0.D0 - df(2, 2) = 4.D0*xi(2) - 1.D0 - df(3, 2) = 4.D0*z*dzdq - dzdq - df(4, 2) = 4.D0*xi(1) - df(5, 2) = 4.D0*z + 4.D0*xi(2)*dzdq - df(6, 2) = 4.D0*xi(1)*dzdq - - else if ( n_nodes==8 ) then - ! SHAPE FUNCTIONS FOR 8 NODED SERENDIPITY ELEMENT - f(1) = -0.25*(1.-xi(1))*(1.-xi(2))*(1.+xi(1)+xi(2)) - f(2) = 0.25*(1.+xi(1))*(1.-xi(2))*(xi(1)-xi(2)-1.) - f(3) = 0.25*(1.+xi(1))*(1.+xi(2))*(xi(1)+xi(2)-1.) - f(4) = 0.25*(1.-xi(1))*(1.+xi(2))*(xi(2)-xi(1)-1.) - f(5) = 0.5*(1.-xi(1)*xi(1))*(1.-xi(2)) - f(6) = 0.5*(1.+xi(1))*(1.-xi(2)*xi(2)) - f(7) = 0.5*(1.-xi(1)*xi(1))*(1.+xi(2)) - f(8) = 0.5*(1.-xi(1))*(1.-xi(2)*xi(2)) - df(1,1) = 0.25*(1.-xi(2))*(2.*xi(1)+xi(2)) - df(1,2) = 0.25*(1.-xi(1))*(xi(1)+2.*xi(2)) - df(2,1) = 0.25*(1.-xi(2))*(2.*xi(1)-xi(2)) - df(2,2) = 0.25*(1.+xi(1))*(2.*xi(2)-xi(1)) - df(3,1) = 0.25*(1.+xi(2))*(2.*xi(1)+xi(2)) - df(3,2) = 0.25*(1.+xi(1))*(2.*xi(2)+xi(1)) - df(4,1) = 0.25*(1.+xi(2))*(2.*xi(1)-xi(2)) - df(4,2) = 0.25*(1.-xi(1))*(2.*xi(2)-xi(1)) - df(5,1) = -xi(1)*(1.-xi(2)) - df(5,2) = -0.5*(1.-xi(1)*xi(1)) - df(6,1) = 0.5*(1.-xi(2)*xi(2)) - df(6,2) = -(1.+xi(1))*xi(2) - df(7,1) = -xi(1)*(1.+xi(2)) - df(7,2) = 0.5*(1.-xi(1)*xi(1)) - df(8,1) = -0.5*(1.-xi(2)*xi(2)) - df(8,2) = -(1.-xi(1))*xi(2) - else if ( n_nodes==9 ) then - ! SHAPE FUNCTIONS FOR 9 NODED LAGRANGIAN ELEMENT - ! 789 - ! 456 - ! 123 - g1 = -.5D0*xi(1)*(1.D0 - xi(1)) - g2 = (1.D0 - xi(1))*(1.D0 + xi(1)) - g3 = .5D0*xi(1)*(1.D0 + xi(1)) - h1 = -.5D0*xi(2)*(1.D0 - xi(2)) - h2 = (1.D0 - xi(2))*(1.D0 + xi(2)) - h3 = .5D0*xi(2)*(1.D0 + xi(2)) - dg1 = xi(1) - 0.5d0 - dg2 = -2.d0*xi(1) - dg3 = xi(1) + 0.5d0 - dh1 = xi(2)-0.5d0 - dh2 = -2.d0*xi(2) - dh3 = xi(2) + 0.5d0 - f(1) = g1*h1 - f(2) = g2*h1 - f(3) = g3*h1 - f(4) = g1*h2 - f(5) = g2*h2 - f(6) = g3*h2 - f(7) = g1*h3 - f(8) = g2*h3 - f(9) = g3*h3 - df(1,1) = dg1*h1 - df(1,2) = g1*dh1 - df(2,1) = dg2*h1 - df(2,2) = g2*dh1 - df(3,1) = dg3*h1 - df(3,2) = g3*dh1 - df(4,1) = dg1*h2 - df(4,2) = g1*dh2 - df(5,1) = dg2*h2 - df(5,2) = g2*dh2 - df(6,1) = dg3*h2 - df(6,2) = g3*dh2 - df(7,1) = dg1*h3 - df(7,2) = g1*dh3 - df(8,1) = dg2*h3 - df(8,2) = g2*dh3 - df(9,1) = dg3*h3 - df(9,2) = g3*dh3 - end if - - end subroutine abq_UEL_2D_shapefunctions - - - subroutine PML_alpha_beta_function(PROPS,x1,x2,x3,PML_alpha_beta) - - implicit none - - double precision, intent(in) :: PROPS(*) - double precision, intent(in) :: x1, x2, x3 +! double precision, intent(in) :: PROPS(*) +! double precision, intent(in) :: x1, x2, x3 - double precision, intent(out) :: PML_alpha_beta(2,3) - - integer EleType_arg - - double precision E, xnu, rho, PML_L, afp, PML_Rcoef - double precision x1_0, x2_0, x3_0, n1, n2, n3, cp_ref, PML_b - double precision alpha_0, beta_0 - double precision RD_half_width_x, RD_half_width_y, RD_depth - - E = PROPS(1) - xnu = PROPS(2) - rho = PROPS(3) - EleType_arg = floor(PROPS(4)) - PML_L = PROPS(5) - afp = PROPS(6) - PML_Rcoef = PROPS(7) - RD_half_width_x = PROPS(8) - RD_half_width_y = PROPS(9) - RD_depth = PROPS(10) +! double precision, intent(out) :: PML_alpha_beta(2,3) + +! integer EleType_arg + +! double precision E, xnu, rho, PML_L, afp, PML_Rcoef +! double precision x1_0, x2_0, x3_0, n1, n2, n3, cp_ref, PML_b +! double precision alpha_0, beta_0 +! double precision RD_half_width_x, RD_half_width_y, RD_depth + +! E = PROPS(1) +! xnu = PROPS(2) +! rho = PROPS(3) +! EleType_arg = floor(PROPS(4)) +! PML_L = PROPS(5) +! afp = PROPS(6) +! PML_Rcoef = PROPS(7) +! RD_half_width_x = PROPS(8) +! RD_half_width_y = PROPS(9) +! RD_depth = PROPS(10) - cp_ref = SQRT(E *(1.d0-xnu)/rho/(1.d0+xnu)/(1.d0-2.d0*xnu)) +! cp_ref = SQRT(E *(1.d0-xnu)/rho/(1.d0+xnu)/(1.d0-2.d0*xnu)) - IF(x2 < -RD_half_width_y) then - IF(x1 < -RD_half_width_x) then - IF(x3 < -RD_depth) then +! IF(x2 < -RD_half_width_y) then +! IF(x1 < -RD_half_width_x) then +! IF(x3 < -RD_depth) then - EleType_arg = 15 +! EleType_arg = 15 - else +! else - EleType_arg = 6 +! EleType_arg = 6 - endif +! endif - ELSEIF(x1 < RD_half_width_x) then - IF(x3 < -RD_depth) then +! ELSEIF(x1 < RD_half_width_x) then +! IF(x3 < -RD_depth) then - EleType_arg = 11 +! EleType_arg = 11 - else +! else - EleType_arg = 2 +! EleType_arg = 2 - endif +! endif - Else - IF(x3 < -RD_depth) then +! Else +! IF(x3 < -RD_depth) then - EleType_arg = 16 +! EleType_arg = 16 - else +! else - EleType_arg = 7 +! EleType_arg = 7 - endif - endif +! endif +! endif - ELSEIF(x2 < RD_half_width_y) then - IF(x1 < -RD_half_width_x) then - IF(x3 < -RD_depth) then +! ELSEIF(x2 < RD_half_width_y) then +! IF(x1 < -RD_half_width_x) then +! IF(x3 < -RD_depth) then - EleType_arg = 14 +! EleType_arg = 14 - else +! else - EleType_arg = 5 +! EleType_arg = 5 - endif +! endif - ELSEIF(x1 < RD_half_width_x) then - IF(x3 < -RD_depth) then +! ELSEIF(x1 < RD_half_width_x) then +! IF(x3 < -RD_depth) then - EleType_arg = 10 +! EleType_arg = 10 - else +! else - EleType_arg = 1 +! EleType_arg = 1 - endif +! endif - Else - IF(x3 < -RD_depth) then +! Else +! IF(x3 < -RD_depth) then - EleType_arg = 12 +! EleType_arg = 12 - else +! else - EleType_arg = 3 +! EleType_arg = 3 - endif - endif +! endif +! endif - Else - IF(x1 < -RD_half_width_x) then - IF(x3 < -RD_depth) then +! Else +! IF(x1 < -RD_half_width_x) then +! IF(x3 < -RD_depth) then - EleType_arg = 18 +! EleType_arg = 18 - else +! else - EleType_arg = 9 +! EleType_arg = 9 - endif +! endif - ELSEIF(x1 < RD_half_width_x) then - IF(x3 < -RD_depth) then +! ELSEIF(x1 < RD_half_width_x) then +! IF(x3 < -RD_depth) then - EleType_arg = 13 +! EleType_arg = 13 - else +! else - EleType_arg = 4 +! EleType_arg = 4 - endif +! endif - Else - IF(x3 < -RD_depth) then +! Else +! IF(x3 < -RD_depth) then - EleType_arg = 17 +! EleType_arg = 17 - else +! else - EleType_arg = 8 +! EleType_arg = 8 - endif - endif +! endif +! endif - endif - ! write(6,*) "EleType_arg ",EleType_arg - select case (EleType_arg) - case(1) !Regular domain (do nothing) - n1 = 0.d0 - n2 = 0.d0 - n3 = 0.d0 - x1_0 = 0 - x2_0 = 0 - x3_0 = 0 - - case(2) ! Top view, bottom surface PML - n1 = 0.d0 - n2 = -1.d0 - n3 = 0.d0 - x1_0 = 0 - x2_0 = -1.d0* RD_half_width_y - x3_0 = 0 - - case(3) ! Top view, right surface PML - n1 = 1.d0 - n2 = 0.d0 - n3 = 0.d0 - x1_0 = 1.d0* RD_half_width_x - x2_0 = 0 - x3_0 = 0 - - case(4) ! Top view, top surface PML - n1 = 0.d0 - n2 = 1.d0 - n3 = 0.d0 - x1_0 = 0 - x2_0 = 1.d0* RD_half_width_y - x3_0 = 0 - - case(5) ! Top view, left surface PML - n1 = -1.d0 - n2 = 0.d0 - n3 = 0.d0 - x1_0 = -1.d0* RD_half_width_x - x2_0 = 0 - x3_0 = 0 - - case(6) ! Top view, left-bottom column PML - n1 = -1.d0 - n2 = -1.d0 - n3 = 0.d0 - x1_0 = -1.d0* RD_half_width_x - x2_0 = -1.d0* RD_half_width_y - x3_0 = 0 - - case(7) ! Top view, right-bottom column PML - n1 = 1.d0 - n2 = -1.d0 - n3 = 0.d0 - x1_0 = 1.d0* RD_half_width_x - x2_0 = -1.d0* RD_half_width_y - x3_0 = 0 - - case(8) ! Top view, right-top column PML - n1 = 1.d0 - n2 = 1.d0 - n3 = 0.d0 - x1_0 = 1.d0* RD_half_width_x - x2_0 = 1.d0* RD_half_width_y - x3_0 = 0 - - case(9) ! Top view, left-top column PML - n1 = -1.d0 - n2 = 1.d0 - n3 = 0.d0 - x1_0 = -1.d0* RD_half_width_x - x2_0 = 1.d0* RD_half_width_y - x3_0 = 0 - - case(10) ! Top view, bottom surface, surface PML - n1 = 0.d0 - n2 = 0.d0 - n3 = -1.d0 - x1_0 = 0 - x2_0 = 0 - x3_0 = -1.d0* RD_depth - - case(11) ! Top view, bottom surface, bottom column PML - n1 = 0.d0 - n2 = -1.d0 - n3 = -1.d0 - x1_0 = 0 - x2_0 = -1.d0* RD_half_width_y - x3_0 = -1.d0* RD_depth - - case(12) ! Top view, bottom surface, right column PML - n1 = 1.d0 - n2 = 0.d0 - n3 = -1.d0 - x1_0 = 1.d0* RD_half_width_x - x2_0 = 0 - x3_0 = -1.d0* RD_depth - - case(13) ! Top view, bottom surface, top column PML - n1 = 0.d0 - n2 = 1.d0 - n3 = -1.d0 - x1_0 = 0 - x2_0 = 1.d0* RD_half_width_y - x3_0 = -1.d0* RD_depth - - case(14) ! Top view, bottom surface, left column PML - n1 = -1.d0 - n2 = 0.d0 - n3 = -1.d0 - x1_0 = -1.d0* RD_half_width_x - x2_0 = 0 - x3_0 = -1.d0* RD_depth - - case(15) ! Top view, bottom surface, left-bottom corner PML - n1 = -1.d0 - n2 = -1.d0 - n3 = -1.d0 - x1_0 = -1.d0* RD_half_width_x - x2_0 = -1.d0* RD_half_width_y - x3_0 = -1.d0* RD_depth - - case(16) ! Top view, bottom surface, right-bottom corner PML - n1 = 1.d0 - n2 = -1.d0 - n3 = -1.d0 - x1_0 = 1.d0* RD_half_width_x - x2_0 = -1.d0* RD_half_width_y - x3_0 = -1.d0* RD_depth - - case(17) ! Top view, bottom surface, right-top corner PML - n1 = 1.d0 - n2 = 1.d0 - n3 = -1.d0 - x1_0 = 1.d0* RD_half_width_x - x2_0 = 1.d0* RD_half_width_y - x3_0 = -1.d0* RD_depth - - case(18) ! Top view, bottom surface, left-top corner PML - n1 = -1.d0 - n2 = 1.d0 - n3 = -1.d0 - x1_0 = -1.d0* RD_half_width_x - x2_0 = 1.d0* RD_half_width_y - x3_0 = -1.d0* RD_depth - - end select - - PML_b = PML_L / 1.d0 !characteristic length (average element size in the PML domain) +! endif +! ! write(6,*) "EleType_arg ",EleType_arg +! select case (EleType_arg) +! case(1) !Regular domain (do nothing) +! n1 = 0.d0 +! n2 = 0.d0 +! n3 = 0.d0 +! x1_0 = 0 +! x2_0 = 0 +! x3_0 = 0 + +! case(2) ! Top view, bottom surface PML +! n1 = 0.d0 +! n2 = -1.d0 +! n3 = 0.d0 +! x1_0 = 0 +! x2_0 = -1.d0* RD_half_width_y +! x3_0 = 0 + +! case(3) ! Top view, right surface PML +! n1 = 1.d0 +! n2 = 0.d0 +! n3 = 0.d0 +! x1_0 = 1.d0* RD_half_width_x +! x2_0 = 0 +! x3_0 = 0 + +! case(4) ! Top view, top surface PML +! n1 = 0.d0 +! n2 = 1.d0 +! n3 = 0.d0 +! x1_0 = 0 +! x2_0 = 1.d0* RD_half_width_y +! x3_0 = 0 + +! case(5) ! Top view, left surface PML +! n1 = -1.d0 +! n2 = 0.d0 +! n3 = 0.d0 +! x1_0 = -1.d0* RD_half_width_x +! x2_0 = 0 +! x3_0 = 0 + +! case(6) ! Top view, left-bottom column PML +! n1 = -1.d0 +! n2 = -1.d0 +! n3 = 0.d0 +! x1_0 = -1.d0* RD_half_width_x +! x2_0 = -1.d0* RD_half_width_y +! x3_0 = 0 + +! case(7) ! Top view, right-bottom column PML +! n1 = 1.d0 +! n2 = -1.d0 +! n3 = 0.d0 +! x1_0 = 1.d0* RD_half_width_x +! x2_0 = -1.d0* RD_half_width_y +! x3_0 = 0 + +! case(8) ! Top view, right-top column PML +! n1 = 1.d0 +! n2 = 1.d0 +! n3 = 0.d0 +! x1_0 = 1.d0* RD_half_width_x +! x2_0 = 1.d0* RD_half_width_y +! x3_0 = 0 + +! case(9) ! Top view, left-top column PML +! n1 = -1.d0 +! n2 = 1.d0 +! n3 = 0.d0 +! x1_0 = -1.d0* RD_half_width_x +! x2_0 = 1.d0* RD_half_width_y +! x3_0 = 0 + +! case(10) ! Top view, bottom surface, surface PML +! n1 = 0.d0 +! n2 = 0.d0 +! n3 = -1.d0 +! x1_0 = 0 +! x2_0 = 0 +! x3_0 = -1.d0* RD_depth + +! case(11) ! Top view, bottom surface, bottom column PML +! n1 = 0.d0 +! n2 = -1.d0 +! n3 = -1.d0 +! x1_0 = 0 +! x2_0 = -1.d0* RD_half_width_y +! x3_0 = -1.d0* RD_depth + +! case(12) ! Top view, bottom surface, right column PML +! n1 = 1.d0 +! n2 = 0.d0 +! n3 = -1.d0 +! x1_0 = 1.d0* RD_half_width_x +! x2_0 = 0 +! x3_0 = -1.d0* RD_depth + +! case(13) ! Top view, bottom surface, top column PML +! n1 = 0.d0 +! n2 = 1.d0 +! n3 = -1.d0 +! x1_0 = 0 +! x2_0 = 1.d0* RD_half_width_y +! x3_0 = -1.d0* RD_depth + +! case(14) ! Top view, bottom surface, left column PML +! n1 = -1.d0 +! n2 = 0.d0 +! n3 = -1.d0 +! x1_0 = -1.d0* RD_half_width_x +! x2_0 = 0 +! x3_0 = -1.d0* RD_depth + +! case(15) ! Top view, bottom surface, left-bottom corner PML +! n1 = -1.d0 +! n2 = -1.d0 +! n3 = -1.d0 +! x1_0 = -1.d0* RD_half_width_x +! x2_0 = -1.d0* RD_half_width_y +! x3_0 = -1.d0* RD_depth + +! case(16) ! Top view, bottom surface, right-bottom corner PML +! n1 = 1.d0 +! n2 = -1.d0 +! n3 = -1.d0 +! x1_0 = 1.d0* RD_half_width_x +! x2_0 = -1.d0* RD_half_width_y +! x3_0 = -1.d0* RD_depth + +! case(17) ! Top view, bottom surface, right-top corner PML +! n1 = 1.d0 +! n2 = 1.d0 +! n3 = -1.d0 +! x1_0 = 1.d0* RD_half_width_x +! x2_0 = 1.d0* RD_half_width_y +! x3_0 = -1.d0* RD_depth + +! case(18) ! Top view, bottom surface, left-top corner PML +! n1 = -1.d0 +! n2 = 1.d0 +! n3 = -1.d0 +! x1_0 = -1.d0* RD_half_width_x +! x2_0 = 1.d0* RD_half_width_y +! x3_0 = -1.d0* RD_depth + +! end select + +! PML_b = PML_L / 1.d0 !characteristic length (average element size in the PML domain) - alpha_0 = ((afp+1)*PML_b) / (2.d0*PML_L )*LOG10(1.d0 / PML_Rcoef) - beta_0 = ((afp+1)*cp_ref) / (2.d0*PML_L )*LOG10(1.d0 / PML_Rcoef) +! alpha_0 = ((afp+1)*PML_b) / (2.d0*PML_L )*LOG10(1.d0 / PML_Rcoef) +! beta_0 = ((afp+1)*cp_ref) / (2.d0*PML_L )*LOG10(1.d0 / PML_Rcoef) -! alpha_0 = 5.d0 -! beta_0 = 800.d0 +! ! alpha_0 = 5.d0 +! ! beta_0 = 800.d0 + +! write(6,*) , "alpha_____0", alpha_0 +! write(6,*) , "beta______0", beta_0 - PML_alpha_beta(1,1) = 1.d0 + alpha_0*((x1 -x1_0) * n1 /PML_L)**afp - PML_alpha_beta(1,2) = 1.d0 + alpha_0*((x2 -x2_0) * n2 /PML_L)**afp - PML_alpha_beta(1,3) = 1.d0 + alpha_0*((x3 -x3_0) * n3 /PML_L)**afp +! PML_alpha_beta(1,1) = 1.d0 + alpha_0*((x1 -x1_0) * n1 /PML_L)**afp +! PML_alpha_beta(1,2) = 1.d0 + alpha_0*((x2 -x2_0) * n2 /PML_L)**afp +! PML_alpha_beta(1,3) = 1.d0 + alpha_0*((x3 -x3_0) * n3 /PML_L)**afp - PML_alpha_beta(2,1) = beta_0*((x1 -x1_0) * n1 /PML_L)**afp - PML_alpha_beta(2,2) = beta_0*((x2 -x2_0) * n2 /PML_L)**afp - PML_alpha_beta(2,3) = beta_0*((x3 -x3_0) * n3 /PML_L)**afp +! PML_alpha_beta(2,1) = beta_0*((x1 -x1_0) * n1 /PML_L)**afp +! PML_alpha_beta(2,2) = beta_0*((x2 -x2_0) * n2 /PML_L)**afp +! PML_alpha_beta(2,3) = beta_0*((x3 -x3_0) * n3 /PML_L)**afp - IF (EleType_arg .EQ.1) THEN - PML_alpha_beta(1:2,1:3) = 0.d0 - end if +! IF (EleType_arg .EQ.1) THEN +! PML_alpha_beta(1:2,1:3) = 0.d0 +! end if - end subroutine PML_alpha_beta_function +! end subroutine PML_alpha_beta_function diff --git a/SRC/material/nD/ElasticIsotropicMaterial.h b/SRC/material/nD/ElasticIsotropicMaterial.h index 2bdea004f8..30dd14e757 100644 --- a/SRC/material/nD/ElasticIsotropicMaterial.h +++ b/SRC/material/nD/ElasticIsotropicMaterial.h @@ -60,6 +60,8 @@ class ElasticIsotropicMaterial : public NDMaterial virtual const char *getClassType(void) const {return "ElasticIsotropicMaterial";}; virtual double getRho( ) ; + virtual double getElasticModulus( ) { return E; } + virtual double getPoissonsRatio( ) { return v; } virtual int setTrialStrain (const Vector &v); virtual int setTrialStrain (const Vector &v, const Vector &r); From 41aa709e6a10cc66d574b1b4b5b9657a266c255f Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Wed, 12 Mar 2025 22:08:15 -0700 Subject: [PATCH 030/261] Add hMatrix and LFLAGS parameters to pml3d_ function in PML3D and PML3DVISCOUS headers for Win32 --- SRC/element/PML/PML3D.h | 5 +++-- SRC/element/PML/PML3DVISCOUS.h | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/SRC/element/PML/PML3D.h b/SRC/element/PML/PML3D.h index 45bc116390..70114d3f93 100644 --- a/SRC/element/PML/PML3D.h +++ b/SRC/element/PML/PML3D.h @@ -52,12 +52,13 @@ extern "C" void pml3d_(double* mMatrix, double* cMatrix, double* kMatrix, double* gMatrix, + double* hMatrix, int* NDOFEL, double* PROPS, - int* NPROPS, double* COORDS, int* MCRD, - int* NNODE); + int* NNODE, + int* LFLAGS); #else diff --git a/SRC/element/PML/PML3DVISCOUS.h b/SRC/element/PML/PML3DVISCOUS.h index 31424008e9..02ad35bcdc 100644 --- a/SRC/element/PML/PML3DVISCOUS.h +++ b/SRC/element/PML/PML3DVISCOUS.h @@ -53,12 +53,13 @@ extern "C" void pml3d_(double* mMatrix, double* cMatrix, double* kMatrix, double* gMatrix, + double* hMatrix, int* NDOFEL, double* PROPS, - int* NPROPS, double* COORDS, int* MCRD, - int* NNODE); + int* NNODE, + int* LFLAGS); #else From f3126648c29fac5d7833c7bed003a5cc73e90d10 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Wed, 19 Mar 2025 18:00:51 +0100 Subject: [PATCH 031/261] first checkpoint buckling --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 1565 +++++++++++++----- SRC/material/uniaxial/ASDSteel1DMaterial.h | 65 +- 2 files changed, 1203 insertions(+), 427 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index 8ccef39dbc..fc19fe9d37 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -19,12 +19,12 @@ ** ****************************************************************** */ // $Revision: 1.0 $ -// $Date: 2042-06-14 11:29:01 $ +// $Date: 2025-01-03 11:29:01 $ // $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/ASDSteel1DMaterial.cpp,v $ -// Massimo Petracca - ASDEA Software, Italy +// Alessia Casalucci - ASDEA Software, Italy // -// A Simple and robust plastic-damage model for concrete and masonry +// todo... // #include @@ -41,45 +41,1015 @@ #include #include #include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif // anonymous namespace for utilities namespace { - enum ErrorCodes { - EC_IMPLEX_Error_Control = -10 + + inline double sign(double x) { return x == 0.0 ? 0.0 : (x > 0.0 ? 1.0 : -1.0); } + + /** + A simple 2D vector + */ + class V2D + { + public: + double x = 0.0; + double y = 0.0; + public: + V2D() = default; + V2D(double _x, double _y) : x(_x), y(_y) {} + inline double normalize() { + double n = x * x + y * y; + if (n > 0.0) { + n = std::sqrt(n); + x /= n; + y /= n; + } + return n; + } + inline double operator()(int i) const { + if (i == 0) return x; + /*if (i == 1) */return y; + } }; + inline V2D operator + (const V2D& a, const V2D& b) { + return V2D(a.x + b.x, a.y + b.y); + } + inline V2D operator - (const V2D& a, const V2D& b) { + return V2D(a.x - b.x, a.y - b.y); + } + inline V2D operator * (double a, const V2D& b) { + return V2D(a * b.x, a * b.y); + } + inline V2D operator * (const V2D& b, double a) { + return a * b; + } + /** - Converts a string into a vector of doubles using whitespace as delimiter + A simple 2D basis matrix */ - bool string_to_double(const std::string& text, double& num) { - num = 0.0; - try { - num = std::stod(text); - return true; + class M2D + { + public: + V2D dx; + V2D dy; + public: + M2D() = default; + M2D(const V2D& x, const V2D& y) : dx(x), dy(y) {} + inline double operator()(int i, int j) const { + if (i == 0) return dx(j); + /*else if (i == 1)*/ return dy(j); } - catch (...) { - return false; + }; + + /** + A quaternion optimized for the 2D case + */ + class Q2D + { + public: + double w = 0.0; + double z = 0.0; + public: + Q2D() = default; + Q2D(double _w, double _z) : w(_w), z(_z) {} + public: + inline Q2D conjugate()const { return Q2D(w, -z); } + inline double toRotationVector()const { + double ww = w; + double zz = z; + if (w < 0.0) { + ww = -ww; + zz = -zz; + } + double vNorm = std::sqrt(zz * zz); + if (vNorm == 0.0) return 0.0; + double mult = vNorm < ww ? (2.0 / vNorm * std::asin(vNorm)) : (2.0 / vNorm * std::acos(ww)); + return zz * mult; + } + inline V2D rotateVector(const V2D& a) const { + V2D b(-2.0 * z * a.y, 2.0 * z * a.x); + V2D c(-z * b.y, z * b.x); + return a + b * w + c; + } + inline void normalize() { + double n = w * w + z * z; + if (n > 0.0) { + n = std::sqrt(n); + w /= n; + z /= n; + } + } + static Q2D identity() { + return Q2D(1.0, 0.0); + } + static Q2D fromRotationVector(double axis) { + double n = std::abs(axis); + if (n == 0.0) + return Q2D::identity(); + if (n != 1.0) + axis /= n; + double halfAngle = n * 0.5; + double q0 = std::cos(halfAngle); + double s = std::sin(halfAngle); + Q2D result(q0, axis * s); + result.normalize(); + return result; + } + static Q2D fromRotationMatrix(const M2D& m) { + double tr = m.dx.x + m.dy.y + 1.0; + if ((tr > m.dx.x) && (tr > m.dy.y) && (tr > 1.0)) { + double S = std::sqrt(tr + 1.0) * 2.0; + Q2D Q(0.25 * S, (m.dy.x - m.dx.y) / S); + Q.normalize(); + return Q; + } + else { + double S = std::sqrt(1.0 + 1.0 - m.dx.x - m.dy.y) * 2.0; + Q2D Q((m.dy.x - m.dx.y) / S, 0.25 * S); + Q.normalize(); + return Q; + } } + }; + inline Q2D operator * (const Q2D& a, const Q2D& b) { + return Q2D(a.w * b.w - a.z * b.z, a.w * b.z + a.z * b.w); } - inline double sign(double x) { return x == 0.0 ? 0.0 : (x > 0.0 ? 1.0 : -1.0); } + /** + Global storage to avoid many dynamic allocation/deallocations. + */ + class Globals + { + private: + Globals() = default; + Globals(const Globals&) = delete; + Globals& operator = (const Globals&) = delete; + + public: + static Globals& instance() { + static Globals _instance; + return _instance; + } + + public: + + // for section + Vector section_stress = Vector(3); + Vector section_strain = Vector(3); + Matrix section_tangent = Matrix(3, 3); + + // for element + Vector element_RHS = Vector(6); + Vector element_RHS_local = Vector(6); + Matrix element_LHS = Matrix(6, 6); + Matrix element_LHS_local = Matrix(6, 6); + Matrix element_T = Matrix(6, 6); + Vector element_U = Vector(6); + Vector element_U_commit = Vector(6); + Vector element_U_local = Vector(6); + Vector element_U_local_commit = Vector(6); + Matrix element_B = Matrix(3, 6); + + // RVE + // node positions (to be set at each setTrialStrain) + Vector rve_dU = Vector(7); + Vector rve_R = Vector(7); + Matrix rve_K = Matrix(7, 7); + Vector rve_Kcr = Vector(7); + Vector rve_Krc = Vector(7); + Vector rve_Kinv_Kcr = Vector(7); + double rve_Krr = 0.0; + double rve_Kred = 0.0; + std::array rve_nodes = { V2D(0.0, 0.0), V2D(0.0, 0.0), V2D(0.0, 0.0), V2D(0.0, 0.0) }; + inline void setRVENodes(double lch) { + double dy = lch / 6.0; // consider half distance, the RVE uses symmetry + for (int i = 0; i < 4; ++i) { + auto& ip = rve_nodes[i]; + ip.y = dy * static_cast(i); // from bottom to top, bottom at 0,0 + ip.x = ip.y * 1.0e-3; // add imperfection + } + } + + }; + + /** + Basic steel component. + */ + class SteelComponent + { + public: + using param_t = ASDSteel1DMaterial::InputParameters; + SteelComponent() = default; + + inline int commitState() { + // store the previously committed variables for next move from n to n - 1 + lambda_commit_old = lambda_commit; + // state variables + alpha1_commit = alpha1; + alpha2_commit = alpha2; + lambda_commit = lambda; + strain_commit = strain; + stress_commit = stress; + // done + return 0; + } + inline void revertToLastCommit() { + // state variables + alpha1 = alpha1_commit; + alpha2 = alpha2_commit; + lambda = lambda_commit; + strain = strain_commit; + stress = stress_commit; + } + inline void revertToStart() { + // state variables + alpha1 = 0.0; + alpha1_commit = 0.0; + alpha2 = 0.0; + alpha2_commit = 0.0; + lambda = 0.0; + lambda_commit = 0.0; + lambda_commit_old = 0.0; + sg_commit = 0.0; + // strain, stress and tangent + strain = 0.0; + strain_commit = 0.0; + stress = 0.0; + stress_commit = 0.0; + } + inline int compute(const param_t& params, bool do_implex, double time_factor, double _strain, double& sigma, double& tangent) { + // REM + /*sigma = _strain * params.E; + tangent = params.E; + return 0;*/ + + + // return value + int retval = 0; + // settings + constexpr int MAX_ITER = 1000; + constexpr double F_REL_TOL = 1.0e-6; + constexpr double L_ABS_TOL = 1.0e-8; + //constexpr double K_alpha = 0.8; //DA TARARE + // base steel response + alpha1 = alpha1_commit; + alpha2 = alpha2_commit; + lambda = lambda_commit; + // elastic predictor + strain = _strain; + double dstrain = strain - strain_commit; + sigma = stress_commit + params.E * dstrain; + tangent = params.E; + // plastic utilities + double sg = 0.0; // plastic flow direction + auto lam_rel_stress = [this, &sigma]() -> double { + return sigma - alpha1 - alpha2; + }; + auto lam_yield_function = [¶ms, &lam_rel_stress]() -> double { + return std::abs(lam_rel_stress()) - params.sy; + }; + auto lam_yield_derivative = [this, &lam_rel_stress, ¶ms](double dlambda) -> double { + // plastic flow direction + double sg = sign(lam_rel_stress()); + // d stress / d lambda + double dsigma = -params.E * sg; + // d backstress / d lambda + double dalpha1 = params.H1 * sg - params.gamma1 * alpha1; + double dalpha2 = params.H2 * sg - params.gamma2 * alpha2; + return sg * (dsigma - dalpha1 - dalpha2); + }; + auto lam_yield_update = [this, &sigma, &lam_rel_stress, ¶ms](double dlambda, double delta_lambda) { + // plastic flow direction + double sg = sign(lam_rel_stress()); + // update stress + sigma -= sg * dlambda * params.E; + // update backstress + alpha1 = sg * params.H1 / params.gamma1 - (sg * params.H1 / params.gamma1 - alpha1_commit) * std::exp(-params.gamma1 * delta_lambda); + alpha2 = sg * params.H2 / params.gamma2 - (sg * params.H2 / params.gamma2 - alpha2_commit) * std::exp(-params.gamma2 * delta_lambda); + }; + // plastic corrector + if (params.implex && do_implex) { + // extrapolate lambda + // xn + time_factor * (xn - xnn); + double delta_lambda = time_factor * (lambda_commit - lambda_commit_old); + lambda = lambda_commit + delta_lambda; + // extrapolate plastic flow direction + sg = sg_commit; + // update stress + sigma -= sg * delta_lambda * params.E; + // update backstress + alpha1 = sg * params.H1 / params.gamma1 - (sg * params.H1 / params.gamma1 - alpha1_commit) * std::exp(-params.gamma1 * delta_lambda); + alpha2 = sg * params.H2 / params.gamma2 - (sg * params.H2 / params.gamma2 - alpha2_commit) * std::exp(-params.gamma2 * delta_lambda); + } + else { + // standard implicit evaluation of lambda + double F = lam_yield_function(); + if (F > 0.0) { + double delta_lambda = 0.0; + double dlambda = 0.0; + bool converged = false; + for (int niter = 0; niter < MAX_ITER; ++niter) { + // form tangent + double dF = lam_yield_derivative(dlambda); + if (dF == 0.0) break; + // solve for dlambda + dlambda = -F / dF; + //constexpr double max_strain_incr = 0.002; + //if (dlambda < -max_strain_incr) + // dlambda = -max_strain_incr; + //else if (dlambda > max_strain_incr) + // dlambda = max_strain_incr; + delta_lambda += dlambda; + // update plastic multiplier increment and sigma + lam_yield_update(dlambda, delta_lambda); + // update residual + F = lam_yield_function(); + // check convergence + if (std::abs(F) < F_REL_TOL * params.sy && std::abs(dlambda) < L_ABS_TOL) { + converged = true; + // update plastic multiplier + lambda += delta_lambda; + // compute tangent + sg = sign(lam_rel_stress()); + double PE = + params.gamma1 * (params.H1 / params.gamma1 - sg * alpha1) + + params.gamma2 * (params.H2 / params.gamma2 - sg * alpha2); + tangent = params.K_alpha*((params.E * PE) / (params.E + PE))+(1-params.K_alpha)*params.E; //tangent correction (K_alpha =1 -> computed tangent, K_alpha=0 -> tangent=E) + break; + } + } + if (!converged) { + opserr << "dlambda !converged\n"; + retval = -1; + } + } + } + // accept solution + stress = sigma; + // save real plastic flow direction, if mp.implex and !do_implex -> called from commit + if (params.implex && !do_implex) { + // save it in implex mode during implicit phase + sg_commit = sg; + } + // done + return retval; + } + + public: + // state variables - backstresses + double alpha1 = 0.0; + double alpha1_commit = 0.0; + double alpha2 = 0.0; + double alpha2_commit = 0.0; + // state variables - plastic multiplier + double lambda = 0.0; + double lambda_commit = 0.0; + double lambda_commit_old = 0.0; // for implex + double sg_commit = 0.0; // plastic flow dir for implex + // strain, stress and tangent + double strain = 0.0; + double strain_commit = 0.0; + double stress = 0.0; + double stress_commit = 0.0; + // methods + static constexpr int NDATA = 12; + }; + + /** + Section component. + */ + template + class SectionComponent + { + private: + SectionComponent() = delete; + }; + + /** + Section component with 1 fiber. + */ + template<> + class SectionComponent<1> + { + public: + SteelComponent fib; + + public: + SectionComponent() = default; + + inline int commitState() { + return fib.commitState(); + } + inline void revertToLastCommit() { + fib.revertToLastCommit(); + } + inline void revertToStart() { + fib.revertToStart(); + } + inline int compute( + const ASDSteel1DMaterial::InputParameters& params, const Vector& strain, + bool do_implex, double time_factor, + Vector& stress, Matrix& tangent) { + //// REM + //tangent.Zero(); + //tangent(0, 0) = tangent(1, 1) = tangent(2, 2) = 3000.0; + //stress.addMatrixVector(0.0, tangent, strain, 1.0); + //return 0; + + + /** + A section with 1 fiber is used for the central element. In this RVE model the + central element has always zero curvature. However, with only 1 fiber the bending + stiffness will be zero, so we use closed-form evaluation of the bending stiffness. + Note also that M = EI*curvature for newton iterations! + */ + double constexpr poiss = 0.3; // built-in poisson ratio + double constexpr kshear = 0.9; // built-in shear correction factor for circular sections + // area + double area = M_PI * params.radius * params.radius; + // compute elastic shear response + double G = params.E / (2.0 * (1.0 + poiss)); + double GAk = G * area * kshear; + tangent(2, 2) = GAk; + stress(2) = GAk * strain(2); + // compute elastic M response (will be zero upon convergence for this model) + double I = M_PI * std::pow(params.radius, 4) / 4.0; + double EI = params.E * I; + stress(1) = EI * strain(1); + tangent(1, 1) = EI; + // nonlinear P reponse + double fiber_stress; + double fiber_tangent; + int retval = fib.compute(params, do_implex, time_factor, strain(0), fiber_stress, fiber_tangent); + double fiber_force = fiber_stress * area; + stress(0) = fiber_force; + tangent(0, 0) = fiber_tangent * area; + // zero terms + tangent(0, 1) = tangent(1, 0) = tangent(0, 2) = tangent(2, 0) = tangent(1, 2) = tangent(2, 1) = 0.0; + // done + return retval; + } + }; + + /** + Section component with 3 fibers. + */ + template<> + class SectionComponent<3> + { + public: + std::array fibers; + //static constexpr std::array positions = { -1.0 / 2.0, 0.0, 1.0 / 2.0 }; + static constexpr std::array positions = { -1.0/3 , 0.0, 1.0/3 }; + static constexpr std::array weights = { 1.0 / 4.0, 1.0 / 2.0, 1.0 / 4.0 }; + + public: + SectionComponent() = default; + inline int commitState() { + int retval = 0; + for (auto& item : fibers) { + int fiber_retval = item.commitState(); + if (fiber_retval != 0) + retval = fiber_retval; + } + return retval; + } + inline void revertToLastCommit() { + for (auto& item : fibers) item.revertToLastCommit(); + } + inline void revertToStart() { + for (auto& item : fibers) item.revertToStart(); + } + inline int compute( + const ASDSteel1DMaterial::InputParameters& params, const Vector& strain, + bool do_implex, double time_factor, + Vector& stress, Matrix& tangent) { + /** + A section with 3 fibers. + */ + double constexpr poiss = 0.3; // built-in poisson ratio + double constexpr kshear = 0.9; // built-in shear correction factor for circular sections + // area + double area = M_PI * params.radius * params.radius; + // zero P-M components for integration + stress.Zero(); + tangent.Zero(); + // compute elastic shear response + double G = params.E / (2.0 * (1.0 + poiss)); + double GAk = G * area * kshear; + tangent(2, 2) = GAk; + stress(2) = GAk * strain(2); + // integrate nonlinear P-M response + for (int i = 0; i < fibers.size(); ++i) { + double fiber_pos = positions[i] * params.radius; + double fiber_area = weights[i] * area; + double fiber_strain = strain(0) - strain(1) * fiber_pos; + double fiber_stress; + double fiber_tangent; + int retval = fibers[i].compute(params, do_implex, time_factor, fiber_strain, fiber_stress, fiber_tangent); + if (retval != 0) + return retval; + double fiber_force = fiber_stress * fiber_area; + stress(0) += fiber_force; + stress(1) -= fiber_force * fiber_pos; + + double EtA = fiber_tangent * fiber_area; + double ya = fiber_pos * EtA; + tangent(0, 0) += EtA; + tangent(0, 1) -= ya; + tangent(1, 0) -= ya; + tangent(1, 1) += ya * fiber_pos; + } + // done + return 0; + } + }; + + + /** + Element Traits: + - 4 nodes - 3 elements RVE + - total number of DOFs = 12 + - free DOFs = 7 + - bottom node - Ux = 0, Uy = macro_strain*L, Rz = 0 + - top node - Uy = 0, Rz = 0 + + logic: + for each dof in DOFs: + if dof < 7 + U_dof = URVE(dof) + else if dof == 8: + U_dof = RY + else + U_dof = 0.0 + + */ + + constexpr int EType_Bot = 1; + constexpr int EType_Mid = 2; + constexpr int EType_Top = 3; + template + class ETypeTraits + { + }; + template<> + class ETypeTraits + { + public: + static constexpr std::array DOFs = {8,7,9, 0,1,2 }; + static constexpr int N1 = 0; + static constexpr int N2 = 1; + }; + template<> + class ETypeTraits + { + public: + static constexpr std::array DOFs = { 0,1,2, 3,4,5 }; + static constexpr int N1 = 1; + static constexpr int N2 = 2; + }; + template<> + class ETypeTraits + { + public: + static constexpr std::array DOFs = { 3,4,5, 6,10,11 }; + static constexpr int N1 = 2; + static constexpr int N2 = 3; + }; + template + inline void getElementDisplacementVector(const Vector& G, Vector& L) { + // G = global vector, size = 8 -> full = 12, semi-full 8 (7 free + 1 Uy imposed) + // L = local vector , size = 6 + for (int i = 0; i < 6; ++i) { + int gdof = ETypeTraits::DOFs[i]; + L(i) = gdof < 8 ? G(gdof) : 0.0; + } + } + template + inline void assembleRHS(const Vector& L, Vector& G) { + // G = global vector, size = 7 (-> full = 12, semi-full 8 (7 free + 1 Uy imposed) only free) + // L = local vector , size = 6 + for (int i = 0; i < 6; ++i) { + int gdof = ETypeTraits::DOFs[i]; + if (gdof < 7) { + G(gdof) += L(i); + } + } + } + template + inline void assembleLHS(const Matrix& M, Matrix& G) { + // G = global matrix, size = 7x7 -> full = 12x12, semi-full 8 (7 free + 1 Uy imposed) + // L = local vector , size = 6 + // M = local matrix , size = 6x6 + for (int i = 0; i < 6; ++i) { + int idof = ETypeTraits::DOFs[i]; + if (idof < 7) { + for (int j = 0; j < 6; ++j) { + int jdof = ETypeTraits::DOFs[j]; + if (jdof < 7) { + G(idof, jdof) += M(i, j); + } + + } + } + } + + } + template + inline void getRetainedComponents(const Matrix& M, double& Krr, Vector& Kcr, Vector& Krc) { + for (int i = 0; i < 6; ++i) { + int idof = ETypeTraits::DOFs[i]; + for (int j = 0; j < 6; ++j) { + int jdof = ETypeTraits::DOFs[j]; + if (idof == 7) { + if (jdof == 7) { + Krr = M(i, j); + } + else if (jdof < 7) { //it is used to assemble krc and kcr for the bottom element -> jdof will be always < 3 + Krc(jdof) = M(i, j); + } + } + else if (jdof == 7 && idof < 7) { + Kcr(idof) = M(j, i); + } + } + } + } + + + + inline M2D computeLocalFrameInternal(const V2D& X1, const V2D& X2, Q2D& Qi, V2D& C) { + C = (X1 + X2) * 0.5; + V2D dx = X2 - X1; + double L = dx.normalize(); + V2D dy(-dx.y, dx.x); + M2D Ri(dx, dy); + Qi = Q2D::fromRotationMatrix(Ri); + return Ri; + } + + inline void computeLocalFrame(const V2D& X1, const V2D& X2, Q2D& Qi, V2D& C) { + computeLocalFrameInternal(X1, X2, Qi, C); + } + inline void computeLocalFrame(const V2D& X1, const V2D& X2, Q2D& Qi, V2D& C, Matrix& T) { + M2D Ri = computeLocalFrameInternal(X1, X2, Qi, C); + for (int i = 0; i < 2;++i) { + for (int j = 0; j < 2;++j) { + T(i, j) = T(i + 3, j + 3) = Ri(i, j) / 2.0; + T(i, j + 3) = T(i + 3, j) = -Ri(i, j) / 2.0; + } + } + T(2,2) = T(5,5) = 1.0; + } + + inline void computeBmatrix(const V2D& X1, const V2D& X2, double& L,Matrix& B) { + V2D dx = X2 - X1; + L = dx.normalize(); + B(0,0) = B(1,2) = B(2,1) = -1.0 / L; + B(0,3) = B(1,5) = B(2,4) = 1.0 / L; + B(2,2) = B(2,5) = -1.0 / 2.0; + } + + class RVEStateVariables + { + public: + Vector UG = Vector(8); + Vector UG_commit = Vector(8); + }; + + /** + Element component. + */ + template + class ElementComponent + { + public: + SectionComponent section; + SectionComponent<1> s1; + SectionComponent<3> s3; + Vector UL_commit = Vector(6); + std::array qn = { Q2D::identity(), Q2D::identity()}; + std::array qn_commit = { Q2D::identity(), Q2D::identity() }; + V2D rn = V2D(0.0, 0.0); + V2D rn_commit = V2D(0.0, 0.0); + + ElementComponent() = default; + + inline int compute(const RVEStateVariables& rve, const ASDSteel1DMaterial::InputParameters& params, bool do_implex, double time_factor ) { + + auto& globals = Globals::instance(); + auto& U = globals.element_U; + auto& U_commit = globals.element_U_commit; + auto& UL = globals.element_U_local; + auto& B = globals.element_B; + auto& T = globals.element_T; + auto& RHS = globals.element_RHS; + auto& RHSL = globals.element_RHS_local; + auto& LHS = globals.element_LHS; + auto& LHSL = globals.element_LHS_local; + auto& stress_s = globals.section_stress; + auto& strain_s = globals.section_strain; + auto& tangent_s = globals.section_tangent; + auto& rve_nodes = globals.rve_nodes; + + int inode = ETypeTraits::N1; + int jnode = ETypeTraits::N2; + + getElementDisplacementVector(rve.UG, U); + getElementDisplacementVector(rve.UG_commit, U_commit); + + // undeformed nodes + V2D node_i = rve_nodes[inode]; + V2D node_j = rve_nodes[jnode]; + + //deformed node position + V2D deformed_node_i = node_i +V2D(U(0), U(1)); + V2D deformed_node_j = node_j +V2D(U(3), U(4)); + + V2D deformed_node_i_old = node_i + V2D(U_commit(0), U_commit(1)); + V2D deformed_node_j_old = node_j + V2D(U_commit(3), U_commit(4)); + + Q2D Q, Q0; + + V2D C; + V2D C0; + double L = 0.0; + + if (do_implex) { + computeLocalFrame(deformed_node_i_old, deformed_node_j_old, Q, C, T); //deformed old nodes + } + else { + computeLocalFrame(deformed_node_i, deformed_node_j, Q, C, T); //deformed nodes + } + computeLocalFrame(node_i, node_j, Q0, C0); //rve nodes + + + if (!do_implex) { + //to monitor the error + /* + Q2D Q_impl; + computeLocalFrame(deformed_node_i_old, deformed_node_j_old, Q_impl, C); + */ + + V2D rn_current = V2D(U(2), U(5)); // rotation at current iteration + V2D dtheta = rn_current - rn; // iterative correction + rn = rn_current; // save current for next iteration + for (int i = 0; i < 2; ++i) { + qn[i] = Q2D::fromRotationVector(dtheta(i)) * qn[i]; // increment quaterion from previous iteration + } + + //position vectors in local reference frame + V2D rf_node1_position = Q0.rotateVector(node_i - C0); + V2D rf_node2_position = Q0.rotateVector(node_j - C0); + + //deformed position vectors in local current frame + V2D cf_node1_deformed = Q.rotateVector(deformed_node_i - C); + V2D cf_node2_deformed = Q.rotateVector(deformed_node_j - C); + + // translational part of deformational local displacements + UL(0) = cf_node1_deformed.x - rf_node1_position.x; + UL(1) = cf_node1_deformed.y - rf_node1_position.y; + UL(3) = cf_node2_deformed.x - rf_node2_position.x; + UL(4) = cf_node2_deformed.y - rf_node2_position.y; + + // rotational part of deformational local rotation + UL(2) = (Q * qn[0] * Q0.conjugate()).toRotationVector(); + UL(5) = (Q * qn[1] * Q0.conjugate()).toRotationVector(); + } + else { + /*static*/ Vector dU(6); + dU = U; + dU.addVector(1.0, U_commit, -1.0); + UL = UL_commit; + UL.addMatrixVector(1.0, T, dU, 1.0); + } + + computeBmatrix(node_i, node_j, L, B); //rve nodes + + // section strain = B*U + strain_s.addMatrixVector(0.0, B, UL, 1.0); + //section compute strain - stress tangent + + int retval = section.compute(params, strain_s, do_implex, time_factor, stress_s, tangent_s); + if (retval != 0) { + opserr << "section !converged\n"; + return retval; + } + + // RHS //B ok + + RHSL.addMatrixTransposeVector(0.0, B, stress_s, L); + RHS.addMatrixTransposeVector(0.0, T, RHSL, 1.0); + // LHS + + + LHSL.addMatrixTripleProduct(0.0, B, tangent_s, L); + LHS.addMatrixTripleProduct(0.0, T, LHSL, 1.0); + + if (params.implex && !do_implex) { + UL_commit = UL; + } + + + return 0; + } + inline int commitState() { + qn_commit = qn; + rn_commit = rn; + return section.commitState(); + } + inline void revertToLastCommit() { + qn = qn_commit; + rn = rn_commit; + section.revertToLastCommit(); + } + inline void revertToStart() { + qn = { Q2D::identity(), Q2D::identity() }; + qn_commit = { Q2D::identity(), Q2D::identity() }; + rn = V2D(0.0, 0.0); + rn_commit = V2D(0.0, 0.0); + section.revertToStart(); + } + + }; + + template + inline int rve_process_element(ElementComponent& ele, const RVEStateVariables& rve, const ASDSteel1DMaterial::InputParameters& params, bool do_implex, double time_factor) { + int retval = ele.compute(rve, params, do_implex, time_factor); + if (retval != 0) { + opserr << "ele !converged\n"; + return retval; + } + auto& globals = Globals::instance(); + assembleRHS(globals.element_RHS, globals.rve_R); + assembleLHS(globals.element_LHS, globals.rve_K); + + return 0; + } + + class RVEModel + { + public: + RVEStateVariables sv; + ElementComponent<3, 1> e1; + ElementComponent<1, 2> e2; + ElementComponent<3, 3> e3; + + RVEModel() = default; + + inline int compute(const ASDSteel1DMaterial::InputParameters& params, double U, bool do_implex, double time_factor, double& N, double& tangent) { + + // output + int retval = -1; + + // start from previous commited state + revertToLastCommit(); + + // globals + double tolR = params.tolR * params.sy; + double tolU = params.tolU * params.length; + //constexpr int max_iter = 200; + auto& globals = Globals::instance(); + + // utility for assembly + auto lam_assemble = [this, &globals, ¶ms, &do_implex, &time_factor]() -> int { + // zero R and K for element integration + globals.rve_R.Zero(); + globals.rve_K.Zero(); + if (rve_process_element< 3, EType_Top>(e3, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 1, EType_Mid>(e2, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 3, EType_Bot>(e1, sv, params, do_implex, time_factor) != 0) return -1; + return 0; + }; + + // impose BC + sv.UG(7) = U; + + // first residual + lam_assemble(); + if (lam_assemble() != 0) + return -1; + // newton loop for this step + // note: do it in reverse order, so that we can access the element RHS for element Bottom to get reaction + double Rnorm = -1.0; + double Unorm = -1.0; + for (int iter = 0; iter < params.max_iter; ++iter) { + + // solve + if (globals.rve_K.Solve(globals.rve_R, globals.rve_dU) != 0) { + opserr << "Solve failed\n"; + + break; + } + + // update free DOFs + for (int i = 0; i < 7; ++i) { + sv.UG(i) -= globals.rve_dU(i); + } + + // assemble + lam_assemble(); + if (lam_assemble() != 0) + break; + + // convergence test + + Rnorm = globals.rve_R.Norm(); + Unorm = globals.rve_dU.Norm(); + opserr << " iter: " << iter << "R: " << Rnorm << ", U: " << Unorm << "\n"; + if (Rnorm < tolR || Unorm < tolU) { + retval = 0; + break; + + } + + + } + + if (retval != 0) { + opserr << "rve !converged\n"; + //opserr << "R: " << Rnorm << ", U: " << Unorm << "\n"; + } + + // do it outside, element Bottom is the last one + getRetainedComponents(globals.element_LHS, globals.rve_Krr, globals.rve_Kcr, globals.rve_Krc); + // get N from element_RHS (note: RHS = Fext-Fint) + N = globals.element_RHS(1); + // perform static condensation + // Kred = Krr - (Krc * inv(Kcc)*Kcr) + globals.rve_K.Solve(globals.rve_Kcr, globals.rve_Kinv_Kcr); + double Krc_dot_Kinv_Kcr = globals.rve_Krc ^ globals.rve_Kinv_Kcr; + globals.rve_Kred = globals.rve_Krr - Krc_dot_Kinv_Kcr; + tangent = globals.rve_Kred; + return retval; + } + inline int commitState() { + + int retval = 0; + + sv.UG_commit = sv.UG; + + int el_retval; + el_retval = e1.commitState(); + if (el_retval != 0) retval = el_retval; + el_retval = e2.commitState(); + if (el_retval != 0) retval = el_retval; + el_retval = e3.commitState(); + if (el_retval != 0) retval = el_retval; + + return retval; + } + inline void revertToLastCommit() { + sv.UG = sv.UG_commit; + e1.revertToLastCommit(); + e2.revertToLastCommit(); + e3.revertToLastCommit(); + } + inline void revertToStart() { + sv.UG.Zero(); + sv.UG_commit.Zero(); + e1.revertToStart(); + e2.revertToStart(); + e3.revertToStart(); + } + }; } +/** + PIMPL pattern + */ +class ASDSteel1DMaterialPIMPL +{ +public: + ASDSteel1DMaterialPIMPL() = default; + ASDSteel1DMaterialPIMPL(const ASDSteel1DMaterialPIMPL&) = default; +public: + RVEModel rve_m; +}; + void* OPS_ASDSteel1DMaterial() { + // some kudos static bool first_done = false; if (!first_done) { opserr << "Using ASDSteel1D - Developed by: Alessia Casalucci, Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; first_done = true; - } - static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu <-implex> <-implexControl $implexErrorTolerance $implexTimeReductionLimit> "; + } + static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu $lch $r <-implex $implex> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; // check arguments int numArgs = OPS_GetNumRemainingInputArgs(); - if (numArgs < 5) { + if (numArgs < 7) { opserr << - "nDMaterial ASDSteel1D Error: Few arguments (< 5).\n" << msg << "\n"; + "uniaxialMaterial ASDSteel1D Error: Few arguments (< 7).\n" << msg << "\n"; return nullptr; } @@ -92,10 +1062,17 @@ void* OPS_ASDSteel1DMaterial() double sy; double su; double eu; + double lch; + double r; bool implex = false; - bool implex_control = false; - double implex_error_tolerance = 0.05; //to set - double implex_time_redution_limit = 0.01; //to set + double K_alpha = 0.6; + double max_iter= 200; + double tolU = 1.0e-6; + double tolR = 1.0e-6; + bool have_K_alpha = false; + bool have_max_iter = false; + bool have_tolU = false; + bool have_tolR = false; // get tag if (OPS_GetInt(&numData, &tag) != 0) { @@ -115,47 +1092,76 @@ void* OPS_ASDSteel1DMaterial() } return true; }; + if (!lam_get_dparam(&E, "E")) return nullptr; + if (!lam_get_dparam(&sy, "sy")) return nullptr; + if (!lam_get_dparam(&su, "su")) return nullptr; + if (!lam_get_dparam(&eu, "eu")) return nullptr; + if (!lam_get_dparam(&lch, "lch")) return nullptr; + if (!lam_get_dparam(&r, "r")) return nullptr; auto lam_optional_double = [&numData](const char* variable, double& value) -> bool { if (OPS_GetNumRemainingInputArgs() > 0) { if (OPS_GetDouble(&numData, &value) < 0) { - opserr << "nDMaterial ASDSteel1D Error: failed to get '" << variable << "'.\n"; + opserr << "nDMaterial ASDConcrete1D Error: failed to get '" << variable << "'.\n"; return false; } } else { - opserr << "nDMaterial ASDSteel1D Error: '" << variable << "' requested but not provided.\n"; + opserr << "nDMaterial ASDConcrete1D Error: '" << variable << "' requested but not provided.\n"; return false; } return true; }; - if (!lam_get_dparam(&E, "E")) return nullptr; - if (!lam_get_dparam(&sy, "sy")) return nullptr; - if (!lam_get_dparam(&su, "su")) return nullptr; - if (!lam_get_dparam(&eu, "eu")) return nullptr; - if (sy >= su) { - opserr << "nDMaterial ASDSteel1D Error: invalid value for 'su' (" << su << "). It should be larger than sy.\n" << msg << "\n"; - return nullptr; - } - + // parse optional arguments while (OPS_GetNumRemainingInputArgs() > 0) { const char* value = OPS_GetString(); if (strcmp(value, "-implex") == 0) { implex = true; } - else if (strcmp(value, "-implexControl") == 0) { - implex_control = true; - if (OPS_GetNumRemainingInputArgs() < 2) { - opserr << "nDMaterial ASDSteel1D Error: '-implexControl' given without the next 2 arguments $implexErrorTolerance $implexTimeReductionLimit.\n"; + if (strcmp(value, "-K_alpha") == 0) { + if (!lam_optional_double("K_alpha", K_alpha)) return nullptr; - } - if (!lam_optional_double("implexErrorTolerance", implex_error_tolerance)) + have_K_alpha = true; + } + if (strcmp(value, "-max_iter") == 0) { + if (!lam_optional_double("max_iter", max_iter)) + return nullptr; + have_max_iter = true; + } + if (strcmp(value, "-tolU") == 0) { + if (!lam_optional_double("tolU", tolU)) return nullptr; - if (!lam_optional_double("implexTimeReductionLimit", implex_time_redution_limit)) + have_tolU = true; + } + if (strcmp(value, "-tolR") == 0) { + if (!lam_optional_double("tolR", tolR)) return nullptr; + have_tolR = true; } } + // checks + if (sy >= su) { + opserr << "nDMaterial ASDSteel1D Error: invalid value for 'su' (" << su << "). It should be larger than sy.\n" << msg << "\n"; + return nullptr; + } + if (E == 0) { + opserr << "nDMaterial ASDSteel1D Error: invalid value for 'E' (" << E << "). It should be non-zero.\n" << msg << "\n"; + return nullptr; + } + if (lch == 0) { + opserr << "nDMaterial ASDSteel1D Error: invalid value for 'lch' (" << lch << "). It should be non-zero.\n" << msg << "\n"; + return nullptr; + } + if (r == 0) { + opserr << "nDMaterial ASDSteel1D Error: invalid value for 'r' (" << r << "). It should be non-zero.\n" << msg << "\n"; + return nullptr; + } + + + + + // obtain chaboche params from E, sy, su, eu // we want to use 2 hardening functions as per chaboche model. // so that the initial slope is close to E and the the stress apporaches su at eu @@ -173,10 +1179,12 @@ void* OPS_ASDSteel1DMaterial() params.H2 = H2 * (1.0 - alpha); params.gamma2 = gamma2; params.implex = implex; - params.implex_control = implex_control; - params.implex_error_tolerance = implex_error_tolerance; - params.implex_time_redution_limit = implex_time_redution_limit; - + params.length = lch; + params.radius = r; + params.K_alpha = K_alpha; + params.max_iter = max_iter; + params.tolU = tolU; + params.tolR = tolR; // create the material UniaxialMaterial* instance = new ASDSteel1DMaterial( // tag @@ -192,73 +1200,12 @@ void* OPS_ASDSteel1DMaterial() return instance; } -void ASDSteel1DMaterial::StateVariablesSteel::commit(const ASDSteel1DMaterial::InputParameters& params) -{ - // store the previously committed variables for next move from n to n - 1 - lambda_commit_old = lambda_commit; - // state variables - alpha1_commit = alpha1; - alpha2_commit = alpha2; - lambda_commit = lambda; - strain_commit = strain; - stress_commit = stress; -} - -void ASDSteel1DMaterial::StateVariablesSteel::revertToLastCommit(const ASDSteel1DMaterial::InputParameters& params) -{ - // state variables - alpha1 = alpha1_commit; - alpha2 = alpha2_commit; - lambda = lambda_commit; - strain = strain_commit; - stress = stress_commit; -} - -void ASDSteel1DMaterial::StateVariablesSteel::revertToStart(const ASDSteel1DMaterial::InputParameters& params) -{ - // state variables - alpha1 = 0.0; - alpha1_commit = 0.0; - alpha2 = 0.0; - alpha2_commit = 0.0; - lambda = 0.0; - lambda_commit = 0.0; - lambda_commit_old = 0.0; - sg_commit = 0.0; - - // strain, stress and tangent - strain = 0.0; - strain_commit = 0.0; - stress = 0.0; - stress_commit = 0.0; - C = params.E; -} -void ASDSteel1DMaterial::StateVariablesSteel::sendSelf(int& counter, Vector& ddata) { - ddata(counter++) = alpha1; - ddata(counter++) = alpha1_commit; - ddata(counter++) = alpha2; - ddata(counter++) = alpha2_commit; - ddata(counter++) = lambda; - ddata(counter++) = lambda_commit; - ddata(counter++) = lambda_commit_old; - ddata(counter++) = sg_commit; -} -void ASDSteel1DMaterial::StateVariablesSteel::recvSelf(int& counter, Vector& ddata) { - alpha1 = ddata(counter++); - alpha1_commit = ddata(counter++); - alpha2 = ddata(counter++); - alpha2_commit = ddata(counter++); - lambda = ddata(counter++); - lambda_commit = ddata(counter++); - lambda_commit_old = ddata(counter++); - sg_commit = ddata(counter++); -} - ASDSteel1DMaterial::ASDSteel1DMaterial( int _tag, const InputParameters& _params) : UniaxialMaterial(_tag, MAT_TAG_ASDSteel1DMaterial) , params(_params) + , pdata(new ASDSteel1DMaterialPIMPL()) { // intialize C as C0 C = getInitialTangent(); @@ -266,67 +1213,37 @@ ASDSteel1DMaterial::ASDSteel1DMaterial( ASDSteel1DMaterial::ASDSteel1DMaterial() : UniaxialMaterial(0, MAT_TAG_ASDSteel1DMaterial) + , pdata(new ASDSteel1DMaterialPIMPL()) +{ +} + +ASDSteel1DMaterial::ASDSteel1DMaterial(const ASDSteel1DMaterial& other) + : UniaxialMaterial(other.getTag(), MAT_TAG_ASDSteel1DMaterial) + , params(other.params) + , pdata(other.pdata ? new ASDSteel1DMaterialPIMPL(*other.pdata) : nullptr) { } ASDSteel1DMaterial::~ASDSteel1DMaterial() { + if(pdata) delete pdata; } int ASDSteel1DMaterial::setTrialStrain(double v, double r) { - // retval - int retval = 0; - // save dT - if (!params.dtime_is_user_defined) { - dtime_n = ops_Dt; - if (!commit_done) { - dtime_0 = dtime_n; - dtime_n_commit = dtime_n; - } + dtime_n = ops_Dt; + if (!commit_done) { + dtime_n_commit = dtime_n; } - // compute real response - steel.strain = v; - //retval = computeBaseSteel(steel, params.implex); - //if (retval < 0) return retval; - if (params.implex) { - if (params.implex_control) { - // initial state - double stress_implicit = 0.0; - retval = computeBaseSteel(steel, false); // implicit solution - if (retval < 0) return retval; - stress_implicit = steel.stress; - - // explicit solution - retval = computeBaseSteel(steel, params.implex); // Implex solution - if (retval < 0) return retval; - - // Implex error - params.implex_error = std::abs(stress_implicit - steel.stress)/params.sy; - if (params.implex_error > params.implex_error_tolerance) { - if (dtime_n >= params.implex_time_redution_limit * dtime_0) { - return EC_IMPLEX_Error_Control; - } - } - } else { - retval = computeBaseSteel(steel, true); // Implex solution - if (retval < 0) return retval; - } - } - else { - retval = computeBaseSteel(steel, false); - } + // save macro strain + strain = v; + // homogenize micro response (stress/tangent) - // todo: homogenize - strain = steel.strain; - stress = steel.stress; - C = steel.C; + int retval = homogenize(params.implex); - // done return retval; - } double ASDSteel1DMaterial::getStress(void) @@ -353,26 +1270,15 @@ int ASDSteel1DMaterial::commitState(void) { // implicit stage if (params.implex) { - int retval; - retval = computeBaseSteel(steel, false); + int retval = homogenize(false); if (retval < 0) return retval; - // todo: homogenize - strain = steel.strain; - stress = steel.stress; - C = steel.C; - /* - // IMPL-EX error - params.implex_error = std::abs(steel.stress - stress); - if (params.implex_control && params.implex_error > params.implex_error_tolerance) { - return -1; // avevamo detto quello implicito? - }*/ } // compute energy energy += 0.5 * (stress_commit + stress) * (strain - strain_commit); - // store committed variables - steel.commit(params); + // forward to all components + pdata->rve_m.commitState(); // state variables strain_commit = strain; @@ -388,8 +1294,8 @@ int ASDSteel1DMaterial::commitState(void) int ASDSteel1DMaterial::revertToLastCommit(void) { - // restore converged values - steel.revertToLastCommit(params); + // forward to all components + pdata->rve_m.revertToLastCommit(); // state variables strain = strain_commit; @@ -404,8 +1310,8 @@ int ASDSteel1DMaterial::revertToLastCommit(void) int ASDSteel1DMaterial::revertToStart(void) { - // state variables - steel.revertToStart(params); + // forward to all components + pdata->rve_m.revertToStart(); // strain, stress and tangent strain = 0.0; @@ -417,21 +1323,19 @@ int ASDSteel1DMaterial::revertToStart(void) // implex dtime_n = 0.0; dtime_n_commit = 0.0; - dtime_0 = 0.0; - - commit_done = false; // output variables energy = 0.0; + // done return 0; } UniaxialMaterial* ASDSteel1DMaterial::getCopy(void) { - // we can safely use the default copy-constructor according to the member variables we're using + // we can safely use the default copy-constructor return new ASDSteel1DMaterial(*this); } @@ -442,83 +1346,71 @@ void ASDSteel1DMaterial::Print(OPS_Stream& s, int flag) int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) { - // aux - int counter; - - // send DBL data - Vector ddata(InputParameters::NDATA + 1*StateVariablesSteel::NDATA + 10); - counter = 0; - ddata(counter++) = static_cast(getTag()); - ddata(counter++) = params.E; - ddata(counter++) = params.sy; - ddata(counter++) = params.H1; - ddata(counter++) = params.H2; - ddata(counter++) = params.gamma1; - ddata(counter++) = params.gamma2; - ddata(counter++) = static_cast(params.implex); - ddata(counter++) = params.implex_error_tolerance; - ddata(counter++) = params.implex_time_redution_limit; - ddata(counter++) = static_cast(params.implex_control); - ddata(counter++) = static_cast(params.dtime_is_user_defined); - ddata(counter++) = params.implex_error; - steel.sendSelf(counter, ddata); - ddata(counter++) = dtime_n; - ddata(counter++) = dtime_n_commit; - ddata(counter++) = dtime_0; - ddata(counter++) = static_cast(commit_done); - ddata(counter++) = strain; - ddata(counter++) = strain_commit; - ddata(counter++) = stress; - ddata(counter++) = stress_commit; - ddata(counter++) = C; - ddata(counter++) = energy; - if (theChannel.sendVector(getDbTag(), commitTag, ddata) < 0) { - opserr << "ASDSteel1DMaterial::sendSelf() - failed to send DBL data\n"; - return -1; - } - - // done + //// aux + //int counter; + + //// send DBL data + //Vector ddata(InputParameters::NDATA + 1*StateVariablesSteel::NDATA + 10); + //counter = 0; + //ddata(counter++) = static_cast(getTag()); + //ddata(counter++) = params.E; + //ddata(counter++) = params.sy; + //ddata(counter++) = params.H1; + //ddata(counter++) = params.H2; + //ddata(counter++) = params.gamma1; + //ddata(counter++) = params.gamma2; + //ddata(counter++) = static_cast(params.implex); + //steel.sendSelf(counter, ddata); + //ddata(counter++) = dtime_n; + //ddata(counter++) = dtime_n_commit; + //ddata(counter++) = static_cast(commit_done); + //ddata(counter++) = strain; + //ddata(counter++) = strain_commit; + //ddata(counter++) = stress; + //ddata(counter++) = stress_commit; + //ddata(counter++) = C; + //ddata(counter++) = energy; + //if (theChannel.sendVector(getDbTag(), commitTag, ddata) < 0) { + // opserr << "ASDSteel1DMaterial::sendSelf() - failed to send DBL data\n"; + // return -1; + //} + + //// done return 0; } int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker) { - // aux - int counter; - - // recv DBL data - Vector ddata(InputParameters::NDATA + 1 * StateVariablesSteel::NDATA + 10); - if (theChannel.recvVector(getDbTag(), commitTag, ddata) < 0) { - opserr << "ASDSteel1DMaterial::recvSelf() - failed to receive DBL data\n"; - return -1; - } - counter = 0; - setTag(ddata(counter++)); - params.E = ddata(counter++); - params.sy = ddata(counter++); - params.H1 = ddata(counter++); - params.H2 = ddata(counter++); - params.gamma1 = ddata(counter++); - params.gamma2 = ddata(counter++); - params.implex = static_cast(ddata(counter++)); - params.implex_error_tolerance = ddata(counter++); - params.implex_time_redution_limit = ddata(counter++); - params.implex_control = static_cast(ddata(counter++)); - params.dtime_is_user_defined = static_cast(ddata(counter++)); - params.implex_error = ddata(counter++); - steel.recvSelf(counter, ddata); - dtime_n = ddata(counter++); - dtime_n_commit = ddata(counter++); - dtime_0 = ddata(counter++); - commit_done = static_cast(ddata(counter++)); - strain = ddata(counter++); - strain_commit = ddata(counter++); - stress = ddata(counter++); - stress_commit = ddata(counter++); - C = ddata(counter++); - energy = ddata(counter++); - - // done + //// aux + //int counter; + + //// recv DBL data + //Vector ddata(InputParameters::NDATA + 1 * StateVariablesSteel::NDATA + 10); + //if (theChannel.recvVector(getDbTag(), commitTag, ddata) < 0) { + // opserr << "ASDSteel1DMaterial::recvSelf() - failed to receive DBL data\n"; + // return -1; + //} + //counter = 0; + //setTag(ddata(counter++)); + //params.E = ddata(counter++); + //params.sy = ddata(counter++); + //params.H1 = ddata(counter++); + //params.H2 = ddata(counter++); + //params.gamma1 = ddata(counter++); + //params.gamma2 = ddata(counter++); + //params.implex = static_cast(ddata(counter++)); + //steel.recvSelf(counter, ddata); + //dtime_n = ddata(counter++); + //dtime_n_commit = ddata(counter++); + //commit_done = static_cast(ddata(counter++)); + //strain = ddata(counter++); + //strain_commit = ddata(counter++); + //stress = ddata(counter++); + //stress_commit = ddata(counter++); + //C = ddata(counter++); + //energy = ddata(counter++); + + //// done return 0; } @@ -532,19 +1424,6 @@ int ASDSteel1DMaterial::updateParameter(int parameterID, Information& info) { switch (parameterID) { // default - case 2000: - dtime_n = info.theDouble; - params.dtime_is_user_defined = true; - return 0; - case 2001: - dtime_n_commit = info.theDouble; - params.dtime_is_user_defined = true; - return 0; - case 2002: - dtime_0 = info.theDouble; - params.dtime_is_user_defined = true; - return 0; - default: return -1; } @@ -568,23 +1447,18 @@ Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Strea // labels static std::vector lb_eqpl_strain = { "PLE" }; - static std::vector lb_implex_error = { "Error" }; // all outputs are 1D static Vector out1(1); - // check specific responses - if (argc > 0) { - // 1000 - base steel output - if (strcmp(argv[0], "equivalentPlasticStrain") == 0 || strcmp(argv[0], "EquivalentPlasticStrain") == 0) { - out1(0) = steel.lambda; - return make_resp(1001, out1, &lb_eqpl_strain); - } - // 3000 - implex error - //if (strcmp(argv[0], "implexError") == 0 || strcmp(argv[0], "ImplexError") == 0) { - //return make_resp(3000, getImplexError(), &lb_implex_error); - //} - } + //// check specific responses + //if (argc > 0) { + // // 1000 - base steel output + // if (strcmp(argv[0], "equivalentPlasticStrain") == 0 || strcmp(argv[0], "EquivalentPlasticStrain") == 0) { + // out1(0) = steel.lambda; + // return make_resp(1001, out1, &lb_eqpl_strain); + // } + //} // otherwise return base-class response return UniaxialMaterial::setResponse(argv, argc, output); @@ -595,15 +1469,14 @@ int ASDSteel1DMaterial::getResponse(int responseID, Information& matInformation) // all outputs are 1D static Vector out1(1); - switch (responseID) { - // 1000 - base steel output - case 1001: - out1(0) = steel.lambda; - return matInformation.setVector(out1); - //case 3000: return matInformation.setVector(getImplexError()); - default: - break; - } + //switch (responseID) { + // // 1000 - base steel output + //case 1001: + // out1(0) = steel.lambda; + // return matInformation.setVector(out1); + //default: + // break; + //} return UniaxialMaterial::getResponse(responseID, matInformation); } @@ -612,122 +1485,44 @@ double ASDSteel1DMaterial::getEnergy(void) return energy; } -int ASDSteel1DMaterial::computeBaseSteel(ASDSteel1DMaterial::StateVariablesSteel& sv, bool do_implex) +int ASDSteel1DMaterial::homogenize(bool do_implex) { + // return value int retval = 0; + auto& globals = Globals::instance(); + globals.setRVENodes(params.length); + // time factor for explicit extrapolation double time_factor = 1.0; if (params.implex && do_implex && (dtime_n_commit > 0.0)) time_factor = dtime_n / dtime_n_commit; - // settings - constexpr int MAX_ITER = 100; - constexpr double F_REL_TOL = 1.0e-6; - constexpr double L_ABS_TOL = 1.0e-8; - // base steel response - sv.alpha1 = sv.alpha1_commit; - sv.alpha2 = sv.alpha2_commit; - sv.lambda = sv.lambda_commit; - // elastic predictor - double dstrain = sv.strain - sv.strain_commit; - double sigma = sv.stress_commit + params.E * dstrain; - double tangent = params.E; - // plastic utilities - double sg = 0.0; // plastic flow direction - auto lam_rel_stress = [&sv, &sigma]() -> double { - return sigma - sv.alpha1 - sv.alpha2; - }; - auto lam_yield_function = [this, &lam_rel_stress]() -> double { - return std::abs(lam_rel_stress()) - params.sy; - }; - auto lam_yield_derivative = [this, &lam_rel_stress, &sv](double dlambda) -> double { - // plastic flow direction - double sg = sign(lam_rel_stress()); - // d stress / d lambda - double dsigma = -params.E * sg; - // d backstress / d lambda - double dalpha1 = params.H1 * sg - params.gamma1 * sv.alpha1; - double dalpha2 = params.H2 * sg - params.gamma2 * sv.alpha2; - return sg * (dsigma - dalpha1 - dalpha2); - }; - auto lam_yield_update = [this, &sigma, &lam_rel_stress, &sv](double dlambda, double delta_lambda) { - // plastic flow direction - double sg = sign(lam_rel_stress()); - // update stress - sigma -= sg * dlambda * params.E; - // update backstress - sv.alpha1 = sg * params.H1 / params.gamma1 - (sg * params.H1 / params.gamma1 - sv.alpha1_commit) * std::exp(-params.gamma1 * delta_lambda); - sv.alpha2 = sg * params.H2 / params.gamma2 - (sg * params.H2 / params.gamma2 - sv.alpha2_commit) * std::exp(-params.gamma2 * delta_lambda); - }; - // plastic corrector - if (params.implex && do_implex) { - // extrapolate lambda - // xn + time_factor * (xn - xnn); - double delta_lambda = time_factor * (sv.lambda_commit - sv.lambda_commit_old); - sv.lambda = sv.lambda_commit + delta_lambda; - // extrapolate plastic flow direction - sg = sv.sg_commit; - // update stress - sigma -= sg * delta_lambda * params.E; - // update backstress - sv.alpha1 = sg * params.H1 / params.gamma1 - (sg * params.H1 / params.gamma1 - sv.alpha1_commit) * std::exp(-params.gamma1 * delta_lambda); - sv.alpha2 = sg * params.H2 / params.gamma2 - (sg * params.H2 / params.gamma2 - sv.alpha2_commit) * std::exp(-params.gamma2 * delta_lambda); - } - else { - // standard implicit evaluation of lambda - double F = lam_yield_function(); - if (F > 0.0) { - double delta_lambda = 0.0; - double dlambda = 0.0; - bool converged = false; - for (int niter = 0; niter < MAX_ITER; ++niter) { - // form tangent - double dF = lam_yield_derivative(dlambda); - if (dF == 0.0) break; - // solve for dlambda - dlambda = -F / dF; - delta_lambda += dlambda; - // update plastic multiplier increment and sigma - lam_yield_update(dlambda, delta_lambda); - // update residual - F = lam_yield_function(); - // check convergence - if (std::abs(F) < F_REL_TOL * params.sy && std::abs(dlambda) < L_ABS_TOL) { - converged = true; - // update plastic multiplier - sv.lambda += delta_lambda; - // compute tangent - sg = sign(lam_rel_stress()); - double PE = - params.gamma1 * (params.H1 / params.gamma1 - sg * sv.alpha1) + - params.gamma2 * (params.H2 / params.gamma2 - sg * sv.alpha2); - tangent = (params.E * PE) / (params.E + PE); - break; - } - } - if (!converged) - retval = -1; - } - } - // accept solution - sv.stress = sigma; - sv.C = tangent; - - // save real plastic flow direction, if mp.implex and !do_implex -> called from commit - if (params.implex && !do_implex) { - // save it in implex mode during implicit phase - sv.sg_commit = sg; + + // from macro strain to micro strain + double macro_strain = strain; + double Uy = -macro_strain * params.length; + + // compute micro response + + double N = 0.0; + double T = 0.0; + double area = 0.0; + retval = pdata->rve_m.compute(params, Uy, do_implex, time_factor, N, T); + + if (retval != 0) { + return retval; } + // from micro stress/tangent to macro stress/tangent + area = M_PI * params.radius * params.radius; + + stress = -N/area; + C = T * params.length/area; + // done return retval; } -/* -const Vector& ASDSteel1DMaterial::getImplexError() const -{ - static Vector d(1); - d(0) = params.implex_error; - return d; -}*/ \ No newline at end of file + + diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index fa081804ae..845a505373 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -38,6 +38,15 @@ #include #include +/** +todo: global material + flag computed_once -> if false -> call update + revert to start -> call update (TO SET INITIAL DATA) + +*/ + +class ASDSteel1DMaterialPIMPL; + class ASDSteel1DMaterial : public UniaxialMaterial { public: @@ -54,41 +63,17 @@ class ASDSteel1DMaterial : public UniaxialMaterial double gamma2 = 0.0; // misc bool implex = false; - double implex_error = 0.0; - double implex_time_redution_limit = 0.01; - double implex_error_tolerance = 0.05; - bool dtime_is_user_defined = false; - // True = keep IMPL-EX error under control - bool implex_control = false; + // buckling + double radius = 0.0; + double length = 0.0; + + //convergence + double K_alpha = 0.0; + double max_iter = 0.0; + double tolU = 0.0; + double tolR = 0.0; // counter - static constexpr int NDATA = 12; - }; - class StateVariablesSteel { - public: - // state variables - backstresses - double alpha1 = 0.0; - double alpha1_commit = 0.0; - double alpha2 = 0.0; - double alpha2_commit = 0.0; - // state variables - plastic multiplier - double lambda = 0.0; - double lambda_commit = 0.0; - double lambda_commit_old = 0.0; // for implex - double sg_commit = 0.0; // plastic flow dir for implex - // strain, stress and tangent - double strain = 0.0; - double strain_commit = 0.0; - double stress = 0.0; - double stress_commit = 0.0; - double C = 0.0; - // methods - static constexpr int NDATA = 13; - void commit(const InputParameters& params); - void revertToLastCommit(const InputParameters& params); - void revertToStart(const InputParameters& params); - void sendSelf(int &counter, Vector& ddata); - void recvSelf(int& counterg, Vector& ddata); - + static constexpr int NDATA = 9; }; public: @@ -97,6 +82,7 @@ class ASDSteel1DMaterial : public UniaxialMaterial int _tag, const InputParameters& _params); ASDSteel1DMaterial(); + ASDSteel1DMaterial(const ASDSteel1DMaterial& other); ~ASDSteel1DMaterial(); // info @@ -111,9 +97,6 @@ class ASDSteel1DMaterial : public UniaxialMaterial double getTangent(void); double getInitialTangent(void); - // get IMPL-EX error - const Vector& getImplexError() const; - // handle state int commitState(void); int revertToLastCommit(void); @@ -135,19 +118,15 @@ class ASDSteel1DMaterial : public UniaxialMaterial double getEnergy(void); private: - int computeBaseSteel(StateVariablesSteel& sv, bool do_implex); + int homogenize(bool do_implex); private: // common input parameters InputParameters params; - // state variables - steel - StateVariablesSteel steel; // state variables - implex double dtime_n = 0.0; double dtime_n_commit = 0.0; - double dtime_0 = 0.0; bool commit_done = false; - // strain, stress and tangent (homogenized) double strain = 0.0; double strain_commit = 0.0; @@ -156,6 +135,8 @@ class ASDSteel1DMaterial : public UniaxialMaterial double C = 0.0; // other variables for output purposes double energy = 0.0; + // private implementation + ASDSteel1DMaterialPIMPL* pdata = nullptr; }; #endif From fffede518c99aaf2b2cc9cf8f1a9e5c77a398eda Mon Sep 17 00:00:00 2001 From: alec0498 Date: Thu, 20 Mar 2025 17:33:36 +0100 Subject: [PATCH 032/261] minor fixes --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 75 ++++++++------------ SRC/material/uniaxial/ASDSteel1DMaterial.h | 2 +- 2 files changed, 32 insertions(+), 45 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index fc19fe9d37..415066ec1d 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -215,6 +215,9 @@ namespace { Vector element_U_local = Vector(6); Vector element_U_local_commit = Vector(6); Matrix element_B = Matrix(3, 6); + Matrix element_TtK = Matrix(6, 6); + Matrix element_BtC = Matrix(6, 3); + Vector element_dU = Vector(6); // RVE // node positions (to be set at each setTrialStrain) @@ -228,11 +231,11 @@ namespace { double rve_Kred = 0.0; std::array rve_nodes = { V2D(0.0, 0.0), V2D(0.0, 0.0), V2D(0.0, 0.0), V2D(0.0, 0.0) }; inline void setRVENodes(double lch) { - double dy = lch / 6.0; // consider half distance, the RVE uses symmetry + double dy = lch / 3.0; for (int i = 0; i < 4; ++i) { auto& ip = rve_nodes[i]; ip.y = dy * static_cast(i); // from bottom to top, bottom at 0,0 - ip.x = ip.y * 1.0e-3; // add imperfection + ip.x = ip.y * 1.0e-3; // add imperfection } } @@ -284,12 +287,6 @@ namespace { stress_commit = 0.0; } inline int compute(const param_t& params, bool do_implex, double time_factor, double _strain, double& sigma, double& tangent) { - // REM - /*sigma = _strain * params.E; - tangent = params.E; - return 0;*/ - - // return value int retval = 0; // settings @@ -456,13 +453,6 @@ namespace { const ASDSteel1DMaterial::InputParameters& params, const Vector& strain, bool do_implex, double time_factor, Vector& stress, Matrix& tangent) { - //// REM - //tangent.Zero(); - //tangent(0, 0) = tangent(1, 1) = tangent(2, 2) = 3000.0; - //stress.addMatrixVector(0.0, tangent, strain, 1.0); - //return 0; - - /** A section with 1 fiber is used for the central element. In this RVE model the central element has always zero curvature. However, with only 1 fiber the bending @@ -505,8 +495,7 @@ namespace { { public: std::array fibers; - //static constexpr std::array positions = { -1.0 / 2.0, 0.0, 1.0 / 2.0 }; - static constexpr std::array positions = { -1.0/3 , 0.0, 1.0/3 }; + static constexpr std::array positions = { -1.0 / 2.0, 0.0, 1.0 / 2.0 }; static constexpr std::array weights = { 1.0 / 4.0, 1.0 / 2.0, 1.0 / 4.0 }; public: @@ -731,8 +720,6 @@ namespace { { public: SectionComponent section; - SectionComponent<1> s1; - SectionComponent<3> s3; Vector UL_commit = Vector(6); std::array qn = { Q2D::identity(), Q2D::identity()}; std::array qn_commit = { Q2D::identity(), Q2D::identity() }; @@ -747,12 +734,15 @@ namespace { auto& U = globals.element_U; auto& U_commit = globals.element_U_commit; auto& UL = globals.element_U_local; + auto& dU = globals.element_dU; auto& B = globals.element_B; auto& T = globals.element_T; auto& RHS = globals.element_RHS; auto& RHSL = globals.element_RHS_local; auto& LHS = globals.element_LHS; auto& LHSL = globals.element_LHS_local; + auto& BtC = globals.element_BtC; + auto& TtK = globals.element_TtK; auto& stress_s = globals.section_stress; auto& strain_s = globals.section_strain; auto& tangent_s = globals.section_tangent; @@ -789,14 +779,7 @@ namespace { } computeLocalFrame(node_i, node_j, Q0, C0); //rve nodes - if (!do_implex) { - //to monitor the error - /* - Q2D Q_impl; - computeLocalFrame(deformed_node_i_old, deformed_node_j_old, Q_impl, C); - */ - V2D rn_current = V2D(U(2), U(5)); // rotation at current iteration V2D dtheta = rn_current - rn; // iterative correction rn = rn_current; // save current for next iteration @@ -823,7 +806,6 @@ namespace { UL(5) = (Q * qn[1] * Q0.conjugate()).toRotationVector(); } else { - /*static*/ Vector dU(6); dU = U; dU.addVector(1.0, U_commit, -1.0); UL = UL_commit; @@ -834,28 +816,28 @@ namespace { // section strain = B*U strain_s.addMatrixVector(0.0, B, UL, 1.0); + //section compute strain - stress tangent - int retval = section.compute(params, strain_s, do_implex, time_factor, stress_s, tangent_s); if (retval != 0) { opserr << "section !converged\n"; return retval; } - // RHS //B ok - + // RHS RHSL.addMatrixTransposeVector(0.0, B, stress_s, L); RHS.addMatrixTransposeVector(0.0, T, RHSL, 1.0); - // LHS - - LHSL.addMatrixTripleProduct(0.0, B, tangent_s, L); - LHS.addMatrixTripleProduct(0.0, T, LHSL, 1.0); + // LHS + BtC.addMatrixTransposeProduct(0.0, B, tangent_s, L); + LHSL.addMatrixProduct(0.0, BtC, B, 1.0); + TtK.addMatrixTransposeProduct(0.0, T, LHSL, 1.0); + LHS.addMatrixProduct(0.0, TtK, T, 1.0); + // SEMI-COMMIT if (params.implex && !do_implex) { UL_commit = UL; } - return 0; } @@ -874,6 +856,7 @@ namespace { qn_commit = { Q2D::identity(), Q2D::identity() }; rn = V2D(0.0, 0.0); rn_commit = V2D(0.0, 0.0); + UL_commit.Zero(); section.revertToStart(); } @@ -889,7 +872,7 @@ namespace { auto& globals = Globals::instance(); assembleRHS(globals.element_RHS, globals.rve_R); assembleLHS(globals.element_LHS, globals.rve_K); - + //opserr << " Etype: " << EType << "rve_r: " << globals.rve_R << ", rve_k: " << globals.rve_K << "\n"; return 0; } @@ -897,9 +880,9 @@ namespace { { public: RVEStateVariables sv; - ElementComponent<3, 1> e1; - ElementComponent<1, 2> e2; - ElementComponent<3, 3> e3; + ElementComponent<3, EType_Bot> e1; + ElementComponent<1, EType_Mid> e2; + ElementComponent<3, EType_Top> e3; RVEModel() = default; @@ -932,9 +915,10 @@ namespace { sv.UG(7) = U; // first residual - lam_assemble(); - if (lam_assemble() != 0) + if (lam_assemble() != 0) { + opserr << "1lam assemble !=0 \n"; return -1; + } // newton loop for this step // note: do it in reverse order, so that we can access the element RHS for element Bottom to get reaction double Rnorm = -1.0; @@ -954,9 +938,10 @@ namespace { } // assemble - lam_assemble(); - if (lam_assemble() != 0) + if (lam_assemble() != 0){ + opserr << "lam assemble !=0 \n"; break; + } // convergence test @@ -1179,7 +1164,7 @@ void* OPS_ASDSteel1DMaterial() params.H2 = H2 * (1.0 - alpha); params.gamma2 = gamma2; params.implex = implex; - params.length = lch; + params.length = lch / 2.0; // consider half distance, the RVE uses symmetry params.radius = r; params.K_alpha = K_alpha; params.max_iter = max_iter; @@ -1241,6 +1226,7 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) strain = v; // homogenize micro response (stress/tangent) + opserr << "MAT set trial (" << (int)params.implex << ")\n"; int retval = homogenize(params.implex); return retval; @@ -1270,6 +1256,7 @@ int ASDSteel1DMaterial::commitState(void) { // implicit stage if (params.implex) { + opserr << "MAT commit (" << (int)false << ")\n"; int retval = homogenize(false); if (retval < 0) return retval; } diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index 845a505373..2ce9af3442 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -73,7 +73,7 @@ class ASDSteel1DMaterial : public UniaxialMaterial double tolU = 0.0; double tolR = 0.0; // counter - static constexpr int NDATA = 9; + static constexpr int NDATA = 13; }; public: From d57f7af321ed5cf178aa3441a667375f57e01b18 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Fri, 21 Mar 2025 12:48:31 +0100 Subject: [PATCH 033/261] commit state fixes --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 106 +++++++++++-------- 1 file changed, 64 insertions(+), 42 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index 415066ec1d..0e2a4bb15b 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -47,6 +47,16 @@ #define M_PI 3.14159265358979323846 #endif +#define ASD_STEEL1D__VERBOSE + +#ifdef ASD_STEEL1D__VERBOSE +#define asd_print_full(X) opserr << __func__ << " (Line " << __LINE__ << "): " << X << "\n" +#define asd_print(X) opserr << X << "\n" +#else +#define asd_print_full(X) +#define asd_print(X) +#endif // ASD_STEEL1D__VERBOSE + // anonymous namespace for utilities namespace { @@ -74,7 +84,7 @@ namespace { } inline double operator()(int i) const { if (i == 0) return x; - /*if (i == 1) */return y; + return y; } }; inline V2D operator + (const V2D& a, const V2D& b) { @@ -103,7 +113,7 @@ namespace { M2D(const V2D& x, const V2D& y) : dx(x), dy(y) {} inline double operator()(int i, int j) const { if (i == 0) return dx(j); - /*else if (i == 1)*/ return dy(j); + return dy(j); } }; @@ -219,8 +229,7 @@ namespace { Matrix element_BtC = Matrix(6, 3); Vector element_dU = Vector(6); - // RVE - // node positions (to be set at each setTrialStrain) + // for RVE Vector rve_dU = Vector(7); Vector rve_R = Vector(7); Matrix rve_K = Matrix(7, 7); @@ -229,6 +238,7 @@ namespace { Vector rve_Kinv_Kcr = Vector(7); double rve_Krr = 0.0; double rve_Kred = 0.0; + // node positions (to be set at each setTrialStrain) std::array rve_nodes = { V2D(0.0, 0.0), V2D(0.0, 0.0), V2D(0.0, 0.0), V2D(0.0, 0.0) }; inline void setRVENodes(double lch) { double dy = lch / 3.0; @@ -287,13 +297,12 @@ namespace { stress_commit = 0.0; } inline int compute(const param_t& params, bool do_implex, double time_factor, double _strain, double& sigma, double& tangent) { - // return value int retval = 0; // settings constexpr int MAX_ITER = 1000; constexpr double F_REL_TOL = 1.0e-6; constexpr double L_ABS_TOL = 1.0e-8; - //constexpr double K_alpha = 0.8; //DA TARARE + //constexpr double K_alpha = 0.8; // base steel response alpha1 = alpha1_commit; alpha2 = alpha2_commit; @@ -357,11 +366,6 @@ namespace { if (dF == 0.0) break; // solve for dlambda dlambda = -F / dF; - //constexpr double max_strain_incr = 0.002; - //if (dlambda < -max_strain_incr) - // dlambda = -max_strain_incr; - //else if (dlambda > max_strain_incr) - // dlambda = max_strain_incr; delta_lambda += dlambda; // update plastic multiplier increment and sigma lam_yield_update(dlambda, delta_lambda); @@ -382,7 +386,7 @@ namespace { } } if (!converged) { - opserr << "dlambda !converged\n"; + asd_print("dlambda !converged"); retval = -1; } } @@ -644,11 +648,9 @@ namespace { if (jdof < 7) { G(idof, jdof) += M(i, j); } - } } } - } template inline void getRetainedComponents(const Matrix& M, double& Krr, Vector& Kcr, Vector& Krc) { @@ -671,8 +673,6 @@ namespace { } } - - inline M2D computeLocalFrameInternal(const V2D& X1, const V2D& X2, Q2D& Qi, V2D& C) { C = (X1 + X2) * 0.5; V2D dx = X2 - X1; @@ -688,6 +688,7 @@ namespace { } inline void computeLocalFrame(const V2D& X1, const V2D& X2, Q2D& Qi, V2D& C, Matrix& T) { M2D Ri = computeLocalFrameInternal(X1, X2, Qi, C); + //T matrix : considering P_t @ R for (int i = 0; i < 2;++i) { for (int j = 0; j < 2;++j) { T(i, j) = T(i + 3, j + 3) = Ri(i, j) / 2.0; @@ -812,7 +813,7 @@ namespace { UL.addMatrixVector(1.0, T, dU, 1.0); } - computeBmatrix(node_i, node_j, L, B); //rve nodes + computeBmatrix(node_i, node_j, L, B); //rve nodes // section strain = B*U strain_s.addMatrixVector(0.0, B, UL, 1.0); @@ -820,7 +821,7 @@ namespace { //section compute strain - stress tangent int retval = section.compute(params, strain_s, do_implex, time_factor, stress_s, tangent_s); if (retval != 0) { - opserr << "section !converged\n"; + asd_print_full("section !converged"); return retval; } @@ -866,13 +867,12 @@ namespace { inline int rve_process_element(ElementComponent& ele, const RVEStateVariables& rve, const ASDSteel1DMaterial::InputParameters& params, bool do_implex, double time_factor) { int retval = ele.compute(rve, params, do_implex, time_factor); if (retval != 0) { - opserr << "ele !converged\n"; + asd_print_full("ele !converged"); return retval; } auto& globals = Globals::instance(); assembleRHS(globals.element_RHS, globals.rve_R); assembleLHS(globals.element_LHS, globals.rve_K); - //opserr << " Etype: " << EType << "rve_r: " << globals.rve_R << ", rve_k: " << globals.rve_K << "\n"; return 0; } @@ -891,8 +891,10 @@ namespace { // output int retval = -1; - // start from previous commited state - revertToLastCommit(); + // start from previous commited state (not in implex commit) + if (!(params.implex && !do_implex)) { + revertToLastCommit(); + } // globals double tolR = params.tolR * params.sy; @@ -901,6 +903,7 @@ namespace { auto& globals = Globals::instance(); // utility for assembly + // note: do it in reverse order, so that we can access the element RHS for element Bottom to get reaction auto lam_assemble = [this, &globals, ¶ms, &do_implex, &time_factor]() -> int { // zero R and K for element integration globals.rve_R.Zero(); @@ -916,19 +919,23 @@ namespace { // first residual if (lam_assemble() != 0) { - opserr << "1lam assemble !=0 \n"; + asd_print_full("1lam assemble !=0"); return -1; } - // newton loop for this step - // note: do it in reverse order, so that we can access the element RHS for element Bottom to get reaction + double Rnorm = -1.0; double Unorm = -1.0; + + //for implicit correction convergence + static std::array U_iterative = { Vector(7), Vector(7), Vector(7), Vector(7), Vector(7), Vector(7), Vector(7), Vector(7), Vector(7), Vector(7)}; + static std::array Rnorm_iterative = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + + // newton loop for this step for (int iter = 0; iter < params.max_iter; ++iter) { // solve if (globals.rve_K.Solve(globals.rve_R, globals.rve_dU) != 0) { - opserr << "Solve failed\n"; - + asd_print_full("Solve failed"); break; } @@ -939,27 +946,44 @@ namespace { // assemble if (lam_assemble() != 0){ - opserr << "lam assemble !=0 \n"; + asd_print_full("lam assemble !=0"); break; } // convergence test - Rnorm = globals.rve_R.Norm(); Unorm = globals.rve_dU.Norm(); - opserr << " iter: " << iter << "R: " << Rnorm << ", U: " << Unorm << "\n"; + asd_print("iter: " << iter << "R: " << Rnorm << ", U: " << Unorm); + + //for implicit correction convergence (max 10 iterations) + if (params.implex && !do_implex) { + U_iterative[iter] = sv.UG; + Rnorm_iterative[iter] = Rnorm; + if (iter >= 9) { + auto minRiter = std::min_element(Rnorm_iterative.begin(), Rnorm_iterative.end()); + double minRnorm = *minRiter; + if (!std::isfinite(minRnorm)) { + Rnorm = std::numeric_limits::max(); + } + Rnorm = minRnorm; + asd_print("minRnorm"< Date: Mon, 24 Mar 2025 23:46:57 +0900 Subject: [PATCH 034/261] libaec-conig.cmake --- .github/workflows/build_cmake.yml | 6 +- CMakeLists.txt | 146 +++++++++++++++--------------- 2 files changed, 79 insertions(+), 73 deletions(-) diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 26900f8cdd..911524cf0a 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -83,6 +83,10 @@ jobs: runs-on: macos-latest timeout-minutes: 30 steps: + - name: Find libaec-config.cmake + run: | + find /usr/local -name "libaec-config.cmake" 2>/dev/null + find /opt/homebrew -name "libaec-config.cmake" 2>/dev/null - name: 2.1. Obtaining OpenSees Source Code uses: actions/checkout@v4 with: @@ -113,7 +117,7 @@ jobs: run: | mkdir build cd build - cmake .. -DMUMPS_DIR=$PWD/../../mumps/build + cmake .. -DMUMPS_DIR=$PWD/../../mumps/build -DCMAKE_PREFIX_PATH=/usr/local/Cellar/libaec/1.1.3/cmake cmake --build . --target OpenSees -j8 cmake --build . --target OpenSeesPy -j8 mv ./OpenSeesPy.dylib ./opensees.so diff --git a/CMakeLists.txt b/CMakeLists.txt index cccba0f85a..efc3a9255d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================== -# +# # OpenSees -- Open System For Earthquake Engineering Simulation # Pacific Earthquake Engineering Research Center # @@ -63,7 +63,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") MESSAGE("COMPILER: GNU") -elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel") +elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel") MESSAGE("COMPILER: Intel") add_compile_options(-fPIC) elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") @@ -75,7 +75,7 @@ else() MESSAGE("COMPILER: UKNOWN COMPILER ${CMAKE_CXX_COMPILER_ID}") endif() - + # # external packages # @@ -83,9 +83,9 @@ endif() add_library(OPS_External_packages INTERFACE) add_library(OPS_OS_Specific_libs INTERFACE) -# +# # Conan (manages external dependencies for a typical build) -# +# MESSAGE("${CMAKE_BINARY_DIR}") @@ -110,6 +110,8 @@ else() include(OpenSeesFunctions) set(NOT_USING_CONAN TRUE) set (CONAN_LIBS ) + find_package(ZLIB REQUIRED) + find_package(libaec REQUIRED) find_package(HDF5 REQUIRED) find_package(TCL REQUIRED) find_package(Eigen3 REQUIRED) @@ -120,7 +122,7 @@ else() endif() # define user-selectable options for end target -set_property(CACHE OPS_FINAL_TARGET PROPERTY STRINGS +set_property(CACHE OPS_FINAL_TARGET PROPERTY STRINGS G3 OpenSees OpenSeesMP OpenSeesSP OpenSeesPy) # @@ -142,7 +144,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") add_compile_definitions(_LINUX _UNIX _TCL85) if (NOT_USING_CONAN) include(OpenSeesDependenciesUnix) - endif() + endif() endif() if(CMAKE_SYSTEM_NAME STREQUAL "Windows") @@ -150,7 +152,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows") add_compile_definitions(_WIN32 _TCL85) if (NOT_USING_CONAN) include(OpenSeesDependenciesWin) - endif() + endif() endif() #============================================================================== @@ -159,7 +161,7 @@ endif() #============================================================================== #---------------------------------------------------------------- # Compilers -#---------------------------------------------------------------- +#---------------------------------------------------------------- # Fortran #-------------------------------------- @@ -191,7 +193,7 @@ set(CMAKE_CXX_ARCHIVE_CREATE " cqls ") # Global Includes #---------------------------------------------------------------- # include paths to main abstract classes - + # NOTE BeamIntegration and MatrixUtil need to be removed from element/forceBEamColumn include_directories( @@ -251,7 +253,7 @@ include_directories( ) # TODO: Temporary fix; include all directories with .h files through glob -file(GLOB_RECURSE ops_include_files CONFIGURE_DEPENDS +file(GLOB_RECURSE ops_include_files CONFIGURE_DEPENDS ${OPS_SRC_DIR}/*.h ${OPS_BUNDLED_DIR}/*.h ) @@ -293,13 +295,13 @@ set (TRIANGLE_LIBRARIES triangle) # set (EIGENAPI_LIBRARIES EIGENAPI) -if (NOT DEFINED LAPACK_LIBRARIES) +if (NOT DEFINED LAPACK_LIBRARIES) find_package(LAPACK) else() set (LAPACK_FOUND TRUE CACHE BOOL "providing own lapack lib") endif() -if (NOT DEFINED Python_LIBRARIES) +if (NOT DEFINED Python_LIBRARIES) find_package(Python COMPONENTS Interpreter Development) else() set (PYTHON_FOUND TRUE CACHE BOOL "providing own python lib") @@ -317,7 +319,7 @@ if(LAPACK_FOUND) message(STATUS "LAPACK_LINKER_FLAGS = ${LAPACK_LINKER_FLAGS}") message(STATUS "LAPACK_LIBRARIES = ${LAPACK_LIBRARIES}" ) else() - add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/BLAS") + add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/BLAS") add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/LAPACK") set(LAPACK_LIBRARIES LAPACK) endif() @@ -327,7 +329,7 @@ if(PYTHON_FOUND) #message("Python_VERSION:${Python_VERSION}") #message("Python_Development_FOUND:${Python_Development_FOUND}") message("Python_LIBRARIES:${Python_LIBRARIES}") - message("Python_INCLUDES:${Python_INCLUDE_DIRS}") + message("Python_INCLUDES:${Python_INCLUDE_DIRS}") else() message(STATUS "PYTHON NOT FOUND") endif() @@ -353,7 +355,7 @@ if(MPI_FOUND) set (MUMPS_FLAG -D_NOMUMPS) set (MUMPS_LIBRARIES "") else() - set (MUMPS_FLAG -D_MUMPS) + set (MUMPS_FLAG -D_MUMPS) if(CMAKE_SYSTEM_NAME STREQUAL "Windows") set (MUMPS_LIBRARIES "${MUMPS_DIR}/dmumps;${MUMPS_DIR}/mumps_common;${MUMPS_DIR}/pord") else() @@ -363,7 +365,7 @@ if(MPI_FOUND) endif() add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/SuperLU_DIST_4.3/SRC") - add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/METIS") + add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/METIS") else() message(STATUS "MPI was NOT found.") endif() @@ -377,7 +379,7 @@ if(MKL_FOUND) if(CMAKE_SYSTEM_NAME STREQUAL "Windows") set (MKL_LPATH ${MKL_ROOT}/lib/intel64) set (SCALAPACK_LIBRARIES "${MKL_LPATH}/mkl_scalapack_ilp64.lib;${MKL_LPATH}/mkl_intel_ilp64.lib;${MKL_LPATH}/mkl_sequential.lib;${MKL_LPATH}/mkl_core.lib;${MKL_LPATH}/mkl_blacs_intelmpi_ilp64.lib") - endif() + endif() else() message(STATUS "MKL NOT found .. user to provide -DSCALAPACK_LIBRARIES=") @@ -385,26 +387,26 @@ else() endif() message(STATUS "SCALAPACK_LIBRARIES=${SCALAPACK_LIBRARIES}") - + #get_cmake_property(_variableNames VARIABLES) #list (SORT _variableNames) #foreach (_variableName ${_variableNames}) # message(STATUS "${_variableName}=${${_variableName}}") -#endforeach() +#endforeach() + - add_library(OPS_Numerics INTERFACE) target_link_libraries(OPS_Numerics INTERFACE ${ARPACK_LIBRARIES} - ${CSPARSE_LIBRARIES} + ${CSPARSE_LIBRARIES} ${SUPERLU_LIBRARIES} ${UMFPACK_LIBRARIES} ${TETGEN_LIBRARIES} - ${TRIANGLE_LIBRARIES} + ${TRIANGLE_LIBRARIES} + ${AMD_LIBRARIES} ${AMD_LIBRARIES} - ${AMD_LIBRARIES} ${LAPACK_LIBRARIES} ${EIGENAPI_LIBRARIES} ) @@ -469,13 +471,13 @@ endif() # OpenSees G3 Library - a slimmed down OpenSees # -add_library(G3) +add_library(G3) target_link_libraries(G3 coordTransformation damping OPS_Matrix - OPS_Analysis + OPS_Analysis OPS_ModelBuilder OPS_Domain OPS_ConvergenceTest @@ -484,10 +486,10 @@ target_link_libraries(G3 OPS_Recorder OPS_Handler OPS_SysOfEqn - OPS_Tagged + OPS_Tagged OPS_Utilities graph - OPS_Actor + OPS_Actor OPS_ObjectBroker OPS_Numerics OPS_INTERPRETER @@ -501,19 +503,19 @@ add_library(OpenSeesLIB EXCLUDE_FROM_ALL) target_link_libraries(OpenSeesLIB ${OPS_Extension_List} - OPS_Actor - OPS_Analysis + OPS_Actor + OPS_Analysis OPS_ConvergenceTest OPS_Damage OPS_Database OPS_Domain graph OPS_Element - OPS_ElementFortran + OPS_ElementFortran OPS_Handler OPS_INTERPRETER OPS_Material - OPS_MaterialFortran + OPS_MaterialFortran OPS_Material_YieldSurface OPS_Matrix OPS_ModelBuilder @@ -526,9 +528,9 @@ target_link_libraries(OpenSeesLIB OPS_Section_Repres OPS_Section_YieldSurface OPS_SysOfEqn - OPS_Thermal + OPS_Thermal OPS_OS_Specific_libs - OPS_Tagged + OPS_Tagged OPS_Utilities ) @@ -547,7 +549,7 @@ target_link_libraries(OpenSeesLIB -add_executable(OpenSees EXCLUDE_FROM_ALL +add_executable(OpenSees EXCLUDE_FROM_ALL ${OPS_SRC_DIR}/tcl/tclAppInit.cpp ${OPS_SRC_DIR}/tcl/tclMain.cpp ${OPS_SRC_DIR}/tcl/commands.cpp @@ -560,7 +562,7 @@ if(NOT EXISTS "${CMAKE_BINARY_DIR}/conanbuildinfo.cmake") FILE(COPY ${CONAN_LIB_DIRS_TCL}/tcl8.6 DESTINATION ${PROJECT_BINARY_DIR}/lib/tcl8.6 FILES_MATCHING PATTERN .tcl) - + else () FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib/tcl8.6) add_custom_command( @@ -574,15 +576,15 @@ endif() target_link_libraries(OpenSees - OPS_InterpTcl + OPS_InterpTcl coordTransformation OpenSeesLIB OPS_Reliability - OPS_ReliabilityTcl + OPS_ReliabilityTcl OPS_Numerics OPS_Recorder - ${CMAKE_DL_LIBS} - ${HDF5_LIBRARIES} + ${CMAKE_DL_LIBS} + ${HDF5_LIBRARIES} ${CONAN_LIBS} ) @@ -594,7 +596,7 @@ target_link_libraries(OpenSees if(MPI_FOUND) - add_executable(OpenSeesSP EXCLUDE_FROM_ALL + add_executable(OpenSeesSP EXCLUDE_FROM_ALL ${OPS_SRC_DIR}/tcl/mpiMain.cpp ${OPS_SRC_DIR}/tcl/tclMain.cpp ${OPS_SRC_DIR}/tcl/commands.cpp @@ -621,15 +623,15 @@ if(MPI_FOUND) target_compile_options(OpenSeesSP PRIVATE ${MPI_CXX_COMPILE_FLAGS}) if (DEFINED OPENMPI) - target_compile_definitions(OpenSeesSP + target_compile_definitions(OpenSeesSP PUBLIC _PARALLEL_PROCESSING ${MUMPS_FLAG} _OPENMPI) else() - target_compile_definitions(OpenSeesSP + target_compile_definitions(OpenSeesSP PUBLIC _PARALLEL_PROCESSING ${MUMPS_FLAG}) endif() - target_link_libraries(OpenSeesSP - OPS_InterpTcl + target_link_libraries(OpenSeesSP + OPS_InterpTcl OpenSeesLIB OPS_Reliability OPS_ReliabilityTcl @@ -638,15 +640,15 @@ if(MPI_FOUND) SUPERLU_DIST OPS_Numerics ${MUMPS_LIBRARIES} - ${CMAKE_DL_LIBS} - ${HDF5_LIBRARIES} + ${CMAKE_DL_LIBS} + ${HDF5_LIBRARIES} ${CONAN_LIBS} ${MPI_CXX_LIBRARIES} ${SCALAPACK_LIBRARIES} - ${MPI_Fortran_LIBRARIES} + ${MPI_Fortran_LIBRARIES} ${MPI_CXX_LINK_FLAGS} ) - + endif() @@ -656,13 +658,13 @@ endif() if(MPI_FOUND) - add_executable(OpenSeesMP EXCLUDE_FROM_ALL + add_executable(OpenSeesMP EXCLUDE_FROM_ALL ${OPS_SRC_DIR}/tcl/mpiParameterMain.cpp ${OPS_SRC_DIR}/tcl/tclMain.cpp ${OPS_SRC_DIR}/tcl/commands.cpp ${OPS_SRC_DIR}/domain/domain/partitioned/PartitionedDomain.cpp ${OPS_SRC_DIR}/domain/domain/partitioned/PartitionedDomainEleIter.cpp - ${OPS_SRC_DIR}/domain/domain/partitioned/PartitionedDomainSubIter.cpp + ${OPS_SRC_DIR}/domain/domain/partitioned/PartitionedDomainSubIter.cpp ${OPS_SRC_DIR}/actor/machineBroker/MPI_MachineBroker.cpp ${OPS_SRC_DIR}/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp ${OPS_SRC_DIR}/system_of_eqn/linearSOE/diagonal/MPIDiagonalSOE.cpp @@ -678,38 +680,38 @@ if(MPI_FOUND) target_include_directories(OpenSeesMP PRIVATE ${MUMPS_DIR}/_deps/mumps-src/include ${MPI_CXX_INCLUDE_DIRS}) target_compile_options(OpenSeesMP PRIVATE ${MPI_CXX_COMPILE_FLAGS}) - + if (NOT DEFINED MUMPS_DIR) add_dependencies(OpenSeesMP mumps) - endif() + endif() if (DEFINED OPENMPI) - target_compile_definitions(OpenSeesMP + target_compile_definitions(OpenSeesMP PUBLIC _PARALLEL_INTERPRETERS ${MUMPS_FLAG} _OPENMPI) else() - target_compile_definitions(OpenSeesMP + target_compile_definitions(OpenSeesMP PUBLIC _PARALLEL_INTERPRETERS ${MUMPS_FLAG}) endif() - - target_link_libraries(OpenSeesMP - OPS_InterpTcl + + target_link_libraries(OpenSeesMP + OPS_InterpTcl OpenSeesLIB OPS_Reliability OPS_ReliabilityTcl - OPS_Recorder + OPS_Recorder METIS SUPERLU_DIST OPS_Numerics ${MUMPS_LIBRARIES} - ${CMAKE_DL_LIBS} - ${HDF5_LIBRARIES} + ${CMAKE_DL_LIBS} + ${HDF5_LIBRARIES} ${CONAN_LIBS} ${MPI_CXX_LIBRARIES} ${SCALAPACK_LIBRARIES} - ${MPI_Fortran_LIBRARIES} + ${MPI_Fortran_LIBRARIES} ${MPI_CXX_LINK_FLAGS} ) - + endif() @@ -727,12 +729,12 @@ set_target_properties(OpenSeesPy PROPERTIES PREFIX "") target_include_directories(OpenSeesPy PUBLIC ${Python_INCLUDE_DIRS}) target_link_libraries(OpenSeesPy - OpenSeesLIB + OpenSeesLIB OPS_Reliability OPS_Recorder - OPS_Numerics - ${HDF5_LIBRARIES} - ${CONAN_LIBS} + OPS_Numerics + ${HDF5_LIBRARIES} + ${CONAN_LIBS} ${Python_LIBRARIES} ) @@ -776,11 +778,11 @@ add_subdirectory(${OPS_SRC_DIR}) #---------------------------- if(FMK) add_compile_definitions( - _HAVE_Damage2p + _HAVE_Damage2p _HAVE_PSUMAT _HAVE_PML _FILIP_LHNMYS - ) + ) endif() #---------------------------- @@ -788,12 +790,12 @@ endif() #---------------------------- message("OPS >>> Configuring OpenSees extensions") foreach(extension IN LISTS OPS_SysOfEqn_List OPS_Element_List OPS_Extension_List) - string(TOUPPER "${extension}" ext_flag) + string(TOUPPER "${extension}" ext_flag) string(REGEX REPLACE "^OPS_" "OPSDEF_" ext_flag "${ext_flag}") add_compile_definitions(${ext_flag}) endforeach() foreach(extension IN LISTS OPS_Exclude_List) - string(TOUPPER "${extension}" ext_flag) + string(TOUPPER "${extension}" ext_flag) string(REGEX REPLACE "^OPS_" "OPS_EXCLUDE_" ext_flag "${ext_flag}") message(" Adding macro definition '${ext_flag}'") add_compile_definitions(${ext_flag}) @@ -842,7 +844,7 @@ if(HDF5_FOUND) if (HDF5_VERSION VERSION_GREATER_EQUAL 1.12.0) add_compile_definitions(_H5DRM) add_compile_definitions(_HDF5) - message(STATUS "OPS >>> Have HDF5 and VERSION >= 1.12.0") + message(STATUS "OPS >>> Have HDF5 and VERSION >= 1.12.0") endif() else() message(STATUS "OPS >>> Could not find HDF5") From d858116c9c634fdfb4e8b46d32ebd02058fcdd9a Mon Sep 17 00:00:00 2001 From: z-ichinohe Date: Tue, 25 Mar 2025 06:59:37 +0900 Subject: [PATCH 035/261] release --- .github/workflows/build_cmake.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 911524cf0a..b6c74adf87 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -83,10 +83,6 @@ jobs: runs-on: macos-latest timeout-minutes: 30 steps: - - name: Find libaec-config.cmake - run: | - find /usr/local -name "libaec-config.cmake" 2>/dev/null - find /opt/homebrew -name "libaec-config.cmake" 2>/dev/null - name: 2.1. Obtaining OpenSees Source Code uses: actions/checkout@v4 with: From 3c270309e766354b331aec055036913b7a9deeb7 Mon Sep 17 00:00:00 2001 From: buceaxll <166997904+buceaxll@users.noreply.github.com> Date: Tue, 25 Mar 2025 10:40:59 +0800 Subject: [PATCH 036/261] Update APDVFD.cpp --- SRC/material/uniaxial/APDVFD.cpp | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/SRC/material/uniaxial/APDVFD.cpp b/SRC/material/uniaxial/APDVFD.cpp index 448ecd4061..a5ffdc51c6 100644 --- a/SRC/material/uniaxial/APDVFD.cpp +++ b/SRC/material/uniaxial/APDVFD.cpp @@ -1,21 +1,7 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** ** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** +** Linlin Xie (xielinlin@bucea.edu.cn) ** +** Cantian Yang (yangcantian@bucea.edu.cn) ** +** Haoxiang Wang (buceawhx@163.com) ** ** ****************************************************************** */ @@ -42,7 +28,7 @@ OPS_APDVFD(void) { if (numAPDVFD == 0) { numAPDVFD++; - opserr << "APDVFD Model by BUCEA\n"; + opserr << "APDVFD Model\n"; } opserr << "Due to known issues and unreliable results, this material has been" << endln; From c0a05445fc82f4f858c8e366fe3ca6a08f5e9122 Mon Sep 17 00:00:00 2001 From: buceaxll <166997904+buceaxll@users.noreply.github.com> Date: Tue, 25 Mar 2025 10:57:18 +0800 Subject: [PATCH 037/261] Update APDFMD.cpp --- SRC/material/uniaxial/APDFMD.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/SRC/material/uniaxial/APDFMD.cpp b/SRC/material/uniaxial/APDFMD.cpp index 9362be541a..3302d89012 100644 --- a/SRC/material/uniaxial/APDFMD.cpp +++ b/SRC/material/uniaxial/APDFMD.cpp @@ -1,3 +1,9 @@ +** Developed by: ** +** Linlin Xie (xielinlin@bucea.edu.cn) ** +** Cantian Yang (yangcantian@bucea.edu.cn) ** +** Bingyan Liu (1373158715@163.com) ** +** ****************************************************************** */ + #include #include "APDFMD.h" #include @@ -12,7 +18,7 @@ void * OPS_APDFMD(void) { if (numAPDFMD == 0) { - opserr << "APDFMD unaxial material - Written by BUCEA 2024; \n"; + opserr << "APDFMD unaxial material; \n"; numAPDFMD++; } From 2583e2f2ccc951ee3adf12f83972b2b418a6610c Mon Sep 17 00:00:00 2001 From: buceaxll <166997904+buceaxll@users.noreply.github.com> Date: Tue, 25 Mar 2025 11:14:58 +0800 Subject: [PATCH 038/261] Update APDMD.cpp --- SRC/material/uniaxial/APDMD.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/SRC/material/uniaxial/APDMD.cpp b/SRC/material/uniaxial/APDMD.cpp index 981d9d2506..2664fdca21 100644 --- a/SRC/material/uniaxial/APDMD.cpp +++ b/SRC/material/uniaxial/APDMD.cpp @@ -1,3 +1,9 @@ +** Developed by: ** +** Linlin Xie (xielinlin@bucea.edu.cn) ** +** Cantian Yang (yangcantian@bucea.edu.cn) ** +** Bingyan Liu (1373158715@163.com) ** +** ****************************************************************** */ + #include #include "APDMD.h" #include @@ -12,7 +18,7 @@ void * OPS_APDMD(void) { if (numAPDMD == 0) { - opserr << "APDMD unaxial material - Written by BUCEA 2024; \n"; + opserr << "APDMD unaxial material; \n"; numAPDMD++; } From 952b5c9eebbaca110bc107dd8add3c0c770462e4 Mon Sep 17 00:00:00 2001 From: buceaxll <166997904+buceaxll@users.noreply.github.com> Date: Tue, 25 Mar 2025 11:15:22 +0800 Subject: [PATCH 039/261] Update APDVFD.cpp From 7f43495d5962487d581c5a059e7905b3ce1e6f22 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Wed, 16 Apr 2025 10:32:36 +0200 Subject: [PATCH 040/261] regularization --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 170 ++++++++++++++++--- SRC/material/uniaxial/ASDSteel1DMaterial.h | 18 +- 2 files changed, 163 insertions(+), 25 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index 0e2a4bb15b..9a07de26d8 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -1040,7 +1040,8 @@ class ASDSteel1DMaterialPIMPL ASDSteel1DMaterialPIMPL() = default; ASDSteel1DMaterialPIMPL(const ASDSteel1DMaterialPIMPL&) = default; public: - RVEModel rve_m; + SteelComponent steel_comp; + RVEModel rve_m; }; void* OPS_ASDSteel1DMaterial() @@ -1052,7 +1053,7 @@ void* OPS_ASDSteel1DMaterial() opserr << "Using ASDSteel1D - Developed by: Alessia Casalucci, Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; first_done = true; } - static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu $lch $r <-implex $implex> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; + static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu $lch $r <-implex $implex> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR> <-p $p> <-n $n>"; // check arguments int numArgs = OPS_GetNumRemainingInputArgs(); @@ -1078,10 +1079,15 @@ void* OPS_ASDSteel1DMaterial() double max_iter= 100; double tolU = 1.0e-6; double tolR = 1.0e-6; + double p = 1.0; + double n = 1.0; bool have_K_alpha = false; bool have_max_iter = false; bool have_tolU = false; bool have_tolR = false; + bool have_p = false; + bool have_n = false; + // get tag if (OPS_GetInt(&numData, &tag) != 0) { @@ -1147,6 +1153,16 @@ void* OPS_ASDSteel1DMaterial() return nullptr; have_tolR = true; } + if (strcmp(value, "-p") == 0) { + if (!lam_optional_double("p", p)) + return nullptr; + have_p = true; + } + if (strcmp(value, "-n") == 0) { + if (!lam_optional_double("n", n)) + return nullptr; + have_n = true; + } } // checks @@ -1194,6 +1210,9 @@ void* OPS_ASDSteel1DMaterial() params.max_iter = max_iter; params.tolU = tolU; params.tolR = tolR; + params.p = p; + params.n = n; + params.lch_element = params.length; // create the material UniaxialMaterial* instance = new ASDSteel1DMaterial( // tag @@ -1206,6 +1225,9 @@ void* OPS_ASDSteel1DMaterial() opserr << "UniaxialMaterial ASDSteel1D Error: failed to allocate a new material.\n"; return nullptr; } + + dynamic_cast(instance)->computeAlphaCr(); + return instance; } @@ -1229,6 +1251,20 @@ ASDSteel1DMaterial::ASDSteel1DMaterial() ASDSteel1DMaterial::ASDSteel1DMaterial(const ASDSteel1DMaterial& other) : UniaxialMaterial(other.getTag(), MAT_TAG_ASDSteel1DMaterial) , params(other.params) + , dtime_n(other.dtime_n) + , dtime_n_commit(other.dtime_n_commit) + , commit_done(other.commit_done) + , strain(other.strain) + , strain_commit(other.strain_commit) + , stress(other.stress) + , stress_commit(other.stress_commit) + , C(other.C) + , stress_rve(other.stress_rve) + , stress_rve_commit(other.stress_rve_commit) + , C_rve(other.C_rve) + , energy(other.energy) + , use_regularization(other.use_regularization) + , alpha_cr(other.alpha_cr) , pdata(other.pdata ? new ASDSteel1DMaterialPIMPL(*other.pdata) : nullptr) { } @@ -1240,6 +1276,7 @@ ASDSteel1DMaterial::~ASDSteel1DMaterial() int ASDSteel1DMaterial::setTrialStrain(double v, double r) { + params.lch_element = ops_TheActiveElement ? ops_TheActiveElement->getCharacteristicLength()/2 : params.length; // save dT dtime_n = ops_Dt; if (!commit_done) { @@ -1252,7 +1289,44 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) asd_print("MAT set trial (" << (int)params.implex << ")"); int retval = homogenize(params.implex); + double sigma_macro = 0.0; + double tangent_macro = 0.0; + // time factor for explicit extrapolation (todo: make a unique function) + double time_factor = 1.0; + if (params.implex && (dtime_n_commit > 0.0)) + time_factor = dtime_n / dtime_n_commit; + //computation of sigma and tangent of steel + pdata->steel_comp.revertToLastCommit(); + pdata->steel_comp.compute(params, params.implex, time_factor, strain, sigma_macro, tangent_macro); + + //regularization for element length lower than physical length (weighted average) + if (use_regularization) { + double alpha0 = 0.0; + double alpha = 0.0; + double p = 2.0; + double n = 2.0; + if (params.lch_element < params.length) { + //horizontal displacement/physical length + double buckstrain = std::abs((params.implex ? pdata->rve_m.sv.UG_commit(6) : pdata->rve_m.sv.UG(6)) / params.length); + double axiallimit = 0.05; + //from relation between max strain and horizontal disp + double bucklimit = std::sqrt(2.0 * axiallimit - axiallimit * axiallimit) / 2.0; + alpha0 = alpha_cr + (1 - alpha_cr) * std::pow((params.lch_element / params.length), params.p); + alpha = std::min(1.0, alpha0 + (1-alpha0) * buckstrain / (std::pow((params.length /params.lch_element),params.n) * bucklimit)); + } + else if (params.lch_element >= params.length) { + alpha = 1.0; + } + stress = (alpha) * stress_rve +(1.0 - alpha) * sigma_macro; + C = alpha * C_rve + ( 1.0 - alpha) * tangent_macro ; + } + else { + C = C_rve; + stress = stress_rve; + } + + // done return retval; } @@ -1283,6 +1357,9 @@ int ASDSteel1DMaterial::commitState(void) asd_print("MAT commit (" << (int)false << ")"); int retval = homogenize(false); if (retval < 0) return retval; + double sigma_macro = 0.0; + double tangent_macro = 0.0; + retval = pdata->steel_comp.compute(params, false, 1.0, strain, sigma_macro, tangent_macro); } // compute energy @@ -1290,6 +1367,7 @@ int ASDSteel1DMaterial::commitState(void) // forward to all components pdata->rve_m.commitState(); + pdata->steel_comp.commitState(); // state variables strain_commit = strain; @@ -1307,10 +1385,12 @@ int ASDSteel1DMaterial::revertToLastCommit(void) { // forward to all components pdata->rve_m.revertToLastCommit(); + pdata->steel_comp.revertToLastCommit(); // state variables strain = strain_commit; stress = stress_commit; + stress_rve = stress_rve_commit; // implex dtime_n = dtime_n_commit; @@ -1323,13 +1403,17 @@ int ASDSteel1DMaterial::revertToStart(void) { // forward to all components pdata->rve_m.revertToStart(); + pdata->steel_comp.revertToStart(); // strain, stress and tangent strain = 0.0; strain_commit = 0.0; stress = 0.0; stress_commit = 0.0; + stress_rve = 0.0; + stress_rve_commit = 0.0; C = getInitialTangent(); + C_rve = getInitialTangent(); // implex dtime_n = 0.0; @@ -1456,19 +1540,19 @@ Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Strea }; // labels - static std::vector lb_eqpl_strain = { "PLE" }; + static std::vector lb_buckling_ratio = { "BI" }; // all outputs are 1D static Vector out1(1); - //// check specific responses - //if (argc > 0) { - // // 1000 - base steel output - // if (strcmp(argv[0], "equivalentPlasticStrain") == 0 || strcmp(argv[0], "EquivalentPlasticStrain") == 0) { - // out1(0) = steel.lambda; - // return make_resp(1001, out1, &lb_eqpl_strain); - // } - //} + // check specific responses + if (argc > 0) { + // 1000 - base steel output + if (strcmp(argv[0], "BI") == 0 || strcmp(argv[0], "BucklingIndicator") == 0) { + out1(0) = pdata->rve_m.sv.UG(6); + return make_resp(1001, out1, &lb_buckling_ratio); + } + } // otherwise return base-class response return UniaxialMaterial::setResponse(argv, argc, output); @@ -1479,14 +1563,14 @@ int ASDSteel1DMaterial::getResponse(int responseID, Information& matInformation) // all outputs are 1D static Vector out1(1); - //switch (responseID) { - // // 1000 - base steel output - //case 1001: - // out1(0) = steel.lambda; - // return matInformation.setVector(out1); - //default: - // break; - //} + switch (responseID) { + // 1000 - base steel output + case 1001: + out1(0) = pdata->rve_m.sv.UG(6); + return matInformation.setVector(out1); + default: + break; + } return UniaxialMaterial::getResponse(responseID, matInformation); } @@ -1508,13 +1592,11 @@ int ASDSteel1DMaterial::homogenize(bool do_implex) if (params.implex && do_implex && (dtime_n_commit > 0.0)) time_factor = dtime_n / dtime_n_commit; - // from macro strain to micro strain double macro_strain = strain; double Uy = -macro_strain * params.length; // compute micro response - double N = 0.0; double T = 0.0; double area = 0.0; @@ -1527,11 +1609,53 @@ int ASDSteel1DMaterial::homogenize(bool do_implex) // from micro stress/tangent to macro stress/tangent area = M_PI * params.radius * params.radius; - stress = -N/area; - C = T * params.length/area; + stress_rve = -N/area; + C_rve = T * params.length/area; // done return retval; } +void ASDSteel1DMaterial::computeAlphaCr() +{ + //preliminary check to determine whether it requires regularization + constexpr int nstep = 100; + constexpr double cstrain = -0.05; + constexpr double d_cstrain = cstrain / nstep; + double residual_stress = 0.0; + // simulate rve steel + use_regularization = false; + + for(int i = 0; i < nstep; ++i) { + setTrialStrain(static_cast(i + 1) * d_cstrain); + commitState(); + residual_stress = -getStress(); + } + + if (residual_stress >= params.sy) { + return; + } + + revertToStart(); + + // simulate no-buckling steel + double residual_stress_nb = 0.0; + double tangent_macro = 0.0; + + for (int i = 0; i < nstep; ++i) { + pdata->steel_comp.revertToLastCommit(); + pdata->steel_comp.compute(params, false, 1.0, cstrain, residual_stress_nb, tangent_macro); + pdata->steel_comp.commitState(); + residual_stress_nb *= -1.0; + } + + pdata->steel_comp.revertToStart(); + + // compute min alpha cr that shows softening + alpha_cr = (params.sy * 0.95 - residual_stress_nb) / (residual_stress - residual_stress_nb); + + use_regularization = true; + +} + diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index 2ce9af3442..19e12b4d14 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -66,14 +66,17 @@ class ASDSteel1DMaterial : public UniaxialMaterial // buckling double radius = 0.0; double length = 0.0; + double lch_element = 0.0; //convergence double K_alpha = 0.0; double max_iter = 0.0; double tolU = 0.0; double tolR = 0.0; + double p = 0.0; + double n = 0.0; // counter - static constexpr int NDATA = 13; + static constexpr int NDATA = 16; }; public: @@ -120,7 +123,10 @@ class ASDSteel1DMaterial : public UniaxialMaterial private: int homogenize(bool do_implex); - private: +public: + void computeAlphaCr(); + + private: // common input parameters InputParameters params; // state variables - implex @@ -133,8 +139,16 @@ class ASDSteel1DMaterial : public UniaxialMaterial double stress = 0.0; double stress_commit = 0.0; double C = 0.0; + double stress_rve = 0.0; + double stress_rve_commit = 0.0; + double C_rve = 0.0; + // other variables for output purposes double energy = 0.0; + + //for regularization + bool use_regularization = true; + double alpha_cr = 1.0; // private implementation ASDSteel1DMaterialPIMPL* pdata = nullptr; }; From 091c65d769cb6cf1e5045a0f52a35d75741c1b6f Mon Sep 17 00:00:00 2001 From: alec0498 Date: Tue, 29 Apr 2025 18:18:57 +0200 Subject: [PATCH 041/261] regularization fixes --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 607 +++++++++++++------ SRC/material/uniaxial/ASDSteel1DMaterial.h | 11 +- 2 files changed, 411 insertions(+), 207 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index 9a07de26d8..9d11bcdf65 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -236,6 +236,12 @@ namespace { Vector rve_Kcr = Vector(7); Vector rve_Krc = Vector(7); Vector rve_Kinv_Kcr = Vector(7); + Vector rve_dU_el = Vector(10); + Vector rve_R_el = Vector(10); + Matrix rve_K_el = Matrix(10, 10); + Vector rve_Kcr_el = Vector(10); + Vector rve_Krc_el = Vector(10); + Vector rve_Kinv_Kcr_el = Vector(10); double rve_Krr = 0.0; double rve_Kred = 0.0; // node positions (to be set at each setTrialStrain) @@ -248,7 +254,18 @@ namespace { ip.x = ip.y * 1.0e-3; // add imperfection } } - + std::array rve_nodes_el = { V2D(0.0, 0.0), V2D(0.0, 0.0), V2D(0.0, 0.0), V2D(0.0, 0.0), V2D(0.0, 0.0) }; + inline void setRVENodes_el(double lch, double length_el) { + double dy = lch / 3.0; + double y_el = (length_el - lch); + for (int i = 1; i < 5; ++i) { + auto& ip = rve_nodes_el[i]; + ip.y = dy * static_cast(i-1) + y_el; // from bottom to top, bottom at 0,0 + ip.x = ip.y * 1.0e-3; // add imperfection + } + rve_nodes_el[0].y = 0.0; + rve_nodes_el[0].x = 0.0; + } }; /** @@ -563,6 +580,54 @@ namespace { return 0; } }; + template<> + class SectionComponent<0> + { + public: + SteelComponent fib; + + public: + SectionComponent() = default; + inline int commitState() { + return 0; + } + inline void revertToLastCommit() { + } + inline void revertToStart() { + } + + inline int compute( + const ASDSteel1DMaterial::InputParameters& params, const Vector& strain, + bool do_implex, double time_factor, + Vector& stress, Matrix& tangent) { + /** + A section with 0 fiber is used for the elastic element. + */ + int retval = 0.0; + double constexpr poiss = 0.3; // built-in poisson ratio + double constexpr kshear = 0.9; // built-in shear correction factor for circular sections + // area + double area = M_PI * params.radius * params.radius; + // compute elastic shear response + double G = params.E / (2.0 * (1.0 + poiss)); + double GAk = G * area * kshear; + tangent(2, 2) = GAk; + stress(2) = GAk * strain(2); + // compute elastic M response (will be zero upon convergence for this model) + double I = M_PI * std::pow(params.radius, 4) / 4.0; + double EI = params.E * I; + stress(1) = EI * strain(1); + tangent(1, 1) = EI; + // compute elastic shear response + double EA = params.E * area; + stress(0) = EA * strain(0); + tangent(0, 0) = EA; + // zero terms + tangent(0, 1) = tangent(1, 0) = tangent(0, 2) = tangent(2, 0) = tangent(1, 2) = tangent(2, 1) = 0.0; + // done + return retval; + } + }; /** @@ -587,6 +652,7 @@ namespace { constexpr int EType_Bot = 1; constexpr int EType_Mid = 2; constexpr int EType_Top = 3; + constexpr int EType_El = 0; template class ETypeTraits { @@ -596,78 +662,150 @@ namespace { { public: static constexpr std::array DOFs = {8,7,9, 0,1,2 }; - static constexpr int N1 = 0; - static constexpr int N2 = 1; + static constexpr int N1 = 1; + static constexpr int N2 = 2; }; template<> class ETypeTraits { public: static constexpr std::array DOFs = { 0,1,2, 3,4,5 }; - static constexpr int N1 = 1; - static constexpr int N2 = 2; + static constexpr int N1 = 2; + static constexpr int N2 = 3; }; template<> class ETypeTraits { public: static constexpr std::array DOFs = { 3,4,5, 6,10,11 }; - static constexpr int N1 = 2; - static constexpr int N2 = 3; + static constexpr int N1 = 3; + static constexpr int N2 = 4; + }; + template<> + class ETypeTraits + { + public: + static constexpr std::array DOFs = { 12,13,14, 8,7,9 }; + static constexpr int N1 = 0; + static constexpr int N2 = 1; }; template - inline void getElementDisplacementVector(const Vector& G, Vector& L) { + inline void getElementDisplacementVector(bool flag, const Vector& G, Vector& L) { // G = global vector, size = 8 -> full = 12, semi-full 8 (7 free + 1 Uy imposed) // L = local vector , size = 6 - for (int i = 0; i < 6; ++i) { - int gdof = ETypeTraits::DOFs[i]; - L(i) = gdof < 8 ? G(gdof) : 0.0; + if (flag) { + for (int i = 0; i < 6; ++i) { + int gdof = ETypeTraits::DOFs[i]; + if (gdof < 10 ) { + L(i) = G(gdof); + + } + else if (gdof == 13) { + L(i) = G(10); + } + else { + L(i) = 0.0; + } + } + } + else { + for (int i = 0; i < 6; ++i) { + int gdof = ETypeTraits::DOFs[i]; + L(i) = gdof < 8 ? G(gdof) : 0.0; + } } } template - inline void assembleRHS(const Vector& L, Vector& G) { + inline void assembleRHS(bool flag, const Vector& L, Vector& G) { // G = global vector, size = 7 (-> full = 12, semi-full 8 (7 free + 1 Uy imposed) only free) // L = local vector , size = 6 - for (int i = 0; i < 6; ++i) { - int gdof = ETypeTraits::DOFs[i]; - if (gdof < 7) { - G(gdof) += L(i); + if (flag) { + for (int i = 0; i < 6; ++i) { + int gdof = ETypeTraits::DOFs[i]; + if (gdof < 10) { + G(gdof) += L(i); + } } } + else { + for (int i = 0; i < 6; ++i) { + int gdof = ETypeTraits::DOFs[i]; + if (gdof < 7) { + G(gdof) += L(i); + } + } + } } template - inline void assembleLHS(const Matrix& M, Matrix& G) { + inline void assembleLHS(bool flag, const Matrix& M, Matrix& G) { // G = global matrix, size = 7x7 -> full = 12x12, semi-full 8 (7 free + 1 Uy imposed) // L = local vector , size = 6 // M = local matrix , size = 6x6 - for (int i = 0; i < 6; ++i) { - int idof = ETypeTraits::DOFs[i]; - if (idof < 7) { - for (int j = 0; j < 6; ++j) { - int jdof = ETypeTraits::DOFs[j]; - if (jdof < 7) { - G(idof, jdof) += M(i, j); + if (flag) { + for (int i = 0; i < 6; ++i) { + int idof = ETypeTraits::DOFs[i]; + if (idof < 10) { + for (int j = 0; j < 6; ++j) { + int jdof = ETypeTraits::DOFs[j]; + if (jdof < 10) { + G(idof, jdof) += M(i, j); + } + } + } + } + } + else { + for (int i = 0; i < 6; ++i) { + int idof = ETypeTraits::DOFs[i]; + if (idof < 7) { + for (int j = 0; j < 6; ++j) { + int jdof = ETypeTraits::DOFs[j]; + if (jdof < 7) { + G(idof, jdof) += M(i, j); + } } } } } + } template - inline void getRetainedComponents(const Matrix& M, double& Krr, Vector& Kcr, Vector& Krc) { - for (int i = 0; i < 6; ++i) { - int idof = ETypeTraits::DOFs[i]; - for (int j = 0; j < 6; ++j) { - int jdof = ETypeTraits::DOFs[j]; - if (idof == 7) { - if (jdof == 7) { - Krr = M(i, j); + inline void getRetainedComponents(bool flag, const Matrix& M, double& Krr, Vector& Kcr, Vector& Krc) { + if (flag) { + for (int i = 0; i < 6; ++i) { + int idof = ETypeTraits::DOFs[i]; + for (int j = 0; j < 6; ++j) { + int jdof = ETypeTraits::DOFs[j]; + if (idof == 13) { + if (jdof == 13) { + Krr = M(i, j); + } + else if (jdof < 10) { //it is used to assemble krc and kcr for the bottom element -> jdof will be always < 3 + Krc(jdof) = M(i, j); + } } - else if (jdof < 7) { //it is used to assemble krc and kcr for the bottom element -> jdof will be always < 3 - Krc(jdof) = M(i, j); + else if (jdof == 13 && idof < 10) { + Kcr(idof) = M(j, i); } } - else if (jdof == 7 && idof < 7) { - Kcr(idof) = M(j, i); + } + } + else { + for (int i = 0; i < 6; ++i) { + int idof = ETypeTraits::DOFs[i]; + for (int j = 0; j < 6; ++j) { + int jdof = ETypeTraits::DOFs[j]; + if (idof == 7) { + if (jdof == 7) { + Krr = M(i, j); + } + else if (jdof < 7) { //it is used to assemble krc and kcr for the bottom element -> jdof will be always < 3 + Krc(jdof) = M(i, j); + } + } + else if (jdof == 7 && idof < 7) { + Kcr(idof) = M(j, i); + } } } } @@ -711,6 +849,8 @@ namespace { public: Vector UG = Vector(8); Vector UG_commit = Vector(8); + Vector UG_el = Vector(11); + Vector UG_el_commit = Vector(11); }; /** @@ -729,7 +869,7 @@ namespace { ElementComponent() = default; - inline int compute(const RVEStateVariables& rve, const ASDSteel1DMaterial::InputParameters& params, bool do_implex, double time_factor ) { + inline int compute(bool flag, const RVEStateVariables& rve, const ASDSteel1DMaterial::InputParameters& params, bool do_implex, double time_factor ) { auto& globals = Globals::instance(); auto& U = globals.element_U; @@ -748,17 +888,43 @@ namespace { auto& strain_s = globals.section_strain; auto& tangent_s = globals.section_tangent; auto& rve_nodes = globals.rve_nodes; + auto& rve_nodes_el = globals.rve_nodes_el; + int inode; + int jnode; + if (flag) { + inode = ETypeTraits::N1; + jnode = ETypeTraits::N2; + } + else { + inode = ETypeTraits::N1-1; + jnode = ETypeTraits::N2-1; + } + + + if (flag) { + getElementDisplacementVector(flag, rve.UG_el, U); + getElementDisplacementVector(flag, rve.UG_el_commit, U_commit); + } + else { - int inode = ETypeTraits::N1; - int jnode = ETypeTraits::N2; + getElementDisplacementVector(flag, rve.UG, U); + getElementDisplacementVector(flag, rve.UG_commit, U_commit); + } - getElementDisplacementVector(rve.UG, U); - getElementDisplacementVector(rve.UG_commit, U_commit); // undeformed nodes - V2D node_i = rve_nodes[inode]; - V2D node_j = rve_nodes[jnode]; - + V2D node_i; + V2D node_j; + if (flag) { + node_i = rve_nodes_el[inode]; + node_j = rve_nodes_el[jnode]; + } + else { + node_i = rve_nodes[inode]; + node_j = rve_nodes[jnode]; + } + + //deformed node position V2D deformed_node_i = node_i +V2D(U(0), U(1)); V2D deformed_node_j = node_j +V2D(U(3), U(4)); @@ -864,15 +1030,22 @@ namespace { }; template - inline int rve_process_element(ElementComponent& ele, const RVEStateVariables& rve, const ASDSteel1DMaterial::InputParameters& params, bool do_implex, double time_factor) { - int retval = ele.compute(rve, params, do_implex, time_factor); + inline int rve_process_element(bool flag, ElementComponent& ele, const RVEStateVariables& rve, const ASDSteel1DMaterial::InputParameters& params, bool do_implex, double time_factor) { + int retval = ele.compute(flag, rve, params, do_implex, time_factor); if (retval != 0) { asd_print_full("ele !converged"); return retval; } auto& globals = Globals::instance(); - assembleRHS(globals.element_RHS, globals.rve_R); - assembleLHS(globals.element_LHS, globals.rve_K); + if (flag) { + assembleRHS(flag, globals.element_RHS, globals.rve_R_el); + assembleLHS(flag, globals.element_LHS, globals.rve_K_el); + } + else { + + assembleRHS(flag, globals.element_RHS, globals.rve_R); + assembleLHS(flag, globals.element_LHS, globals.rve_K); + } return 0; } @@ -883,10 +1056,11 @@ namespace { ElementComponent<3, EType_Bot> e1; ElementComponent<1, EType_Mid> e2; ElementComponent<3, EType_Top> e3; + ElementComponent<0, EType_El> e0; RVEModel() = default; - inline int compute(const ASDSteel1DMaterial::InputParameters& params, double U, bool do_implex, double time_factor, double& N, double& tangent) { + inline int compute(bool flag, const ASDSteel1DMaterial::InputParameters& params, double U, bool do_implex, double time_factor, double& N, double& tangent) { // output int retval = -1; @@ -904,19 +1078,41 @@ namespace { // utility for assembly // note: do it in reverse order, so that we can access the element RHS for element Bottom to get reaction - auto lam_assemble = [this, &globals, ¶ms, &do_implex, &time_factor]() -> int { + auto lam_assemble = [this, flag, &globals, ¶ms, &do_implex, &time_factor]() -> int { // zero R and K for element integration globals.rve_R.Zero(); globals.rve_K.Zero(); - if (rve_process_element< 3, EType_Top>(e3, sv, params, do_implex, time_factor) != 0) return -1; - if (rve_process_element< 1, EType_Mid>(e2, sv, params, do_implex, time_factor) != 0) return -1; - if (rve_process_element< 3, EType_Bot>(e1, sv, params, do_implex, time_factor) != 0) return -1; + globals.rve_R_el.Zero(); + globals.rve_K_el.Zero(); + if (flag) { + if (rve_process_element< 3, EType_Top>(flag, e3, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 1, EType_Mid>(flag, e2, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 3, EType_Bot>(flag, e1, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 0, EType_El>(flag, e0, sv, params, do_implex, time_factor) != 0) return -1; + } + else { + if (rve_process_element< 3, EType_Top>(flag, e3, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 1, EType_Mid>(flag, e2, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 3, EType_Bot>(flag, e1, sv, params, do_implex, time_factor) != 0) return -1; + double I = M_PI * std::pow(params.radius, 4) / 4.0; + double EI = params.E * I; + double fact = 0.04 * params.length / (params.radius * 5.0); + double penalty = 12.0 * EI * fact / std::pow(2.0*params.length, 3.0); + double KReg = std::max(0.0, (params.length / params.lch_element - 1)) * penalty; + globals.rve_K(6, 6) = globals.rve_K(6, 6) + KReg; + globals.rve_R(6) = globals.rve_R(6) + KReg * sv.UG(6); + } return 0; }; // impose BC - sv.UG(7) = U; - + if (flag) { + sv.UG_el(10) = U; + } + else { + sv.UG(7) = U; + } + // first residual if (lam_assemble() != 0) { asd_print_full("1lam assemble !=0"); @@ -928,72 +1124,136 @@ namespace { //for implicit correction convergence static std::array U_iterative = { Vector(7), Vector(7), Vector(7), Vector(7), Vector(7), Vector(7), Vector(7), Vector(7), Vector(7), Vector(7)}; + static std::array U_iterative_el = { Vector(10), Vector(10), Vector(10), Vector(10), Vector(10), Vector(10), Vector(10), Vector(10), Vector(10), Vector(10) }; static std::array Rnorm_iterative = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; // newton loop for this step for (int iter = 0; iter < params.max_iter; ++iter) { // solve - if (globals.rve_K.Solve(globals.rve_R, globals.rve_dU) != 0) { - asd_print_full("Solve failed"); - break; - } + if (flag) { + if (globals.rve_K_el.Solve(globals.rve_R_el, globals.rve_dU_el) != 0) { + asd_print_full("Solve failed"); + break; + } - // update free DOFs - for (int i = 0; i < 7; ++i) { - sv.UG(i) -= globals.rve_dU(i); - } + // update free DOFs + for (int i = 0; i < 10; ++i) { + sv.UG_el(i) -= globals.rve_dU_el(i); + } + + // assemble + if (lam_assemble() != 0) { + asd_print_full("lam assemble !=0"); + break; + } - // assemble - if (lam_assemble() != 0){ - asd_print_full("lam assemble !=0"); - break; - } - - // convergence test - Rnorm = globals.rve_R.Norm(); - Unorm = globals.rve_dU.Norm(); - asd_print("iter: " << iter << "R: " << Rnorm << ", U: " << Unorm); - - //for implicit correction convergence (max 10 iterations) - if (params.implex && !do_implex) { - U_iterative[iter] = sv.UG; - Rnorm_iterative[iter] = Rnorm; - if (iter >= 9) { - auto minRiter = std::min_element(Rnorm_iterative.begin(), Rnorm_iterative.end()); - double minRnorm = *minRiter; - if (!std::isfinite(minRnorm)) { - Rnorm = std::numeric_limits::max(); + // convergence test + + Rnorm = globals.rve_R_el.Norm(); + Unorm = globals.rve_dU_el.Norm(); + asd_print("iter: " << iter << "R: " << Rnorm << ", U: " << Unorm); + + //for implicit correction convergence (max 10 iterations) + if (params.implex && !do_implex) { + U_iterative_el[iter] = sv.UG_el; + Rnorm_iterative[iter] = Rnorm; + if (iter >= 9) { + auto minRiter = std::min_element(Rnorm_iterative.begin(), Rnorm_iterative.end()); + double minRnorm = *minRiter; + if (!std::isfinite(minRnorm)) { + Rnorm = std::numeric_limits::max(); + } + Rnorm = minRnorm; + asd_print("minRnorm" << minRnorm); + int pos_min = std::distance(Rnorm_iterative.begin(), minRiter); + sv.UG_el = U_iterative_el[pos_min]; + lam_assemble(); + retval = 0; + break; } - Rnorm = minRnorm; - asd_print("minRnorm"<= 9) { + auto minRiter = std::min_element(Rnorm_iterative.begin(), Rnorm_iterative.end()); + double minRnorm = *minRiter; + if (!std::isfinite(minRnorm)) { + Rnorm = std::numeric_limits::max(); + } + Rnorm = minRnorm; + asd_print("minRnorm" << minRnorm); + int pos_min = std::distance(Rnorm_iterative.begin(), minRiter); + sv.UG = U_iterative[pos_min]; + lam_assemble(); + retval = 0; + break; + } + } + + if (Rnorm < tolR || Unorm < tolU) { + retval = 0; + break; + } + } + } if (retval != 0) { asd_print_full("rve !converged"); } - + double Krc_dot_Kinv_Kcr = 0.0; // do it outside, element Bottom is the last one - getRetainedComponents(globals.element_LHS, globals.rve_Krr, globals.rve_Kcr, globals.rve_Krc); + if (flag) { + getRetainedComponents(flag, globals.element_LHS, globals.rve_Krr, globals.rve_Kcr_el, globals.rve_Krc_el); + globals.rve_K_el.Solve(globals.rve_Kcr_el, globals.rve_Kinv_Kcr_el); + Krc_dot_Kinv_Kcr = globals.rve_Krc_el ^ globals.rve_Kinv_Kcr_el; + } + else { + + getRetainedComponents(flag, globals.element_LHS, globals.rve_Krr, globals.rve_Kcr, globals.rve_Krc); + globals.rve_K.Solve(globals.rve_Kcr, globals.rve_Kinv_Kcr); + Krc_dot_Kinv_Kcr = globals.rve_Krc ^ globals.rve_Kinv_Kcr; + } // get N from element_RHS (note: RHS = Fext-Fint) N = globals.element_RHS(1); // perform static condensation // Kred = Krr - (Krc * inv(Kcc)*Kcr) - globals.rve_K.Solve(globals.rve_Kcr, globals.rve_Kinv_Kcr); - double Krc_dot_Kinv_Kcr = globals.rve_Krc ^ globals.rve_Kinv_Kcr; + + globals.rve_Kred = globals.rve_Krr - Krc_dot_Kinv_Kcr; tangent = globals.rve_Kred; return retval; @@ -1003,7 +1263,7 @@ namespace { int retval = 0; sv.UG_commit = sv.UG; - + sv.UG_el_commit = sv.UG_el; int el_retval; el_retval = e1.commitState(); if (el_retval != 0) retval = el_retval; @@ -1011,11 +1271,15 @@ namespace { if (el_retval != 0) retval = el_retval; el_retval = e3.commitState(); if (el_retval != 0) retval = el_retval; + el_retval = e0.commitState(); + if (el_retval != 0) retval = el_retval; return retval; } inline void revertToLastCommit() { sv.UG = sv.UG_commit; + sv.UG_el = sv.UG_el_commit; + e0.revertToLastCommit(); e1.revertToLastCommit(); e2.revertToLastCommit(); e3.revertToLastCommit(); @@ -1023,6 +1287,9 @@ namespace { inline void revertToStart() { sv.UG.Zero(); sv.UG_commit.Zero(); + sv.UG_el.Zero(); + sv.UG_el_commit.Zero(); + e0.revertToStart(); e1.revertToStart(); e2.revertToStart(); e3.revertToStart(); @@ -1053,7 +1320,7 @@ void* OPS_ASDSteel1DMaterial() opserr << "Using ASDSteel1D - Developed by: Alessia Casalucci, Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; first_done = true; } - static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu $lch $r <-implex $implex> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR> <-p $p> <-n $n>"; + static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu $lch $r <-implex $implex> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; // check arguments int numArgs = OPS_GetNumRemainingInputArgs(); @@ -1079,14 +1346,10 @@ void* OPS_ASDSteel1DMaterial() double max_iter= 100; double tolU = 1.0e-6; double tolR = 1.0e-6; - double p = 1.0; - double n = 1.0; bool have_K_alpha = false; bool have_max_iter = false; bool have_tolU = false; bool have_tolR = false; - bool have_p = false; - bool have_n = false; // get tag @@ -1153,16 +1416,6 @@ void* OPS_ASDSteel1DMaterial() return nullptr; have_tolR = true; } - if (strcmp(value, "-p") == 0) { - if (!lam_optional_double("p", p)) - return nullptr; - have_p = true; - } - if (strcmp(value, "-n") == 0) { - if (!lam_optional_double("n", n)) - return nullptr; - have_n = true; - } } // checks @@ -1210,8 +1463,6 @@ void* OPS_ASDSteel1DMaterial() params.max_iter = max_iter; params.tolU = tolU; params.tolR = tolR; - params.p = p; - params.n = n; params.lch_element = params.length; // create the material UniaxialMaterial* instance = new ASDSteel1DMaterial( @@ -1225,8 +1476,6 @@ void* OPS_ASDSteel1DMaterial() opserr << "UniaxialMaterial ASDSteel1D Error: failed to allocate a new material.\n"; return nullptr; } - - dynamic_cast(instance)->computeAlphaCr(); return instance; } @@ -1263,8 +1512,7 @@ ASDSteel1DMaterial::ASDSteel1DMaterial(const ASDSteel1DMaterial& other) , stress_rve_commit(other.stress_rve_commit) , C_rve(other.C_rve) , energy(other.energy) - , use_regularization(other.use_regularization) - , alpha_cr(other.alpha_cr) + , elastic_correction(other.elastic_correction) , pdata(other.pdata ? new ASDSteel1DMaterialPIMPL(*other.pdata) : nullptr) { } @@ -1282,50 +1530,36 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) if (!commit_done) { dtime_n_commit = dtime_n; } - + if (params.lch_element > params.length) { + elastic_correction = true; + } // save macro strain strain = v; // homogenize micro response (stress/tangent) asd_print("MAT set trial (" << (int)params.implex << ")"); - int retval = homogenize(params.implex); - double sigma_macro = 0.0; - double tangent_macro = 0.0; + int retval; // time factor for explicit extrapolation (todo: make a unique function) - double time_factor = 1.0; - if (params.implex && (dtime_n_commit > 0.0)) - time_factor = dtime_n / dtime_n_commit; - - //computation of sigma and tangent of steel - pdata->steel_comp.revertToLastCommit(); - pdata->steel_comp.compute(params, params.implex, time_factor, strain, sigma_macro, tangent_macro); + //double time_factor = 1.0; + //if (params.implex && (dtime_n_commit > 0.0)) + // time_factor = dtime_n / dtime_n_commit; + // + ////computation of sigma and tangent of steel + //pdata->steel_comp.revertToLastCommit(); + //pdata->steel_comp.compute(params, params.implex, time_factor, strain, sigma_macro, tangent_macro); //regularization for element length lower than physical length (weighted average) - if (use_regularization) { - double alpha0 = 0.0; - double alpha = 0.0; - double p = 2.0; - double n = 2.0; - if (params.lch_element < params.length) { - //horizontal displacement/physical length - double buckstrain = std::abs((params.implex ? pdata->rve_m.sv.UG_commit(6) : pdata->rve_m.sv.UG(6)) / params.length); - double axiallimit = 0.05; - //from relation between max strain and horizontal disp - double bucklimit = std::sqrt(2.0 * axiallimit - axiallimit * axiallimit) / 2.0; - alpha0 = alpha_cr + (1 - alpha_cr) * std::pow((params.lch_element / params.length), params.p); - alpha = std::min(1.0, alpha0 + (1-alpha0) * buckstrain / (std::pow((params.length /params.lch_element),params.n) * bucklimit)); - } - else if (params.lch_element >= params.length) { - alpha = 1.0; - } - stress = (alpha) * stress_rve +(1.0 - alpha) * sigma_macro; - C = alpha * C_rve + ( 1.0 - alpha) * tangent_macro ; + if (elastic_correction) { + retval = homogenize(elastic_correction, params.implex); + C = C_rve; + stress = stress_rve; } - else { + else { + retval = homogenize(false, params.implex); C = C_rve; stress = stress_rve; } - + // done return retval; } @@ -1355,7 +1589,7 @@ int ASDSteel1DMaterial::commitState(void) // implicit stage if (params.implex) { asd_print("MAT commit (" << (int)false << ")"); - int retval = homogenize(false); + int retval = homogenize(elastic_correction,false); if (retval < 0) return retval; double sigma_macro = 0.0; double tangent_macro = 0.0; @@ -1579,13 +1813,18 @@ double ASDSteel1DMaterial::getEnergy(void) return energy; } -int ASDSteel1DMaterial::homogenize(bool do_implex) +int ASDSteel1DMaterial::homogenize(bool flag, bool do_implex) { // return value int retval = 0; auto& globals = Globals::instance(); - globals.setRVENodes(params.length); + if (flag) { + globals.setRVENodes_el(params.length,params.lch_element); + } + else { + globals.setRVENodes(params.length); + } // time factor for explicit extrapolation double time_factor = 1.0; @@ -1594,13 +1833,17 @@ int ASDSteel1DMaterial::homogenize(bool do_implex) // from macro strain to micro strain double macro_strain = strain; - double Uy = -macro_strain * params.length; - - // compute micro response + double Uy; + if (flag) { + Uy = -macro_strain * params.lch_element; + } + else { + Uy = -macro_strain * params.length; + } double N = 0.0; double T = 0.0; double area = 0.0; - retval = pdata->rve_m.compute(params, Uy, do_implex, time_factor, N, T); + retval = pdata->rve_m.compute(flag,params, Uy, do_implex, time_factor, N, T); if (retval != 0) { return retval; @@ -1610,52 +1853,18 @@ int ASDSteel1DMaterial::homogenize(bool do_implex) area = M_PI * params.radius * params.radius; stress_rve = -N/area; - C_rve = T * params.length/area; - - // done - return retval; -} - -void ASDSteel1DMaterial::computeAlphaCr() -{ - //preliminary check to determine whether it requires regularization - constexpr int nstep = 100; - constexpr double cstrain = -0.05; - constexpr double d_cstrain = cstrain / nstep; - double residual_stress = 0.0; - // simulate rve steel - use_regularization = false; - - for(int i = 0; i < nstep; ++i) { - setTrialStrain(static_cast(i + 1) * d_cstrain); - commitState(); - residual_stress = -getStress(); + if (flag) { + C_rve = T * params.lch_element / area; } - - if (residual_stress >= params.sy) { - return; + else { + C_rve = T * params.length / area; } - - revertToStart(); - // simulate no-buckling steel - double residual_stress_nb = 0.0; - double tangent_macro = 0.0; - - for (int i = 0; i < nstep; ++i) { - pdata->steel_comp.revertToLastCommit(); - pdata->steel_comp.compute(params, false, 1.0, cstrain, residual_stress_nb, tangent_macro); - pdata->steel_comp.commitState(); - residual_stress_nb *= -1.0; - } - pdata->steel_comp.revertToStart(); + // done + return retval; +} - // compute min alpha cr that shows softening - alpha_cr = (params.sy * 0.95 - residual_stress_nb) / (residual_stress - residual_stress_nb); - - use_regularization = true; -} diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index 19e12b4d14..554c0470bc 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -73,10 +73,8 @@ class ASDSteel1DMaterial : public UniaxialMaterial double max_iter = 0.0; double tolU = 0.0; double tolR = 0.0; - double p = 0.0; - double n = 0.0; // counter - static constexpr int NDATA = 16; + static constexpr int NDATA = 14; }; public: @@ -121,10 +119,8 @@ class ASDSteel1DMaterial : public UniaxialMaterial double getEnergy(void); private: - int homogenize(bool do_implex); + int homogenize(bool flag, bool do_implex); -public: - void computeAlphaCr(); private: // common input parameters @@ -147,8 +143,7 @@ class ASDSteel1DMaterial : public UniaxialMaterial double energy = 0.0; //for regularization - bool use_regularization = true; - double alpha_cr = 1.0; + bool elastic_correction = false; // private implementation ASDSteel1DMaterialPIMPL* pdata = nullptr; }; From 4fe914e5468df4af6dc58c07a2a131fbd84f6666 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Wed, 30 Apr 2025 11:00:28 +0200 Subject: [PATCH 042/261] buckling option --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 54 +++++++++++--------- SRC/material/uniaxial/ASDSteel1DMaterial.h | 7 ++- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index 9d11bcdf65..8952dac8c4 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -1320,7 +1320,7 @@ void* OPS_ASDSteel1DMaterial() opserr << "Using ASDSteel1D - Developed by: Alessia Casalucci, Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; first_done = true; } - static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu $lch $r <-implex $implex> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; + static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu $lch $r <-implex $implex> <-buckling $buckling> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; // check arguments int numArgs = OPS_GetNumRemainingInputArgs(); @@ -1342,6 +1342,7 @@ void* OPS_ASDSteel1DMaterial() double lch; double r; bool implex = false; + bool buckling = false; double K_alpha = 0.5; double max_iter= 100; double tolU = 1.0e-6; @@ -1396,6 +1397,9 @@ void* OPS_ASDSteel1DMaterial() if (strcmp(value, "-implex") == 0) { implex = true; } + if (strcmp(value, "-buckling") == 0) { + buckling = true; + } if (strcmp(value, "-K_alpha") == 0) { if (!lam_optional_double("K_alpha", K_alpha)) return nullptr; @@ -1457,6 +1461,7 @@ void* OPS_ASDSteel1DMaterial() params.H2 = H2 * (1.0 - alpha); params.gamma2 = gamma2; params.implex = implex; + params.buckling = buckling; params.length = lch / 2.0; // consider half distance, the RVE uses symmetry params.radius = r; params.K_alpha = K_alpha; @@ -1512,7 +1517,6 @@ ASDSteel1DMaterial::ASDSteel1DMaterial(const ASDSteel1DMaterial& other) , stress_rve_commit(other.stress_rve_commit) , C_rve(other.C_rve) , energy(other.energy) - , elastic_correction(other.elastic_correction) , pdata(other.pdata ? new ASDSteel1DMaterialPIMPL(*other.pdata) : nullptr) { } @@ -1530,9 +1534,10 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) if (!commit_done) { dtime_n_commit = dtime_n; } - if (params.lch_element > params.length) { - elastic_correction = true; - } + double time_factor = 1.0; + if (params.implex && (dtime_n_commit > 0.0)) + time_factor = dtime_n / dtime_n_commit; + // save macro strain strain = v; // homogenize micro response (stress/tangent) @@ -1540,26 +1545,22 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) asd_print("MAT set trial (" << (int)params.implex << ")"); int retval; // time factor for explicit extrapolation (todo: make a unique function) - //double time_factor = 1.0; - //if (params.implex && (dtime_n_commit > 0.0)) - // time_factor = dtime_n / dtime_n_commit; - // - ////computation of sigma and tangent of steel - //pdata->steel_comp.revertToLastCommit(); - //pdata->steel_comp.compute(params, params.implex, time_factor, strain, sigma_macro, tangent_macro); - - //regularization for element length lower than physical length (weighted average) - if (elastic_correction) { - retval = homogenize(elastic_correction, params.implex); + + if (params.buckling) { + //regularization for element length lower than physical length (weighted average) + retval = homogenize(params.implex); C = C_rve; stress = stress_rve; } else { - retval = homogenize(false, params.implex); - C = C_rve; - stress = stress_rve; + opserr << "HERE\n"; + ////computation of sigma and tangent of steel + pdata->steel_comp.revertToLastCommit(); + pdata->steel_comp.compute(params, params.implex, time_factor, strain, stress, C); } + // then apply damage on stress e C + // done return retval; } @@ -1589,7 +1590,7 @@ int ASDSteel1DMaterial::commitState(void) // implicit stage if (params.implex) { asd_print("MAT commit (" << (int)false << ")"); - int retval = homogenize(elastic_correction,false); + int retval = homogenize(false); if (retval < 0) return retval; double sigma_macro = 0.0; double tangent_macro = 0.0; @@ -1813,13 +1814,16 @@ double ASDSteel1DMaterial::getEnergy(void) return energy; } -int ASDSteel1DMaterial::homogenize(bool flag, bool do_implex) +int ASDSteel1DMaterial::homogenize(bool do_implex) { // return value int retval = 0; + // check for elastic correction + bool elastic_correction = params.lch_element > params.length; + auto& globals = Globals::instance(); - if (flag) { + if (elastic_correction) { globals.setRVENodes_el(params.length,params.lch_element); } else { @@ -1834,7 +1838,7 @@ int ASDSteel1DMaterial::homogenize(bool flag, bool do_implex) // from macro strain to micro strain double macro_strain = strain; double Uy; - if (flag) { + if (elastic_correction) { Uy = -macro_strain * params.lch_element; } else { @@ -1843,7 +1847,7 @@ int ASDSteel1DMaterial::homogenize(bool flag, bool do_implex) double N = 0.0; double T = 0.0; double area = 0.0; - retval = pdata->rve_m.compute(flag,params, Uy, do_implex, time_factor, N, T); + retval = pdata->rve_m.compute(elastic_correction, params, Uy, do_implex, time_factor, N, T); if (retval != 0) { return retval; @@ -1853,7 +1857,7 @@ int ASDSteel1DMaterial::homogenize(bool flag, bool do_implex) area = M_PI * params.radius * params.radius; stress_rve = -N/area; - if (flag) { + if (elastic_correction) { C_rve = T * params.lch_element / area; } else { diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index 554c0470bc..7aee145bdf 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -63,6 +63,7 @@ class ASDSteel1DMaterial : public UniaxialMaterial double gamma2 = 0.0; // misc bool implex = false; + bool buckling = false; // buckling double radius = 0.0; double length = 0.0; @@ -74,7 +75,7 @@ class ASDSteel1DMaterial : public UniaxialMaterial double tolU = 0.0; double tolR = 0.0; // counter - static constexpr int NDATA = 14; + static constexpr int NDATA = 15; }; public: @@ -119,7 +120,7 @@ class ASDSteel1DMaterial : public UniaxialMaterial double getEnergy(void); private: - int homogenize(bool flag, bool do_implex); + int homogenize(bool do_implex); private: @@ -142,8 +143,6 @@ class ASDSteel1DMaterial : public UniaxialMaterial // other variables for output purposes double energy = 0.0; - //for regularization - bool elastic_correction = false; // private implementation ASDSteel1DMaterialPIMPL* pdata = nullptr; }; From 3ce6924aa48d0b8374d7fc1d0e613413c8cf9492 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Tue, 6 May 2025 15:25:42 +0200 Subject: [PATCH 043/261] fracture --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 307 ++++++++++--------- SRC/material/uniaxial/ASDSteel1DMaterial.h | 5 +- 2 files changed, 165 insertions(+), 147 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index 8952dac8c4..d5db3d1a0e 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -281,6 +281,7 @@ namespace { // store the previously committed variables for next move from n to n - 1 lambda_commit_old = lambda_commit; // state variables + epl_commit = epl; alpha1_commit = alpha1; alpha2_commit = alpha2; lambda_commit = lambda; @@ -291,6 +292,7 @@ namespace { } inline void revertToLastCommit() { // state variables + epl = epl_commit; alpha1 = alpha1_commit; alpha2 = alpha2_commit; lambda = lambda_commit; @@ -299,6 +301,8 @@ namespace { } inline void revertToStart() { // state variables + epl = 0.0; + epl_commit = 0.0; alpha1 = 0.0; alpha1_commit = 0.0; alpha2 = 0.0; @@ -324,6 +328,7 @@ namespace { alpha1 = alpha1_commit; alpha2 = alpha2_commit; lambda = lambda_commit; + epl = epl_commit; // elastic predictor strain = _strain; double dstrain = strain - strain_commit; @@ -358,12 +363,15 @@ namespace { }; // plastic corrector if (params.implex && do_implex) { + // extrapolate plastic flow direction + sg = sg_commit; // extrapolate lambda // xn + time_factor * (xn - xnn); double delta_lambda = time_factor * (lambda_commit - lambda_commit_old); lambda = lambda_commit + delta_lambda; - // extrapolate plastic flow direction - sg = sg_commit; + // update plastic strain + if (sg > 0.0) + epl = epl_commit + sg * delta_lambda; // update stress sigma -= sg * delta_lambda * params.E; // update backstress @@ -391,10 +399,13 @@ namespace { // check convergence if (std::abs(F) < F_REL_TOL * params.sy && std::abs(dlambda) < L_ABS_TOL) { converged = true; + sg = sign(lam_rel_stress()); // update plastic multiplier lambda += delta_lambda; + // update plastic strain + if (sg > 0.0) + epl += sg * delta_lambda; // compute tangent - sg = sign(lam_rel_stress()); double PE = params.gamma1 * (params.H1 / params.gamma1 - sg * alpha1) + params.gamma2 * (params.H2 / params.gamma2 - sg * alpha2); @@ -425,6 +436,9 @@ namespace { double alpha1_commit = 0.0; double alpha2 = 0.0; double alpha2_commit = 0.0; + // positive plastic strain (for fracture) + double epl = 0.0; + double epl_commit = 0.0; // state variables - plastic multiplier double lambda = 0.0; double lambda_commit = 0.0; @@ -580,55 +594,6 @@ namespace { return 0; } }; - template<> - class SectionComponent<0> - { - public: - SteelComponent fib; - - public: - SectionComponent() = default; - inline int commitState() { - return 0; - } - inline void revertToLastCommit() { - } - inline void revertToStart() { - } - - inline int compute( - const ASDSteel1DMaterial::InputParameters& params, const Vector& strain, - bool do_implex, double time_factor, - Vector& stress, Matrix& tangent) { - /** - A section with 0 fiber is used for the elastic element. - */ - int retval = 0.0; - double constexpr poiss = 0.3; // built-in poisson ratio - double constexpr kshear = 0.9; // built-in shear correction factor for circular sections - // area - double area = M_PI * params.radius * params.radius; - // compute elastic shear response - double G = params.E / (2.0 * (1.0 + poiss)); - double GAk = G * area * kshear; - tangent(2, 2) = GAk; - stress(2) = GAk * strain(2); - // compute elastic M response (will be zero upon convergence for this model) - double I = M_PI * std::pow(params.radius, 4) / 4.0; - double EI = params.E * I; - stress(1) = EI * strain(1); - tangent(1, 1) = EI; - // compute elastic shear response - double EA = params.E * area; - stress(0) = EA * strain(0); - tangent(0, 0) = EA; - // zero terms - tangent(0, 1) = tangent(1, 0) = tangent(0, 2) = tangent(2, 0) = tangent(1, 2) = tangent(2, 1) = 0.0; - // done - return retval; - } - }; - /** Element Traits: @@ -690,10 +655,10 @@ namespace { static constexpr int N2 = 1; }; template - inline void getElementDisplacementVector(bool flag, const Vector& G, Vector& L) { + inline void getElementDisplacementVector(bool elastic_correction, const Vector& G, Vector& L) { // G = global vector, size = 8 -> full = 12, semi-full 8 (7 free + 1 Uy imposed) // L = local vector , size = 6 - if (flag) { + if (elastic_correction) { for (int i = 0; i < 6; ++i) { int gdof = ETypeTraits::DOFs[i]; if (gdof < 10 ) { @@ -716,10 +681,10 @@ namespace { } } template - inline void assembleRHS(bool flag, const Vector& L, Vector& G) { + inline void assembleRHS(bool elastic_correction, const Vector& L, Vector& G) { // G = global vector, size = 7 (-> full = 12, semi-full 8 (7 free + 1 Uy imposed) only free) // L = local vector , size = 6 - if (flag) { + if (elastic_correction) { for (int i = 0; i < 6; ++i) { int gdof = ETypeTraits::DOFs[i]; if (gdof < 10) { @@ -737,11 +702,11 @@ namespace { } } template - inline void assembleLHS(bool flag, const Matrix& M, Matrix& G) { + inline void assembleLHS(bool elastic_correction, const Matrix& M, Matrix& G) { // G = global matrix, size = 7x7 -> full = 12x12, semi-full 8 (7 free + 1 Uy imposed) // L = local vector , size = 6 // M = local matrix , size = 6x6 - if (flag) { + if (elastic_correction) { for (int i = 0; i < 6; ++i) { int idof = ETypeTraits::DOFs[i]; if (idof < 10) { @@ -770,8 +735,8 @@ namespace { } template - inline void getRetainedComponents(bool flag, const Matrix& M, double& Krr, Vector& Kcr, Vector& Krc) { - if (flag) { + inline void getRetainedComponents(bool elastic_correction, const Matrix& M, double& Krr, Vector& Kcr, Vector& Krc) { + if (elastic_correction) { for (int i = 0; i < 6; ++i) { int idof = ETypeTraits::DOFs[i]; for (int j = 0; j < 6; ++j) { @@ -835,6 +800,17 @@ namespace { } T(2,2) = T(5,5) = 1.0; } + inline void computeLocalFrameLinearKin(const V2D& X1, const V2D& X2, Q2D& Qi, V2D& C, Matrix& T) { + M2D Ri = computeLocalFrameInternal(X1, X2, Qi, C); + //T matrix : R + for (int i = 0; i < 2;++i) { + for (int j = 0; j < 2;++j) { + T(i, j) = T(i + 3, j + 3) = Ri(i, j); + T(i, j + 3) = T(i + 3, j) = 0.0; + } + } + T(2, 2) = T(5, 5) = 1.0; + } inline void computeBmatrix(const V2D& X1, const V2D& X2, double& L,Matrix& B) { V2D dx = X2 - X1; @@ -869,8 +845,9 @@ namespace { ElementComponent() = default; - inline int compute(bool flag, const RVEStateVariables& rve, const ASDSteel1DMaterial::InputParameters& params, bool do_implex, double time_factor ) { + inline int compute(bool elastic_correction, const RVEStateVariables& rve, const ASDSteel1DMaterial::InputParameters& params, bool do_implex, double time_factor ) { + // get global variables auto& globals = Globals::instance(); auto& U = globals.element_U; auto& U_commit = globals.element_U_commit; @@ -889,9 +866,11 @@ namespace { auto& tangent_s = globals.section_tangent; auto& rve_nodes = globals.rve_nodes; auto& rve_nodes_el = globals.rve_nodes_el; + + // determine node numbering (changes for elastic correction) int inode; int jnode; - if (flag) { + if (elastic_correction) { inode = ETypeTraits::N1; jnode = ETypeTraits::N2; } @@ -900,22 +879,21 @@ namespace { jnode = ETypeTraits::N2-1; } - - if (flag) { - getElementDisplacementVector(flag, rve.UG_el, U); - getElementDisplacementVector(flag, rve.UG_el_commit, U_commit); + // obtain global displacement vectors (size changes for elastic correction) + if (elastic_correction) { + getElementDisplacementVector(elastic_correction, rve.UG_el, U); + getElementDisplacementVector(elastic_correction, rve.UG_el_commit, U_commit); } else { - - getElementDisplacementVector(flag, rve.UG, U); - getElementDisplacementVector(flag, rve.UG_commit, U_commit); + getElementDisplacementVector(elastic_correction, rve.UG, U); + getElementDisplacementVector(elastic_correction, rve.UG_commit, U_commit); } // undeformed nodes V2D node_i; V2D node_j; - if (flag) { + if (elastic_correction) { node_i = rve_nodes_el[inode]; node_j = rve_nodes_el[jnode]; } @@ -924,61 +902,78 @@ namespace { node_j = rve_nodes[jnode]; } - - //deformed node position - V2D deformed_node_i = node_i +V2D(U(0), U(1)); - V2D deformed_node_j = node_j +V2D(U(3), U(4)); - - V2D deformed_node_i_old = node_i + V2D(U_commit(0), U_commit(1)); - V2D deformed_node_j_old = node_j + V2D(U_commit(3), U_commit(4)); - - Q2D Q, Q0; - + // current orientation and center + Q2D Q; V2D C; - V2D C0; - double L = 0.0; - - if (do_implex) { - computeLocalFrame(deformed_node_i_old, deformed_node_j_old, Q, C, T); //deformed old nodes + if (EType == EType_El) { + + // use linear kinematics + computeLocalFrameLinearKin(node_i, node_j, Q, C, T); // undeformed nodes + UL.addMatrixVector(0.0, T, U, 1.0); } else { - computeLocalFrame(deformed_node_i, deformed_node_j, Q, C, T); //deformed nodes - } - computeLocalFrame(node_i, node_j, Q0, C0); //rve nodes - - if (!do_implex) { - V2D rn_current = V2D(U(2), U(5)); // rotation at current iteration - V2D dtheta = rn_current - rn; // iterative correction - rn = rn_current; // save current for next iteration - for (int i = 0; i < 2; ++i) { - qn[i] = Q2D::fromRotationVector(dtheta(i)) * qn[i]; // increment quaterion from previous iteration + + // use nonlinear (corotational) kinematics + + if (!do_implex) { + + // computed deformed node position + V2D deformed_node_i = node_i + V2D(U(0), U(1)); + V2D deformed_node_j = node_j + V2D(U(3), U(4)); + + // compute local frame in current configuration + computeLocalFrame(deformed_node_i, deformed_node_j, Q, C, T); + + // compute also local frame in the undeformed configuration + Q2D Q0; + V2D C0; + computeLocalFrame(node_i, node_j, Q0, C0); + + V2D rn_current = V2D(U(2), U(5)); // rotation at current iteration + V2D dtheta = rn_current - rn; // iterative correction + rn = rn_current; // save current for next iteration + for (int i = 0; i < 2; ++i) { + qn[i] = Q2D::fromRotationVector(dtheta(i)) * qn[i]; // increment quaterion from previous iteration + } + + //position vectors in local reference frame + V2D rf_node1_position = Q0.rotateVector(node_i - C0); + V2D rf_node2_position = Q0.rotateVector(node_j - C0); + + //deformed position vectors in local current frame + V2D cf_node1_deformed = Q.rotateVector(deformed_node_i - C); + V2D cf_node2_deformed = Q.rotateVector(deformed_node_j - C); + + // translational part of deformational local displacements + UL(0) = cf_node1_deformed.x - rf_node1_position.x; + UL(1) = cf_node1_deformed.y - rf_node1_position.y; + UL(3) = cf_node2_deformed.x - rf_node2_position.x; + UL(4) = cf_node2_deformed.y - rf_node2_position.y; + + // rotational part of deformational local rotation + UL(2) = (Q * qn[0] * Q0.conjugate()).toRotationVector(); + UL(5) = (Q * qn[1] * Q0.conjugate()).toRotationVector(); } + else { - //position vectors in local reference frame - V2D rf_node1_position = Q0.rotateVector(node_i - C0); - V2D rf_node2_position = Q0.rotateVector(node_j - C0); + // computed deformed node position with committed displacement + V2D deformed_node_i_old = node_i + V2D(U_commit(0), U_commit(1)); + V2D deformed_node_j_old = node_j + V2D(U_commit(3), U_commit(4)); - //deformed position vectors in local current frame - V2D cf_node1_deformed = Q.rotateVector(deformed_node_i - C); - V2D cf_node2_deformed = Q.rotateVector(deformed_node_j - C); + // compute local frame in deformed committed configuration + computeLocalFrame(deformed_node_i_old, deformed_node_j_old, Q, C, T); - // translational part of deformational local displacements - UL(0) = cf_node1_deformed.x - rf_node1_position.x; - UL(1) = cf_node1_deformed.y - rf_node1_position.y; - UL(3) = cf_node2_deformed.x - rf_node2_position.x; - UL(4) = cf_node2_deformed.y - rf_node2_position.y; + // transform only the incremental part with this explicit approximation + dU = U; + dU.addVector(1.0, U_commit, -1.0); + UL = UL_commit; + UL.addMatrixVector(1.0, T, dU, 1.0); + } - // rotational part of deformational local rotation - UL(2) = (Q * qn[0] * Q0.conjugate()).toRotationVector(); - UL(5) = (Q * qn[1] * Q0.conjugate()).toRotationVector(); - } - else { - dU = U; - dU.addVector(1.0, U_commit, -1.0); - UL = UL_commit; - UL.addMatrixVector(1.0, T, dU, 1.0); } - + + // strain-displacement matrix in local frame + double L = 0.0; computeBmatrix(node_i, node_j, L, B); //rve nodes // section strain = B*U @@ -1030,21 +1025,21 @@ namespace { }; template - inline int rve_process_element(bool flag, ElementComponent& ele, const RVEStateVariables& rve, const ASDSteel1DMaterial::InputParameters& params, bool do_implex, double time_factor) { - int retval = ele.compute(flag, rve, params, do_implex, time_factor); + inline int rve_process_element(bool elastic_correction, ElementComponent& ele, const RVEStateVariables& rve, const ASDSteel1DMaterial::InputParameters& params, bool do_implex, double time_factor) { + int retval = ele.compute(elastic_correction, rve, params, do_implex, time_factor); if (retval != 0) { asd_print_full("ele !converged"); return retval; } auto& globals = Globals::instance(); - if (flag) { - assembleRHS(flag, globals.element_RHS, globals.rve_R_el); - assembleLHS(flag, globals.element_LHS, globals.rve_K_el); + if (elastic_correction) { + assembleRHS(elastic_correction, globals.element_RHS, globals.rve_R_el); + assembleLHS(elastic_correction, globals.element_LHS, globals.rve_K_el); } else { - assembleRHS(flag, globals.element_RHS, globals.rve_R); - assembleLHS(flag, globals.element_LHS, globals.rve_K); + assembleRHS(elastic_correction, globals.element_RHS, globals.rve_R); + assembleLHS(elastic_correction, globals.element_LHS, globals.rve_K); } return 0; } @@ -1056,11 +1051,11 @@ namespace { ElementComponent<3, EType_Bot> e1; ElementComponent<1, EType_Mid> e2; ElementComponent<3, EType_Top> e3; - ElementComponent<0, EType_El> e0; + ElementComponent<1, EType_El> e0; // nonlinear section (1 fiber), but linear kinematics RVEModel() = default; - inline int compute(bool flag, const ASDSteel1DMaterial::InputParameters& params, double U, bool do_implex, double time_factor, double& N, double& tangent) { + inline int compute(bool elastic_correction, const ASDSteel1DMaterial::InputParameters& params, double U, bool do_implex, double time_factor, double& N, double& tangent) { // output int retval = -1; @@ -1078,22 +1073,22 @@ namespace { // utility for assembly // note: do it in reverse order, so that we can access the element RHS for element Bottom to get reaction - auto lam_assemble = [this, flag, &globals, ¶ms, &do_implex, &time_factor]() -> int { + auto lam_assemble = [this, elastic_correction, &globals, ¶ms, &do_implex, &time_factor]() -> int { // zero R and K for element integration globals.rve_R.Zero(); globals.rve_K.Zero(); globals.rve_R_el.Zero(); globals.rve_K_el.Zero(); - if (flag) { - if (rve_process_element< 3, EType_Top>(flag, e3, sv, params, do_implex, time_factor) != 0) return -1; - if (rve_process_element< 1, EType_Mid>(flag, e2, sv, params, do_implex, time_factor) != 0) return -1; - if (rve_process_element< 3, EType_Bot>(flag, e1, sv, params, do_implex, time_factor) != 0) return -1; - if (rve_process_element< 0, EType_El>(flag, e0, sv, params, do_implex, time_factor) != 0) return -1; + if (elastic_correction) { + if (rve_process_element< 3, EType_Top>(elastic_correction, e3, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 1, EType_Mid>(elastic_correction, e2, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 3, EType_Bot>(elastic_correction, e1, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 1, EType_El>(elastic_correction, e0, sv, params, do_implex, time_factor) != 0) return -1; } else { - if (rve_process_element< 3, EType_Top>(flag, e3, sv, params, do_implex, time_factor) != 0) return -1; - if (rve_process_element< 1, EType_Mid>(flag, e2, sv, params, do_implex, time_factor) != 0) return -1; - if (rve_process_element< 3, EType_Bot>(flag, e1, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 3, EType_Top>(elastic_correction, e3, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 1, EType_Mid>(elastic_correction, e2, sv, params, do_implex, time_factor) != 0) return -1; + if (rve_process_element< 3, EType_Bot>(elastic_correction, e1, sv, params, do_implex, time_factor) != 0) return -1; double I = M_PI * std::pow(params.radius, 4) / 4.0; double EI = params.E * I; double fact = 0.04 * params.length / (params.radius * 5.0); @@ -1106,7 +1101,7 @@ namespace { }; // impose BC - if (flag) { + if (elastic_correction) { sv.UG_el(10) = U; } else { @@ -1131,7 +1126,7 @@ namespace { for (int iter = 0; iter < params.max_iter; ++iter) { // solve - if (flag) { + if (elastic_correction) { if (globals.rve_K_el.Solve(globals.rve_R_el, globals.rve_dU_el) != 0) { asd_print_full("Solve failed"); break; @@ -1237,14 +1232,14 @@ namespace { } double Krc_dot_Kinv_Kcr = 0.0; // do it outside, element Bottom is the last one - if (flag) { - getRetainedComponents(flag, globals.element_LHS, globals.rve_Krr, globals.rve_Kcr_el, globals.rve_Krc_el); + if (elastic_correction) { + getRetainedComponents(elastic_correction, globals.element_LHS, globals.rve_Krr, globals.rve_Kcr_el, globals.rve_Krc_el); globals.rve_K_el.Solve(globals.rve_Kcr_el, globals.rve_Kinv_Kcr_el); Krc_dot_Kinv_Kcr = globals.rve_Krc_el ^ globals.rve_Kinv_Kcr_el; } else { - getRetainedComponents(flag, globals.element_LHS, globals.rve_Krr, globals.rve_Kcr, globals.rve_Krc); + getRetainedComponents(elastic_correction, globals.element_LHS, globals.rve_Krr, globals.rve_Kcr, globals.rve_Krc); globals.rve_K.Solve(globals.rve_Kcr, globals.rve_Kinv_Kcr); Krc_dot_Kinv_Kcr = globals.rve_Krc ^ globals.rve_Kinv_Kcr; } @@ -1320,7 +1315,7 @@ void* OPS_ASDSteel1DMaterial() opserr << "Using ASDSteel1D - Developed by: Alessia Casalucci, Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; first_done = true; } - static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu $lch $r <-implex $implex> <-buckling $buckling> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; + static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu $lch $r <-implex $implex> <-buckling $buckling> <-fracture $fracture> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; // check arguments int numArgs = OPS_GetNumRemainingInputArgs(); @@ -1343,6 +1338,7 @@ void* OPS_ASDSteel1DMaterial() double r; bool implex = false; bool buckling = false; + bool fracture = false; double K_alpha = 0.5; double max_iter= 100; double tolU = 1.0e-6; @@ -1400,6 +1396,9 @@ void* OPS_ASDSteel1DMaterial() if (strcmp(value, "-buckling") == 0) { buckling = true; } + if (strcmp(value, "-fracture") == 0) { + fracture = true; + } if (strcmp(value, "-K_alpha") == 0) { if (!lam_optional_double("K_alpha", K_alpha)) return nullptr; @@ -1456,12 +1455,14 @@ void* OPS_ASDSteel1DMaterial() ASDSteel1DMaterial::InputParameters params; params.E = E; params.sy = sy; + params.eu = eu; params.H1 = H1 * alpha; params.gamma1 = gamma1; params.H2 = H2 * (1.0 - alpha); params.gamma2 = gamma2; params.implex = implex; params.buckling = buckling; + params.fracture = fracture; params.length = lch / 2.0; // consider half distance, the RVE uses symmetry params.radius = r; params.K_alpha = K_alpha; @@ -1545,22 +1546,36 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) asd_print("MAT set trial (" << (int)params.implex << ")"); int retval; // time factor for explicit extrapolation (todo: make a unique function) - + double epl = 0.0; if (params.buckling) { //regularization for element length lower than physical length (weighted average) retval = homogenize(params.implex); C = C_rve; stress = stress_rve; + epl = pdata->rve_m.e2.section.fib.epl; + + } else { - opserr << "HERE\n"; ////computation of sigma and tangent of steel pdata->steel_comp.revertToLastCommit(); - pdata->steel_comp.compute(params, params.implex, time_factor, strain, stress, C); + retval = pdata->steel_comp.compute(params, params.implex, time_factor, strain, stress, C); + epl = pdata->steel_comp.epl; + } + if (params.fracture) { + double d = 0.0; + double eupl = params.eu - params.sy / params.E; + if (epl > eupl) { + double epl_max = eupl + eupl * params.length / params.lch_element; + double G = (epl_max-eupl) * params.sy / 2.0; + double sigma_damaged = std::max(1.0e-4 * params.sy, params.sy * exp(-params.sy * (epl-eupl) / G)); + d = 1.0 - sigma_damaged / params.sy; + } + //apply damage on stress e C + stress *= (1.0 - d); + C *= (1.0 - d); //tangent for implex, secant for implicit } - // then apply damage on stress e C - // done return retval; } @@ -1668,7 +1683,7 @@ UniaxialMaterial* ASDSteel1DMaterial::getCopy(void) return new ASDSteel1DMaterial(*this); } -void ASDSteel1DMaterial::Print(OPS_Stream& s, int flag) +void ASDSteel1DMaterial::Print(OPS_Stream& s, int elastic_correction) { s << "ASDSteel1D Material, tag: " << this->getTag() << "\n"; } diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index 7aee145bdf..55fc06ebbb 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -56,6 +56,8 @@ class ASDSteel1DMaterial : public UniaxialMaterial double E = 0.0; // Yield stress double sy = 0.0; + // ultimate strain for damage initialization + double eu = 0.0; // Chaboche kinematic hardening parameters double H1 = 0.0; double H2 = 0.0; @@ -64,6 +66,7 @@ class ASDSteel1DMaterial : public UniaxialMaterial // misc bool implex = false; bool buckling = false; + bool fracture = false; // buckling double radius = 0.0; double length = 0.0; @@ -75,7 +78,7 @@ class ASDSteel1DMaterial : public UniaxialMaterial double tolU = 0.0; double tolR = 0.0; // counter - static constexpr int NDATA = 15; + static constexpr int NDATA = 17; }; public: From bb1907e26d01e95a17570f8d0deb01a02998e1e0 Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Wed, 7 May 2025 16:25:41 +0200 Subject: [PATCH 044/261] fix oop shear order to match voigt notation in nd materials --- .../DoubleMembranePlateFiberSection.cpp | 124 +++++++++--------- .../section/LayeredShellFiberSection.cpp | 64 ++++----- .../LayeredShellFiberSectionThermal.cpp | 64 ++++----- .../section/MembranePlateFiberSection.cpp | 64 ++++----- .../MembranePlateFiberSectionThermal.cpp | 64 ++++----- 5 files changed, 190 insertions(+), 190 deletions(-) diff --git a/SRC/material/section/DoubleMembranePlateFiberSection.cpp b/SRC/material/section/DoubleMembranePlateFiberSection.cpp index 974fc790fc..a2dac0c976 100644 --- a/SRC/material/section/DoubleMembranePlateFiberSection.cpp +++ b/SRC/material/section/DoubleMembranePlateFiberSection.cpp @@ -271,8 +271,8 @@ setTrialSectionDeformation( const Vector &strainResultant_from_element) double z ; - strain(3) = root56*strainResultant(6) ; - strain(4) = root56*strainResultant(7) ; + strain(4) = root56*strainResultant(6) ; + strain(3) = root56*strainResultant(7) ; for ( i = 0; i < numFibers; i++ ) { @@ -346,9 +346,9 @@ const Vector& DoubleMembranePlateFiberSection::getStressResultant( ) stressResultant(5) += ( z*stress(2) ) * weight ; //shear - stressResultant(6) += stress(3)*weight ; + stressResultant(6) += stress(4)*weight ; - stressResultant(7) += stress(4)*weight ; + stressResultant(7) += stress(3)*weight ; z = -z; @@ -370,9 +370,9 @@ const Vector& DoubleMembranePlateFiberSection::getStressResultant( ) stressResultant(5) += ( z*stress(2) ) * weight ; //shear - stressResultant(6) += stress(3)*weight ; + stressResultant(6) += stress(4)*weight ; - stressResultant(7) += stress(4)*weight ; + stressResultant(7) += stress(3)*weight ; } //end for i @@ -465,8 +465,8 @@ const Matrix& DoubleMembranePlateFiberSection::getSectionTangent( ) tangent(0,3) += -z*dd(0,0) ; tangent(0,4) += -z*dd(0,1) ; tangent(0,5) += -z*dd(0,2) ; - tangent(0,6) += root56*dd(0,3) ; - tangent(0,7) += root56*dd(0,4) ; + tangent(0,6) += root56*dd(0,4) ; + tangent(0,7) += root56*dd(0,3) ; //row 2 //[ d21, d22, d23, -z*d21, -z*d22, -z*d23, d24*root56, d25*root56] @@ -476,8 +476,8 @@ const Matrix& DoubleMembranePlateFiberSection::getSectionTangent( ) tangent(1,3) += -z*dd(1,0) ; tangent(1,4) += -z*dd(1,1) ; tangent(1,5) += -z*dd(1,2) ; - tangent(1,6) += root56*dd(1,3) ; - tangent(1,7) += root56*dd(1,4) ; + tangent(1,6) += root56*dd(1,4) ; + tangent(1,7) += root56*dd(1,3) ; //row 3 //[ d31, d32, d33, -z*d31, -z*d32, -z*d33, d34*root56, d35*root56] @@ -487,8 +487,8 @@ const Matrix& DoubleMembranePlateFiberSection::getSectionTangent( ) tangent(2,3) += -z*dd(2,0) ; tangent(2,4) += -z*dd(2,1) ; tangent(2,5) += -z*dd(2,2) ; - tangent(2,6) += root56*dd(2,3) ; - tangent(2,7) += root56*dd(2,4) ; + tangent(2,6) += root56*dd(2,4) ; + tangent(2,7) += root56*dd(2,3) ; //row 4 //[ z*d11, z*d12, z*d13, -z^2*d11, -z^2*d12, -z^2*d13, z*d14*root56, z*d15*root56] @@ -498,8 +498,8 @@ const Matrix& DoubleMembranePlateFiberSection::getSectionTangent( ) tangent(3,3) += -z*z*dd(0,0) ; tangent(3,4) += -z*z*dd(0,1) ; tangent(3,5) += -z*z*dd(0,2) ; - tangent(3,6) += z*root56*dd(0,3) ; - tangent(3,7) += z*root56*dd(0,4) ; + tangent(3,6) += z*root56*dd(0,4) ; + tangent(3,7) += z*root56*dd(0,3) ; //row 5 //[ z*d21, z*d22, z*d23, -z^2*d21, -z^2*d22, -z^2*d23, z*d24*root56, z*d25*root56] @@ -509,8 +509,8 @@ const Matrix& DoubleMembranePlateFiberSection::getSectionTangent( ) tangent(4,3) += -z*z*dd(1,0) ; tangent(4,4) += -z*z*dd(1,1) ; tangent(4,5) += -z*z*dd(1,2) ; - tangent(4,6) += z*root56*dd(1,3) ; - tangent(4,7) += z*root56*dd(1,4) ; + tangent(4,6) += z*root56*dd(1,4) ; + tangent(4,7) += z*root56*dd(1,3) ; //row 6 //[ z*d31, z*d32, z*d33, -z^2*d31, -z^2*d32, -z^2*d33, z*d34*root56, z*d35*root56] @@ -520,30 +520,30 @@ const Matrix& DoubleMembranePlateFiberSection::getSectionTangent( ) tangent(5,3) += -z*z*dd(2,0) ; tangent(5,4) += -z*z*dd(2,1) ; tangent(5,5) += -z*z*dd(2,2) ; - tangent(5,6) += z*root56*dd(2,3) ; - tangent(5,7) += z*root56*dd(2,4) ; + tangent(5,6) += z*root56*dd(2,4) ; + tangent(5,7) += z*root56*dd(2,3) ; //row 7 //[ root56*d41, root56*d42, root56*d43, -root56*d41*z, -root56*d42*z, -root56*d43*z, root56^2*d44, root56^2*d45] - tangent(6,0) += root56*dd(3,0) ; - tangent(6,1) += root56*dd(3,1) ; - tangent(6,2) += root56*dd(3,2) ; - tangent(6,3) += -root56*z*dd(3,0) ; - tangent(6,4) += -root56*z*dd(3,1) ; - tangent(6,5) += -root56*z*dd(3,2) ; - tangent(6,6) += root56*root56*dd(3,3) ; - tangent(6,7) += root56*root56*dd(3,4) ; + tangent(6,0) += root56*dd(4,0) ; + tangent(6,1) += root56*dd(4,1) ; + tangent(6,2) += root56*dd(4,2) ; + tangent(6,3) += -root56*z*dd(4,0) ; + tangent(6,4) += -root56*z*dd(4,1) ; + tangent(6,5) += -root56*z*dd(4,2) ; + tangent(6,6) += root56*root56*dd(4,4) ; + tangent(6,7) += root56*root56*dd(4,3) ; //row 8 //[ root56*d51, root56*d52, root56*d53, -root56*d51*z, -root56*d52*z, -root56*d53*z, root56^2*d54, root56^2*d55] - tangent(7,0) += root56*dd(4,0) ; - tangent(7,1) += root56*dd(4,1) ; - tangent(7,2) += root56*dd(4,2) ; - tangent(7,3) += -root56*z*dd(4,0) ; - tangent(7,4) += -root56*z*dd(4,1) ; - tangent(7,5) += -root56*z*dd(4,2) ; - tangent(7,6) += root56*root56*dd(4,3) ; - tangent(7,7) += root56*root56*dd(4,4) ; + tangent(7,0) += root56*dd(3,0) ; + tangent(7,1) += root56*dd(3,1) ; + tangent(7,2) += root56*dd(3,2) ; + tangent(7,3) += -root56*z*dd(3,0) ; + tangent(7,4) += -root56*z*dd(3,1) ; + tangent(7,5) += -root56*z*dd(3,2) ; + tangent(7,6) += root56*root56*dd(3,4) ; + tangent(7,7) += root56*root56*dd(3,3) ; @@ -611,8 +611,8 @@ const Matrix& DoubleMembranePlateFiberSection::getSectionTangent( ) tangent(0,3) += -z*dd(0,0) ; tangent(0,4) += -z*dd(0,1) ; tangent(0,5) += -z*dd(0,2) ; - tangent(0,6) += root56*dd(0,3) ; - tangent(0,7) += root56*dd(0,4) ; + tangent(0,6) += root56*dd(0,4) ; + tangent(0,7) += root56*dd(0,3) ; //row 2 //[ d21, d22, d23, -z*d21, -z*d22, -z*d23, d24*root56, d25*root56] @@ -622,8 +622,8 @@ const Matrix& DoubleMembranePlateFiberSection::getSectionTangent( ) tangent(1,3) += -z*dd(1,0) ; tangent(1,4) += -z*dd(1,1) ; tangent(1,5) += -z*dd(1,2) ; - tangent(1,6) += root56*dd(1,3) ; - tangent(1,7) += root56*dd(1,4) ; + tangent(1,6) += root56*dd(1,4) ; + tangent(1,7) += root56*dd(1,3) ; //row 3 //[ d31, d32, d33, -z*d31, -z*d32, -z*d33, d34*root56, d35*root56] @@ -633,8 +633,8 @@ const Matrix& DoubleMembranePlateFiberSection::getSectionTangent( ) tangent(2,3) += -z*dd(2,0) ; tangent(2,4) += -z*dd(2,1) ; tangent(2,5) += -z*dd(2,2) ; - tangent(2,6) += root56*dd(2,3) ; - tangent(2,7) += root56*dd(2,4) ; + tangent(2,6) += root56*dd(2,4) ; + tangent(2,7) += root56*dd(2,3) ; //row 4 //[ z*d11, z*d12, z*d13, -z^2*d11, -z^2*d12, -z^2*d13, z*d14*root56, z*d15*root56] @@ -644,8 +644,8 @@ const Matrix& DoubleMembranePlateFiberSection::getSectionTangent( ) tangent(3,3) += -z*z*dd(0,0) ; tangent(3,4) += -z*z*dd(0,1) ; tangent(3,5) += -z*z*dd(0,2) ; - tangent(3,6) += z*root56*dd(0,3) ; - tangent(3,7) += z*root56*dd(0,4) ; + tangent(3,6) += z*root56*dd(0,4) ; + tangent(3,7) += z*root56*dd(0,3) ; //row 5 //[ z*d21, z*d22, z*d23, -z^2*d21, -z^2*d22, -z^2*d23, z*d24*root56, z*d25*root56] @@ -655,8 +655,8 @@ const Matrix& DoubleMembranePlateFiberSection::getSectionTangent( ) tangent(4,3) += -z*z*dd(1,0) ; tangent(4,4) += -z*z*dd(1,1) ; tangent(4,5) += -z*z*dd(1,2) ; - tangent(4,6) += z*root56*dd(1,3) ; - tangent(4,7) += z*root56*dd(1,4) ; + tangent(4,6) += z*root56*dd(1,4) ; + tangent(4,7) += z*root56*dd(1,3) ; //row 6 //[ z*d31, z*d32, z*d33, -z^2*d31, -z^2*d32, -z^2*d33, z*d34*root56, z*d35*root56] @@ -666,30 +666,30 @@ const Matrix& DoubleMembranePlateFiberSection::getSectionTangent( ) tangent(5,3) += -z*z*dd(2,0) ; tangent(5,4) += -z*z*dd(2,1) ; tangent(5,5) += -z*z*dd(2,2) ; - tangent(5,6) += z*root56*dd(2,3) ; - tangent(5,7) += z*root56*dd(2,4) ; + tangent(5,6) += z*root56*dd(2,4) ; + tangent(5,7) += z*root56*dd(2,3) ; //row 7 //[ root56*d41, root56*d42, root56*d43, -root56*d41*z, -root56*d42*z, -root56*d43*z, root56^2*d44, root56^2*d45] - tangent(6,0) += root56*dd(3,0) ; - tangent(6,1) += root56*dd(3,1) ; - tangent(6,2) += root56*dd(3,2) ; - tangent(6,3) += -root56*z*dd(3,0) ; - tangent(6,4) += -root56*z*dd(3,1) ; - tangent(6,5) += -root56*z*dd(3,2) ; - tangent(6,6) += root56*root56*dd(3,3) ; - tangent(6,7) += root56*root56*dd(3,4) ; + tangent(6,0) += root56*dd(4,0) ; + tangent(6,1) += root56*dd(4,1) ; + tangent(6,2) += root56*dd(4,2) ; + tangent(6,3) += -root56*z*dd(4,0) ; + tangent(6,4) += -root56*z*dd(4,1) ; + tangent(6,5) += -root56*z*dd(4,2) ; + tangent(6,6) += root56*root56*dd(4,4) ; + tangent(6,7) += root56*root56*dd(4,3) ; //row 8 //[ root56*d51, root56*d52, root56*d53, -root56*d51*z, -root56*d52*z, -root56*d53*z, root56^2*d54, root56^2*d55] - tangent(7,0) += root56*dd(4,0) ; - tangent(7,1) += root56*dd(4,1) ; - tangent(7,2) += root56*dd(4,2) ; - tangent(7,3) += -root56*z*dd(4,0) ; - tangent(7,4) += -root56*z*dd(4,1) ; - tangent(7,5) += -root56*z*dd(4,2) ; - tangent(7,6) += root56*root56*dd(4,3) ; - tangent(7,7) += root56*root56*dd(4,4) ; + tangent(7,0) += root56*dd(3,0) ; + tangent(7,1) += root56*dd(3,1) ; + tangent(7,2) += root56*dd(3,2) ; + tangent(7,3) += -root56*z*dd(3,0) ; + tangent(7,4) += -root56*z*dd(3,1) ; + tangent(7,5) += -root56*z*dd(3,2) ; + tangent(7,6) += root56*root56*dd(3,4) ; + tangent(7,7) += root56*root56*dd(3,3) ; } //end for i diff --git a/SRC/material/section/LayeredShellFiberSection.cpp b/SRC/material/section/LayeredShellFiberSection.cpp index e8c379e3ef..0ad528605e 100644 --- a/SRC/material/section/LayeredShellFiberSection.cpp +++ b/SRC/material/section/LayeredShellFiberSection.cpp @@ -440,9 +440,9 @@ setTrialSectionDeformation( const Vector &strainResultant_from_element) strain(2) = strainResultant(2) - z*strainResultant(5) ; - strain(3) = strainResultant(6) ; + strain(4) = strainResultant(6) ; - strain(4) = strainResultant(7) ; + strain(3) = strainResultant(7) ; success += theFibers[i]->setTrialStrain( strain ) ; @@ -494,9 +494,9 @@ const Vector& LayeredShellFiberSection::getStressResultant( ) stressResultant(5) += ( z*stress(2) ) * weight ; //shear - stressResultant(6) += stress(3)*weight ; + stressResultant(6) += stress(4)*weight ; - stressResultant(7) += stress(4)*weight ; + stressResultant(7) += stress(3)*weight ; } //end for i @@ -584,8 +584,8 @@ const Matrix& LayeredShellFiberSection::getSectionTangent( ) tangent(0,3) += -z*dd(0,0) ; tangent(0,4) += -z*dd(0,1) ; tangent(0,5) += -z*dd(0,2) ; - tangent(0,6) += dd(0,3) ; - tangent(0,7) += dd(0,4) ; + tangent(0,6) += dd(0,4) ; + tangent(0,7) += dd(0,3) ; //row 2 //[ d21, d22, d23, -z*d21, -z*d22, -z*d23, d24, d25] @@ -595,8 +595,8 @@ const Matrix& LayeredShellFiberSection::getSectionTangent( ) tangent(1,3) += -z*dd(1,0) ; tangent(1,4) += -z*dd(1,1) ; tangent(1,5) += -z*dd(1,2) ; - tangent(1,6) += dd(1,3) ; - tangent(1,7) += dd(1,4) ; + tangent(1,6) += dd(1,4) ; + tangent(1,7) += dd(1,3) ; //row 3 //[ d31, d32, d33, -z*d31, -z*d32, -z*d33, d34, d35] @@ -606,8 +606,8 @@ const Matrix& LayeredShellFiberSection::getSectionTangent( ) tangent(2,3) += -z*dd(2,0) ; tangent(2,4) += -z*dd(2,1) ; tangent(2,5) += -z*dd(2,2) ; - tangent(2,6) += dd(2,3) ; - tangent(2,7) += dd(2,4) ; + tangent(2,6) += dd(2,4) ; + tangent(2,7) += dd(2,3) ; //row 4 //[ z*d11, z*d12, z*d13, -z^2*d11, -z^2*d12, -z^2*d13, z*d14, z*d15] @@ -617,8 +617,8 @@ const Matrix& LayeredShellFiberSection::getSectionTangent( ) tangent(3,3) += -z*z*dd(0,0) ; tangent(3,4) += -z*z*dd(0,1) ; tangent(3,5) += -z*z*dd(0,2) ; - tangent(3,6) += z*dd(0,3) ; - tangent(3,7) += z*dd(0,4) ; + tangent(3,6) += z*dd(0,4) ; + tangent(3,7) += z*dd(0,3) ; //row 5 //[ z*d21, z*d22, z*d23, -z^2*d21, -z^2*d22, -z^2*d23, z*d24, z*d25] @@ -628,8 +628,8 @@ const Matrix& LayeredShellFiberSection::getSectionTangent( ) tangent(4,3) += -z*z*dd(1,0) ; tangent(4,4) += -z*z*dd(1,1) ; tangent(4,5) += -z*z*dd(1,2) ; - tangent(4,6) += z*dd(1,3) ; - tangent(4,7) += z*dd(1,4) ; + tangent(4,6) += z*dd(1,4) ; + tangent(4,7) += z*dd(1,3) ; //row 6 //[ z*d31, z*d32, z*d33, -z^2*d31, -z^2*d32, -z^2*d33, z*d34, z*d35] @@ -639,30 +639,30 @@ const Matrix& LayeredShellFiberSection::getSectionTangent( ) tangent(5,3) += -z*z*dd(2,0) ; tangent(5,4) += -z*z*dd(2,1) ; tangent(5,5) += -z*z*dd(2,2) ; - tangent(5,6) += z*dd(2,3) ; - tangent(5,7) += z*dd(2,4) ; + tangent(5,6) += z*dd(2,4) ; + tangent(5,7) += z*dd(2,3) ; //row 7 //[ d41, d42, d43, -d41*z, -d42*z, -d43*z, d44, d45] - tangent(6,0) += dd(3,0) ; - tangent(6,1) += dd(3,1) ; - tangent(6,2) += dd(3,2) ; - tangent(6,3) += -z*dd(3,0) ; - tangent(6,4) += -z*dd(3,1) ; - tangent(6,5) += -z*dd(3,2) ; - tangent(6,6) += dd(3,3) ; - tangent(6,7) += dd(3,4) ; + tangent(6,0) += dd(4,0) ; + tangent(6,1) += dd(4,1) ; + tangent(6,2) += dd(4,2) ; + tangent(6,3) += -z*dd(4,0) ; + tangent(6,4) += -z*dd(4,1) ; + tangent(6,5) += -z*dd(4,2) ; + tangent(6,6) += dd(4,4) ; + tangent(6,7) += dd(4,3) ; //row 8 //[ d51, d52, d53, -d51*z, -d52*z, -d53*z, d54, d55] - tangent(7,0) += dd(4,0) ; - tangent(7,1) += dd(4,1) ; - tangent(7,2) += dd(4,2) ; - tangent(7,3) += -z*dd(4,0) ; - tangent(7,4) += -z*dd(4,1) ; - tangent(7,5) += -z*dd(4,2) ; - tangent(7,6) += dd(4,3) ; - tangent(7,7) += dd(4,4) ; + tangent(7,0) += dd(3,0) ; + tangent(7,1) += dd(3,1) ; + tangent(7,2) += dd(3,2) ; + tangent(7,3) += -z*dd(3,0) ; + tangent(7,4) += -z*dd(3,1) ; + tangent(7,5) += -z*dd(3,2) ; + tangent(7,6) += dd(3,4) ; + tangent(7,7) += dd(3,3) ; } //end for i diff --git a/SRC/material/section/LayeredShellFiberSectionThermal.cpp b/SRC/material/section/LayeredShellFiberSectionThermal.cpp index 66b6de14af..736b23ac45 100644 --- a/SRC/material/section/LayeredShellFiberSectionThermal.cpp +++ b/SRC/material/section/LayeredShellFiberSectionThermal.cpp @@ -434,9 +434,9 @@ setTrialSectionDeformation( const Vector &strainResultant_from_element) strain(2) = strainResultant(2) - z*strainResultant(5) ; - strain(3) = root56*strainResultant(6) ; + strain(4) = root56*strainResultant(6) ; - strain(4) = root56*strainResultant(7) ; + strain(3) = root56*strainResultant(7) ; success += theFibers[i]->setTrialStrain( strain ) ; @@ -536,9 +536,9 @@ const Vector& LayeredShellFiberSectionThermal::getStressResultant( ) stressResultant(5) += ( z*stress(2) ) * weight ; //shear - stressResultant(6) += stress(3)*weight ; + stressResultant(6) += stress(4)*weight ; - stressResultant(7) += stress(4)*weight ; + stressResultant(7) += stress(3)*weight ; } //end for i @@ -631,8 +631,8 @@ const Matrix& LayeredShellFiberSectionThermal::getSectionTangent( ) tangent(0,3) += -z*dd(0,0) ; tangent(0,4) += -z*dd(0,1) ; tangent(0,5) += -z*dd(0,2) ; - tangent(0,6) += dd(0,3) ; - tangent(0,7) += dd(0,4) ; + tangent(0,6) += dd(0,4) ; + tangent(0,7) += dd(0,3) ; //row 2 //[ d21, d22, d23, -z*d21, -z*d22, -z*d23, d24, d25] @@ -642,8 +642,8 @@ const Matrix& LayeredShellFiberSectionThermal::getSectionTangent( ) tangent(1,3) += -z*dd(1,0) ; tangent(1,4) += -z*dd(1,1) ; tangent(1,5) += -z*dd(1,2) ; - tangent(1,6) += dd(1,3) ; - tangent(1,7) += dd(1,4) ; + tangent(1,6) += dd(1,4) ; + tangent(1,7) += dd(1,3) ; //row 3 //[ d31, d32, d33, -z*d31, -z*d32, -z*d33, d34, d35] @@ -653,8 +653,8 @@ const Matrix& LayeredShellFiberSectionThermal::getSectionTangent( ) tangent(2,3) += -z*dd(2,0) ; tangent(2,4) += -z*dd(2,1) ; tangent(2,5) += -z*dd(2,2) ; - tangent(2,6) += dd(2,3) ; - tangent(2,7) += dd(2,4) ; + tangent(2,6) += dd(2,4) ; + tangent(2,7) += dd(2,3) ; //row 4 //[ z*d11, z*d12, z*d13, -z^2*d11, -z^2*d12, -z^2*d13, z*d14, z*d15] @@ -664,8 +664,8 @@ const Matrix& LayeredShellFiberSectionThermal::getSectionTangent( ) tangent(3,3) += -z*z*dd(0,0) ; tangent(3,4) += -z*z*dd(0,1) ; tangent(3,5) += -z*z*dd(0,2) ; - tangent(3,6) += z*dd(0,3) ; - tangent(3,7) += z*dd(0,4) ; + tangent(3,6) += z*dd(0,4) ; + tangent(3,7) += z*dd(0,3) ; //row 5 //[ z*d21, z*d22, z*d23, -z^2*d21, -z^2*d22, -z^2*d23, z*d24, z*d25] @@ -675,8 +675,8 @@ const Matrix& LayeredShellFiberSectionThermal::getSectionTangent( ) tangent(4,3) += -z*z*dd(1,0) ; tangent(4,4) += -z*z*dd(1,1) ; tangent(4,5) += -z*z*dd(1,2) ; - tangent(4,6) += z*dd(1,3) ; - tangent(4,7) += z*dd(1,4) ; + tangent(4,6) += z*dd(1,4) ; + tangent(4,7) += z*dd(1,3) ; //row 6 //[ z*d31, z*d32, z*d33, -z^2*d31, -z^2*d32, -z^2*d33, z*d34, z*d35] @@ -686,30 +686,30 @@ const Matrix& LayeredShellFiberSectionThermal::getSectionTangent( ) tangent(5,3) += -z*z*dd(2,0) ; tangent(5,4) += -z*z*dd(2,1) ; tangent(5,5) += -z*z*dd(2,2) ; - tangent(5,6) += z*dd(2,3) ; - tangent(5,7) += z*dd(2,4) ; + tangent(5,6) += z*dd(2,4) ; + tangent(5,7) += z*dd(2,3) ; //row 7 //[ d41, d42, d43, -d41*z, -d42*z, -d43*z, d44, d45] - tangent(6,0) += dd(3,0) ; - tangent(6,1) += dd(3,1) ; - tangent(6,2) += dd(3,2) ; - tangent(6,3) += -z*dd(3,0) ; - tangent(6,4) += -z*dd(3,1) ; - tangent(6,5) += -z*dd(3,2) ; - tangent(6,6) += dd(3,3) ; - tangent(6,7) += dd(3,4) ; + tangent(6,0) += dd(4,0) ; + tangent(6,1) += dd(4,1) ; + tangent(6,2) += dd(4,2) ; + tangent(6,3) += -z*dd(4,0) ; + tangent(6,4) += -z*dd(4,1) ; + tangent(6,5) += -z*dd(4,2) ; + tangent(6,6) += dd(4,4) ; + tangent(6,7) += dd(4,3) ; //row 8 //[ d51, d52, d53, -d51*z, -d52*z, -d53*z, d54, d55] - tangent(7,0) += dd(4,0) ; - tangent(7,1) += dd(4,1) ; - tangent(7,2) += dd(4,2) ; - tangent(7,3) += -z*dd(4,0) ; - tangent(7,4) += -z*dd(4,1) ; - tangent(7,5) += -z*dd(4,2) ; - tangent(7,6) += dd(4,3) ; - tangent(7,7) += dd(4,4) ; + tangent(7,0) += dd(3,0) ; + tangent(7,1) += dd(3,1) ; + tangent(7,2) += dd(3,2) ; + tangent(7,3) += -z*dd(3,0) ; + tangent(7,4) += -z*dd(3,1) ; + tangent(7,5) += -z*dd(3,2) ; + tangent(7,6) += dd(3,4) ; + tangent(7,7) += dd(3,3) ; } //end for i diff --git a/SRC/material/section/MembranePlateFiberSection.cpp b/SRC/material/section/MembranePlateFiberSection.cpp index 6dddec5b57..050197abc3 100644 --- a/SRC/material/section/MembranePlateFiberSection.cpp +++ b/SRC/material/section/MembranePlateFiberSection.cpp @@ -274,9 +274,9 @@ setTrialSectionDeformation( const Vector &strainResultant_from_element) strain(2) = strainResultant(2) - z*strainResultant(5) ; - strain(3) = root56*strainResultant(6) ; + strain(4) = root56*strainResultant(6) ; - strain(4) = root56*strainResultant(7) ; + strain(3) = root56*strainResultant(7) ; success += theFibers[i]->setTrialStrain( strain ) ; @@ -329,9 +329,9 @@ const Vector& MembranePlateFiberSection::getStressResultant( ) stressResultant(5) += ( z*stress(2) ) * weight ; //shear - stressResultant(6) += stress(3)*weight ; + stressResultant(6) += stress(4)*weight ; - stressResultant(7) += stress(4)*weight ; + stressResultant(7) += stress(3)*weight ; } //end for i @@ -424,8 +424,8 @@ const Matrix& MembranePlateFiberSection::getSectionTangent( ) tangent(0,3) += -z*dd(0,0) ; tangent(0,4) += -z*dd(0,1) ; tangent(0,5) += -z*dd(0,2) ; - tangent(0,6) += root56*dd(0,3) ; - tangent(0,7) += root56*dd(0,4) ; + tangent(0,6) += root56*dd(0,4) ; + tangent(0,7) += root56*dd(0,3) ; //row 2 //[ d21, d22, d23, -z*d21, -z*d22, -z*d23, d24*root56, d25*root56] @@ -435,8 +435,8 @@ const Matrix& MembranePlateFiberSection::getSectionTangent( ) tangent(1,3) += -z*dd(1,0) ; tangent(1,4) += -z*dd(1,1) ; tangent(1,5) += -z*dd(1,2) ; - tangent(1,6) += root56*dd(1,3) ; - tangent(1,7) += root56*dd(1,4) ; + tangent(1,6) += root56*dd(1,4) ; + tangent(1,7) += root56*dd(1,3) ; //row 3 //[ d31, d32, d33, -z*d31, -z*d32, -z*d33, d34*root56, d35*root56] @@ -446,8 +446,8 @@ const Matrix& MembranePlateFiberSection::getSectionTangent( ) tangent(2,3) += -z*dd(2,0) ; tangent(2,4) += -z*dd(2,1) ; tangent(2,5) += -z*dd(2,2) ; - tangent(2,6) += root56*dd(2,3) ; - tangent(2,7) += root56*dd(2,4) ; + tangent(2,6) += root56*dd(2,4) ; + tangent(2,7) += root56*dd(2,3) ; //row 4 //[ z*d11, z*d12, z*d13, -z^2*d11, -z^2*d12, -z^2*d13, z*d14*root56, z*d15*root56] @@ -457,8 +457,8 @@ const Matrix& MembranePlateFiberSection::getSectionTangent( ) tangent(3,3) += -z*z*dd(0,0) ; tangent(3,4) += -z*z*dd(0,1) ; tangent(3,5) += -z*z*dd(0,2) ; - tangent(3,6) += z*root56*dd(0,3) ; - tangent(3,7) += z*root56*dd(0,4) ; + tangent(3,6) += z*root56*dd(0,4) ; + tangent(3,7) += z*root56*dd(0,3) ; //row 5 //[ z*d21, z*d22, z*d23, -z^2*d21, -z^2*d22, -z^2*d23, z*d24*root56, z*d25*root56] @@ -468,8 +468,8 @@ const Matrix& MembranePlateFiberSection::getSectionTangent( ) tangent(4,3) += -z*z*dd(1,0) ; tangent(4,4) += -z*z*dd(1,1) ; tangent(4,5) += -z*z*dd(1,2) ; - tangent(4,6) += z*root56*dd(1,3) ; - tangent(4,7) += z*root56*dd(1,4) ; + tangent(4,6) += z*root56*dd(1,4) ; + tangent(4,7) += z*root56*dd(1,3) ; //row 6 //[ z*d31, z*d32, z*d33, -z^2*d31, -z^2*d32, -z^2*d33, z*d34*root56, z*d35*root56] @@ -479,30 +479,30 @@ const Matrix& MembranePlateFiberSection::getSectionTangent( ) tangent(5,3) += -z*z*dd(2,0) ; tangent(5,4) += -z*z*dd(2,1) ; tangent(5,5) += -z*z*dd(2,2) ; - tangent(5,6) += z*root56*dd(2,3) ; - tangent(5,7) += z*root56*dd(2,4) ; + tangent(5,6) += z*root56*dd(2,4) ; + tangent(5,7) += z*root56*dd(2,3) ; //row 7 //[ root56*d41, root56*d42, root56*d43, -root56*d41*z, -root56*d42*z, -root56*d43*z, root56^2*d44, root56^2*d45] - tangent(6,0) += root56*dd(3,0) ; - tangent(6,1) += root56*dd(3,1) ; - tangent(6,2) += root56*dd(3,2) ; - tangent(6,3) += -root56*z*dd(3,0) ; - tangent(6,4) += -root56*z*dd(3,1) ; - tangent(6,5) += -root56*z*dd(3,2) ; - tangent(6,6) += root56*root56*dd(3,3) ; - tangent(6,7) += root56*root56*dd(3,4) ; + tangent(6,0) += root56*dd(4,0) ; + tangent(6,1) += root56*dd(4,1) ; + tangent(6,2) += root56*dd(4,2) ; + tangent(6,3) += -root56*z*dd(4,0) ; + tangent(6,4) += -root56*z*dd(4,1) ; + tangent(6,5) += -root56*z*dd(4,2) ; + tangent(6,6) += root56*root56*dd(4,4) ; + tangent(6,7) += root56*root56*dd(4,3) ; //row 8 //[ root56*d51, root56*d52, root56*d53, -root56*d51*z, -root56*d52*z, -root56*d53*z, root56^2*d54, root56^2*d55] - tangent(7,0) += root56*dd(4,0) ; - tangent(7,1) += root56*dd(4,1) ; - tangent(7,2) += root56*dd(4,2) ; - tangent(7,3) += -root56*z*dd(4,0) ; - tangent(7,4) += -root56*z*dd(4,1) ; - tangent(7,5) += -root56*z*dd(4,2) ; - tangent(7,6) += root56*root56*dd(4,3) ; - tangent(7,7) += root56*root56*dd(4,4) ; + tangent(7,0) += root56*dd(3,0) ; + tangent(7,1) += root56*dd(3,1) ; + tangent(7,2) += root56*dd(3,2) ; + tangent(7,3) += -root56*z*dd(3,0) ; + tangent(7,4) += -root56*z*dd(3,1) ; + tangent(7,5) += -root56*z*dd(3,2) ; + tangent(7,6) += root56*root56*dd(3,4) ; + tangent(7,7) += root56*root56*dd(3,3) ; } //end for i diff --git a/SRC/material/section/MembranePlateFiberSectionThermal.cpp b/SRC/material/section/MembranePlateFiberSectionThermal.cpp index 0cf348cd5e..60147c06e2 100644 --- a/SRC/material/section/MembranePlateFiberSectionThermal.cpp +++ b/SRC/material/section/MembranePlateFiberSectionThermal.cpp @@ -302,9 +302,9 @@ setTrialSectionDeformation( const Vector &strainResultant_from_element) strain(2) = strainResultant(2) - z*strainResultant(5) ; - strain(3) = root56*strainResultant(6) ; + strain(4) = root56*strainResultant(6) ; - strain(4) = root56*strainResultant(7) ; + strain(3) = root56*strainResultant(7) ; //J.Jiang add to see strain double strain0, strain1,strain2, strain3, strain4; strain0=strain(0); @@ -367,9 +367,9 @@ const Vector& MembranePlateFiberSectionThermal::getStressResultant( ) stressResultant(5) += ( z*stress(2) ) * weight ; //shear - stressResultant(6) += stress(3)*weight ; + stressResultant(6) += stress(4)*weight ; - stressResultant(7) += stress(4)*weight ; + stressResultant(7) += stress(3)*weight ; } //end for i @@ -551,8 +551,8 @@ const Matrix& MembranePlateFiberSectionThermal::getSectionTangent( ) tangent(0,3) += -z*dd(0,0) ; tangent(0,4) += -z*dd(0,1) ; tangent(0,5) += -z*dd(0,2) ; - tangent(0,6) += root56*dd(0,3) ; - tangent(0,7) += root56*dd(0,4) ; + tangent(0,6) += root56*dd(0,4) ; + tangent(0,7) += root56*dd(0,3) ; //row 2 //[ d21, d22, d23, -z*d21, -z*d22, -z*d23, d24*root56, d25*root56] @@ -562,8 +562,8 @@ const Matrix& MembranePlateFiberSectionThermal::getSectionTangent( ) tangent(1,3) += -z*dd(1,0) ; tangent(1,4) += -z*dd(1,1) ; tangent(1,5) += -z*dd(1,2) ; - tangent(1,6) += root56*dd(1,3) ; - tangent(1,7) += root56*dd(1,4) ; + tangent(1,6) += root56*dd(1,4) ; + tangent(1,7) += root56*dd(1,3) ; //row 3 //[ d31, d32, d33, -z*d31, -z*d32, -z*d33, d34*root56, d35*root56] @@ -573,8 +573,8 @@ const Matrix& MembranePlateFiberSectionThermal::getSectionTangent( ) tangent(2,3) += -z*dd(2,0) ; tangent(2,4) += -z*dd(2,1) ; tangent(2,5) += -z*dd(2,2) ; - tangent(2,6) += root56*dd(2,3) ; - tangent(2,7) += root56*dd(2,4) ; + tangent(2,6) += root56*dd(2,4) ; + tangent(2,7) += root56*dd(2,3) ; //row 4 //[ z*d11, z*d12, z*d13, -z^2*d11, -z^2*d12, -z^2*d13, z*d14*root56, z*d15*root56] @@ -584,8 +584,8 @@ const Matrix& MembranePlateFiberSectionThermal::getSectionTangent( ) tangent(3,3) += -z*z*dd(0,0) ; tangent(3,4) += -z*z*dd(0,1) ; tangent(3,5) += -z*z*dd(0,2) ; - tangent(3,6) += z*root56*dd(0,3) ; - tangent(3,7) += z*root56*dd(0,4) ; + tangent(3,6) += z*root56*dd(0,4) ; + tangent(3,7) += z*root56*dd(0,3) ; //row 5 //[ z*d21, z*d22, z*d23, -z^2*d21, -z^2*d22, -z^2*d23, z*d24*root56, z*d25*root56] @@ -595,8 +595,8 @@ const Matrix& MembranePlateFiberSectionThermal::getSectionTangent( ) tangent(4,3) += -z*z*dd(1,0) ; tangent(4,4) += -z*z*dd(1,1) ; tangent(4,5) += -z*z*dd(1,2) ; - tangent(4,6) += z*root56*dd(1,3) ; - tangent(4,7) += z*root56*dd(1,4) ; + tangent(4,6) += z*root56*dd(1,4) ; + tangent(4,7) += z*root56*dd(1,3) ; //row 6 //[ z*d31, z*d32, z*d33, -z^2*d31, -z^2*d32, -z^2*d33, z*d34*root56, z*d35*root56] @@ -606,30 +606,30 @@ const Matrix& MembranePlateFiberSectionThermal::getSectionTangent( ) tangent(5,3) += -z*z*dd(2,0) ; tangent(5,4) += -z*z*dd(2,1) ; tangent(5,5) += -z*z*dd(2,2) ; - tangent(5,6) += z*root56*dd(2,3) ; - tangent(5,7) += z*root56*dd(2,4) ; + tangent(5,6) += z*root56*dd(2,4) ; + tangent(5,7) += z*root56*dd(2,3) ; //row 7 //[ root56*d41, root56*d42, root56*d43, -root56*d41*z, -root56*d42*z, -root56*d43*z, root56^2*d44, root56^2*d45] - tangent(6,0) += root56*dd(3,0) ; - tangent(6,1) += root56*dd(3,1) ; - tangent(6,2) += root56*dd(3,2) ; - tangent(6,3) += -root56*z*dd(3,0) ; - tangent(6,4) += -root56*z*dd(3,1) ; - tangent(6,5) += -root56*z*dd(3,2) ; - tangent(6,6) += root56*root56*dd(3,3) ; - tangent(6,7) += root56*root56*dd(3,4) ; + tangent(6,0) += root56*dd(4,0) ; + tangent(6,1) += root56*dd(4,1) ; + tangent(6,2) += root56*dd(4,2) ; + tangent(6,3) += -root56*z*dd(4,0) ; + tangent(6,4) += -root56*z*dd(4,1) ; + tangent(6,5) += -root56*z*dd(4,2) ; + tangent(6,6) += root56*root56*dd(4,4) ; + tangent(6,7) += root56*root56*dd(4,3) ; //row 8 //[ root56*d51, root56*d52, root56*d53, -root56*d51*z, -root56*d52*z, -root56*d53*z, root56^2*d54, root56^2*d55] - tangent(7,0) += root56*dd(4,0) ; - tangent(7,1) += root56*dd(4,1) ; - tangent(7,2) += root56*dd(4,2) ; - tangent(7,3) += -root56*z*dd(4,0) ; - tangent(7,4) += -root56*z*dd(4,1) ; - tangent(7,5) += -root56*z*dd(4,2) ; - tangent(7,6) += root56*root56*dd(4,3) ; - tangent(7,7) += root56*root56*dd(4,4) ; + tangent(7,0) += root56*dd(3,0) ; + tangent(7,1) += root56*dd(3,1) ; + tangent(7,2) += root56*dd(3,2) ; + tangent(7,3) += -root56*z*dd(3,0) ; + tangent(7,4) += -root56*z*dd(3,1) ; + tangent(7,5) += -root56*z*dd(3,2) ; + tangent(7,6) += root56*root56*dd(3,4) ; + tangent(7,7) += root56*root56*dd(3,3) ; } //end for i From 61ba34d95d334ff579cd0edbcc23320a16bdcc78 Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Thu, 8 May 2025 16:44:26 +0200 Subject: [PATCH 045/261] Update AutoConstraintHandler.cpp --- SRC/analysis/handler/AutoConstraintHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/SRC/analysis/handler/AutoConstraintHandler.cpp b/SRC/analysis/handler/AutoConstraintHandler.cpp index dd86793a3b..b3ebd1bc8e 100644 --- a/SRC/analysis/handler/AutoConstraintHandler.cpp +++ b/SRC/analysis/handler/AutoConstraintHandler.cpp @@ -63,6 +63,7 @@ #include #include #include +#include // for parallel #ifdef _PARALLEL_PROCESSING From 10b51ffa32d783df62f8f1ab5a86e11b2d62a9c3 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Wed, 14 May 2025 17:24:40 -0700 Subject: [PATCH 046/261] Update Concrete07.cpp --- SRC/material/uniaxial/Concrete07.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SRC/material/uniaxial/Concrete07.cpp b/SRC/material/uniaxial/Concrete07.cpp index eb4864beec..cb077f9d1f 100644 --- a/SRC/material/uniaxial/Concrete07.cpp +++ b/SRC/material/uniaxial/Concrete07.cpp @@ -75,6 +75,10 @@ void* OPS_Concrete07() Concrete07::Concrete07 (int tag, double FPC, double EPSC0, double EC, double FPT, double EPST0, double XCRP, double XCRN, double R) :UniaxialMaterial(tag, MAT_TAG_Concrete07), fpc(FPC), epsc0(EPSC0), Ec(EC), fpt(FPT), epst0(EPST0), xcrp(XCRP), xcrn(XCRN), r(R) { + // Ensure negative signs + fpc = -fabs(fpc); + epsc0 = -fabs(epsc0); + // Calculate the variables that are needed to define the envelopw nn = (Ec*epsc0)/fpc; np = (Ec*epst0)/fpt; From c558e2960d82fa3bd128edbaf84a1d73d0e1160e Mon Sep 17 00:00:00 2001 From: alec0498 Date: Thu, 15 May 2025 17:19:45 +0200 Subject: [PATCH 047/261] slip --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 274 +++++++++++++++++-- SRC/material/uniaxial/ASDSteel1DMaterial.h | 5 +- 2 files changed, 248 insertions(+), 31 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index d5db3d1a0e..eaa937c339 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -47,7 +47,7 @@ #define M_PI 3.14159265358979323846 #endif -#define ASD_STEEL1D__VERBOSE +//#define ASD_STEEL1D__VERBOSE #ifdef ASD_STEEL1D__VERBOSE #define asd_print_full(X) opserr << __func__ << " (Line " << __LINE__ << "): " << X << "\n" @@ -453,6 +453,129 @@ namespace { static constexpr int NDATA = 12; }; + /* + Series comonent. + */ + class SeriesComponent + { + public: + SteelComponent steel_material; + UniaxialMaterial* slip_material = nullptr; + public: + using param_t = ASDSteel1DMaterial::InputParameters; + SeriesComponent() = default; + SeriesComponent(const SeriesComponent& c) + : steel_material(c.steel_material) + , slip_material(nullptr) + { + setSlipMaterial(c.slip_material); + } + ~SeriesComponent() { + if (slip_material) + delete slip_material; + } + + inline int commitState() { + // store the previously committed variables for next move from n to n - 1 + + // state variables + + int retval = 0; + + retval = steel_material.commitState(); + + if (slip_material) + retval = slip_material->commitState(); + + // done + return retval; + } + inline void revertToLastCommit() { + // state variables + steel_material.revertToLastCommit(); + + if (slip_material) + slip_material->revertToLastCommit(); + + } + inline void revertToStart() { + // state variables + steel_material.revertToStart(); + + if (slip_material) + slip_material->revertToStart(); + + } + inline int compute(const param_t& params, bool do_implex, double time_factor, double _strain, double& sigma, double& tangent) { + if (slip_material) { + + // compute series response + constexpr int MAX_ITER = 100; + constexpr double TOL = 1e-6; + + // initial guess for the slip strain + double strain_slip = slip_material->getStrain() / params.lch_anchor; + double strain_steel = _strain - strain_slip; + + // iterative procedure to impose the iso-stress condition + double sigma_steel; + double tangent_steel; + double Ktol = 1.0e-12 * params.E; + double Rtol = TOL * params.sy; + double Stol = TOL; + for (int iter = 0; iter < MAX_ITER; ++iter) { + int Tsteel = steel_material.compute(params, do_implex, time_factor, strain_steel, sigma_steel, tangent_steel); + int Tslip = slip_material->setTrialStrain(strain_slip * params.lch_anchor); + double sigma_slip = slip_material->getStress() * 2.0 * params.lch_anchor/ params.radius; + double tangent_slip = slip_material->getTangent() * 2.0 * params.lch_anchor * params.lch_anchor / params.radius; + double residual = sigma_slip - sigma_steel; + double residual_derivative = tangent_steel + tangent_slip; + if (std::abs(residual_derivative) < Ktol) { + residual_derivative = params.E + slip_material->getInitialTangent() * 2.0 * params.lch_anchor * params.lch_anchor / params.radius; + } + double strain_increment = - residual / residual_derivative; + strain_slip += strain_increment; + strain_steel = _strain - strain_slip; + + if (std::abs(residual) < Rtol || std::abs(strain_increment) < Stol) { + sigma = sigma_steel; + if (std::abs(tangent_steel) < Ktol) tangent_steel = Ktol; + if (std::abs(tangent_slip) < Ktol) tangent_slip = Ktol; + tangent = 1.0 / (1.0 / tangent_steel + 1.0 / tangent_slip); + asd_print("iter: " << iter); + return 0; + } + + + + } + + asd_print_full("series failed"); + return -1; + } + else { + return steel_material.compute(params, do_implex, time_factor, _strain, sigma, tangent); + } + } + + inline void setSlipMaterial(UniaxialMaterial* prototype) { + if (slip_material) { + delete slip_material; + slip_material = nullptr; + } + if (prototype) { + slip_material = prototype->getCopy(); + asd_print("setting slip material: " << slip_material->getClassType()); + } + } + + public: + // state variables - backstresses + + // methods + static constexpr int NDATA = 10; + }; + /** Section component. */ @@ -470,19 +593,19 @@ namespace { class SectionComponent<1> { public: - SteelComponent fib; + SeriesComponent series; public: SectionComponent() = default; inline int commitState() { - return fib.commitState(); + return series.commitState(); } inline void revertToLastCommit() { - fib.revertToLastCommit(); + series.revertToLastCommit(); } inline void revertToStart() { - fib.revertToStart(); + series.revertToStart(); } inline int compute( const ASDSteel1DMaterial::InputParameters& params, const Vector& strain, @@ -511,7 +634,9 @@ namespace { // nonlinear P reponse double fiber_stress; double fiber_tangent; - int retval = fib.compute(params, do_implex, time_factor, strain(0), fiber_stress, fiber_tangent); + int retval; + retval = series.compute(params, do_implex, time_factor, strain(0), fiber_stress, fiber_tangent); + double fiber_force = fiber_stress * area; stress(0) = fiber_force; tangent(0, 0) = fiber_tangent * area; @@ -520,6 +645,10 @@ namespace { // done return retval; } + inline void setSlipMaterial(UniaxialMaterial* prototype) + { + series.setSlipMaterial(prototype); + } }; /** @@ -978,9 +1107,18 @@ namespace { // section strain = B*U strain_s.addMatrixVector(0.0, B, UL, 1.0); - + int retval; //section compute strain - stress tangent - int retval = section.compute(params, strain_s, do_implex, time_factor, stress_s, tangent_s); + //if (params.slip) { + // if (EType == EType_Mid) { + // retval = section.compute(params, strain_s, do_implex, params.slip, time_factor, stress_s, tangent_s); + // } + // opserr << "slip\n"; + //} + //else { + retval = section.compute(params, strain_s, do_implex, time_factor, stress_s, tangent_s); + //} + if (retval != 0) { asd_print_full("section !converged"); return retval; @@ -1055,6 +1193,10 @@ namespace { RVEModel() = default; + inline void setSlipMaterial(UniaxialMaterial* prototype) { + e2.section.setSlipMaterial(prototype); + } + inline int compute(bool elastic_correction, const ASDSteel1DMaterial::InputParameters& params, double U, bool do_implex, double time_factor, double& N, double& tangent) { // output @@ -1301,6 +1443,9 @@ class ASDSteel1DMaterialPIMPL public: ASDSteel1DMaterialPIMPL() = default; ASDSteel1DMaterialPIMPL(const ASDSteel1DMaterialPIMPL&) = default; + inline void setSlipMaterial(UniaxialMaterial* prototype) { + rve_m.setSlipMaterial(prototype); + } public: SteelComponent steel_comp; RVEModel rve_m; @@ -1315,13 +1460,13 @@ void* OPS_ASDSteel1DMaterial() opserr << "Using ASDSteel1D - Developed by: Alessia Casalucci, Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; first_done = true; } - static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu $lch $r <-implex $implex> <-buckling $buckling> <-fracture $fracture> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; + static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu <-implex> <-buckling $lch < $r>> <-fracture> <-slip $matTag $lch_anc <$r>> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; // check arguments int numArgs = OPS_GetNumRemainingInputArgs(); - if (numArgs < 7) { + if (numArgs < 5) { opserr << - "uniaxialMaterial ASDSteel1D Error: Few arguments (< 7).\n" << msg << "\n"; + "uniaxialMaterial ASDSteel1D Error: Few arguments (< 5).\n" << msg << "\n"; return nullptr; } @@ -1336,9 +1481,13 @@ void* OPS_ASDSteel1DMaterial() double eu; double lch; double r; + double r_buck; + double r_slip; bool implex = false; bool buckling = false; bool fracture = false; + bool slip = false; + double lch_anc; double K_alpha = 0.5; double max_iter= 100; double tolU = 1.0e-6; @@ -1347,6 +1496,9 @@ void* OPS_ASDSteel1DMaterial() bool have_max_iter = false; bool have_tolU = false; bool have_tolR = false; + bool have_Rbuck = false; + bool have_Rslip = false; + UniaxialMaterial* matSlip = nullptr; // get tag @@ -1358,11 +1510,11 @@ void* OPS_ASDSteel1DMaterial() // get steel base arguments auto lam_get_dparam = [&numData](double* val, const char* valname) -> bool { if (OPS_GetDouble(&numData, val) != 0) { - opserr << "nDMaterial ASDSteel1D Error: invalid '" << valname << "'.\n" << msg << "\n"; + opserr << "1DMaterial ASDSteel1D Error: invalid '" << valname << "'.\n" << msg << "\n"; return false; } if (*val <= 0.0) { - opserr << "nDMaterial ASDSteel1D Error: invalid value for '" << valname << "' (" << *val << "). It should be strictly positive.\n" << msg << "\n"; + opserr << "1DMaterial ASDSteel1D Error: invalid value for '" << valname << "' (" << *val << "). It should be strictly positive.\n" << msg << "\n"; return false; } return true; @@ -1371,17 +1523,17 @@ void* OPS_ASDSteel1DMaterial() if (!lam_get_dparam(&sy, "sy")) return nullptr; if (!lam_get_dparam(&su, "su")) return nullptr; if (!lam_get_dparam(&eu, "eu")) return nullptr; - if (!lam_get_dparam(&lch, "lch")) return nullptr; - if (!lam_get_dparam(&r, "r")) return nullptr; + //if (!lam_get_dparam(&lch, "lch")) return nullptr; + //if (!lam_get_dparam(&r, "r")) return nullptr; auto lam_optional_double = [&numData](const char* variable, double& value) -> bool { if (OPS_GetNumRemainingInputArgs() > 0) { if (OPS_GetDouble(&numData, &value) < 0) { - opserr << "nDMaterial ASDConcrete1D Error: failed to get '" << variable << "'.\n"; + opserr << "1DMaterial ASDSteel1D Error: failed to get '" << variable << "'.\n"; return false; } } else { - opserr << "nDMaterial ASDConcrete1D Error: '" << variable << "' requested but not provided.\n"; + opserr << "1DMaterial ASDSteel1D Error: '" << variable << "' requested but not provided.\n"; return false; } return true; @@ -1395,10 +1547,63 @@ void* OPS_ASDSteel1DMaterial() } if (strcmp(value, "-buckling") == 0) { buckling = true; + if (OPS_GetNumRemainingInputArgs() < 2) { + opserr << "ASDSteel1D: '-buckling' requires '$lch' after.\n"; + return nullptr; + } + if(!lam_optional_double("lch", lch)) return nullptr; + //if (lam_optional_double("r", r_buck)) { have_Rbuck = true; + //} + if (OPS_GetNumRemainingInputArgs() > 0) { + const char* peek = OPS_GetString(); + + // flag argument ( "-slip", "-fracture", etc.) + if (peek[0] != '-') { + + OPS_ResetCurrentInputArg(-1); + if (lam_optional_double("r", r_buck)) { + have_Rbuck = true; + } + } + else { + OPS_ResetCurrentInputArg(-1); + } + } } if (strcmp(value, "-fracture") == 0) { fracture = true; } + if (strcmp(value, "-slip") == 0) { + slip = true; + if (OPS_GetNumRemainingInputArgs() < 2) { + opserr << "ASDSteel1D: '-slip' requires '$matTag'and '$lch_anc' after.\n"; + return nullptr; + } + + int matTag; + int one = 1; + if (OPS_GetInt(&one, &matTag) != 0) { + opserr << "Error: OPS_GetInt\n"; + return nullptr; + } + + // Retrieve the UniaxialMaterial* + matSlip = OPS_getUniaxialMaterial(matTag); + if (matSlip == nullptr) { + opserr << "ASDSteel1D Error: No existing UniaxialMaterial with tag " << matTag << " for -slip option.\n"; + return nullptr; + } + + + + if (!lam_optional_double( "lch_anc", lch_anc )) return nullptr; + + + + if (lam_optional_double("r", r_slip)) { + have_Rslip = true; + } + } if (strcmp(value, "-K_alpha") == 0) { if (!lam_optional_double("K_alpha", K_alpha)) return nullptr; @@ -1423,22 +1628,26 @@ void* OPS_ASDSteel1DMaterial() // checks if (sy >= su) { - opserr << "nDMaterial ASDSteel1D Error: invalid value for 'su' (" << su << "). It should be larger than sy.\n" << msg << "\n"; + opserr << "1DMaterial ASDSteel1D Error: invalid value for 'su' (" << su << "). It should be larger than sy (" << sy << ").\n" << msg << "\n"; return nullptr; } if (E == 0) { - opserr << "nDMaterial ASDSteel1D Error: invalid value for 'E' (" << E << "). It should be non-zero.\n" << msg << "\n"; + opserr << "1DMaterial ASDSteel1D Error: invalid value for 'E' (" << E << "). It should be non-zero.\n" << msg << "\n"; return nullptr; } - if (lch == 0) { - opserr << "nDMaterial ASDSteel1D Error: invalid value for 'lch' (" << lch << "). It should be non-zero.\n" << msg << "\n"; - return nullptr; - } - if (r == 0) { - opserr << "nDMaterial ASDSteel1D Error: invalid value for 'r' (" << r << "). It should be non-zero.\n" << msg << "\n"; - return nullptr; + + if (buckling && slip) { + if(!have_Rbuck && !have_Rslip) { + opserr << "1DMaterial ASDSteel1D Error: when using both -buckling and -slip at least one 'r' must be provided\n" << msg << "\n"; + } + if (have_Rbuck && have_Rslip && std::abs(r_buck-r_slip)>1e-10) { + opserr << "1DMaterial ASDSteel1D Error: inconsistent 'r' values for -buckling and -slip, they must be the same\n" << msg << "\n"; + return nullptr; + } } - + if (have_Rbuck) r = r_buck; + else if (have_Rslip) r = r_slip; + @@ -1463,6 +1672,8 @@ void* OPS_ASDSteel1DMaterial() params.implex = implex; params.buckling = buckling; params.fracture = fracture; + params.slip = slip; + params.lch_anchor = lch_anc; params.length = lch / 2.0; // consider half distance, the RVE uses symmetry params.radius = r; params.K_alpha = K_alpha; @@ -1473,7 +1684,7 @@ void* OPS_ASDSteel1DMaterial() // create the material UniaxialMaterial* instance = new ASDSteel1DMaterial( // tag - tag, params); + tag, params, matSlip); // base steel args //E, sy, H1*alpha, gamma1, H2*(1.0-alpha), gamma2 // others.. @@ -1488,11 +1699,14 @@ void* OPS_ASDSteel1DMaterial() ASDSteel1DMaterial::ASDSteel1DMaterial( int _tag, - const InputParameters& _params) + const InputParameters& _params, + UniaxialMaterial* slip_material) : UniaxialMaterial(_tag, MAT_TAG_ASDSteel1DMaterial) , params(_params) , pdata(new ASDSteel1DMaterialPIMPL()) { + // set the slip material if defined + pdata->setSlipMaterial(slip_material); // intialize C as C0 C = getInitialTangent(); } @@ -1552,7 +1766,7 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) retval = homogenize(params.implex); C = C_rve; stress = stress_rve; - epl = pdata->rve_m.e2.section.fib.epl; + epl = pdata->rve_m.e2.section.series.steel_material.epl; } diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index 55fc06ebbb..d368525842 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -67,6 +67,8 @@ class ASDSteel1DMaterial : public UniaxialMaterial bool implex = false; bool buckling = false; bool fracture = false; + bool slip = false; + double lch_anchor = 0.0; // buckling double radius = 0.0; double length = 0.0; @@ -85,7 +87,8 @@ class ASDSteel1DMaterial : public UniaxialMaterial // life-cycle ASDSteel1DMaterial( int _tag, - const InputParameters& _params); + const InputParameters& _params, + UniaxialMaterial* slip_material); ASDSteel1DMaterial(); ASDSteel1DMaterial(const ASDSteel1DMaterial& other); ~ASDSteel1DMaterial(); From a17255b1f6db257900389d3b8045c641fd2da21e Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 16 May 2025 09:15:02 -0700 Subject: [PATCH 048/261] Update APDFMD.cpp --- SRC/material/uniaxial/APDFMD.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/material/uniaxial/APDFMD.cpp b/SRC/material/uniaxial/APDFMD.cpp index 3302d89012..3d6ddcf50d 100644 --- a/SRC/material/uniaxial/APDFMD.cpp +++ b/SRC/material/uniaxial/APDFMD.cpp @@ -1,4 +1,4 @@ -** Developed by: ** +/** Developed by: ** ** Linlin Xie (xielinlin@bucea.edu.cn) ** ** Cantian Yang (yangcantian@bucea.edu.cn) ** ** Bingyan Liu (1373158715@163.com) ** From 9b6e7dbe0e19ccaf3fa833474f5c2a83cb61a031 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 16 May 2025 09:15:29 -0700 Subject: [PATCH 049/261] Update APDMD.cpp --- SRC/material/uniaxial/APDMD.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/material/uniaxial/APDMD.cpp b/SRC/material/uniaxial/APDMD.cpp index 2664fdca21..92d248e01f 100644 --- a/SRC/material/uniaxial/APDMD.cpp +++ b/SRC/material/uniaxial/APDMD.cpp @@ -1,4 +1,4 @@ -** Developed by: ** +/** Developed by: ** ** Linlin Xie (xielinlin@bucea.edu.cn) ** ** Cantian Yang (yangcantian@bucea.edu.cn) ** ** Bingyan Liu (1373158715@163.com) ** From f95b4c9a0e87caa3faebd651ba27b6f8e7494cc8 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 16 May 2025 09:15:52 -0700 Subject: [PATCH 050/261] Update APDVFD.cpp --- SRC/material/uniaxial/APDVFD.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/material/uniaxial/APDVFD.cpp b/SRC/material/uniaxial/APDVFD.cpp index a5ffdc51c6..b66450e36b 100644 --- a/SRC/material/uniaxial/APDVFD.cpp +++ b/SRC/material/uniaxial/APDVFD.cpp @@ -1,4 +1,4 @@ -** Developed by: ** +/** Developed by: ** ** Linlin Xie (xielinlin@bucea.edu.cn) ** ** Cantian Yang (yangcantian@bucea.edu.cn) ** ** Haoxiang Wang (buceawhx@163.com) ** From fb772606de2a9a8ebd921fc178705326b0b74302 Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Fri, 16 May 2025 14:00:05 -0700 Subject: [PATCH 051/261] Update PML3DVISCOUS.cpp changing OPS_GetNDMaterial to OPS_getNDMaterial. --- SRC/element/PML/PML3DVISCOUS.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/element/PML/PML3DVISCOUS.cpp b/SRC/element/PML/PML3DVISCOUS.cpp index 7ef4ccf6f8..385ec9e0be 100644 --- a/SRC/element/PML/PML3DVISCOUS.cpp +++ b/SRC/element/PML/PML3DVISCOUS.cpp @@ -331,7 +331,7 @@ void* OPS_PML3DVISCOUS() return 0; } - NDMaterial* mat = OPS_GetNDMaterial(matTag); + NDMaterial* mat = OPS_getNDMaterial(matTag); if (mat == 0) { opserr << "WARNING material not found\n"; opserr << "material tag: " << matTag; From 2c1a783d25e14ff57c948005a62cd6ccd0d3ad50 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Sun, 18 May 2025 07:39:45 -0700 Subject: [PATCH 052/261] Update PML3DVISCOUS.cpp --- SRC/element/PML/PML3DVISCOUS.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/SRC/element/PML/PML3DVISCOUS.cpp b/SRC/element/PML/PML3DVISCOUS.cpp index 385ec9e0be..7246092b06 100644 --- a/SRC/element/PML/PML3DVISCOUS.cpp +++ b/SRC/element/PML/PML3DVISCOUS.cpp @@ -303,13 +303,16 @@ void* OPS_PML3DVISCOUS() opserr << "WARNING: invalid integer data : could be the tag or the node numbers \n"; return 0; } + // THIS SHOULD BE DONE IN setDomain() // calculate the number center of the element by averaging the node coordinates double elementCenter[3] = {0.0, 0.0, 0.0}; + /* // OPS_GetNodeCrd(int* nodeTag, int* sizeData, double* data); for (int i = 1; i < 9; i++) { int nodeTag = idata[i]; double nodeCoord[3] = {0.0, 0.0, 0.0}; num = 3; + // REWRITE TO DO THIS IN setDomain of the element, not in the OPS_command if (OPS_GetNodeCrd(&nodeTag, &num, nodeCoord) < 0) { opserr << "WARNING: invalid node tag: " << nodeTag << endln; return 0; @@ -321,7 +324,7 @@ void* OPS_PML3DVISCOUS() for (int j = 0; j < 3; j++) { elementCenter[j] /= 8; } - + */ // get the material tag int matTag; From 43256730ee612fa3ecdbc0d7090eb7fa181339a4 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Mon, 26 May 2025 15:17:01 +0200 Subject: [PATCH 053/261] recvSelf_sendSelf_Response --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 507 ++++++++++++++++--- SRC/material/uniaxial/ASDSteel1DMaterial.h | 7 +- 2 files changed, 437 insertions(+), 77 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index eaa937c339..1c0f2aebfa 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -276,7 +277,9 @@ namespace { public: using param_t = ASDSteel1DMaterial::InputParameters; SteelComponent() = default; - + int serializationDataSize() const; + void serialize(Vector& data, int& pos); + void deserialize(Vector& data, int& pos); inline int commitState() { // store the previously committed variables for next move from n to n - 1 lambda_commit_old = lambda_commit; @@ -450,9 +453,46 @@ namespace { double stress = 0.0; double stress_commit = 0.0; // methods - static constexpr int NDATA = 12; + static constexpr int NDATA = 14; }; + int SteelComponent::serializationDataSize() const + { + return NDATA; //= 14 + } + + void SteelComponent::serialize(Vector& data, int& pos) + { + data(pos++) = epl; + data(pos++) = epl_commit; + data(pos++) = alpha1; + data(pos++) = alpha1_commit; + data(pos++) = alpha2; + data(pos++) = alpha2_commit; + data(pos++) = lambda; + data(pos++) = lambda_commit; + data(pos++) = sg_commit; + data(pos++) = strain; + data(pos++) = strain_commit; + data(pos++) = stress; + data(pos++) = stress_commit; + } + void SteelComponent::deserialize(Vector& data, int& pos) + { + epl = data(pos++); + epl_commit = data(pos++); + alpha1 = data(pos++); + alpha1_commit = data(pos++); + alpha2 = data(pos++); + alpha2_commit = data(pos++); + lambda = data(pos++); + lambda_commit = data(pos++); + sg_commit = data(pos++); + strain = data(pos++); + strain_commit = data(pos++); + stress = data(pos++); + stress_commit = data(pos++); + } /* Series comonent. */ @@ -461,6 +501,11 @@ namespace { public: SteelComponent steel_material; UniaxialMaterial* slip_material = nullptr; + int serializationDataSize() const; + void serialize(Vector& data, int& pos, int commitTag, Channel& theChannel); + void deserialize(Vector& data, int& pos, int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker); + void serialize_slip(int commitTag, Channel& theChannel); + void deserialize_slip(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker); public: using param_t = ASDSteel1DMaterial::InputParameters; SeriesComponent() = default; @@ -568,13 +613,72 @@ namespace { asd_print("setting slip material: " << slip_material->getClassType()); } } - - public: - // state variables - backstresses - - // methods - static constexpr int NDATA = 10; + }; + int SeriesComponent::serializationDataSize() const + { + return 2; + } + + void SeriesComponent::serialize(Vector& data, int& pos, int commitTag, Channel& theChannel) + { + if (slip_material) { + data(pos++) = static_cast(slip_material->getClassTag()); + int mat_db_tag = slip_material->getDbTag(); + if (mat_db_tag == 0) { + mat_db_tag = theChannel.getDbTag(); + if (mat_db_tag != 0) + slip_material->setDbTag(mat_db_tag); + } + data(pos++) = static_cast(mat_db_tag); + } + else { + + data(pos++) = -1.0; // classTag + data(pos++) = -1.0; // dbTag + } + } + + void SeriesComponent::deserialize(Vector& data, int& pos, int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker) { + if (slip_material) { + delete slip_material; + slip_material = nullptr; + } + int classTag = static_cast(data(pos++)); + int mat_db_tag = static_cast(data(pos++)); + if (classTag >= 0) { + UniaxialMaterial* new_slip_material = theBroker.getNewUniaxialMaterial(classTag); + if (!new_slip_material) { + opserr << "SeriesComponent::deserialize - failed to get new UniaxialMaterial from broker\n"; + return; + } + new_slip_material->setDbTag(mat_db_tag); + slip_material = new_slip_material; + } + + } + + void SeriesComponent::serialize_slip(int commitTag, Channel& theChannel) + { + if (slip_material) { + int send_result = slip_material->sendSelf(commitTag, theChannel); + if (send_result < 0) { + opserr << "SeriesComponent:: serialize - failed to send slip material \n"; + } + } + } + + void SeriesComponent::deserialize_slip(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker) { + + if (slip_material) { + if (slip_material->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "SeriesComponent::deserialize - failed to receive slip material\n"; + delete slip_material; + slip_material = nullptr; + return; + } + } + } /** Section component. @@ -584,6 +688,10 @@ namespace { { private: SectionComponent() = delete; + public: + inline int serializationDataSize() const { return 0; } + inline void serialize(Vector& data, int& pos) {} + inline void deserialize(Vector& data, int& pos) {} }; /** @@ -649,6 +757,10 @@ namespace { { series.setSlipMaterial(prototype); } + + inline int serializationDataSize() const { return series.steel_material.serializationDataSize(); } + inline void serialize(Vector& data, int& pos) { series.steel_material.serialize(data, pos); } + inline void deserialize(Vector& data, int& pos) { series.steel_material.deserialize(data, pos); } }; /** @@ -722,6 +834,21 @@ namespace { // done return 0; } + inline int serializationDataSize() const { + return fibers[0].serializationDataSize() + + fibers[1].serializationDataSize() + + fibers[2].serializationDataSize(); + } + inline void serialize(Vector& data, int& pos) { + for (int i = 0; i < fibers.size(); ++i) { + fibers[i].serialize(data, pos); + } + } + inline void deserialize(Vector& data, int& pos) { + for (int i = 0; i < fibers.size(); ++i) { + fibers[i].deserialize(data, pos); + } + } }; /** @@ -956,7 +1083,30 @@ namespace { Vector UG_commit = Vector(8); Vector UG_el = Vector(11); Vector UG_el_commit = Vector(11); + + int serializationDataSize() const; + void serialize(Vector& data, int& pos); + void deserialize(Vector& data, int& pos); }; + int RVEStateVariables::serializationDataSize() const + { + return 38; + } + + void RVEStateVariables::serialize(Vector& data, int& pos) + { + for (int i = 0; i < 8; ++i) data(pos++) = UG[i]; + for (int i = 0; i < 8; ++i) data(pos++) = UG_commit[i]; + for (int i = 0; i < 11; ++i) data(pos++) = UG_el[i]; + for (int i = 0; i < 11; ++i) data(pos++) = UG_el_commit[i]; + } + void RVEStateVariables::deserialize(Vector& data, int& pos) + { + for (int i = 0; i < 8; ++i) UG[i] = data(pos++); + for (int i = 0; i < 8; ++i) UG_commit[i] = data(pos++); + for (int i = 0; i < 11; ++i) UG_el[i] = data(pos++); + for (int i = 0; i < 11; ++i) UG_el_commit[i] = data(pos++); + } /** Element component. @@ -971,6 +1121,11 @@ namespace { std::array qn_commit = { Q2D::identity(), Q2D::identity() }; V2D rn = V2D(0.0, 0.0); V2D rn_commit = V2D(0.0, 0.0); + + int serializationDataSize() const; + void serialize(Vector& data, int& pos); + void deserialize(Vector& data, int& pos); + ElementComponent() = default; @@ -1108,16 +1263,9 @@ namespace { // section strain = B*U strain_s.addMatrixVector(0.0, B, UL, 1.0); int retval; - //section compute strain - stress tangent - //if (params.slip) { - // if (EType == EType_Mid) { - // retval = section.compute(params, strain_s, do_implex, params.slip, time_factor, stress_s, tangent_s); - // } - // opserr << "slip\n"; - //} - //else { + retval = section.compute(params, strain_s, do_implex, time_factor, stress_s, tangent_s); - //} + if (retval != 0) { asd_print_full("section !converged"); @@ -1159,9 +1307,41 @@ namespace { UL_commit.Zero(); section.revertToStart(); } + + + }; + template + inline int ElementComponent::serializationDataSize() const{ + int size = 18 + section.serializationDataSize(); + return size; + } + + template + inline void ElementComponent::serialize(Vector& data, int& pos) { + for (int i = 0; i < 6; ++i) data(pos++) = UL_commit(i); + for (int i = 0; i < 2; ++i) data(pos++) = qn[i].toRotationVector(); + for (int i = 0; i < 2; ++i) data(pos++) = qn_commit[i].toRotationVector(); + data(pos++) = rn.x; + data(pos++) = rn.y; + data(pos++) = rn_commit.x; + data(pos++) = rn_commit.y; + section.serialize(data, pos); + } + template + inline void ElementComponent::deserialize(Vector& data, int& pos) { + for (int i = 0; i < 6; ++i) UL_commit(i) = data(pos++); + for (int i = 0; i < 2; ++i) qn[i] = Q2D::fromRotationVector(data(pos++)); + for (int i = 0; i < 2; ++i) qn_commit[i] = Q2D::fromRotationVector(data(pos++)); + rn.x = data(pos++); + rn.y = data(pos++); + rn_commit.x = data(pos++); + rn_commit.y = data(pos++); + section.deserialize(data, pos); + } + template inline int rve_process_element(bool elastic_correction, ElementComponent& ele, const RVEStateVariables& rve, const ASDSteel1DMaterial::InputParameters& params, bool do_implex, double time_factor) { int retval = ele.compute(elastic_correction, rve, params, do_implex, time_factor); @@ -1190,7 +1370,9 @@ namespace { ElementComponent<1, EType_Mid> e2; ElementComponent<3, EType_Top> e3; ElementComponent<1, EType_El> e0; // nonlinear section (1 fiber), but linear kinematics - + int serializationDataSize() const; + void serialize(Vector& data, int& pos); + void deserialize(Vector& data, int& pos); RVEModel() = default; inline void setSlipMaterial(UniaxialMaterial* prototype) { @@ -1433,6 +1615,28 @@ namespace { } }; + int RVEModel::serializationDataSize() const { + return sv.serializationDataSize() + + e1.serializationDataSize() + + e2.serializationDataSize() + + e3.serializationDataSize() + + e0.serializationDataSize(); + } + void RVEModel::serialize(Vector& data, int& pos) { + sv.serialize(data, pos); + e1.serialize(data, pos); + e2.serialize(data, pos); + e3.serialize(data, pos); + e0.serialize(data, pos); + } + void RVEModel::deserialize(Vector& data, int& pos) { + sv.deserialize(data, pos); + e1.deserialize(data, pos); + e2.deserialize(data, pos); + e3.deserialize(data, pos); + e0.deserialize(data, pos); + } + } /** @@ -1891,6 +2095,7 @@ int ASDSteel1DMaterial::revertToStart(void) return 0; } + UniaxialMaterial* ASDSteel1DMaterial::getCopy(void) { // we can safely use the default copy-constructor @@ -1905,33 +2110,72 @@ void ASDSteel1DMaterial::Print(OPS_Stream& s, int elastic_correction) int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) { //// aux - //int counter; + int counter; //// send DBL data - //Vector ddata(InputParameters::NDATA + 1*StateVariablesSteel::NDATA + 10); - //counter = 0; - //ddata(counter++) = static_cast(getTag()); - //ddata(counter++) = params.E; - //ddata(counter++) = params.sy; - //ddata(counter++) = params.H1; - //ddata(counter++) = params.H2; - //ddata(counter++) = params.gamma1; - //ddata(counter++) = params.gamma2; - //ddata(counter++) = static_cast(params.implex); - //steel.sendSelf(counter, ddata); - //ddata(counter++) = dtime_n; - //ddata(counter++) = dtime_n_commit; - //ddata(counter++) = static_cast(commit_done); - //ddata(counter++) = strain; - //ddata(counter++) = strain_commit; - //ddata(counter++) = stress; - //ddata(counter++) = stress_commit; - //ddata(counter++) = C; - //ddata(counter++) = energy; - //if (theChannel.sendVector(getDbTag(), commitTag, ddata) < 0) { - // opserr << "ASDSteel1DMaterial::sendSelf() - failed to send DBL data\n"; - // return -1; - //} + counter = 0; + + // variable DBL data size + + int nv_dbl = 13 + + params.NDATA + + pdata->rve_m.serializationDataSize() + + pdata->steel_comp.serializationDataSize() + + pdata->rve_m.e2.section.series.serializationDataSize(); + + + + Vector ddata(nv_dbl); + + // this data + ddata(counter++) = static_cast(getTag()); + ddata(counter++) = dtime_n; + ddata(counter++) = dtime_n_commit; + ddata(counter++) = static_cast(commit_done); + ddata(counter++) = strain; + ddata(counter++) = strain_commit; + ddata(counter++) = stress; + ddata(counter++) = stress_commit; + ddata(counter++) = C; + ddata(counter++) = stress_rve; + ddata(counter++) = stress_rve_commit; + ddata(counter++) = C_rve; + ddata(counter++) = energy; + // params + ddata(counter++) = params.E; + ddata(counter++) = params.sy; + ddata(counter++) = params.eu; + ddata(counter++) = params.H1; + ddata(counter++) = params.H2; + ddata(counter++) = params.gamma1; + ddata(counter++) = params.gamma2; + ddata(counter++) = static_cast(params.implex); + ddata(counter++) = static_cast(params.buckling); + ddata(counter++) = static_cast(params.fracture); + ddata(counter++) = static_cast(params.slip); + ddata(counter++) = params.lch_anchor; + ddata(counter++) = params.radius; + ddata(counter++) = params.length; + ddata(counter++) = params.lch_element; + ddata(counter++) = params.K_alpha; + ddata(counter++) = params.max_iter; + ddata(counter++) = params.tolU; + ddata(counter++) = params.tolR; + // rve + pdata->rve_m.serialize(ddata, counter); + // steel for regularization + pdata->steel_comp.serialize(ddata, counter); + // slip + pdata->rve_m.e2.section.series.serialize(ddata, counter, commitTag, theChannel); + + + + if (theChannel.sendVector(getDbTag(), commitTag, ddata) < 0) { + opserr << "ASDSteel1DMaterial::sendSelf() - failed to send DBL data\n"; + return -1; + } + + pdata->rve_m.e2.section.series.serialize_slip(commitTag, theChannel); //// done return 0; @@ -1940,33 +2184,70 @@ int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker) { //// aux - //int counter; + int counter; + + // variable DBL data size + int nv_dbl = nv_dbl = 13 + + params.NDATA + + pdata->rve_m.serializationDataSize() + + pdata->steel_comp.serializationDataSize(); + + // pdata->rve_m.e0.section.series.serializationDataSize() + pdata->rve_m.e2.section.series.serializationDataSize() + pdata->steel_comp.serializationDataSize(); + Vector ddata(nv_dbl); //// recv DBL data //Vector ddata(InputParameters::NDATA + 1 * StateVariablesSteel::NDATA + 10); - //if (theChannel.recvVector(getDbTag(), commitTag, ddata) < 0) { - // opserr << "ASDSteel1DMaterial::recvSelf() - failed to receive DBL data\n"; - // return -1; - //} - //counter = 0; - //setTag(ddata(counter++)); - //params.E = ddata(counter++); - //params.sy = ddata(counter++); - //params.H1 = ddata(counter++); - //params.H2 = ddata(counter++); - //params.gamma1 = ddata(counter++); - //params.gamma2 = ddata(counter++); - //params.implex = static_cast(ddata(counter++)); - //steel.recvSelf(counter, ddata); - //dtime_n = ddata(counter++); - //dtime_n_commit = ddata(counter++); - //commit_done = static_cast(ddata(counter++)); - //strain = ddata(counter++); - //strain_commit = ddata(counter++); - //stress = ddata(counter++); - //stress_commit = ddata(counter++); - //C = ddata(counter++); - //energy = ddata(counter++); + if (theChannel.recvVector(getDbTag(), commitTag, ddata) < 0) { + opserr << "ASDSteel1DMaterial::recvSelf() - failed to receive DBL data\n"; + return -1; + } + + counter = 0; + + // this data + setTag(ddata(counter++)); + dtime_n = ddata(counter++); + dtime_n_commit = ddata(counter++); + commit_done = static_cast(ddata(counter++)); + strain = ddata(counter++); + strain_commit = ddata(counter++); + stress = ddata(counter++); + stress_commit = ddata(counter++); + C = ddata(counter++); + stress_rve_commit = ddata(counter++); + C_rve = ddata(counter++); + stress_rve = ddata(counter++); + energy = ddata(counter++); + + //params + params.E = ddata(counter++); + params.sy = ddata(counter++); + params.eu = ddata(counter++); + params.H1 = ddata(counter++); + params.H2 = ddata(counter++); + params.gamma1 = ddata(counter++); + params.gamma2 = ddata(counter++); + params.implex = static_cast(ddata(counter++)); + params.buckling = static_cast(ddata(counter++)); + params.fracture = static_cast(ddata(counter++)); + params.slip = static_cast(ddata(counter++)); + params.lch_anchor = ddata(counter++); + params.radius = ddata(counter++); + params.length = ddata(counter++); + params.lch_element = ddata(counter++); + params.K_alpha = ddata(counter++); + params.max_iter = ddata(counter++); + params.tolU = ddata(counter++); + params.tolR = ddata(counter++); + // rve + pdata->rve_m.deserialize(ddata, counter); + // steel for regularization + pdata->steel_comp.deserialize(ddata, counter); + // slip + pdata->rve_m.e2.section.series.deserialize(ddata, counter, commitTag, theChannel, theBroker); + + + pdata->rve_m.e2.section.series.deserialize_slip(commitTag, theChannel, theBroker); //// done return 0; @@ -2005,16 +2286,30 @@ Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Strea // labels static std::vector lb_buckling_ratio = { "BI" }; + static std::vector lb_damage = { "D" }; + static std::vector lb_eqpl_strain = { "PLE" }; + + static std::vector lb_slip_resp = { "Slip", "Tau" }; + static std::vector lb_steel_resp = { "strain_steel", "stress_steel" }; + - // all outputs are 1D - static Vector out1(1); // check specific responses if (argc > 0) { - // 1000 - base steel output if (strcmp(argv[0], "BI") == 0 || strcmp(argv[0], "BucklingIndicator") == 0) { - out1(0) = pdata->rve_m.sv.UG(6); - return make_resp(1001, out1, &lb_buckling_ratio); + return make_resp(1001, getBucklingIndicator(), &lb_buckling_ratio); + } + if (strcmp(argv[0], "D") == 0 || strcmp(argv[0], "Damage") == 0) { + return make_resp(1002, getDamage(), &lb_damage); + } + if (strcmp(argv[0], "PLE") == 0 || strcmp(argv[0], "EquivalentPlasticStrain") == 0) { + return make_resp(1003, getEqPlStrain(), &lb_eqpl_strain); + } + if (strcmp(argv[0], "SlipResponse") == 0){ + return make_resp(1004, getSlipResponse(), &lb_slip_resp); + } + if (strcmp(argv[0], "SteelResponse") == 0) { + return make_resp(1005, getSteelResponse(), &lb_steel_resp); } } @@ -2025,13 +2320,20 @@ Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Strea int ASDSteel1DMaterial::getResponse(int responseID, Information& matInformation) { // all outputs are 1D - static Vector out1(1); + //static Vector out1(1); switch (responseID) { // 1000 - base steel output - case 1001: - out1(0) = pdata->rve_m.sv.UG(6); - return matInformation.setVector(out1); + case 1001: + return matInformation.setVector(getBucklingIndicator()); + case 1002: + return matInformation.setVector(getDamage()); + case 1003: + return matInformation.setVector(getEqPlStrain()); + case 1004: + return matInformation.setVector(getSlipResponse()); + case 1005: + return matInformation.setVector(getSteelResponse()); default: break; } @@ -2043,6 +2345,59 @@ double ASDSteel1DMaterial::getEnergy(void) return energy; } +const Vector& ASDSteel1DMaterial::getBucklingIndicator() const +{ + static Vector d(1); + d.Zero(); + d(0) = pdata->rve_m.sv.UG(6); + return d; +} + +const Vector& ASDSteel1DMaterial::getDamage() const +{ + static Vector d(1); + d.Zero(); + if (params.fracture) { + double eupl = params.eu - params.sy / params.E; + if (pdata->rve_m.e2.section.series.steel_material.epl > eupl) { + double epl_max = eupl + eupl * params.length / params.lch_element; + double G = (epl_max - eupl) * params.sy / 2.0; + double sigma_damaged = std::max(1.0e-4 * params.sy, params.sy * exp(-params.sy * (pdata->rve_m.e2.section.series.steel_material.epl - eupl) / G)); + d(0) = 1.0 - sigma_damaged / params.sy; + } + } + return d; +} + +const Vector& ASDSteel1DMaterial::getEqPlStrain() const +{ + static Vector d(1); + d.Zero(); + d(0) = pdata->rve_m.e2.section.series.steel_material.epl; + return d; +} +const Vector& ASDSteel1DMaterial::getSlipResponse() const +{ + static Vector d(2); + d.Zero(); + if (params.slip) { + d(0) = pdata->rve_m.e2.section.series.slip_material->getStrain(); + d(1) = pdata->rve_m.e2.section.series.slip_material->getStress(); + } + return d; +} + +const Vector& ASDSteel1DMaterial::getSteelResponse() const +{ + static Vector d(2); + d.Zero(); + if (params.slip) { + d(0) = pdata->rve_m.e2.section.series.steel_material.strain; + d(1) = pdata->rve_m.e2.section.series.steel_material.stress; + } + return d; +} + int ASDSteel1DMaterial::homogenize(bool do_implex) { // return value diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index d368525842..3c26e8e3dc 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -80,7 +80,7 @@ class ASDSteel1DMaterial : public UniaxialMaterial double tolU = 0.0; double tolR = 0.0; // counter - static constexpr int NDATA = 17; + static constexpr int NDATA = 19; }; public: @@ -127,6 +127,11 @@ class ASDSteel1DMaterial : public UniaxialMaterial private: int homogenize(bool do_implex); + const Vector& getBucklingIndicator() const; + const Vector& getDamage() const; + const Vector& getEqPlStrain() const; + const Vector& getSlipResponse() const; + const Vector& getSteelResponse() const; private: From 66e7a4729dae26acc62de16d14df41ff677e3717 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 26 May 2025 08:20:11 -0700 Subject: [PATCH 054/261] Update SFI_MVLEM.cpp --- SRC/element/mvlem/SFI_MVLEM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/element/mvlem/SFI_MVLEM.cpp b/SRC/element/mvlem/SFI_MVLEM.cpp index bcf69155af..80f81bc1b2 100755 --- a/SRC/element/mvlem/SFI_MVLEM.cpp +++ b/SRC/element/mvlem/SFI_MVLEM.cpp @@ -616,7 +616,7 @@ void SFI_MVLEM::setDomain(Domain *theDomain) // Create coordinates wrt top and bottom element node double xLoc_temp = end1Crd(0) + x[i]; double yLoc_temp = 0.5*(end1Crd(1)+end2Crd(1)); // Mid-height - double zloc_temp = end1Crd(2); // Not currently used since Domain is 2D + //double zloc_temp = end1Crd(2); // Not currently used since Domain is 2D // Create Node and add it to the domain Node *theNode = 0; From c2c84ec57bdff93b153e91bc901512a6d1ad6ba3 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Thu, 29 May 2025 12:06:32 +0200 Subject: [PATCH 055/261] slip regularization --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 189 ++++++++++--------- 1 file changed, 96 insertions(+), 93 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index 1c0f2aebfa..d52286fad4 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -557,6 +557,18 @@ namespace { // compute series response constexpr int MAX_ITER = 100; constexpr double TOL = 1e-6; + double scale_factor = 1.0; + // if in RVE for buckling, only 1 element has the slip material (1/3 of the rve length) + if (params.buckling) { + if (params.lch_element > params.length) { + scale_factor = params.length / (3.0 * params.lch_element); + } + else { + scale_factor = 1.0 / 3.0; + } + } + + _strain *= scale_factor; // initial guess for the slip strain double strain_slip = slip_material->getStrain() / params.lch_anchor; @@ -586,15 +598,11 @@ namespace { sigma = sigma_steel; if (std::abs(tangent_steel) < Ktol) tangent_steel = Ktol; if (std::abs(tangent_slip) < Ktol) tangent_slip = Ktol; - tangent = 1.0 / (1.0 / tangent_steel + 1.0 / tangent_slip); + tangent = scale_factor * 1.0 / (1.0 / tangent_steel + 1.0 / tangent_slip); asd_print("iter: " << iter); return 0; - } - - - + } } - asd_print_full("series failed"); return -1; } @@ -1306,10 +1314,7 @@ namespace { rn_commit = V2D(0.0, 0.0); UL_commit.Zero(); section.revertToStart(); - } - - - + } }; template @@ -1546,8 +1551,7 @@ namespace { break; } - } - + } } @@ -1651,7 +1655,7 @@ class ASDSteel1DMaterialPIMPL rve_m.setSlipMaterial(prototype); } public: - SteelComponent steel_comp; + SeriesComponent steel_comp; RVEModel rve_m; }; @@ -1679,19 +1683,17 @@ void* OPS_ASDSteel1DMaterial() // data int tag; - double E; - double sy; - double su; - double eu; - double lch; - double r; - double r_buck; - double r_slip; + double E = 0.0; + double sy = 0.0; + double su = 0.0; + double eu = 0.0; + double lch = 0.0; + double r = 0.0; // default to 0.0, means not provided bool implex = false; bool buckling = false; bool fracture = false; bool slip = false; - double lch_anc; + double lch_anc = 0.0; double K_alpha = 0.5; double max_iter= 100; double tolU = 1.0e-6; @@ -1700,25 +1702,23 @@ void* OPS_ASDSteel1DMaterial() bool have_max_iter = false; bool have_tolU = false; bool have_tolR = false; - bool have_Rbuck = false; - bool have_Rslip = false; UniaxialMaterial* matSlip = nullptr; // get tag if (OPS_GetInt(&numData, &tag) != 0) { - opserr << "nDMaterial ASDSteel1D Error: invalid 'tag'.\n"; + opserr << "UniaxialMaterial ASDSteel1D Error: invalid 'tag'.\n"; return nullptr; } // get steel base arguments auto lam_get_dparam = [&numData](double* val, const char* valname) -> bool { if (OPS_GetDouble(&numData, val) != 0) { - opserr << "1DMaterial ASDSteel1D Error: invalid '" << valname << "'.\n" << msg << "\n"; + opserr << "UniaxialMaterial ASDSteel1D Error: invalid '" << valname << "'.\n" << msg << "\n"; return false; } if (*val <= 0.0) { - opserr << "1DMaterial ASDSteel1D Error: invalid value for '" << valname << "' (" << *val << "). It should be strictly positive.\n" << msg << "\n"; + opserr << "UniaxialMaterial ASDSteel1D Error: invalid value for '" << valname << "' (" << *val << "). It should be strictly positive.\n" << msg << "\n"; return false; } return true; @@ -1727,17 +1727,15 @@ void* OPS_ASDSteel1DMaterial() if (!lam_get_dparam(&sy, "sy")) return nullptr; if (!lam_get_dparam(&su, "su")) return nullptr; if (!lam_get_dparam(&eu, "eu")) return nullptr; - //if (!lam_get_dparam(&lch, "lch")) return nullptr; - //if (!lam_get_dparam(&r, "r")) return nullptr; auto lam_optional_double = [&numData](const char* variable, double& value) -> bool { if (OPS_GetNumRemainingInputArgs() > 0) { if (OPS_GetDouble(&numData, &value) < 0) { - opserr << "1DMaterial ASDSteel1D Error: failed to get '" << variable << "'.\n"; + opserr << "UniaxialMaterial ASDSteel1D Error: failed to get '" << variable << "'.\n"; return false; } } else { - opserr << "1DMaterial ASDSteel1D Error: '" << variable << "' requested but not provided.\n"; + opserr << "UniaxialMaterial ASDSteel1D Error: '" << variable << "' requested but not provided.\n"; return false; } return true; @@ -1751,26 +1749,30 @@ void* OPS_ASDSteel1DMaterial() } if (strcmp(value, "-buckling") == 0) { buckling = true; - if (OPS_GetNumRemainingInputArgs() < 2) { - opserr << "ASDSteel1D: '-buckling' requires '$lch' after.\n"; + // lch is mandatory + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "UniaxialMaterial ASDSteel1D: '-buckling' requires at least '$lch'\n"; return nullptr; } if(!lam_optional_double("lch", lch)) return nullptr; - //if (lam_optional_double("r", r_buck)) { have_Rbuck = true; - //} + // radius is optional (can be defined either here or in -slip) if (OPS_GetNumRemainingInputArgs() > 0) { - const char* peek = OPS_GetString(); - - // flag argument ( "-slip", "-fracture", etc.) - if (peek[0] != '-') { - + double trial_radius; + if (OPS_GetDouble(&numData, &trial_radius) < 0) { + // radius not provided, go back OPS_ResetCurrentInputArg(-1); - if (lam_optional_double("r", r_buck)) { - have_Rbuck = true; - } } else { - OPS_ResetCurrentInputArg(-1); + // radius give, do cheks + if (trial_radius != r && r != 0.0) { + opserr << "UniaxialMaterial ASDSteel1D: radius provied in -buckling (" << trial_radius << ") does not match the one provided in -slip (" << r << "). Please use it only once.\n"; + return nullptr; + } + if (trial_radius <= 0.0) { + opserr << "UniaxialMaterial ASDSteel1D: radius provied in -buckling should be strictly positive.\n"; + return nullptr; + } + r = trial_radius; } } } @@ -1780,32 +1782,41 @@ void* OPS_ASDSteel1DMaterial() if (strcmp(value, "-slip") == 0) { slip = true; if (OPS_GetNumRemainingInputArgs() < 2) { - opserr << "ASDSteel1D: '-slip' requires '$matTag'and '$lch_anc' after.\n"; + opserr << "UniaxialMaterial ASDSteel1D: '-slip' requires '$matTag'and '$lch_anc'.\n"; return nullptr; } - + // get slip material int matTag; - int one = 1; - if (OPS_GetInt(&one, &matTag) != 0) { - opserr << "Error: OPS_GetInt\n"; + if (OPS_GetInt(&numData, &matTag) != 0) { + opserr << "UniaxialMaterial ASDSteel1D: cannot get slip material tag\n"; return nullptr; } - // Retrieve the UniaxialMaterial* matSlip = OPS_getUniaxialMaterial(matTag); if (matSlip == nullptr) { opserr << "ASDSteel1D Error: No existing UniaxialMaterial with tag " << matTag << " for -slip option.\n"; return nullptr; } - - - if (!lam_optional_double( "lch_anc", lch_anc )) return nullptr; - - - - if (lam_optional_double("r", r_slip)) { - have_Rslip = true; + // radius is optional (can be defined either here or in -buckling) + if (OPS_GetNumRemainingInputArgs() > 0) { + double trial_radius; + if (OPS_GetDouble(&numData, &trial_radius) < 0) { + // radius not provided, go back + OPS_ResetCurrentInputArg(-1); + } + else { + // radius give, do cheks + if (trial_radius != r && r != 0.0) { + opserr << "UniaxialMaterial ASDSteel1D: radius provied in -slip (" << trial_radius << ") does not match the one provided in -buckling (" << r << "). Please use it only once.\n"; + return nullptr; + } + if (trial_radius <= 0.0) { + opserr << "UniaxialMaterial ASDSteel1D: radius provied in -slip should be strictly positive.\n"; + return nullptr; + } + r = trial_radius; + } } } if (strcmp(value, "-K_alpha") == 0) { @@ -1840,22 +1851,6 @@ void* OPS_ASDSteel1DMaterial() return nullptr; } - if (buckling && slip) { - if(!have_Rbuck && !have_Rslip) { - opserr << "1DMaterial ASDSteel1D Error: when using both -buckling and -slip at least one 'r' must be provided\n" << msg << "\n"; - } - if (have_Rbuck && have_Rslip && std::abs(r_buck-r_slip)>1e-10) { - opserr << "1DMaterial ASDSteel1D Error: inconsistent 'r' values for -buckling and -slip, they must be the same\n" << msg << "\n"; - return nullptr; - } - } - if (have_Rbuck) r = r_buck; - else if (have_Rslip) r = r_slip; - - - - - // obtain chaboche params from E, sy, su, eu // we want to use 2 hardening functions as per chaboche model. // so that the initial slope is close to E and the the stress apporaches su at eu @@ -1909,8 +1904,10 @@ ASDSteel1DMaterial::ASDSteel1DMaterial( , params(_params) , pdata(new ASDSteel1DMaterialPIMPL()) { - // set the slip material if defined + // set the slip material if defined for the RVE... pdata->setSlipMaterial(slip_material); + // ... and for the base material + pdata->steel_comp.setSlipMaterial(slip_material); // intialize C as C0 C = getInitialTangent(); } @@ -1975,10 +1972,10 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) } else { - ////computation of sigma and tangent of steel + //computation of sigma and tangent of steel pdata->steel_comp.revertToLastCommit(); retval = pdata->steel_comp.compute(params, params.implex, time_factor, strain, stress, C); - epl = pdata->steel_comp.epl; + epl = pdata->steel_comp.steel_material.epl; } if (params.fracture) { double d = 0.0; @@ -2022,12 +2019,17 @@ int ASDSteel1DMaterial::commitState(void) { // implicit stage if (params.implex) { - asd_print("MAT commit (" << (int)false << ")"); - int retval = homogenize(false); - if (retval < 0) return retval; - double sigma_macro = 0.0; - double tangent_macro = 0.0; - retval = pdata->steel_comp.compute(params, false, 1.0, strain, sigma_macro, tangent_macro); + if (params.buckling) { + asd_print("MAT commit (" << (int)false << ")"); + int retval = homogenize(false); + if (retval < 0) return retval; + } + else { + double sigma_macro = 0.0; + double tangent_macro = 0.0; + int retval = pdata->steel_comp.compute(params, false, 1.0, strain, sigma_macro, tangent_macro); + if (retval < 0) return retval; + } } // compute energy @@ -2163,8 +2165,8 @@ int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) ddata(counter++) = params.tolR; // rve pdata->rve_m.serialize(ddata, counter); - // steel for regularization - pdata->steel_comp.serialize(ddata, counter); + // steel base (no buckling) + pdata->steel_comp.serialize(ddata, counter, commitTag, theChannel); // slip pdata->rve_m.e2.section.series.serialize(ddata, counter, commitTag, theChannel); @@ -2175,15 +2177,17 @@ int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) return -1; } + pdata->steel_comp.serialize_slip(commitTag, theChannel); pdata->rve_m.e2.section.series.serialize_slip(commitTag, theChannel); - //// done + + // done return 0; } int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker) { - //// aux + // aux int counter; // variable DBL data size @@ -2195,7 +2199,7 @@ int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectB // pdata->rve_m.e0.section.series.serializationDataSize() + pdata->rve_m.e2.section.series.serializationDataSize() + pdata->steel_comp.serializationDataSize(); Vector ddata(nv_dbl); - //// recv DBL data + // recv DBL data //Vector ddata(InputParameters::NDATA + 1 * StateVariablesSteel::NDATA + 10); if (theChannel.recvVector(getDbTag(), commitTag, ddata) < 0) { opserr << "ASDSteel1DMaterial::recvSelf() - failed to receive DBL data\n"; @@ -2241,15 +2245,14 @@ int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectB params.tolR = ddata(counter++); // rve pdata->rve_m.deserialize(ddata, counter); - // steel for regularization - pdata->steel_comp.deserialize(ddata, counter); + // steel base (in case of no buckling) + pdata->steel_comp.deserialize(ddata, counter, commitTag, theChannel, theBroker); + pdata->steel_comp.deserialize_slip(commitTag, theChannel, theBroker); // slip pdata->rve_m.e2.section.series.deserialize(ddata, counter, commitTag, theChannel, theBroker); - - pdata->rve_m.e2.section.series.deserialize_slip(commitTag, theChannel, theBroker); - //// done + // done return 0; } From 8dc5809ac36c621a5d8dcdae7089a30b88f789e9 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Fri, 30 May 2025 17:33:37 +0200 Subject: [PATCH 056/261] fixes slip and fracture --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 25 +++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index d52286fad4..7b3a9b473a 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -1873,7 +1873,7 @@ void* OPS_ASDSteel1DMaterial() params.fracture = fracture; params.slip = slip; params.lch_anchor = lch_anc; - params.length = lch / 2.0; // consider half distance, the RVE uses symmetry + params.length = buckling ? lch / 2.0 : 1.0; // consider half distance, the RVE uses symmetry params.radius = r; params.K_alpha = K_alpha; params.max_iter = max_iter; @@ -1898,7 +1898,7 @@ void* OPS_ASDSteel1DMaterial() ASDSteel1DMaterial::ASDSteel1DMaterial( int _tag, - const InputParameters& _params, + const ASDSteel1DMaterial::InputParameters& _params, UniaxialMaterial* slip_material) : UniaxialMaterial(_tag, MAT_TAG_ASDSteel1DMaterial) , params(_params) @@ -1981,7 +1981,7 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) double d = 0.0; double eupl = params.eu - params.sy / params.E; if (epl > eupl) { - double epl_max = eupl + eupl * params.length / params.lch_element; + double epl_max = eupl + eupl * 1.0 / params.lch_element; double G = (epl_max-eupl) * params.sy / 2.0; double sigma_damaged = std::max(1.0e-4 * params.sy, params.sy * exp(-params.sy * (epl-eupl) / G)); d = 1.0 - sigma_damaged / params.sy; @@ -2362,10 +2362,11 @@ const Vector& ASDSteel1DMaterial::getDamage() const d.Zero(); if (params.fracture) { double eupl = params.eu - params.sy / params.E; - if (pdata->rve_m.e2.section.series.steel_material.epl > eupl) { - double epl_max = eupl + eupl * params.length / params.lch_element; + double epl = params.buckling ? pdata->rve_m.e2.section.series.steel_material.epl : pdata->steel_comp.steel_material.epl; + if (epl > eupl) { + double epl_max = eupl + eupl * 1.0 / params.lch_element; double G = (epl_max - eupl) * params.sy / 2.0; - double sigma_damaged = std::max(1.0e-4 * params.sy, params.sy * exp(-params.sy * (pdata->rve_m.e2.section.series.steel_material.epl - eupl) / G)); + double sigma_damaged = std::max(1.0e-4 * params.sy, params.sy * exp(-params.sy * (epl - eupl) / G)); d(0) = 1.0 - sigma_damaged / params.sy; } } @@ -2383,9 +2384,15 @@ const Vector& ASDSteel1DMaterial::getSlipResponse() const { static Vector d(2); d.Zero(); - if (params.slip) { - d(0) = pdata->rve_m.e2.section.series.slip_material->getStrain(); - d(1) = pdata->rve_m.e2.section.series.slip_material->getStress(); + if (params.slip) { + if (params.buckling) { + d(0) = pdata->rve_m.e2.section.series.slip_material->getStrain(); + d(1) = pdata->rve_m.e2.section.series.slip_material->getStress(); + } + else { + d(0) = pdata->steel_comp.slip_material->getStrain(); + d(1) = pdata->steel_comp.slip_material->getStress(); + } } return d; } From 1e861dcf81a1fec46699fdc9dd812b1fc33d014f Mon Sep 17 00:00:00 2001 From: fmckenna Date: Fri, 30 May 2025 11:16:26 -0700 Subject: [PATCH 057/261] fmk - modifying nodeMas to be same as python, returns single value or values on the diag --- SRC/tcl/commands.cpp | 47 ++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index b727b8e577..9caaa8c22f 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -7315,7 +7315,7 @@ nodeDOFs(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING nodeMass nodeTag? nodeDOF? \n"; + opserr << "WARNING nodeDOFs nodeTag? nodeDOF? \n"; return TCL_ERROR; } @@ -7345,21 +7345,24 @@ nodeDOFs(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) int nodeMass(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { - if (argc < 3) { - opserr << "WARNING want - nodeMass nodeTag? nodeDOF?\n"; + if (argc < 2) { + opserr << "WARNING want - nodeMass nodeTag? \n"; return TCL_ERROR; } - int tag, dof; + int tag; + int dof = -1; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { opserr << "WARNING nodeMass nodeTag? nodeDOF? \n"; return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeMass nodeTag? nodeDOF? \n"; - return TCL_ERROR; - } + } + + if (argc == 3) + if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { + opserr << "WARNING nodeMass nodeTag? nodeDOF? \n"; + return TCL_ERROR; + } char buffer[40]; @@ -7369,14 +7372,24 @@ nodeMass(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) return TCL_ERROR; } int numDOF = theNode->getNumberDOF(); - if (dof < 1 || dof > numDOF) { - opserr << "WARNING nodeMass dof " << dof << " not in range" << endln; - return TCL_ERROR; - } - else { - const Matrix &mass = theNode->getMass(); - sprintf(buffer, "%35.20f", mass(dof-1,dof-1)); - Tcl_AppendResult(interp, buffer, NULL); + if (dof == -1) { + const Matrix &mass = theNode->getMass(); + for (int i =0; i numDOF) { + opserr << "WARNING nodeMass dof " << dof << " not in range" << endln; + return TCL_ERROR; + } + else { + const Matrix &mass = theNode->getMass(); + + sprintf(buffer, "%35.20f", mass(dof-1,dof-1)); + Tcl_AppendResult(interp, buffer, NULL); + } } return TCL_OK; From 76116092b1c60ee92262ddd7a45f515bb27275a5 Mon Sep 17 00:00:00 2001 From: zwaezi84 <133272845+zwaezi84@users.noreply.github.com> Date: Sat, 31 May 2025 13:48:01 +1200 Subject: [PATCH 058/261] Update SFI_MVLEM.h To fix its tangent Incosistency Issue This commit proposes a refined formulation of the SFI_MVLEM element aimed at improving the consistency and tractability of the numerical solution procedure. The enhanced model introduces explicit implementation of the interaction between axial and shear stress-strain relationships. Furthermore, the refinement accounts for axial-shear interaction effects via an extended constitutive matrix that preserves coupling between normal and shear responses. The resulting formulation improves the consistency of tangent stiffness computation, particularly for nonlinear material models, and ensures better equilibrium with residual forces during iterative analysis. The proposed refinements advance the modelling fidelity and computational robustness of the SFI_MVLEM element, making it more suitable for complex nonlinear dynamic simulations of RC shear wall structures. --- SRC/element/mvlem/SFI_MVLEM.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/SRC/element/mvlem/SFI_MVLEM.h b/SRC/element/mvlem/SFI_MVLEM.h index a08c44d4ce..4797a3cc83 100644 --- a/SRC/element/mvlem/SFI_MVLEM.h +++ b/SRC/element/mvlem/SFI_MVLEM.h @@ -57,7 +57,8 @@ class SFI_MVLEM : public Element double *Thickness, // array of macro-fiber thickness double *Width, // array of macro-fiber widths int mm, // number of macro-fibers (RC panels) - double cc); // center of rotation + double cc, // center of rotation + int coupling); // type of coupling between stresses in RC panels SFI_MVLEM(); @@ -123,6 +124,10 @@ class SFI_MVLEM : public Element Vector *theLoad; // pointer to element load double c; // center of rotation int m; // no. of RC panels + const int Coupling; // Coupling Type between shear strain and axial strains can be 0,1,or 2. + // coupling = 0 :(default) no coupling between stresses and strains, same as the original SFI_MVLEM + // coupling = 1 : only coupling between axial stresses sigmax and sigmay in RC panels + // coupling = 2 : complete coupling between all stresses, including axial and shear ones // calculated element parameters ID externalNodes; // contains the id's of end nodes From 15e628a8dbf0d0fdacb6081a38998fa889a94e16 Mon Sep 17 00:00:00 2001 From: zwaezi84 <133272845+zwaezi84@users.noreply.github.com> Date: Sat, 31 May 2025 14:05:56 +1200 Subject: [PATCH 059/261] Update SFI_MVLEM.cpp to fixt tangent inconsistency issue This commit proposes a refined formulation of the SFI_MVLEM element aimed at improving the consistency and tractability of the numerical solution procedure. The enhanced model introduces explicit implementation of the interaction between axial and shear stress-strain relationships. Furthermore, the refinement accounts for axial-shear interaction effects via an extended constitutive matrix that preserves coupling between normal and shear responses. The resulting formulation improves the consistency of tangent stiffness computation, particularly for nonlinear material models, and ensures better equilibrium with residual forces during iterative analysis. The proposed refinements advance the modelling fidelity and computational robustness of the SFI_MVLEM element, making it more suitable for complex nonlinear dynamic simulations of RC shear wall structures. --- SRC/element/mvlem/SFI_MVLEM.cpp | 432 ++++++++++++++++++++++++++------ 1 file changed, 353 insertions(+), 79 deletions(-) diff --git a/SRC/element/mvlem/SFI_MVLEM.cpp b/SRC/element/mvlem/SFI_MVLEM.cpp index bcf69155af..10dbf132cd 100755 --- a/SRC/element/mvlem/SFI_MVLEM.cpp +++ b/SRC/element/mvlem/SFI_MVLEM.cpp @@ -68,6 +68,7 @@ void *OPS_SFI_MVLEM(void) int iData[4]; double dData[1]; + int coupling = 0; int numData = 4; if (OPS_GetIntInput(&numData, iData) != 0) { @@ -134,10 +135,25 @@ void *OPS_SFI_MVLEM(void) numArgs = OPS_GetNumRemainingInputArgs(); } +if (numArgs > 0) { + str = OPS_GetString(); + numData = 1; + if (strcmp(str, "-Coupling") == 0) { + if (OPS_GetIntInput(&numData, &coupling) != 0) { + opserr << "WARNING invalid coupling data for element SFI_MVLEM" << endln; + return 0; + } + if (coupling < 0 || coupling>2) { + opserr << "WARNING invalid int data for element SFI_MVLEM coupling (it should be 0,1,or 2)" << endln; + return 0; + } + + } + } theElement = new SFI_MVLEM(iData[0], iData[1], iData[2], theMaterials, - theThickness, theWidth, iData[3], dData[0]); + theThickness, theWidth , iData[3], dData[0], coupling); // Cleanup dynamic memory @@ -161,14 +177,15 @@ SFI_MVLEM::SFI_MVLEM(int tag, double *thickness, double *width, int mm, - double cc) + double cc, + int coupling) :Element(tag,ELE_TAG_SFI_MVLEM), theNd1(0), theNd2(0), theNodesX(0), theNodesALL(0), theMaterial(0), theLoad(0), - m(mm),c(cc), + m(mm),c(cc),Coupling(coupling), externalNodes(2+m), SFI_MVLEMStrainX(0),SFI_MVLEMStrainY(0),SFI_MVLEMStrainXY(0),SFI_MVLEMStrain(0), x(0), b(0), AcX(0), AcY(0), kx(0), ky(0), kh(0), Fx(0), Fy(0), Fxy(0), Dens(0), Dx(0), Dy(0), Dxy(0), @@ -396,7 +413,7 @@ SFI_MVLEM::SFI_MVLEM() x(0), b(0), AcX(0), AcY(0), kx(0), ky(0), kh(0), Fx(0), Fy(0), Fxy(0), Dens(0), Dx(0), Dy(0), Dxy(0), SFI_MVLEMK(6+m,6+m), SFI_MVLEMR(6+m), SFI_MVLEMD(6+m,6+m), SFI_MVLEMM(6+m,6+m), P_6DOF(6), - m(0),c(0) + m(0),c(0), Coupling(0) { if (externalNodes.Size() != 2+m) opserr << "FATAL SFI_MVLEM::SFI_MVLEM() - out of memory, could not create an ID of size 2\n"; @@ -1161,6 +1178,7 @@ int SFI_MVLEM::getResponse(int responseID, Information &eleInfo) const Matrix & SFI_MVLEM::getInitialStiff(void) { double Kh=0.0; +SFI_MVLEMK.Zero(); for (int i=0; i < m; i++) { @@ -1174,8 +1192,136 @@ const Matrix & SFI_MVLEM::getInitialStiff(void) kx[i] = D00 * h*t[i] / b[i]; ky[i] = D11 * b[i]*t[i] / h; Kh += D22 * b[i]*t[i] / h; + + // defining the coupling terms of stress strain relationship + double kxy = D01 * t[i]; //Zakariya Waezi + double ktaux = D02 * t[i]; //Zakariya Waezi + double ktauy = D12 * b[i] * t[i] / h; //Zakariya Waezi + + double exy = kxy * x[i]; //Zakariya Waezi + double etauy = ktauy * x[i]; //Zakariya Waezi + double etaux = ktaux * x[i]; //Zakariya Waezi + + //Considering the coupling between axial stresses sigmax and sigma y is taken care of here: Zakariya Waezi + // if the material is linear elastic, Coupling 1 is enough + if (Coupling == 1 || Coupling==2) { //Zakariya Waezi + SFI_MVLEMK(1, 6 + i) = -kxy; + SFI_MVLEMK(6 + i, 1) = SFI_MVLEMK(1, 6 + i); + + SFI_MVLEMK(2, 6 + i) = -exy; + SFI_MVLEMK(6 + i, 2) = SFI_MVLEMK(2, 6 + i); + + SFI_MVLEMK(4, 6 + i) = kxy; + SFI_MVLEMK(6 + i, 4) = SFI_MVLEMK(4, 6 + i); + + SFI_MVLEMK(5, 6 + i) = exy; + SFI_MVLEMK(6 + i, 5) = SFI_MVLEMK(5, 6 + i); + } + + //Considering the coupling between shear stress and axial stresses in addition to axial stresses coupling + // is taken care of here: + // if the material is nonlinear, for complete consideration of coupling, Coupling variable should be 2 + // Zakariya Waezi + if (Coupling == 2) { + //SFI_MVLEMK(0, 0) += 0; + + SFI_MVLEMK(0, 1) += ktauy; + + SFI_MVLEMK(0, 2) += etauy; + + //SFI_MVLEMK(0, 3) += 0; + + SFI_MVLEMK(0, 4) += -ktauy; + + SFI_MVLEMK(0, 5) += -etauy; + + SFI_MVLEMK(0, 6 + i) += -ktaux; + + SFI_MVLEMK(1, 0) += ktauy; + + //SFI_MVLEMK(1, 1) += 0; + + SFI_MVLEMK(1, 2) += -c * h * ktauy; + + SFI_MVLEMK(1, 3) += -ktauy; + + //SFI_MVLEMK(1, 4) += 0; + + SFI_MVLEMK(1, 5) += (-1 + c) * h * ktauy; + + //SFI_MVLEMK(1, 6+i) += 0; + + SFI_MVLEMK(2, 0) += etauy; + + SFI_MVLEMK(2, 1) += -c * h * ktauy; + + SFI_MVLEMK(2, 2) += -2 * c * etauy * h; + + SFI_MVLEMK(2, 3) += -etauy; + + SFI_MVLEMK(2, 4) += c * h * ktauy; + + SFI_MVLEMK(2, 5) += (-1 + 2 * c) * etauy * h; + + SFI_MVLEMK(2, 6 + i) += c * h * ktaux; + + //SFI_MVLEMK(3, 0) += 0; + + SFI_MVLEMK(3, 1) += -ktauy; + + SFI_MVLEMK(3, 2) += -etauy; + + //SFI_MVLEMK(3, 3) += 0; + + SFI_MVLEMK(3, 4) += ktauy; + + SFI_MVLEMK(3, 5) += etauy; + + SFI_MVLEMK(3, 6 + i) += ktaux; + + SFI_MVLEMK(4, 0) += -ktauy; + + //SFI_MVLEMK(4, 1) += 0; + + SFI_MVLEMK(4, 2) += c * h * ktauy; + + SFI_MVLEMK(4, 3) += ktauy; + + //SFI_MVLEMK(4, 4) += 0; + + SFI_MVLEMK(4, 5) += -(-1 + c) * h * ktauy; + + //SFI_MVLEMK(4, 6+i) += 0; + + SFI_MVLEMK(5, 0) += -etauy; + + SFI_MVLEMK(5, 1) += (-1 + c) * h * ktauy; + + SFI_MVLEMK(5, 2) += (-1 + 2 * c) * etauy * h; + + SFI_MVLEMK(5, 3) += etauy; + + SFI_MVLEMK(5, 4) += (1 - c) * h * ktauy; + + SFI_MVLEMK(5, 5) += 2 * (1 - c) * etauy * h; + + SFI_MVLEMK(5, 6 + i) += (1 - c) * h * ktaux; + + SFI_MVLEMK(6 + i, 0) += -ktaux; + + //SFI_MVLEMK(6+i, 1) += 0; + + SFI_MVLEMK(6 + i, 2) += c * h * ktaux; + + SFI_MVLEMK(6 + i, 3) += ktaux; + + //SFI_MVLEMK(6+i, 4) += 0; + + SFI_MVLEMK(6 + i, 5) += (1 - c) * h * ktaux; + } } + // end of coupling terms effect ZW // Build the initial stiffness matrix double Kv=0.0; double Km=0.0; double e=0.0; double ex=0.0; @@ -1186,50 +1332,50 @@ const Matrix & SFI_MVLEM::getInitialStiff(void) Km+=ky[i]*x[i]*x[i]; e+=ky[i]*x[i]; - SFI_MVLEMK(6+i,6+i) = kx[i]; // Diagonal terms accounting for horizontal stiffness + SFI_MVLEMK(6+i,6+i) += kx[i]; // Diagonal terms accounting for horizontal stiffness } - SFI_MVLEMK(0,0) = Kh; - SFI_MVLEMK(0,1) = 0.0; - SFI_MVLEMK(0,2) = -Kh*c*h; - SFI_MVLEMK(0,3) = -Kh; - SFI_MVLEMK(0,4) = 0.0; - SFI_MVLEMK(0,5) = -Kh*(1-c)*h; + SFI_MVLEMK(0,0) += Kh; + //SFI_MVLEMK(0,1) += 0.0; + SFI_MVLEMK(0,2) += -Kh*c*h; + SFI_MVLEMK(0,3) += -Kh; + //SFI_MVLEMK(0,4) += 0.0; + SFI_MVLEMK(0,5) += -Kh*(1-c)*h; SFI_MVLEMK(1,0) = SFI_MVLEMK(0,1); - SFI_MVLEMK(1,1) = Kv; - SFI_MVLEMK(1,2) = e; - SFI_MVLEMK(1,3) = 0.0; - SFI_MVLEMK(1,4) = -Kv; - SFI_MVLEMK(1,5) = -e; + SFI_MVLEMK(1,1) += Kv; + SFI_MVLEMK(1,2) += e; + //SFI_MVLEMK(1,3) += 0.0; + SFI_MVLEMK(1,4) += -Kv; + SFI_MVLEMK(1,5) += -e; SFI_MVLEMK(2,0) = SFI_MVLEMK(0,2); SFI_MVLEMK(2,1) = SFI_MVLEMK(1,2); - SFI_MVLEMK(2,2) = h*h*c*c*Kh+Km; - SFI_MVLEMK(2,3) = h*c*Kh; - SFI_MVLEMK(2,4) = -e; - SFI_MVLEMK(2,5) = (1-c)*c*h*h*Kh-Km; + SFI_MVLEMK(2,2) += h*h*c*c*Kh+Km; + SFI_MVLEMK(2,3) += h*c*Kh; + SFI_MVLEMK(2,4) += -e; + SFI_MVLEMK(2,5) += (1-c)*c*h*h*Kh-Km; SFI_MVLEMK(3,0) = SFI_MVLEMK(0,3); SFI_MVLEMK(3,1) = SFI_MVLEMK(1,3); SFI_MVLEMK(3,2) = SFI_MVLEMK(2,3); - SFI_MVLEMK(3,3) = Kh; - SFI_MVLEMK(3,4) = 0.0; - SFI_MVLEMK(3,5) = Kh*(1-c)*h; + SFI_MVLEMK(3,3) += Kh; + //SFI_MVLEMK(3,4) += 0.0; + SFI_MVLEMK(3,5) += Kh*(1-c)*h; SFI_MVLEMK(4,0) = SFI_MVLEMK(0,4); SFI_MVLEMK(4,1) = SFI_MVLEMK(1,4); SFI_MVLEMK(4,2) = SFI_MVLEMK(2,4); SFI_MVLEMK(4,3) = SFI_MVLEMK(3,4); - SFI_MVLEMK(4,4) = Kv; - SFI_MVLEMK(4,5) = e; + SFI_MVLEMK(4,4) += Kv; + SFI_MVLEMK(4,5) += e; SFI_MVLEMK(5,0) = SFI_MVLEMK(0,5); SFI_MVLEMK(5,1) = SFI_MVLEMK(1,5); SFI_MVLEMK(5,2) = SFI_MVLEMK(2,5); SFI_MVLEMK(5,3) = SFI_MVLEMK(3,5); SFI_MVLEMK(5,4) = SFI_MVLEMK(4,5); - SFI_MVLEMK(5,5) = (1-c)*(1-c)*h*h*Kh+Km; + SFI_MVLEMK(5,5) += (1-c)*(1-c)*h*h*Kh+Km; for(int i=0; i<6+m; ++i) { @@ -1263,62 +1409,190 @@ const Matrix & SFI_MVLEM::getTangentStiff(void) ky[i] = D11 * b[i]*t[i] / h; Kh += D22 * b[i]*t[i] / h; - } + // defining the coupling terms of stress-strain relationship + double kxy = D01 * t[i]; //Zakariya Waezi + double ktaux = D02 * t[i]; //Zakariya Waezi + double ktauy = D12 * b[i] * t[i] / h; //Zakariya Waezi - // Build the tangent stiffness matrix - double Kv=0.0; double Km=0.0; double e=0.0; double ex=0.0; + double exy = kxy * x[i]; //Zakariya Waezi + double etauy = ktauy * x[i]; //Zakariya Waezi + double etaux = ktaux * x[i]; //Zakariya Waezi - for(int i=0; i Date: Thu, 5 Jun 2025 16:34:47 -0700 Subject: [PATCH 060/261] Add SWMR support for HDF5 file handling in VTKHDF_Recorder and adding _HDF macro --- SRC/recorder/VTKHDF_Recorder.cpp | 56 ++++++++++++++++++++++++++------ SRC/recorder/VTKHDF_Recorder.h | 3 ++ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/SRC/recorder/VTKHDF_Recorder.cpp b/SRC/recorder/VTKHDF_Recorder.cpp index 6851231354..e7a8c754e5 100644 --- a/SRC/recorder/VTKHDF_Recorder.cpp +++ b/SRC/recorder/VTKHDF_Recorder.cpp @@ -18,6 +18,7 @@ ** ** ** ****************************************************************** */ +#ifdef _HDF5 #include "VTKHDF_Recorder.h" #include #include @@ -212,16 +213,45 @@ VTKHDF_Recorder::VTKHDF_Recorder(const char *inputName, strcpy(name, inputName); - VTKHDF_Recorder::setVTKType(); - - // ----------------------- - // 1) Create (or overwrite) the HDF5 file using the C API + VTKHDF_Recorder::setVTKType(); // ----------------------- + // 1) Create (or overwrite) the HDF5 file using the C API with SWMR support // ----------------------- - file_id = H5Fcreate(name, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + // Create file access property list for SWMR (Single Writer Multiple Reader) + hid_t fapl_id = H5Pcreate(H5P_FILE_ACCESS); + if (fapl_id < 0) { + opserr << "Error: Could not create file access property list for " << name << endln; + return; + } + + // Enable latest version of the library format (required for SWMR) + herr_t ret = H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); + if (ret < 0) { + opserr << "Error: Could not set library version bounds for " << name << endln; + H5Pclose(fapl_id); + return; + } + + // Create the file with SWMR-compatible settings + file_id = H5Fcreate(name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); if (file_id < 0) { opserr << "Error: Could not create HDF5 file " << name << endln; - return; // Handle the error as needed, or throw an exception + H5Pclose(fapl_id); + return; } + + // Close the file temporarily to reopen it in SWMR write mode + H5Fclose(file_id); + + // Reopen the file in SWMR write mode + file_id = H5Fopen(name, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl_id); + if (file_id < 0) { + opserr << "Error: Could not reopen HDF5 file in SWMR write mode " << name << endln; + H5Pclose(fapl_id); + return; + } + + // Close the file access property list + H5Pclose(fapl_id); // 4) Create the group "/VTKHDF" group_id = H5Gcreate(file_id, "/VTKHDF", @@ -1367,13 +1397,17 @@ VTKHDF_Recorder::VTKHDF_Recorder(const char *inputName, initDone = false; - numSteps = 0; - - // opserr << "initilization done\n"; + numSteps = 0; // opserr << "initilization done\n"; CurrentDispOffset = 0; CurrentVelOffset = 0; CurrentAccelOffset = 0; + // Enable SWMR mode for concurrent reading + if (H5Fstart_swmr_write(file_id) < 0) { + opserr << "Warning: Could not enable SWMR write mode for " << name << endln; + opserr << " File will still be created but concurrent reading may not work optimally" << endln; + } + } @@ -3269,6 +3303,7 @@ void VTKHDF_Recorder::setVTKType() vtktypes[ELE_TAG_PML2DVISCOUS] = VTK_QUAD; vtktypes[ELE_TAG_PML2D] = VTK_QUAD; vtktypes[ELE_TAG_PML3D] = VTK_HEXAHEDRON; + vtktypes[ELE_TAG_PML3DVISCOUS] = VTK_HEXAHEDRON; } @@ -3614,4 +3649,5 @@ int VTKHDF_Recorder::extendOffsetDataset(hid_t group_id, H5Dclose(dset_id); return 0; -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/SRC/recorder/VTKHDF_Recorder.h b/SRC/recorder/VTKHDF_Recorder.h index f37166379f..67916eb94a 100644 --- a/SRC/recorder/VTKHDF_Recorder.h +++ b/SRC/recorder/VTKHDF_Recorder.h @@ -23,6 +23,7 @@ // Purpose: Class definition for VTKHDF_Recorder to store responses in HDF5 format. // Include existing headers plus HDF5 +#ifdef _HDF5 #include #include #include @@ -278,3 +279,5 @@ class VTKHDF_Recorder : public Recorder { }; #endif + +#endif From 803158cd28680615ee792032cea3d1ae282594f5 Mon Sep 17 00:00:00 2001 From: amnp95 Date: Thu, 5 Jun 2025 16:36:04 -0700 Subject: [PATCH 061/261] fixing updward casting for PMLVISCOUS element --- SRC/element/PML/PML3DVISCOUS.cpp | 62 ++++++++++++++++++++++++++------ SRC/element/PML/PML3DVISCOUS.h | 5 +-- 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/SRC/element/PML/PML3DVISCOUS.cpp b/SRC/element/PML/PML3DVISCOUS.cpp index 7246092b06..0a4fd9ba27 100644 --- a/SRC/element/PML/PML3DVISCOUS.cpp +++ b/SRC/element/PML/PML3DVISCOUS.cpp @@ -347,12 +347,31 @@ void* OPS_PML3DVISCOUS() return 0; } - // cast the material to ElasticIsotropicMaterial - ElasticIsotropicMaterial* Elasmat = (ElasticIsotropicMaterial*)mat; + double E = 0.0, nu = 0.0, rho = 0.0; - double E = Elasmat->getElasticModulus(); - double nu = Elasmat->getPoissonsRatio(); - double rho = Elasmat->getRho(); + const char* argv_E[] = {"E"}; + const char* argv_nu[] = {"nu"}; + + Parameter paramE(1); + Parameter paramNu(2); + + // This is the intended way to access material properties + if (mat->setParameter(argv_E, 1, paramE) >= 0) { + E = paramE.getValue(); + } else { + opserr << "Warning: Material doesn't support E parameter\n"; + } + + if (mat->setParameter(argv_nu, 1, paramNu) >= 0) { + nu = paramNu.getValue(); + } else { + opserr << "Warning: Material doesn't support nu parameter\n"; + } + + // Always available in NDMaterial base class + rho = mat->getRho(); + + // opserr << "PML3DVISCOUS element: E=" << E << ", nu=" << nu << ", rho=" << rho << endln; @@ -583,7 +602,7 @@ void* OPS_PML3DVISCOUS() return new PML3DVISCOUS(idata[0], &idata[1], - Elasmat, PMLThickness, + mat, PMLThickness, Xref, Normal, alpha_0, beta_0, ExplicitAlphaBeta, Cp, m_coeff, R, @@ -662,6 +681,9 @@ PML3DVISCOUS::PML3DVISCOUS() alpha0 = 0; beta0 = 0; ExplicitAlphaBeta = false; + E = 0.0; + nu = 0.0; + rho = 0.0; } @@ -670,7 +692,7 @@ PML3DVISCOUS::PML3DVISCOUS() // Full constructor // ======================================================================= PML3DVISCOUS::PML3DVISCOUS(int tag, int* nodeTags, - ElasticIsotropicMaterial* theMat, + NDMaterial* theMat, double PMLThickness, double* Xref, double* Normal, double alpha_0, double beta_0, bool explicitAB, @@ -725,6 +747,26 @@ PML3DVISCOUS::PML3DVISCOUS(int tag, int* nodeTags, ny = Normal[1]; nz = Normal[2]; + Parameter paramE(1); + Parameter paramNu(2); + const char* argv_E[] = {"E"}; + const char* argv_nu[] = {"nu"}; + if (strcmp(theMaterial->getClassType(), "ElasticIsotropicMaterial") == 0) { + int res = 0; + res = theMaterial->setParameter(argv_nu, 1, paramNu); + res = theMaterial->setParameter(argv_E, 1, paramE); + if (res >= 0) { + nu = paramNu.getValue(); + E = paramE.getValue(); + } else { + opserr << "Error: PML3DVISCOUS element only supports ElasticIsotropicMaterial\n"; + opserr << "\tMaterial provided is of type: " << theMaterial->getClassType() << endln; + return; + } + } + rho = theMaterial->getRho(); + // opserr << "PML3DVISCOUS element(Domain): E=" << E << ", nu=" << nu << ", rho=" << theMaterial->getRho() << endln; + // print out the information // opserr << "PML3DVISCOUS element, tag: " << this->getTag() << endln; // opserr << "Node 1: " << connectedExternalNodes(0) << endln; @@ -817,9 +859,9 @@ void PML3DVISCOUS::calculateMatrices() double betarayleigh = (betaK0 > betaK) ? betaK0 : betaK; betarayleigh = (betaKc > betarayleigh) ? betaKc : betarayleigh; double props[16]; - props[0] = theMaterial->getElasticModulus(); - props[1] = theMaterial->getPoissonsRatio(); - props[2] = theMaterial->getRho(); + props[0] = E; + props[1] = nu; + props[2] = rho; props[3] = 6.0; props[4] = PML_L; props[5] = xref; diff --git a/SRC/element/PML/PML3DVISCOUS.h b/SRC/element/PML/PML3DVISCOUS.h index 02ad35bcdc..42755d49df 100644 --- a/SRC/element/PML/PML3DVISCOUS.h +++ b/SRC/element/PML/PML3DVISCOUS.h @@ -86,7 +86,7 @@ class PML3DVISCOUS : public Element { PML3DVISCOUS(); //null constructor // PML3DVISCOUS(int tag, int* nodeTags, double* newmarks, double* dData); // full constructor PML3DVISCOUS(int tag, int* nodeTags, - ElasticIsotropicMaterial* theMat, double PMLThickness, + NDMaterial* theMat, double PMLThickness, double* Xref, double* Normal, double alpha_0, double beta_0, bool explicitAB, double Cp, double m_coeff, double R, @@ -166,7 +166,8 @@ class PML3DVISCOUS : public Element { double cp_ref; // reference wave speed bool ExplicitAlphaBeta; // flag for explicit alpha beta - ElasticIsotropicMaterial* theMaterial; // pointer to the material + NDMaterial* theMaterial; // pointer to the material + double E, nu, rho; // material properties: E, nu, rho }; From 55e9dcac9b1017770061e2fd4b59cd061a36c6f2 Mon Sep 17 00:00:00 2001 From: fmckenna Date: Thu, 5 Jun 2025 22:54:11 -0700 Subject: [PATCH 062/261] fmk - adding nodeCoord command for python compilation --- SRC/interpreter/OpenSeesOutputCommands.cpp | 65 ++++++++++++++++++++++ SRC/interpreter/PythonWrapper.cpp | 12 ++++ 2 files changed, 77 insertions(+) diff --git a/SRC/interpreter/OpenSeesOutputCommands.cpp b/SRC/interpreter/OpenSeesOutputCommands.cpp index ebbb95d435..ee36a2c319 100644 --- a/SRC/interpreter/OpenSeesOutputCommands.cpp +++ b/SRC/interpreter/OpenSeesOutputCommands.cpp @@ -250,6 +250,71 @@ int OPS_nodeDisp() return 0; } + +int OPS_nodeCrd() +{ + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING insufficient args: nodeDisp nodeTag \n"; + return -1; + } + + // tag and dof + int data[2] = {0, -1}; + int numdata = OPS_GetNumRemainingInputArgs(); + if (numdata > 2) { + numdata = 2; + } + + if (OPS_GetIntInput(&numdata, data) < 0) { + opserr<<"WARNING nodeDisp - failed to read int inputs\n"; + return -1; + } + data[1]--; + + // get Crds + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + Node *theNode = theDomain->getNode(data[0]); + if (theNode == 0) return -1; + + const Vector &crd = theNode->getCrds(); + + + // set outputs + int size = crd.Size(); + if (data[1] >= 0) { + if (data[1] >= size) { + opserr << "WARNING nodeDisp nodeTag? dof? - dofTag? too large\n"; + return -1; + } + + double value = crd(data[1]); + numdata = 1; + + if (OPS_SetDoubleOutput(&numdata, &value, true) < 0) { + opserr<<"WARNING nodeDisp - failed to read double inputs\n"; + return -1; + } + + + } else { + + int size = crd.Size(); + std::vector values(size); + for (int i=0; igetResults(); } +static PyObject *Py_ops_nodeCrd(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_nodeCoord() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + static PyObject *Py_ops_nodeVel(PyObject *self, PyObject *args) { wrapper->resetCommandLine(PyTuple_Size(args), 1, args); From 02efd7bcfe199d84df64b4611646d90da83a5baf Mon Sep 17 00:00:00 2001 From: fmckenna Date: Fri, 6 Jun 2025 10:49:05 -0700 Subject: [PATCH 063/261] fmk - removing ifrdef HDF5 from VTKHDF recorder as files only included if _HDF5 provided, so these ifdef are redundant --- SRC/recorder/VTKHDF_Recorder.cpp | 2 -- SRC/recorder/VTKHDF_Recorder.h | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/SRC/recorder/VTKHDF_Recorder.cpp b/SRC/recorder/VTKHDF_Recorder.cpp index e7a8c754e5..09931775f6 100644 --- a/SRC/recorder/VTKHDF_Recorder.cpp +++ b/SRC/recorder/VTKHDF_Recorder.cpp @@ -18,7 +18,6 @@ ** ** ** ****************************************************************** */ -#ifdef _HDF5 #include "VTKHDF_Recorder.h" #include #include @@ -3650,4 +3649,3 @@ int VTKHDF_Recorder::extendOffsetDataset(hid_t group_id, return 0; } -#endif \ No newline at end of file diff --git a/SRC/recorder/VTKHDF_Recorder.h b/SRC/recorder/VTKHDF_Recorder.h index 67916eb94a..d5ab0fea18 100644 --- a/SRC/recorder/VTKHDF_Recorder.h +++ b/SRC/recorder/VTKHDF_Recorder.h @@ -23,7 +23,7 @@ // Purpose: Class definition for VTKHDF_Recorder to store responses in HDF5 format. // Include existing headers plus HDF5 -#ifdef _HDF5 + #include #include #include @@ -279,5 +279,3 @@ class VTKHDF_Recorder : public Recorder { }; #endif - -#endif From e059fb017ce6361af00566027488dc5aa7b4ec05 Mon Sep 17 00:00:00 2001 From: fmckenna Date: Fri, 6 Jun 2025 10:49:56 -0700 Subject: [PATCH 064/261] fmk - updating release tag to 3.7.2 --- SRC/OPS_Globals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/OPS_Globals.h b/SRC/OPS_Globals.h index 916a67046c..194c5a2ebb 100644 --- a/SRC/OPS_Globals.h +++ b/SRC/OPS_Globals.h @@ -27,7 +27,7 @@ // Description: This file contains global variables used in OpenSees files. // if you change some of the variables, you must recompile ALL the code. -#define OPS_VERSION "3.7.1" +#define OPS_VERSION "3.7.2" #ifdef _WIN32 #ifndef _WIN64 From ac6e19599a431ec7abd33b246b8996a54886a4ac Mon Sep 17 00:00:00 2001 From: alec0498 Date: Mon, 9 Jun 2025 08:51:34 +0200 Subject: [PATCH 065/261] flag no regularization --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 169 +++++++++++++------ SRC/material/uniaxial/ASDSteel1DMaterial.h | 4 +- 2 files changed, 125 insertions(+), 48 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index 7b3a9b473a..269a5135cb 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -919,10 +919,10 @@ namespace { static constexpr int N2 = 1; }; template - inline void getElementDisplacementVector(bool elastic_correction, const Vector& G, Vector& L) { + inline void getElementDisplacementVector(const ASDSteel1DMaterial::InputParameters& params, bool elastic_correction, const Vector& G, Vector& L) { // G = global vector, size = 8 -> full = 12, semi-full 8 (7 free + 1 Uy imposed) // L = local vector , size = 6 - if (elastic_correction) { + if (elastic_correction && params.auto_regularization) { for (int i = 0; i < 6; ++i) { int gdof = ETypeTraits::DOFs[i]; if (gdof < 10 ) { @@ -945,10 +945,10 @@ namespace { } } template - inline void assembleRHS(bool elastic_correction, const Vector& L, Vector& G) { + inline void assembleRHS(const ASDSteel1DMaterial::InputParameters& params, bool elastic_correction, const Vector& L, Vector& G) { // G = global vector, size = 7 (-> full = 12, semi-full 8 (7 free + 1 Uy imposed) only free) // L = local vector , size = 6 - if (elastic_correction) { + if (elastic_correction && params.auto_regularization) { for (int i = 0; i < 6; ++i) { int gdof = ETypeTraits::DOFs[i]; if (gdof < 10) { @@ -966,11 +966,11 @@ namespace { } } template - inline void assembleLHS(bool elastic_correction, const Matrix& M, Matrix& G) { + inline void assembleLHS(const ASDSteel1DMaterial::InputParameters& params, bool elastic_correction, const Matrix& M, Matrix& G) { // G = global matrix, size = 7x7 -> full = 12x12, semi-full 8 (7 free + 1 Uy imposed) // L = local vector , size = 6 // M = local matrix , size = 6x6 - if (elastic_correction) { + if (elastic_correction && params.auto_regularization) { for (int i = 0; i < 6; ++i) { int idof = ETypeTraits::DOFs[i]; if (idof < 10) { @@ -999,8 +999,8 @@ namespace { } template - inline void getRetainedComponents(bool elastic_correction, const Matrix& M, double& Krr, Vector& Kcr, Vector& Krc) { - if (elastic_correction) { + inline void getRetainedComponents(const ASDSteel1DMaterial::InputParameters& params,bool elastic_correction, const Matrix& M, double& Krr, Vector& Kcr, Vector& Krc) { + if (elastic_correction && params.auto_regularization) { for (int i = 0; i < 6; ++i) { int idof = ETypeTraits::DOFs[i]; for (int j = 0; j < 6; ++j) { @@ -1162,7 +1162,7 @@ namespace { // determine node numbering (changes for elastic correction) int inode; int jnode; - if (elastic_correction) { + if (elastic_correction && params.auto_regularization) { inode = ETypeTraits::N1; jnode = ETypeTraits::N2; } @@ -1172,20 +1172,20 @@ namespace { } // obtain global displacement vectors (size changes for elastic correction) - if (elastic_correction) { - getElementDisplacementVector(elastic_correction, rve.UG_el, U); - getElementDisplacementVector(elastic_correction, rve.UG_el_commit, U_commit); - } - else { - getElementDisplacementVector(elastic_correction, rve.UG, U); - getElementDisplacementVector(elastic_correction, rve.UG_commit, U_commit); + if (elastic_correction && params.auto_regularization) { + getElementDisplacementVector(params, elastic_correction, rve.UG_el, U); + getElementDisplacementVector(params, elastic_correction, rve.UG_el_commit, U_commit); + } + else { + getElementDisplacementVector(params, elastic_correction, rve.UG, U); + getElementDisplacementVector(params, elastic_correction, rve.UG_commit, U_commit); } // undeformed nodes V2D node_i; V2D node_j; - if (elastic_correction) { + if (elastic_correction && params.auto_regularization) { node_i = rve_nodes_el[inode]; node_j = rve_nodes_el[jnode]; } @@ -1355,14 +1355,14 @@ namespace { return retval; } auto& globals = Globals::instance(); - if (elastic_correction) { - assembleRHS(elastic_correction, globals.element_RHS, globals.rve_R_el); - assembleLHS(elastic_correction, globals.element_LHS, globals.rve_K_el); + if (elastic_correction && params.auto_regularization) { + assembleRHS(params, elastic_correction, globals.element_RHS, globals.rve_R_el); + assembleLHS(params, elastic_correction, globals.element_LHS, globals.rve_K_el); } else { - assembleRHS(elastic_correction, globals.element_RHS, globals.rve_R); - assembleLHS(elastic_correction, globals.element_LHS, globals.rve_K); + assembleRHS(params, elastic_correction, globals.element_RHS, globals.rve_R); + assembleLHS(params, elastic_correction, globals.element_LHS, globals.rve_K); } return 0; } @@ -1408,7 +1408,7 @@ namespace { globals.rve_K.Zero(); globals.rve_R_el.Zero(); globals.rve_K_el.Zero(); - if (elastic_correction) { + if (elastic_correction && params.auto_regularization) { if (rve_process_element< 3, EType_Top>(elastic_correction, e3, sv, params, do_implex, time_factor) != 0) return -1; if (rve_process_element< 1, EType_Mid>(elastic_correction, e2, sv, params, do_implex, time_factor) != 0) return -1; if (rve_process_element< 3, EType_Bot>(elastic_correction, e1, sv, params, do_implex, time_factor) != 0) return -1; @@ -1422,7 +1422,13 @@ namespace { double EI = params.E * I; double fact = 0.04 * params.length / (params.radius * 5.0); double penalty = 12.0 * EI * fact / std::pow(2.0*params.length, 3.0); - double KReg = std::max(0.0, (params.length / params.lch_element - 1)) * penalty; + double KReg; + if (!params.auto_regularization) { + KReg = 0.0; + } + else { + KReg = std::max(0.0, (params.length / params.lch_element - 1)) * penalty; + } globals.rve_K(6, 6) = globals.rve_K(6, 6) + KReg; globals.rve_R(6) = globals.rve_R(6) + KReg * sv.UG(6); } @@ -1430,7 +1436,7 @@ namespace { }; // impose BC - if (elastic_correction) { + if (elastic_correction && params.auto_regularization) { sv.UG_el(10) = U; } else { @@ -1455,7 +1461,7 @@ namespace { for (int iter = 0; iter < params.max_iter; ++iter) { // solve - if (elastic_correction) { + if (elastic_correction && params.auto_regularization) { if (globals.rve_K_el.Solve(globals.rve_R_el, globals.rve_dU_el) != 0) { asd_print_full("Solve failed"); break; @@ -1560,14 +1566,14 @@ namespace { } double Krc_dot_Kinv_Kcr = 0.0; // do it outside, element Bottom is the last one - if (elastic_correction) { - getRetainedComponents(elastic_correction, globals.element_LHS, globals.rve_Krr, globals.rve_Kcr_el, globals.rve_Krc_el); + if (elastic_correction && params.auto_regularization) { + getRetainedComponents(params, elastic_correction, globals.element_LHS, globals.rve_Krr, globals.rve_Kcr_el, globals.rve_Krc_el); globals.rve_K_el.Solve(globals.rve_Kcr_el, globals.rve_Kinv_Kcr_el); Krc_dot_Kinv_Kcr = globals.rve_Krc_el ^ globals.rve_Kinv_Kcr_el; } else { - getRetainedComponents(elastic_correction, globals.element_LHS, globals.rve_Krr, globals.rve_Kcr, globals.rve_Krc); + getRetainedComponents(params, elastic_correction, globals.element_LHS, globals.rve_Krr, globals.rve_Kcr, globals.rve_Krc); globals.rve_K.Solve(globals.rve_Kcr, globals.rve_Kinv_Kcr); Krc_dot_Kinv_Kcr = globals.rve_Krc ^ globals.rve_Kinv_Kcr; } @@ -1661,14 +1667,13 @@ class ASDSteel1DMaterialPIMPL void* OPS_ASDSteel1DMaterial() { - // some kudos static bool first_done = false; if (!first_done) { opserr << "Using ASDSteel1D - Developed by: Alessia Casalucci, Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; first_done = true; } - static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu <-implex> <-buckling $lch < $r>> <-fracture> <-slip $matTag $lch_anc <$r>> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; + static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu <-implex> <-auto_regularization> <-buckling $lch < $r>> <-fracture $r_frac> <-slip $matTag $lch_anc <$r>> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; // check arguments int numArgs = OPS_GetNumRemainingInputArgs(); @@ -1689,7 +1694,9 @@ void* OPS_ASDSteel1DMaterial() double eu = 0.0; double lch = 0.0; double r = 0.0; // default to 0.0, means not provided + double r_frac = 0.0; bool implex = false; + bool auto_regularization = false; bool buckling = false; bool fracture = false; bool slip = false; @@ -1742,11 +1749,15 @@ void* OPS_ASDSteel1DMaterial() }; // parse optional arguments + int trials = 0; while (OPS_GetNumRemainingInputArgs() > 0) { const char* value = OPS_GetString(); if (strcmp(value, "-implex") == 0) { implex = true; } + if (strcmp(value, "-auto_regularization") == 0) { + auto_regularization = true; + } if (strcmp(value, "-buckling") == 0) { buckling = true; // lch is mandatory @@ -1758,14 +1769,17 @@ void* OPS_ASDSteel1DMaterial() // radius is optional (can be defined either here or in -slip) if (OPS_GetNumRemainingInputArgs() > 0) { double trial_radius; + auto old_num_rem = OPS_GetNumRemainingInputArgs(); if (OPS_GetDouble(&numData, &trial_radius) < 0) { // radius not provided, go back - OPS_ResetCurrentInputArg(-1); + auto new_num_rem = OPS_GetNumRemainingInputArgs(); + if (new_num_rem < old_num_rem) + OPS_ResetCurrentInputArg(-1); } else { // radius give, do cheks if (trial_radius != r && r != 0.0) { - opserr << "UniaxialMaterial ASDSteel1D: radius provied in -buckling (" << trial_radius << ") does not match the one provided in -slip (" << r << "). Please use it only once.\n"; + opserr << "UniaxialMaterial ASDSteel1D: radius provied in -buckling (" << trial_radius << ") does not match the one provided in -slip or -fracture (" << r << "). Please use it only once.\n"; return nullptr; } if (trial_radius <= 0.0) { @@ -1778,6 +1792,33 @@ void* OPS_ASDSteel1DMaterial() } if (strcmp(value, "-fracture") == 0) { fracture = true; + //if (OPS_GetNumRemainingInputArgs() < 1) { + // opserr << "UniaxialMaterial ASDSteel1D: '-fracture' requires at least '$r'\n"; + // return nullptr; + //} + //if (!lam_optional_double("r_frac", r_frac)) return nullptr; + if (OPS_GetNumRemainingInputArgs() > 0) { + double trial_radius; + auto old_num_rem = OPS_GetNumRemainingInputArgs(); + if (OPS_GetDouble(&numData, &trial_radius) < 0) { + // radius not provided, go back + auto new_num_rem = OPS_GetNumRemainingInputArgs(); + if (new_num_rem < old_num_rem) + OPS_ResetCurrentInputArg(-1); + } + else { + // radius give, do cheks + if (trial_radius != r && r != 0.0) { + opserr << "UniaxialMaterial ASDSteel1D: radius provied in -fracture (" << trial_radius << ") does not match the one provided in -slip or -buckling (" << r << "). Please use it only once.\n"; + return nullptr; + } + if (trial_radius <= 0.0) { + opserr << "UniaxialMaterial ASDSteel1D: radius provied in -fracture should be strictly positive.\n"; + return nullptr; + } + r = trial_radius; + } + } } if (strcmp(value, "-slip") == 0) { slip = true; @@ -1801,14 +1842,17 @@ void* OPS_ASDSteel1DMaterial() // radius is optional (can be defined either here or in -buckling) if (OPS_GetNumRemainingInputArgs() > 0) { double trial_radius; + auto old_num_rem = OPS_GetNumRemainingInputArgs(); if (OPS_GetDouble(&numData, &trial_radius) < 0) { // radius not provided, go back - OPS_ResetCurrentInputArg(-1); + auto new_num_rem = OPS_GetNumRemainingInputArgs(); + if (new_num_rem < old_num_rem) + OPS_ResetCurrentInputArg(-1); } else { // radius give, do cheks if (trial_radius != r && r != 0.0) { - opserr << "UniaxialMaterial ASDSteel1D: radius provied in -slip (" << trial_radius << ") does not match the one provided in -buckling (" << r << "). Please use it only once.\n"; + opserr << "UniaxialMaterial ASDSteel1D: radius provied in -slip (" << trial_radius << ") does not match the one provided in -buckling or -fracture (" << r << "). Please use it only once.\n"; return nullptr; } if (trial_radius <= 0.0) { @@ -1854,11 +1898,26 @@ void* OPS_ASDSteel1DMaterial() // obtain chaboche params from E, sy, su, eu // we want to use 2 hardening functions as per chaboche model. // so that the initial slope is close to E and the the stress apporaches su at eu - double dy = su - sy; - double H1 = E / 1000.0 / eu * dy / 40.0; - double gamma1 = H1 / dy; - double H2 = H1 * 50; - double gamma2 = gamma1 * 50; + //double dy = su - sy; + //double H1 = E / 1000.0 / eu * dy / 40.0/1000.0; + //double gamma1 = H1 / dy; + //double H2 = H1 * 50; + //double gamma2 = gamma1 * 50; + //double alpha = 0.9; + double sy_norm = sy / E; + double su_norm = su / E; + double dy_norm = su_norm - sy_norm; + + double n = 400.0; + double m = 50.0; + + double H1_norm = (1.0 / n) / eu; + double gamma1_norm = H1_norm / dy_norm; + double H1 = H1_norm * E; + double gamma1 = gamma1_norm ; + + double H2 = H1 * m; + double gamma2 = gamma1 * m; double alpha = 0.9; ASDSteel1DMaterial::InputParameters params; params.E = E; @@ -1869,12 +1928,14 @@ void* OPS_ASDSteel1DMaterial() params.H2 = H2 * (1.0 - alpha); params.gamma2 = gamma2; params.implex = implex; + params.auto_regularization = auto_regularization; params.buckling = buckling; params.fracture = fracture; params.slip = slip; params.lch_anchor = lch_anc; params.length = buckling ? lch / 2.0 : 1.0; // consider half distance, the RVE uses symmetry params.radius = r; + //params.radius_frac = r_frac; params.K_alpha = K_alpha; params.max_iter = max_iter; params.tolU = tolU; @@ -1981,8 +2042,14 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) double d = 0.0; double eupl = params.eu - params.sy / params.E; if (epl > eupl) { - double epl_max = eupl + eupl * 1.0 / params.lch_element; - double G = (epl_max-eupl) * params.sy / 2.0; + double epl_max; + if (!params.auto_regularization) { + epl_max = eupl + eupl; + } + else { + epl_max = eupl + eupl * (16.0 * params.radius) / (2.0 * params.lch_element); + } + double G = (epl_max-eupl) * params.sy/4.0; double sigma_damaged = std::max(1.0e-4 * params.sy, params.sy * exp(-params.sy * (epl-eupl) / G)); d = 1.0 - sigma_damaged / params.sy; } @@ -2152,6 +2219,7 @@ int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) ddata(counter++) = params.gamma1; ddata(counter++) = params.gamma2; ddata(counter++) = static_cast(params.implex); + ddata(counter++) = static_cast(params.auto_regularization); ddata(counter++) = static_cast(params.buckling); ddata(counter++) = static_cast(params.fracture); ddata(counter++) = static_cast(params.slip); @@ -2232,6 +2300,7 @@ int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectB params.gamma1 = ddata(counter++); params.gamma2 = ddata(counter++); params.implex = static_cast(ddata(counter++)); + params.auto_regularization = static_cast(ddata(counter++)); params.buckling = static_cast(ddata(counter++)); params.fracture = static_cast(ddata(counter++)); params.slip = static_cast(ddata(counter++)); @@ -2364,8 +2433,14 @@ const Vector& ASDSteel1DMaterial::getDamage() const double eupl = params.eu - params.sy / params.E; double epl = params.buckling ? pdata->rve_m.e2.section.series.steel_material.epl : pdata->steel_comp.steel_material.epl; if (epl > eupl) { - double epl_max = eupl + eupl * 1.0 / params.lch_element; - double G = (epl_max - eupl) * params.sy / 2.0; + double epl_max; + if (!params.auto_regularization) { + epl_max = eupl + eupl; + } + else { + epl_max = eupl + eupl * (16.0 * params.radius) / (2.0 * params.lch_element); + } + double G = (epl_max - eupl) * params.sy / 4.0; double sigma_damaged = std::max(1.0e-4 * params.sy, params.sy * exp(-params.sy * (epl - eupl) / G)); d(0) = 1.0 - sigma_damaged / params.sy; } @@ -2417,7 +2492,7 @@ int ASDSteel1DMaterial::homogenize(bool do_implex) bool elastic_correction = params.lch_element > params.length; auto& globals = Globals::instance(); - if (elastic_correction) { + if (elastic_correction && params.auto_regularization) { globals.setRVENodes_el(params.length,params.lch_element); } else { @@ -2432,7 +2507,7 @@ int ASDSteel1DMaterial::homogenize(bool do_implex) // from macro strain to micro strain double macro_strain = strain; double Uy; - if (elastic_correction) { + if (elastic_correction && params.auto_regularization) { Uy = -macro_strain * params.lch_element; } else { @@ -2451,7 +2526,7 @@ int ASDSteel1DMaterial::homogenize(bool do_implex) area = M_PI * params.radius * params.radius; stress_rve = -N/area; - if (elastic_correction) { + if (elastic_correction && params.auto_regularization) { C_rve = T * params.lch_element / area; } else { diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index 3c26e8e3dc..d27db83814 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -65,12 +65,14 @@ class ASDSteel1DMaterial : public UniaxialMaterial double gamma2 = 0.0; // misc bool implex = false; + bool auto_regularization = true; bool buckling = false; bool fracture = false; bool slip = false; double lch_anchor = 0.0; // buckling double radius = 0.0; + double radius_frac = 0.0; double length = 0.0; double lch_element = 0.0; @@ -80,7 +82,7 @@ class ASDSteel1DMaterial : public UniaxialMaterial double tolU = 0.0; double tolR = 0.0; // counter - static constexpr int NDATA = 19; + static constexpr int NDATA = 20; }; public: From 679b84bc6b932889504569d4640b7f47d9098888 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Fri, 20 Jun 2025 19:03:39 +0200 Subject: [PATCH 066/261] fixes in bond_slip regularization --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 37 +++++--------------- SRC/material/uniaxial/ASDSteel1DMaterial.h | 1 - 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index 269a5135cb..1b816343bd 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -571,7 +571,8 @@ namespace { _strain *= scale_factor; // initial guess for the slip strain - double strain_slip = slip_material->getStrain() / params.lch_anchor; + double lch_ele = 2.0 * params.lch_element; // it was divided in constructor for RVE symmetry + double strain_slip = slip_material->getStrain() / lch_ele; double strain_steel = _strain - strain_slip; // iterative procedure to impose the iso-stress condition @@ -582,13 +583,13 @@ namespace { double Stol = TOL; for (int iter = 0; iter < MAX_ITER; ++iter) { int Tsteel = steel_material.compute(params, do_implex, time_factor, strain_steel, sigma_steel, tangent_steel); - int Tslip = slip_material->setTrialStrain(strain_slip * params.lch_anchor); + int Tslip = slip_material->setTrialStrain(strain_slip * lch_ele); double sigma_slip = slip_material->getStress() * 2.0 * params.lch_anchor/ params.radius; - double tangent_slip = slip_material->getTangent() * 2.0 * params.lch_anchor * params.lch_anchor / params.radius; + double tangent_slip = slip_material->getTangent() * 2.0 * lch_ele * params.lch_anchor / params.radius; double residual = sigma_slip - sigma_steel; double residual_derivative = tangent_steel + tangent_slip; if (std::abs(residual_derivative) < Ktol) { - residual_derivative = params.E + slip_material->getInitialTangent() * 2.0 * params.lch_anchor * params.lch_anchor / params.radius; + residual_derivative = params.E + slip_material->getInitialTangent() * 2.0 * lch_ele * params.lch_anchor / params.radius; } double strain_increment = - residual / residual_derivative; strain_slip += strain_increment; @@ -1673,7 +1674,7 @@ void* OPS_ASDSteel1DMaterial() opserr << "Using ASDSteel1D - Developed by: Alessia Casalucci, Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; first_done = true; } - static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu <-implex> <-auto_regularization> <-buckling $lch < $r>> <-fracture $r_frac> <-slip $matTag $lch_anc <$r>> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; + static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu <-implex> <-auto_regularization> <-buckling $lch < $r>> <-fracture <$r>> <-slip $matTag $lch_anc <$r>> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; // check arguments int numArgs = OPS_GetNumRemainingInputArgs(); @@ -1694,7 +1695,6 @@ void* OPS_ASDSteel1DMaterial() double eu = 0.0; double lch = 0.0; double r = 0.0; // default to 0.0, means not provided - double r_frac = 0.0; bool implex = false; bool auto_regularization = false; bool buckling = false; @@ -1792,11 +1792,6 @@ void* OPS_ASDSteel1DMaterial() } if (strcmp(value, "-fracture") == 0) { fracture = true; - //if (OPS_GetNumRemainingInputArgs() < 1) { - // opserr << "UniaxialMaterial ASDSteel1D: '-fracture' requires at least '$r'\n"; - // return nullptr; - //} - //if (!lam_optional_double("r_frac", r_frac)) return nullptr; if (OPS_GetNumRemainingInputArgs() > 0) { double trial_radius; auto old_num_rem = OPS_GetNumRemainingInputArgs(); @@ -2362,7 +2357,6 @@ Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Strea static std::vector lb_eqpl_strain = { "PLE" }; static std::vector lb_slip_resp = { "Slip", "Tau" }; - static std::vector lb_steel_resp = { "strain_steel", "stress_steel" }; @@ -2380,9 +2374,6 @@ Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Strea if (strcmp(argv[0], "SlipResponse") == 0){ return make_resp(1004, getSlipResponse(), &lb_slip_resp); } - if (strcmp(argv[0], "SteelResponse") == 0) { - return make_resp(1005, getSteelResponse(), &lb_steel_resp); - } } // otherwise return base-class response @@ -2404,8 +2395,6 @@ int ASDSteel1DMaterial::getResponse(int responseID, Information& matInformation) return matInformation.setVector(getEqPlStrain()); case 1004: return matInformation.setVector(getSlipResponse()); - case 1005: - return matInformation.setVector(getSteelResponse()); default: break; } @@ -2452,9 +2441,10 @@ const Vector& ASDSteel1DMaterial::getEqPlStrain() const { static Vector d(1); d.Zero(); - d(0) = pdata->rve_m.e2.section.series.steel_material.epl; + d(0) = params.buckling ? pdata->rve_m.e2.section.series.steel_material.epl : pdata->steel_comp.steel_material.epl; return d; } + const Vector& ASDSteel1DMaterial::getSlipResponse() const { static Vector d(2); @@ -2472,17 +2462,6 @@ const Vector& ASDSteel1DMaterial::getSlipResponse() const return d; } -const Vector& ASDSteel1DMaterial::getSteelResponse() const -{ - static Vector d(2); - d.Zero(); - if (params.slip) { - d(0) = pdata->rve_m.e2.section.series.steel_material.strain; - d(1) = pdata->rve_m.e2.section.series.steel_material.stress; - } - return d; -} - int ASDSteel1DMaterial::homogenize(bool do_implex) { // return value diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index d27db83814..e6204fb3e4 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -72,7 +72,6 @@ class ASDSteel1DMaterial : public UniaxialMaterial double lch_anchor = 0.0; // buckling double radius = 0.0; - double radius_frac = 0.0; double length = 0.0; double lch_element = 0.0; From acd8cbb226d9f910c603b19f5602fe0c24fef3a1 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 067/261] add BasicFrameTransf.h --- .../Frame/BasicFrameTransf.h | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 SRC/coordTransformation/Frame/BasicFrameTransf.h diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.h b/SRC/coordTransformation/Frame/BasicFrameTransf.h new file mode 100644 index 0000000000..5fa241eb08 --- /dev/null +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.h @@ -0,0 +1,114 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// The purpose of this class is to wrap the more general FrameTransform<> +// templates to reproduce the legacy CrdTransf classes that were derived +// for elements in a "basic" coordinate system. +// +// cmp +// +#ifndef BasicFrameTransf3d_h +#define BasicFrameTransf3d_h + +#include +#include +#include +#include + +namespace OpenSees { + +template +class BasicFrameTransf3d: public CrdTransf +{ +public: + BasicFrameTransf3d(FrameTransform<2,ndf> *t); + + ~BasicFrameTransf3d(); + + virtual int getLocalAxes(Vector &x, Vector &y, Vector &z); + + virtual CrdTransf *getCopy3d() final; + + virtual double getInitialLength(); + virtual double getDeformedLength(); + + virtual int initialize(Node *ni, Node *nj) final; + virtual int update() final; + virtual int commitState() final; + virtual int revertToLastCommit() final; + virtual int revertToStart() final; + + virtual const Vector &getBasicTrialDisp() final; + virtual const Vector &getBasicIncrDisp() final; + virtual const Vector &getBasicIncrDeltaDisp() final; + virtual const Vector &getBasicTrialVel() final; + + virtual const Vector &getGlobalResistingForce(const Vector &basicForce, const Vector &p0) final; + virtual const Matrix &getGlobalStiffMatrix(const Matrix &basicStiff, const Vector &basicForce) final; + virtual const Matrix &getInitialGlobalStiffMatrix(const Matrix &basicStiff) final; + + // rotate consistent mass matrix + const Matrix &getGlobalMatrixFromLocal(const Matrix &local); + + // methods used in post-processing only + const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); + const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps); + const Vector &getPointLocalDisplFromBasic( double xi, const Vector &basicDisps); + + // + // Sensitivity + // + const Vector & getBasicDisplFixedGrad(); + const Vector & getBasicDisplTotalGrad(int grad); + const Vector &getGlobalResistingForceShapeSensitivity (const Vector &basicForce, const Vector &p0, int grad); + bool isShapeSensitivity(); + double getLengthGrad(); + double getd1overLdh(); + + + // MovableObject + virtual int sendSelf(int tag, Channel &); + virtual int recvSelf(int tag, Channel &, FEM_ObjectBroker &); + const char *getClassType() const {return "BasicFrameTransf3d";} + + // TaggedObject + void Print(OPS_Stream &s, int flag = 0); + + + FrameTransform<2,ndf> &t; +protected: +private: + + constexpr static int NBV = 6; + constexpr static int NDF = ndf; + enum : int { + inx = -12, // 0 + iny = -12, // 1 + inz = -12, // 2 + imx = -12, // 3 + imy = 3, // 4 + imz = 1, // 5 + jnx = 0, // 6 + jny = -12, // 7 + jnz = -12, // 8 + jmx = 5, // 9 + jmy = 4, // 10 + jmz = 2, // 11 + }; + + constexpr static int iq[] = { + // jnx, imz, jmz, imy, jmy, imx + inx, iny, inz, imx, imy, imz, + jnx, jny, jnz, jmx, jmy, jmz + }; + +}; +} // namespace OpenSees +#include "BasicFrameTransf.tpp" +#endif + From 21b0d0186cbb569d09006db0f9631d45ebbdc134 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 068/261] add BasicFrameTransf.tpp --- .../Frame/BasicFrameTransf.tpp | 415 ++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100644 SRC/coordTransformation/Frame/BasicFrameTransf.tpp diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp new file mode 100644 index 0000000000..5dd44da0bf --- /dev/null +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -0,0 +1,415 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// +#include +#include +#include +#include +#include +#include +#include + +using namespace OpenSees; + +template +BasicFrameTransf3d::BasicFrameTransf3d(FrameTransform<2,ndf> *t) +: CrdTransf(t->getTag(), 0), + t(*t) +{ + +} + +template +BasicFrameTransf3d::~BasicFrameTransf3d() +{ + delete &t; +} + +template +int +BasicFrameTransf3d::commitState() +{ + return t.commit(); +} + +template +int +BasicFrameTransf3d::revertToLastCommit() +{ + return t.revertToLastCommit(); +} + +template +int +BasicFrameTransf3d::revertToStart() +{ + return t.revertToStart(); +} + +template +int +BasicFrameTransf3d::update() +{ + return t.update(); +} + + +template +int +BasicFrameTransf3d::initialize(Node *i, Node *j) +{ + std::array nodes = {i, j}; + return t.initialize(nodes); +} + +template +int +BasicFrameTransf3d::getLocalAxes(Vector &XAxis, Vector &YAxis, Vector &ZAxis) +{ + Vector3D x, y, z; + int s = t.getLocalAxes(x, y, z); + for (int i=0; i<3; i++) { + XAxis(i) = x[i]; + YAxis(i) = y[i]; + ZAxis(i) = z[i]; + } + return s; +} + +template +double +BasicFrameTransf3d::getInitialLength() +{ + return t.getInitialLength(); +} + +template +double +BasicFrameTransf3d::getDeformedLength() +{ + return t.getDeformedLength(); +} + + +template +const Vector & +BasicFrameTransf3d::getBasicTrialDisp() +{ + static VectorND<6> ub; + static Vector wrapper(ub); + Vector3D wi = t.getNodeRotationLogarithm(0), + wj = t.getNodeRotationLogarithm(1); + ub[0] = t.getNodePosition(1)[0]; + ub[1] = wi[2]; + ub[2] = wj[2]; + ub[3] = wi[1]; + ub[4] = wj[1]; + ub[5] = wj[0] - wi[0]; + return wrapper; +} + +template +const Vector & +BasicFrameTransf3d::getBasicIncrDeltaDisp() +{ + static VectorND<6> ub; + static Vector wrapper(ub); + VectorND ul = t.getStateVariation(); + ub[0] = ul[1*ndf+0]; // Nj + ub[1] = ul[0*ndf+5]; + ub[2] = ul[1*ndf+5]; + ub[3] = ul[0*ndf+4]; + ub[4] = ul[1*ndf+4]; + ub[5] = ul[1*ndf+3] - ul[0*ndf+3]; + return wrapper; +} + +template +const Vector & +BasicFrameTransf3d::getBasicIncrDisp() +{ + static VectorND<6> ub; + static Vector wrapper(ub); + opserr << "Unimplemented method\n"; + return wrapper; +} + +template +const Vector & +BasicFrameTransf3d::getBasicTrialVel() +{ + static VectorND<6> ub; + static Vector wrapper(ub); + opserr << "Unimplemented method\n"; + return wrapper; +} + + +template +const Vector & +BasicFrameTransf3d::getGlobalResistingForce(const Vector &q_pres, const Vector &p0) +{ + // transform resisting forces from the basic system to local coordinates + + VectorND pl{}; + pl[0*NDF+0] = -q_pres[jnx]; // Ni + pl[0*NDF+3] = -q_pres[jmx]; // Ti + pl[0*NDF+4] = q_pres[imy]; + pl[0*NDF+5] = q_pres[imz]; + pl[1*NDF+0] = q_pres[jnx]; // Nj + pl[1*NDF+3] = q_pres[jmx]; // Tj + pl[1*NDF+4] = q_pres[jmy]; + pl[1*NDF+5] = q_pres[jmz]; + + VectorND pf; + pf.zero(); + pf[0*NDF + 0] = p0[0]; + pf[0*NDF + 1] = p0[1]; + pf[0*NDF + 2] = p0[3]; + pf[1*NDF + 1] = p0[2]; + pf[1*NDF + 2] = p0[4]; + + static VectorND pg; + static Vector wrapper(pg); + + pg = t.pushResponse(pl); + pg += t.pushConstant(pf); + return wrapper; +} + + +template +const Matrix & +BasicFrameTransf3d::getGlobalStiffMatrix(const Matrix &kb, const Vector &q_pres) +{ + + VectorND pl{}; + pl[0*NDF+0] = -q_pres[jnx]; // Ni + pl[0*NDF+3] = -q_pres[jmx]; // Ti + pl[0*NDF+4] = q_pres[imy]; + pl[0*NDF+5] = q_pres[imz]; + pl[1*NDF+0] = q_pres[jnx]; // Nj + pl[1*NDF+3] = q_pres[jmx]; // Tj + pl[1*NDF+4] = q_pres[jmy]; + pl[1*NDF+5] = q_pres[jmz]; + + + MatrixND<2*NDF,2*NDF> kl; + kl.zero(); +#ifndef DO_BASIC + for (int i=0; i= NBV) + continue; + + for (int j=0; j= NBV) + continue; + + kl(i,j) = kb(ii, jj)*c; + } + } + + for (int i = 0; i < 2*NDF; i++) { + kl(0*NDF+0, i) = kl(i, 0*NDF+0) = i==0? kl(NDF+0, NDF+0): (i==3? kl(NDF+0, NDF+3) : -kl( NDF+0, i)); + kl(0*NDF+3, i) = kl(i, 0*NDF+3) = i==0? kl(NDF+3, NDF+0): (i==3? kl(NDF+3, NDF+3) : -kl( NDF+3, i)); + } +#endif + + static MatrixND<2*NDF,2*NDF> Kg; + static Matrix Wrapper(Kg); + + Kg = t.pushResponse(kl, pl); + + return Wrapper; +} + + +template +const Matrix & +BasicFrameTransf3d::getInitialGlobalStiffMatrix(const Matrix &KB) +{ + static double kb[6][6]; // Basic stiffness + static MatrixND<2*ndf,2*ndf> kl; // Local stiffness + double tmp[6][12]{}; // Temporary storage + + for (int i = 0; i < 6; i++) + for (int j = 0; j < 6; j++) + kb[i][j] = KB(i, j); + + // Transform basic stiffness to local system + // First compute kb*T_{bl} + for (int i = 0; i < 6; i++) { + tmp[i][0] = -kb[i][0]; + tmp[i][3] = -kb[i][5]; + tmp[i][4] = kb[i][3]; + tmp[i][5] = kb[i][1]; + tmp[i][6] = kb[i][0]; + tmp[i][9] = kb[i][5]; + tmp[i][10] = kb[i][4]; + tmp[i][11] = kb[i][2]; + } + // TODO: + // Now compute T'_{bl}*(kb*T_{bl}) + for (int i = 0; i < 12; i++) { + kl( 0, i) = -tmp[0][i]; + kl( 3, i) = -tmp[5][i]; + kl( 4, i) = tmp[3][i]; + kl( 5, i) = tmp[1][i]; + + kl( 6, i) = tmp[0][i]; + kl( 9, i) = tmp[5][i]; + kl(10, i) = tmp[4][i]; + kl(11, i) = tmp[2][i]; + } + + static MatrixND kg; + static Matrix M(kg); + + kg = t.pushConstant(kl); + + return M; +} + + +template +CrdTransf * +BasicFrameTransf3d::getCopy3d() +{ + BasicFrameTransf3d *theCopy = new BasicFrameTransf3d(t.getCopy()); + return theCopy; +} + + +template +const Matrix & +BasicFrameTransf3d::getGlobalMatrixFromLocal(const Matrix &M) +{ + // + // Do diag(R)*M*diag(R)' + // + static MatrixND Kout; + static Matrix wrapper(Kout); + wrapper = M; + MatrixND Kg = t.pushConstant(Kout); + Kout = Kg; + return wrapper; +} + +template +const Vector & +BasicFrameTransf3d::getPointGlobalCoordFromLocal(const Vector &xl) +{ + static Vector xg(3); + return xg; +} + +template +const Vector & +BasicFrameTransf3d::getPointGlobalDisplFromBasic(double xi, const Vector &uxb) +{ + static Vector uxg(3); + return uxg; +} + +template +const Vector & +BasicFrameTransf3d::getPointLocalDisplFromBasic(double xi, const Vector &uxb) +{ + static Vector uxl(3); + return uxl; +} + +// +// Sensitivity +// +template +bool +BasicFrameTransf3d::isShapeSensitivity() +{ + return t.isShapeSensitivity(); +} + + +template +double +BasicFrameTransf3d::getLengthGrad() +{ + return t.getLengthGrad(); +} + +template +double +BasicFrameTransf3d::getd1overLdh() +{ + double L = t.getInitialLength(); + return -getLengthGrad()/(L*L); +} + +template +const Vector & +BasicFrameTransf3d::getGlobalResistingForceShapeSensitivity(const Vector &pb, + const Vector &p0, + int gradNumber) +{ + // return t.getGlobalResistingForceShapeSensitivity(pb, p0, gradNumber); + + static VectorND<6> dub; + static Vector wrapper(dub); + opserr << "WARNING unimplemented method\n"; + return wrapper; +} + + +template +const Vector & +BasicFrameTransf3d::getBasicDisplFixedGrad() +{ + static VectorND<6> dub; + static Vector wrapper(dub); + opserr << "WARNING unimplemented method\n"; + return wrapper; +} + +template +const Vector & +BasicFrameTransf3d::getBasicDisplTotalGrad(int gradNumber) +{ + static VectorND<6> dub; + static Vector wrapper(dub); + opserr << "WARNING unimplemented method\n"; + return wrapper; +} + + +template +void +BasicFrameTransf3d::Print(OPS_Stream &s, int flag) +{ + t.Print(s, flag); +} + + +template +int +BasicFrameTransf3d::sendSelf(int cTag, Channel &theChannel) +{ + return -1; +} + + +template +int +BasicFrameTransf3d::recvSelf(int cTag, Channel &, + FEM_ObjectBroker &theBroker) +{ + return -1; +} From 78fcbc49d6ad1baac49ffdbe403da27401f6a83d Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 069/261] add CMakeLists.txt --- SRC/coordTransformation/Frame/CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 SRC/coordTransformation/Frame/CMakeLists.txt diff --git a/SRC/coordTransformation/Frame/CMakeLists.txt b/SRC/coordTransformation/Frame/CMakeLists.txt new file mode 100644 index 0000000000..e90629c8b8 --- /dev/null +++ b/SRC/coordTransformation/Frame/CMakeLists.txt @@ -0,0 +1,10 @@ +#============================================================================== +# +# OpenSees -- Open System For Earthquake Engineering Simulation +# Pacific Earthquake Engineering Research Center +# +#============================================================================== + +# target_sources(OPS_Transform PRIVATE BasicFrameTransf.cpp) +target_include_directories(OPS_Transform PUBLIC ${CMAKE_CURRENT_LIST_DIR}) + From af1ef6837cf04f13e7ccf238d8006a437d5b140c Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 070/261] add LinearFrameTransf.hpp --- .../Frame/LinearFrameTransf.hpp | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 SRC/coordTransformation/Frame/LinearFrameTransf.hpp diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.hpp b/SRC/coordTransformation/Frame/LinearFrameTransf.hpp new file mode 100644 index 0000000000..7a2f3513fd --- /dev/null +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.hpp @@ -0,0 +1,126 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// Description: This file contains the class definition for +// LinearFrameTransf.h. LinearFrameTransf provides the +// abstraction of a linear transformation for a spatial frame +// between the global and basic coordinate systems +// +// Written: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) +// Created: 04/2000 +// +#ifndef LinearFrameTransf_hpp +#define LinearFrameTransf_hpp + +#include +#include +#include +#include + +template +class LinearFrameTransf: public FrameTransform +{ +public: + constexpr static int n = nn*ndf; + + LinearFrameTransf(int tag, + const Vector3D &vecxz, + const std::array *offset=nullptr, + int offset_flags = 0); + + ~LinearFrameTransf(); + + const char *getClassType() const {return "LinearFrameTransf";} + + virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; + + virtual FrameTransform *getCopy() const; + + virtual double getInitialLength(); + virtual double getDeformedLength(); + virtual const std::array *getRigidOffsets() const {return offsets;} + + virtual int initialize(std::array& new_nodes) final; + virtual int update() final; + virtual int commit() final; + virtual int revertToLastCommit() final; + virtual int revertToStart() final; + + virtual VectorND getStateVariation() final; + virtual Vector3D getNodePosition(int tag) final; + virtual Vector3D getNodeRotationLogarithm(int tag) final; + + virtual VectorND pushResponse(VectorND&pl) final; + virtual MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + + // // method used to rotate consistent mass matrix + // const Matrix &getGlobalMatrixFromLocal(const Matrix &local); + + + // Sensitivity + // + const Vector & getBasicDisplFixedGrad(); + const Vector & getBasicDisplTotalGrad(int gradNumber); + const Vector &getGlobalResistingForceShapeSensitivity (const Vector &basicForce, const Vector &p0, int grad); + bool isShapeSensitivity(); + double getLengthGrad(); + double getd1overLdh(); + + // TaggedObject + void Print(OPS_Stream &s, int flag = 0); + + // Personal + Vector3D getDelta() {return Du;} + +private: + + int computeElemtLengthAndOrient(); + + inline VectorND + pullConstant(const VectorND& ug, + const Matrix3D& R, + const std::array *offset = nullptr, + int offset_flags = 0); + + template + const Vector3D + pullPosition(int node) + { + const Vector &u = (nodes[node]->*Getter)(); + + Vector3D v; + for (int i=0; i<3; i++) + v[i] = u[i]; + + // 1) Offsets + if (offsets) { + if (!(offset_flags&OffsetLocal)) { + Vector3D w {u[3], u[4], u[5]}; + v -= offsets->at(node).cross(w); + } + } + + // 2) Constant Rotation + return R^v; + } + + std::array nodes; + Vector3D Du; + + std::array *offsets; + int offset_flags; + + Vector3D xi, xj, vz; + Matrix3D R; // rotation matrix + double L; // undeformed element length + + std::array*, nn> u_init; + bool initialDispChecked; +}; + +#include "LinearFrameTransf.tpp" +#endif + From 327d95d4093e76eb6bbd35be3facf6335162a91b Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 071/261] add LinearFrameTransf.tpp --- .../Frame/LinearFrameTransf.tpp | 680 ++++++++++++++++++ 1 file changed, 680 insertions(+) create mode 100644 SRC/coordTransformation/Frame/LinearFrameTransf.tpp diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp new file mode 100644 index 0000000000..74c41a059b --- /dev/null +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -0,0 +1,680 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Description: This file contains the implementation for the +// LinearFrameTransf class. LinearFrameTransf is a linear +// transformation for a space frame between the global +// and basic coordinate systems +// +// Adapted: Remo Magalhaes de Souza +// Created: 04/2000 +// +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace OpenSees; + +static inline MatrixND<3,3> +FrameOrientationGradient(const Vector3D& xi, const Vector3D& xj, + const Vector3D& vz, int di, int dj, int dv) +{ + Vector3D v1 = xj - xi; + double L = v1.norm(); + Vector3D e1 = v1/L; + + Vector3D v2 = vz.cross(e1); + + Vector3D e2 = v2 / v2.norm(); +// Vector3D v3 = e1.cross(e2); +// Vector3D e3 = v3 / v3.norm(); + + // + Vector3D dvz{0.0}; + Vector3D dxi{0.0}; + Vector3D dxj{0.0}; + + if (di != 0) + dxi(di-1) = 1.0; + if (dj != 0) + dxj(dj-1) = 1.0; + if (dv != 0) + dvz(dv-1) = 1.0; + + double dL = 1/L*(xj - xi).dot(dxj - dxi); + Vector3D dv1 = dxj - dxi; + Vector3D de1 = 1/(L*L)*(dv1*L - v1*dL); + + double L2 = v2.norm(); + Vector3D dv2 = dvz.cross(e1) + vz.cross(de1); + double dL2 = 1/L2*v2.dot(dv2); + Vector3D de2 = 1/(L2*L2)*(dv2*L2 - v2*dL2); + + Vector3D de3 = de1.cross(e2) + e1.cross(de2); + + MatrixND<3,3> dR; + dR(0,0) = de1(0); + dR(1,0) = de1(1); + dR(2,0) = de1(2); + + dR(0,1) = de2(0); + dR(1,1) = de2(1); + dR(2,1) = de2(2); + + dR(0,2) = de3(0); + dR(1,2) = de3(1); + dR(2,2) = de3(2); + + return dR; +} + +template +LinearFrameTransf::LinearFrameTransf(int tag, + const Vector3D &vecxz, + const std::array *offset, + int offset_flags) + : FrameTransform(tag), + Du{0}, + L(0), + offsets{nullptr}, + offset_flags(offset_flags), + u_init{nullptr}, initialDispChecked(false) +{ + R.zero(); + + for (int i=0; i<3; i++) + vz[i] = vecxz[i]; + + R(0,2) = vz(0); + R(1,2) = vz(1); + R(2,2) = vz(2); + + // Rigid joint offsets + if (offset != nullptr) { + offsets = new std::array{}; + *offsets = *offset; + } +} + + + +template +LinearFrameTransf::~LinearFrameTransf() +{ + if (offsets != nullptr) + delete offsets; + + for (int i=0; i +int +LinearFrameTransf::commit() +{ + return 0; +} + +template +int +LinearFrameTransf::revertToLastCommit() +{ + return 0; +} + +template +int +LinearFrameTransf::revertToStart() +{ + return 0; +} + + +template +int +LinearFrameTransf::initialize(std::array& new_nodes) +{ + + for (int i=0; igetDisp(); + + for (int j = 0; j < ndf; j++) + if (u(j) != 0.0) { + u_init[i] = new VectorND{}; + for (int l = 0; l < ndf; l++) + (*u_init[i])[l] = u(l); + // break out + j = ndf; + } + } + initialDispChecked = true; + } + + int error; + // get element length and orientation + if ((error = this->computeElemtLengthAndOrient())) + return error; + + return 0; +} + + +template +int +LinearFrameTransf::computeElemtLengthAndOrient() +{ + + const Vector &XI = nodes[ 0]->getCrds(); + const Vector &XJ = nodes[nn-1]->getCrds(); + + for (int i=0; i<3; i++) { + xi[i] = XI[i]; + xj[i] = XJ[i]; + } + + Vector3D dx = xj - xi; + + if (offsets != nullptr) { + for (int i=0; i<3; i++) + dx(i) -= (*offsets)[ 0][i]; + for (int i=0; i<3; i++) + dx(i) += (*offsets)[nn-1][i]; + } + + + if (u_init[0] != 0) { + for (int i=0; i<3; i++) + dx(i) -= (*u_init[0])[i]; + } + + if (u_init[nn-1] != 0) { + for (int i=0; i<3; i++) + dx(i) += (*u_init[nn-1])[i]; + } + + // calculate the element length + L = dx.norm(); + + if (L == 0.0) + return -2; + + return FrameTransform::Orient(dx, vz, R); +} + + +template +int +LinearFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector3D &e3) const +{ + for (int i = 0; i < 3; i++) { + e1[i] = R(i,0); + e2[i] = R(i,1); + e3[i] = R(i,2); + } + return 0; +} + +template +double +LinearFrameTransf::getInitialLength() +{ + return L; +} + +template +double +LinearFrameTransf::getDeformedLength() +{ + return L; +} + + +// +// Pull +// + +template +int +LinearFrameTransf::update() +{ + Du = this->pullPosition<&Node::getTrialDisp>(nn-1) - this->pullPosition<&Node::getTrialDisp>(0); + return 0; +} + +template +VectorND +LinearFrameTransf::pullConstant(const VectorND& ug, + const Matrix3D& R, + const std::array *offset, + int offset_flags) +{ + + constexpr static int N = nn * ndf; + + // Initialize ul = ug + VectorND ul = ug; + + // (1) + // Do ui -= ri x wi + if constexpr (ndf >= 6) + if (offset && !(offset_flags&OffsetLocal)) [[unlikely]] { + const std::array& offsets = *offset; + for (int i=0; i= 6) + if (offset && (offset_flags&OffsetLocal)) [[unlikely]] { + const std::array& offsets = *offset; + for (int i=0; i2) + constexpr static Vector3D iv {1,0,0}; + Vector3D uI = ul.template extract<3>(0); + Vector3D Du = ul.template extract<3>((nn-1)*ndf) - uI; + Vector3D ixDu = iv.cross(Du); + for (int i=0; i +VectorND +LinearFrameTransf::getStateVariation() +{ + + static VectorND ug; + for (int i=0; igetIncrDeltaDisp(); + for (int j = 0; j < ndf; j++) { + ug[i*ndf+j] = ddu(j); + } + } + return LinearFrameTransf::pullConstant(ug, R, offsets, offset_flags); +} + +template +Vector3D +LinearFrameTransf::getNodePosition(int node) +{ + Vector3D v{}; + if (node == 0) { + return v; + } else if (node == nn-1) { + v[0] = Du[0]; + return v; + } + // TODO(nn>2) + return v; +} + +template +Vector3D +LinearFrameTransf::getNodeRotationLogarithm(int node) +{ + constexpr Vector3D iv{1, 0, 0}; + constexpr Matrix3D ix = Hat(iv); + + Vector3D w; + const Vector& u = nodes[node]->getTrialDisp(); + for (int i=0; i<3; i++) { + w[i] = u[3+i]; + } + + w = R^w; + + w.addMatrixVector(1, ix, Du, -1.0/L); + return w; +} + + +// +// Push +// +template +VectorND +LinearFrameTransf::pushResponse(VectorND&p) +{ + VectorND pa = p; + constexpr Vector3D iv{1, 0, 0}; + constexpr Matrix3D ix = Hat(iv); + + // 1.1) Sum of moments: m = sum_i mi + sum_i (xi x ni) + Vector3D m{}; + for (int i=0; iFrameTransform::pushConstant(pa); + return pg; +} + +template +MatrixND +LinearFrameTransf::pushResponse(MatrixND&kb, const VectorND&) +{ + + MatrixND A{}; + A.addDiagonal(1.0); + constexpr Vector3D axis{1, 0, 0}; + constexpr Matrix3D ix = Hat(axis); + constexpr Matrix3D ioi = axis.bun(axis); + + MatrixND<3,ndf> Gb{}; + Gb.template insert<0, 3>(ioi, 0.5); + for (int a = 0; a2): Interpolate coordinate + if (b == 0) + Gb.template insert<0,0>(ix, -1/L); + else if (b == nn-1) + Gb.template insert<0,0>(ix, 1/L); + // TODO(nn>2): Interpolate coordinate + A.assemble(ix*Gb, a*ndf , b*ndf, double(a)/double(nn-1)*L); + A.assemble( Gb, a*ndf+3, b*ndf, -1.0); + } + } + + MatrixND kl; + kl.addMatrixTripleProduct(0, A, kb, 1); + return this->FrameTransform::pushConstant(kl); +} + + +template +FrameTransform * +LinearFrameTransf::getCopy() const +{ + + Vector3D xz; + xz(0) = R(0,2); + xz(1) = R(1,2); + xz(2) = R(2,2); + + + LinearFrameTransf *theCopy = new LinearFrameTransf(this->getTag(), xz, offsets); + + theCopy->nodes = nodes; + theCopy->L = L; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + theCopy->R(j,i) = R(j,i); + + return theCopy; +} + + +// +// Sensitivity +// +template +bool +LinearFrameTransf::isShapeSensitivity() +{ + int nodeParameterI = nodes[ 0]->getCrdsSensitivity(); + int nodeParameterJ = nodes[nn-1]->getCrdsSensitivity(); + // TODO(sensitivity): implement dvz + + return (nodeParameterI != 0 || nodeParameterJ != 0); +} + + +template +double +LinearFrameTransf::getLengthGrad() +{ + const int di = nodes[0]->getCrdsSensitivity(); + const int dj = nodes[1]->getCrdsSensitivity(); + + Vector3D dxi{0.0}; + Vector3D dxj{0.0}; + + if (di != 0) + dxi(di-1) = 1.0; + if (dj != 0) + dxj(dj-1) = 1.0; + + return 1/L*(xj - xi).dot(dxj - dxi); +} + +template +double +LinearFrameTransf::getd1overLdh() +{ + return -getLengthGrad()/(L*L); +} + +template +const Vector & +LinearFrameTransf::getGlobalResistingForceShapeSensitivity(const Vector &pb, + const Vector &p0, + int gradNumber) +{ + + static Vector pg(nn*ndf); + pg.Zero(); + + // + // dp = T_{lg}' pl + // + int dv = 0; // TODO + int di = nodes[0]->getCrdsSensitivity(); + int dj = nodes[1]->getCrdsSensitivity(); + + VectorND pl = pushLocal(pb, L); + + pl[0] += p0[0]; + pl[1] += p0[1]; + pl[7] += p0[2]; + pl[2] += p0[3]; + pl[8] += p0[4]; + + Matrix3D dR = FrameOrientationGradient(xi, xj, vz, di, dj, dv); + for (int i=0; i<4; i++) + for (int j=0; j<3; j++) + pg(i*3+j) = dR(j,0) * pl(3*i) + dR(j,1) * pl(3*i+1) + dR(j,2) * pl(3*i+2); + + + // + // dp += T_{gl} dpl + // + double dL = this->getLengthGrad(); + double doneOverL = -dL/(L*L); + VectorND dpl{0.0}; + dpl[1] = doneOverL * (pb[1] + pb[2]); // Viy + dpl[2] = -doneOverL * (pb[3] + pb[4]); // Viz + dpl[7] = -dpl[1]; // Vjy + dpl[8] = -dpl[2]; // Vjz + + for (int i=0; i<4; i++) + for (int j=0; j<3; j++) + pg(i*3+j) += R(j,0) * dpl(3*i) + R(j,1) * dpl(3*i+1) + R(j,2) * dpl(3*i+2); + + return pg; +} + + +template +const Vector & +LinearFrameTransf::getBasicDisplFixedGrad() +{ + static VectorND<6> dub; + static Vector wrapper(dub); + // + // Form ug + // + // TODO(sensitivity) +#if 0 + VectorND ug; + for (int i = 0; i < nn; i++) { + const Vector& u = nodes[i]->getTrialDisp(); + for (int j = 0; j < ndf; j++) { + ug[i*ndf+j] = u(j); + } + } + + if (u_init[0] != 0) { + for (int j = 0; j < ndf; j++) + ug[j] -= (*u_init[0])[j]; + } + + if (u_init[nn-1] != 0) { + for (int j = 0; j < ndf; j++) + ug[j + 6] -= (*u_init[nn-1])[j]; + } + + // + // dub += (T_{bl}' T_{lg} + T_{bl} T_{lg}') * ug + // + int dv = 0; // TODO(sensitivity) + + // TODO: Sensitivity + int di = nodes[0]->getCrdsSensitivity(); + int dj = nodes[1]->getCrdsSensitivity(); + + + // TODO(sensitivity) + // Matrix3D dR = FrameOrientationGradient(xi, xj, vz, di, dj, dv); + // dub = getBasic(ug, 1/L); + + // + // + VectorND ul = LinearFrameTransf::pullConstant(ug, R, offsets); + // + dub[0] += 0; + double dL = this->getLengthGrad(); + double doneOverL = -dL/(L*L); + double tmp = doneOverL * (ul[1] - ul[7]); + dub[1] += tmp; + dub[2] += tmp; + tmp = doneOverL * (ul[8] - ul[2]); + dub[3] += tmp; + dub[4] += tmp; +#endif + return wrapper; +} + +template +const Vector & +LinearFrameTransf::getBasicDisplTotalGrad(int gradNumber) +{ + + double dug[12]; + for (int i = 0; i < 6; i++) { + dug[i] = nodes[0]->getDispSensitivity((i + 1), gradNumber); + dug[i + 6] = nodes[1]->getDispSensitivity((i + 1), gradNumber); + } + + static VectorND<6> dub; + static Vector wrapper(dub); + + // dub = T_{bl} T_{lg} * ug' + // TODO + // dub = getBasic(dug, R, offsets[0], offsets[nn-1], 1/L); + + wrapper += getBasicDisplFixedGrad(); + + return wrapper; +} + + +template +void +LinearFrameTransf::Print(OPS_Stream &s, int flag) +{ + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << OPS_PRINT_JSON_MATE_INDENT << "{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"LinearFrameTransf\""; + s << ", \"vecxz\": [" + << R(0,2) << ", " + << R(1,2) << ", " + << R(2,2) << "]"; + if (offsets != nullptr) { + s << ", \"offsets\": ["; + for (int i=0; igetTag() << " Type: LinearFrameTransf\n"; + s << "\tOrientation: " << Matrix(&R(0,0), 3,3) << "\n"; + } +} + From 4fcaf155756eee41ae7412aa9214adbc6b38e197 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 072/261] add CrisfieldTransform.h --- .../Frame/Orient/CrisfieldTransform.h | 274 ++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 SRC/coordTransformation/Frame/Orient/CrisfieldTransform.h diff --git a/SRC/coordTransformation/Frame/Orient/CrisfieldTransform.h b/SRC/coordTransformation/Frame/Orient/CrisfieldTransform.h new file mode 100644 index 0000000000..3bca193c16 --- /dev/null +++ b/SRC/coordTransformation/Frame/Orient/CrisfieldTransform.h @@ -0,0 +1,274 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +#pragma once +#include +#include +#include +#include +#include + +class CrisfieldTransform { +public: + CrisfieldTransform() {} + + int + update(const Versor& qI, const Versor& qJ, const Vector3D& dx) + { + + Ln = dx.norm(); + + { + Vector3D gammaw = CayleyFromVersor(qJ.mult_conj(qI)); + + gammaw *= 0.5; + + // Qbar = VersorProduct(VersorFromMatrix(CaySO3(gammaw)), qI); + Qbar = VersorFromMatrix(CaySO3(gammaw)*MatrixFromVersor(qI)); + Triad r{CaySO3(gammaw)*MatrixFromVersor(qI)}; + r1 = r[1]; + r2 = r[2]; + r3 = r[3]; + } + + // + // Compute the base vectors e2, e3 + // + { + // 'rotate' the mean rotation matrix Rbar on to e1 to + // obtain e2 and e3 (using the 'mid-point' procedure) + // + // Vector3D e1, e2, e3; + e[0] = dx; + e[0] /= Ln; + Matrix3D Rbar = MatrixFromVersor(Qbar); + Triad r = Triad{Rbar}; + Vector3D r1 = r[1], + r2 = r[2], + r3 = r[3]; + + // e2 = r2 - (e1 + r1)*((r2^e1)*0.5); + + Vector3D tmp; + tmp = e[0]; + tmp += r1;//Qbar.rotate(E1); + + e[1] = tmp; + { + // const Vector3D r2 = Qbar.rotate(E2); + e[1] *= 0.5*r2.dot(e[0]); + e[1].addVector(-1.0, r2, 1.0); + } + + // e3 = r3 - (e1 + r1)*((r3^e1)*0.5); + e[2] = tmp; + { + // const Vector3D r3 = Qbar.rotate(E3); + e[2] *= r3.dot(e[0])*0.5; + e[2].addVector(-1.0, r3, 1.0); + } + } + return 0; + } + + inline Matrix3D + getRotation() const noexcept + { + Matrix3D E; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + E(i,j) = e[j][i]; + return E; + } + + constexpr const Vector3D& + getBasisE1() const noexcept + { + return e[0]; + } + + constexpr const Vector3D& + getBasisE2() const noexcept + { + return e[1]; + } + constexpr const Vector3D& + getBasisE3() const noexcept + { + return e[2]; + } + + + const Versor& + getReference() + { + return Qbar; + } + + static inline void + getLMatrix(const Matrix3D& A, const Vector3D& e1, const Vector3D& r1, const Vector3D &ri, MatrixND<12,3>& L) + { + static Matrix3D L1, L2; + static Matrix3D rie1r1; + static Matrix3D e1e1r1; + + const double rie1 = ri.dot(e1); + + for (int k = 0; k < 3; k++) { + const double e1r1k = (e1[k] + r1[k]); + for (int j = 0; j < 3; j++) { + rie1r1(j,k) = ri[j]*e1r1k; + e1e1r1(j,k) = e1[j]*e1r1k; + } + } + + // L1 = ri'*e1 * A/2 + A*ri*(e1 + r1)'/2; + L1.zero(); + L1.addMatrix(A, rie1*0.5); + L1.addMatrixProduct(A, rie1r1, 0.5); + + // L2 = Sri/2 - ri'*e1*S(r1)/4 - Sri*e1*(e1 + r1)'/4; + L2.zero(); + L2.addSpin(ri, 0.5); + L2.addSpin(r1, -rie1/4.0); + L2.addSpinMatrixProduct(ri, e1e1r1, -0.25); + + // L = [L1 + // L2 + // -L1 + // L2]; + + L.zero(); + L.assemble(L1, 0, 0, 1.0); + L.assemble(L2, 3, 0, 1.0); + L.assemble(L1, 6, 0, -1.0); + L.assemble(L2, 9, 0, 1.0); + + } + + static inline const MatrixND<12,12> & + getKs2Matrix(Matrix3D& A, const Vector3D& e1, const Vector3D& r1, const double Ln, const Vector3D &ri, const Vector3D &z) + { + static MatrixND<12,12> ks2; + + // Ksigma2 = [ K11 K12 -K11 K12 + // K12' K22 -K12' K22 + // -K11 -K12 K11 -K12 + // K12' K22 -K12' K22]; + + // U = (-1/2)*A*z*ri'*A + ri'*e1*A*z*e1'/(2*Ln)+... + // z'*(e1+r1)*A*ri*e1'/(2*Ln); + + const double rite1 = ri.dot(e1); + const double zte1 = z.dot(e1); + const double ztr1 = z.dot(r1); + + static Matrix3D zrit, ze1t; + static Matrix rizt(3,3), rie1t(3,3); + static Matrix3D e1zt; + + // const Matrix3D e1zt = e1.bun(z); + + // Chrystal's looping order + for (int j = 0; j < 3; j++) { + for (int i = 0; i < 3; i++) { + zrit(i,j) = z[i]*ri[j]; + rizt(i,j) = ri[i]*z[j]; + ze1t(i,j) = z[i]*e1[j]; + e1zt(i,j) = e1[i]*z[j]; + rie1t(i,j) = ri[i]*e1[j]; + } + } + + static Matrix3D U; + + U.addMatrixTripleProduct(0.0, A, zrit, -0.5); + U.addMatrixProduct(A, ze1t, rite1/(2*Ln)); + U.addMatrixProduct(A, rie1t, (zte1 + ztr1)/(2*Ln)); + + static Matrix3D ks; + static Matrix3D m1; + + // K11 = U + U' + ri'*e1*(2*(e1'*z)+z'*r1)*A/(2*Ln); + ks.zero(); + ks.addMatrix(U, 1.0); + + // Add matrix U transpose + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + ks(i,j) += U(j,i); + + ks.addMatrix(A, rite1*(2*zte1 + ztr1)/(2*Ln)); + + ks2.zero(); + ks2.assemble(ks, 0, 0, 1.0); + ks2.assemble(ks, 0, 6, -1.0); + ks2.assemble(ks, 6, 0, -1.0); + ks2.assemble(ks, 6, 6, 1.0); + + // K12 = (1/4)*(-A*z*e1'*Sri - A*ri*z'*Sr1 - z'*(e1+r1)*A*Sri); + m1.zero(); + m1.addMatrixProduct(A, ze1t, -1.0); + ks.zero(); + ks.addMatrixSpinProduct(m1, ri, 0.25); + + m1.zero(); + m1.addMatrixProduct(A, rizt, -1.0); + ks.addMatrixSpinProduct(m1, r1, 0.25); + ks.addMatrixSpinProduct(A, ri, -0.25*(zte1+ztr1)); + + ks2.assemble(ks, 0, 3, 1.0); + ks2.assemble(ks, 0, 9, 1.0); + ks2.assemble(ks, 6, 3, -1.0); + ks2.assemble(ks, 6, 9, -1.0); + + ks2.assembleTranspose(ks, 3, 0, 1.0); + ks2.assembleTranspose(ks, 3, 6, -1.0); + ks2.assembleTranspose(ks, 9, 0, 1.0); + ks2.assembleTranspose(ks, 9, 6, -1.0); + + // K22 = (1/8)*((-ri'*e1)*Sz*Sr1 + Sr1*z*e1'*Sri + ... + // Sri*e1*z'*Sr1 - (e1+r1)'*z*S(e1)*Sri + 2*Sz*Sri); + + ks.zero(); + ks.addSpinProduct(z, r1, -0.125*(rite1)); + + m1.zero(); + m1.addSpinMatrixProduct( r1, ze1t, 1.0); + ks.addMatrixSpinProduct( m1, ri, 0.125); + + m1.zero(); + m1.addSpinMatrixProduct(ri, e1zt, 1.0); + ks.addMatrixSpinProduct(m1, r1, 0.125); + + ks.addSpinProduct(e1, ri, -0.125*(zte1 + ztr1)); + ks.addSpinProduct( z, ri, 0.25); + + // Ksigma2 = [ K11 K12 -K11 K12; + // K12t K22 -K12t K22; + // -K11 -K12 K11 -K12; + // K12t K22 -K12t K22]; + + ks2.assemble(ks, 3, 3, 1.0); + ks2.assemble(ks, 3, 9, 1.0); + ks2.assemble(ks, 9, 3, 1.0); + ks2.assemble(ks, 9, 9, 1.0); + + return ks2; + } + +private: + Versor Qbar; + Vector3D r1, r2, r3; + Vector3D e[3]; + double Ln; + + // Auxiliary +// Matrix3D A; +// MatrixND<12,3> Lr2, Lr3; // auxiliary matrices +}; From 713c2296dae2c869f97fbe16e475db8bcf523790 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 073/261] add FrameBasis.h --- .../Frame/Orient/FrameBasis.h | 279 ++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 SRC/coordTransformation/Frame/Orient/FrameBasis.h diff --git a/SRC/coordTransformation/Frame/Orient/FrameBasis.h b/SRC/coordTransformation/Frame/Orient/FrameBasis.h new file mode 100644 index 0000000000..e40b917dd5 --- /dev/null +++ b/SRC/coordTransformation/Frame/Orient/FrameBasis.h @@ -0,0 +1,279 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRIAD C2 +namespace OpenSees { + +class FrameBasis +{ +public: + virtual int initialize() =0; + virtual int update() =0; + + virtual double getLength() const =0; + // x, \Lambda + virtual Matrix3D getRotation() const =0; + virtual Vector3D getPosition() =0; + // \psi + virtual Vector3D getPositionVariation(int ndf, double* du) =0; + virtual Vector3D getRotationVariation(int ndf, double* du) =0; + virtual Matrix3D getRotationDelta() =0; + // + virtual MatrixND<3,6> getRotationGradient(int node) =0; + +}; + + +template +class RankineBasis : public FrameBasis +{ +public: + RankineBasis(std::array& nodes, const Vector3D& vecxz) + : nodes{nodes}, vz(vecxz), Xc{}, c{}, R{} { + } + + void + setOffsets(std::array* offsets) { + this->offsets = offsets; + } + + virtual int + initialize() { + + for (int i=0; igetTrialRotation(); + + const Vector &XI = nodes[ 0]->getCrds(); + const Vector &XJ = nodes[nn-1]->getCrds(); + + + for (int i=0; i<3; i++) + dX[i] = XJ[i] - XI[i]; + + L = dX.norm(); + Ln = L; + Vector3D e1 = dX/L; + + // + Vector3D e2 = vz.cross(e1); + + const double ynorm = e2.norm(); + + if (ynorm == 0.0) + return -1; + + e2 /= ynorm; + + Vector3D e3 = e1.cross(e2); + + e2 = e3.cross(e1); + + for (int i = 0; i < 3; i++) { + R[init](i,0) = e1[i]; + R[init](i,1) = e2[i]; + R[init](i,2) = e3[i]; + } + +#if 1 + Xc = nodes[ic]->getCrds(); + c[init] = R[init]^(Xc); +#endif + + update(); + return 0; + } + + virtual int + update() { + + Vector3D e1 = dX; + { + // + // Update state + // + { + const Vector& uI = nodes[ 0]->getTrialDisp(); + const Vector& uJ = nodes[nn-1]->getTrialDisp(); + for (int k = 0; k < 3; k++) + e1[k] += uJ(k) - uI(k); + + if (offsets != nullptr) [[unlikely]] { + e1.addVector(1.0, (*offsets)[ 0], 1.0); + e1.addVector(1.0, nodes[0]->getTrialRotation().rotate((*offsets)[0]), -1.0); + e1.addVector(1.0, (*offsets)[nn-1], -1.0); + e1.addVector(1.0, nodes[nn-1]->getTrialRotation().rotate((*offsets)[nn-1]), 1.0); + } + // Calculate the deformed length + Ln = e1.norm(); + + if (Ln == 0.0) [[unlikely]] { + opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; + return -2; + } + + e1 /= Ln; + } + } + + { +#if 1 // TRIAD==R2 + constexpr static Vector3D D2 {0,1,0}; + const Vector3D E2 = R[init]*D2; + Vector3D e2 = MatrixFromVersor(nodes[0]->getTrialRotation())*E2; //*R[init]; + e2.addVector(0.5, MatrixFromVersor(nodes[1]->getTrialRotation())*E2, 0.5); + n = e2[0]/e2[1]; + Vector3D e3 = e1.cross(e2); + e3 /= e3.norm(); + + e2 = e3.cross(e1); + + for (int i = 0; i < 3; i++) { + R[pres](i,0) = e1[i]; + R[pres](i,1) = e2[i]; + R[pres](i,2) = e3[i]; + } + +#elif 1 // TRIAD==C2 + Versor q0 = VersorFromMatrix(R[init]); + Versor qI = nodes[0]->getTrialRotation()*q0; + Versor qJ = nodes[nn-1]->getTrialRotation()*q0; + Vector3D gammaw = CayleyFromVersor(qJ.mult_conj(qI)); + + gammaw *= 0.5; + + // Qbar = VersorProduct(VersorFromMatrix(CaySO3(gammaw)), qI); + Matrix3D Rbar = CaySO3(gammaw)*MatrixFromVersor(qI); // *q0); + Vector3D v { Rbar(0,0), Rbar(1,0), Rbar(2,0) }; + double dot = v.dot(e1); + if (std::fabs(std::fabs(dot)-1.0) < 1.0e-10) { + R[pres] = Rbar; + } else { + v = v.cross(e1); + double scale = std::acos(dot)/v.norm(); + v *= scale; // ::acos(r1.dot(e1)); + + R[pres] = ExpSO3(v)*Rbar; + + Vector3D r1 { R[pres](0,0), R[pres](1,0), R[pres](2,0) }; + Vector3D r2 { R[pres](0,1), R[pres](1,1), R[pres](2,1) }; + Vector3D r3 { R[pres](0,2), R[pres](1,2), R[pres](2,2) }; + // opserr << Vector(r1-e1); + // R[pres] = Rbar^ExpSO3(v); + } +#else + Vector3D e2 = vz.cross(e1); +#endif + + } + + Vector3D uc = nodes[ic]->getTrialDisp(); + if (offsets != nullptr) { + uc.addVector(1.0, (*offsets)[ic], -1.0); + uc.addVector(1.0, nodes[ic]->getTrialRotation().rotate((*offsets)[ic]), 1.0); + } + Vector3D X = nodes[ic]->getCrds(); + c[pres] = R[pres]^(X + uc); + return 0; + }; + + virtual double + getLength() const override { + return Ln; + } + + + virtual Vector3D + getRotationVariation(int ndf, double* du) { + // psi_r = omega + Vector3D w{}; + for (int i=0; igetIncrDeltaDisp(); + auto Wi = this->getRotationGradient(i); + for (int j=0; j<3; j++) + for (int k=0; k<6; k++) + w[j] += Wi(j,k) * du[ndf*i + k]; + } + return w; + } + + + virtual MatrixND<3,6> + getRotationGradient(int node) { + MatrixND<3,6> Gb{}; + + constexpr Vector3D axis{1, 0, 0}; + constexpr Matrix3D ix = Hat(axis); + constexpr Matrix3D ioi = axis.bun(axis); + Gb.template insert<0, 3>(ioi, 0.5); + if (node == 0) + Gb.template insert<0,0>(ix, -1/Ln); + else if (node == nn-1) + Gb.template insert<0,0>(ix, 1/Ln); + + Gb(0,2) = (node == 0? 1.0 : -1.0)*n; + return Gb; + } + + + virtual Matrix3D + getRotation() const override { + return R[pres]; + } + + + virtual Matrix3D + getRotationDelta() { + return R[pres] - R[init]; + } + + Vector3D + getLocation() { + return c[pres]; + } + + virtual Vector3D + getPosition() { + // Return Delta c + Vector3D X = nodes[ic]->getCrds(); + Vector3D Dc = c[pres] - (R[init]^X) ; // (R[pres]^c[init]); + return Dc; + } + + virtual Vector3D + getPositionVariation(int ndf, double* du) { + return Vector3D {du[ndf*ic+0], du[ndf*ic+1], du[ndf*ic+2]}; + } + +private: + constexpr static int ic = 0; // std::floor(0.5*(nn+1)); + enum { pres, prev, init}; + double L, Ln; + double n = 0, + n11 = 1, + n12 = 0, + n21 = 0, + n22 = 1; + Vector3D vz, dX, Xc; + Matrix3D R[3]; + Vector3D c[3]; + Matrix3D dR; + std::array& nodes; + std::array* offsets = nullptr; // offsets +}; + +} // namespace OpenSees From da8323090a3f8b02df337ad7bd0cb7b6a868d259 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 074/261] add PDeltaFrameTransf3d.hpp --- .../Frame/PDeltaFrameTransf3d.hpp | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp new file mode 100644 index 0000000000..f82ead8e7c --- /dev/null +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Description: This file contains the class definition for +// PDeltaFrameTransf.h. PDeltaFrameTransf provides the +// abstraction of a linear transformation for a spatial frame +// between the global and basic coordinate systems +// +// Adapted: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) +// Created: 04/2000 +// +#ifndef PDeltaFrameTransf_h +#define PDeltaFrameTransf_h + +#include +#include +#include +#include + +template +class PDeltaFrameTransf: public FrameTransform +{ +public: + + PDeltaFrameTransf(int tag, + const Vector3D &vecxz, + const std::array *offset=nullptr, + int offset_flags = 0); + + ~PDeltaFrameTransf(); + + const char *getClassType() const {return "PDeltaFrameTransf";} + + double getInitialLength(); + double getDeformedLength(); + + int initialize(std::array& new_nodes) final; + int update() final; + int commit() final; + int revertToLastCommit() final; + int revertToStart() final; + + VectorND getStateVariation() final; + Vector3D getNodePosition(int tag) final; + Vector3D getNodeRotationLogarithm(int tag) final; + virtual const std::array *getRigidOffsets() const { return linear.getRigidOffsets();} + + virtual VectorND pushResponse(VectorND&pl) final; + virtual MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + + virtual FrameTransform *getCopy() const; + + virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; + + // Sensitivity + double getLengthGrad(); + + // Tagged Object + void Print(OPS_Stream &s, int flag = 0); + + private: + int offset_flags; + LinearFrameTransf linear; + +}; +#include "PDeltaFrameTransf3d.tpp" +#endif From 53628301e22258259c30312fccd59a70fbf5a343 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 075/261] add PDeltaFrameTransf3d.tpp --- .../Frame/PDeltaFrameTransf3d.tpp | 196 ++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp new file mode 100644 index 0000000000..c7db5e6611 --- /dev/null +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp @@ -0,0 +1,196 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// Description: This file contains the implementation for the +// PDeltaFrameTransf class. PDeltaFrameTransf is a nonlinear +// transformation for a 3D frame between the global +// and basic coordinate systems +// +// Adapted: Remo Magalhaes de Souza +// 04/2000 +// +#include +#include +#include +#include +#include +#include +#include + +using OpenSees::Matrix3D; + +#define THREAD_LOCAL static + + + + +template +PDeltaFrameTransf::PDeltaFrameTransf(int tag, + const Vector3D &vecxz, + const std::array *offset, + int offset_flags) + : FrameTransform(tag), + offset_flags(offset_flags), + linear(tag, vecxz, offset, offset_flags) +{ + +} + + +template +PDeltaFrameTransf::~PDeltaFrameTransf() +{ + +} + +template +int +PDeltaFrameTransf::commit() +{ + return linear.commit(); +} + +template +int +PDeltaFrameTransf::revertToLastCommit() +{ + return linear.revertToLastCommit(); +} + +template +int +PDeltaFrameTransf::revertToStart() +{ + return linear.revertToStart(); +} + +template +int +PDeltaFrameTransf::initialize(std::array& new_nodes) +{ + return linear.initialize(new_nodes); +} + +template +int +PDeltaFrameTransf::update() +{ + return linear.update(); +} + +template +int +PDeltaFrameTransf::getLocalAxes(Vector3D &XAxis, Vector3D &YAxis, Vector3D &ZAxis) const +{ + return linear.getLocalAxes(XAxis, YAxis, ZAxis); +} + +template +double +PDeltaFrameTransf::getInitialLength() +{ + return linear.getInitialLength(); +} + +template +double +PDeltaFrameTransf::getDeformedLength() +{ + return linear.getDeformedLength(); +} + + +template +VectorND +PDeltaFrameTransf::pushResponse(VectorND&pl) +{ + // + // Include leaning column effects (P-Delta) + // + // Axial force + const double N = pl[1*ndf+0]; + + const Vector3D Du = linear.getDelta()/linear.getInitialLength(); + + pl[0*ndf+1] -= Du[1] * N; + pl[1*ndf+1] += Du[1] * N; + + pl[0*ndf+2] -= Du[2] * N; + pl[1*ndf+2] += Du[2] * N; + + return linear.pushResponse(pl); +} + + +template +MatrixND +PDeltaFrameTransf::pushResponse(MatrixND& kl, const VectorND &pl) +{ + // Include geometric stiffness effects in local system; + // + // Kl += [ ] + double NoverL = pl[6] / linear.getInitialLength(); + kl(1, 1) += NoverL; + kl(2, 2) += NoverL; + kl(7, 7) += NoverL; + kl(8, 8) += NoverL; + + kl(1, 7) -= NoverL; + kl(7, 1) -= NoverL; + kl(2, 8) -= NoverL; + kl(8, 2) -= NoverL; + return linear.pushResponse(kl, pl); +} + + +template +VectorND +PDeltaFrameTransf::getStateVariation() +{ + return linear.getStateVariation(); +} + +template +Vector3D +PDeltaFrameTransf::getNodePosition(int tag) +{ + return linear.getNodePosition(tag); +} + +template +Vector3D +PDeltaFrameTransf::getNodeRotationLogarithm(int tag) +{ + return linear.getNodeRotationLogarithm(tag); +} + +template +FrameTransform * +PDeltaFrameTransf::getCopy() const +{ + Vector3D e1, e2, e3; + linear.getLocalAxes(e1, e2, e3); + + return new PDeltaFrameTransf(this->getTag(), + e3, + linear.getRigidOffsets(), + offset_flags); +} + + +template +double +PDeltaFrameTransf::getLengthGrad() +{ + return linear.getLengthGrad(); +} + +template +void +PDeltaFrameTransf::Print(OPS_Stream &s, int flag) +{ + linear.Print(s, flag); +} From 32f4d4a4e54de7b9755bf8cd01567993cf91a81d Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 076/261] add RigidFrameTransf.hpp --- .../Frame/RigidFrameTransf.hpp | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 SRC/coordTransformation/Frame/RigidFrameTransf.hpp diff --git a/SRC/coordTransformation/Frame/RigidFrameTransf.hpp b/SRC/coordTransformation/Frame/RigidFrameTransf.hpp new file mode 100644 index 0000000000..1f47b58bcf --- /dev/null +++ b/SRC/coordTransformation/Frame/RigidFrameTransf.hpp @@ -0,0 +1,140 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Description: This file contains the class definition for +// RigidFrameTransf.h. RigidFrameTransf provides the +// abstraction of a linear transformation for a spatial frame +// between the global and basic coordinate systems +// +// Written: cmp +// Created: 04/2025 +// +#ifndef RigidFrameTransf_hpp +#define RigidFrameTransf_hpp + +#include +#include +#include +#include + +template +class RigidFrameTransf: public FrameTransform +{ +public: + constexpr static int n = nn*ndf; + + RigidFrameTransf(int tag, + const Vector3D &vecxz, + const std::array *offset=nullptr, + int offset_flags = 0); + + ~RigidFrameTransf(); + + const char *getClassType() const {return "RigidFrameTransf";} + + virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; + + virtual FrameTransform *getCopy() const; + + double getInitialLength() final; + double getDeformedLength() final; + const std::array *getRigidOffsets() const final {return offsets;} + + int initialize(std::array& new_nodes) final; + int update() final; + int commit() final; + int revertToLastCommit() final; + int revertToStart() final; + + VectorND getStateVariation() final; + Vector3D getNodePosition(int tag) final; + Versor getNodeRotation(int tag) /* final */; + Vector3D getNodeRotationLogarithm(int tag) final; + + VectorND pushResponse(VectorND&pl) final; + MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + + // // method used to rotate consistent mass matrix + // const Matrix &getGlobalMatrixFromLocal(const Matrix &local); + + + // Sensitivity + // + bool isShapeSensitivity(); + double getLengthGrad(); + double getd1overLdh(); + + // TaggedObject + void Print(OPS_Stream &s, int flag = 0); + +private: + + inline MatrixND + getProjection() { + + MatrixND A{}; + A.addDiagonal(1.0); + + // double L = basis.getLength(); + constexpr Vector3D axis{1, 0, 0}; + constexpr Matrix3D ix = Hat(axis); + MatrixND<3,ndf> Gb{}; + for (int a = 0; a(basis.getRotationGradient(b), 1.0); + // TODO(nn>2): Interpolate coordinate? + A.assemble(ix*Gb, a*ndf , b*ndf, double(a)/double(nn-1)*L); + A.assemble( Gb, a*ndf+3, b*ndf, -1.0); + } + } + + return A; + } + + int computeElemtLengthAndOrient(); + + template + const Vector3D + pullPosition(int node) + { + const Vector &u = (nodes[node]->*Getter)(); + + Vector3D v; + for (int i=0; i<3; i++) + v[i] = u[i]; + + // 1) Offsets + if (offsets) [[unlikely]] { + if (!(offset_flags&OffsetLocal)) { + Vector3D w {u[3], u[4], u[5]}; + v -= offsets->at(node).cross(w); + } + } + + // 2) Constant Rotation + Matrix3D R = basis.getRotation(); + return R^v; + } + + std::array nodes; + std::array ur; // rotation vector + std::array ux; // displacement vector + + std::array *offsets; + int offset_flags; + Matrix3D R0; + Vector3D xi, xj, vz; + double L; // undeformed element length + + BasisT basis; +}; + +#include "RigidFrameTransf.tpp" +#endif + From 6e9980515b1d7843cc93c041709ae1c194ccf932 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 077/261] add RigidFrameTransf.tpp --- .../Frame/RigidFrameTransf.tpp | 490 ++++++++++++++++++ 1 file changed, 490 insertions(+) create mode 100644 SRC/coordTransformation/Frame/RigidFrameTransf.tpp diff --git a/SRC/coordTransformation/Frame/RigidFrameTransf.tpp b/SRC/coordTransformation/Frame/RigidFrameTransf.tpp new file mode 100644 index 0000000000..3bc5ad1614 --- /dev/null +++ b/SRC/coordTransformation/Frame/RigidFrameTransf.tpp @@ -0,0 +1,490 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Description: This file contains the implementation for the +// RigidFrameTransf class. RigidFrameTransf is a nonlinear +// transformation for a space frame +// +// Written: cmp +// Created: 04/2025 +// +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace OpenSees; + + +template +RigidFrameTransf::RigidFrameTransf(int tag, + const Vector3D &vecxz, + const std::array *offset, + int offset_flags) + : FrameTransform(tag), + L(0), + nodes{}, + ur{}, + offsets{nullptr}, + offset_flags(offset_flags), + basis{nodes, vecxz} +{ + R0.zero(); + R0.addDiagonal(1.0); + double nz = vecxz.norm(); + for (int i=0; i<3; i++) + vz[i] = vecxz[i]/nz; + + // Rigid joint offsets + if (offset != nullptr) { + offsets = new std::array{}; + *offsets = *offset; + basis.setOffsets(offsets); + } +} + + + +template +RigidFrameTransf::~RigidFrameTransf() +{ + if (offsets != nullptr) + delete offsets; +} + +template +int +RigidFrameTransf::commit() +{ + return 0; +} + +template +int +RigidFrameTransf::revertToLastCommit() +{ + return 0; +} + +template +int +RigidFrameTransf::revertToStart() +{ + return 0; +} + + +template +int +RigidFrameTransf::initialize(std::array& new_nodes) +{ + + for (int i=0; igetTrialRotation(); + } + + int error; + // set element length and orientation + if ((error = this->computeElemtLengthAndOrient())) + return error; + + R0 = basis.getRotation(); + return 0; +} + + +template +int +RigidFrameTransf::computeElemtLengthAndOrient() +{ + + const Vector &XI = nodes[ 0]->getCrds(); + const Vector &XJ = nodes[nn-1]->getCrds(); + + for (int i=0; i<3; i++) { + xi[i] = XI[i]; + xj[i] = XJ[i]; + } + + Vector3D dx = xj - xi; + + if (offsets != nullptr) { + for (int i=0; i<3; i++) + dx(i) -= (*offsets)[ 0][i]; + for (int i=0; i<3; i++) + dx(i) += (*offsets)[nn-1][i]; + } + + // calculate the element length + L = dx.norm(); + + if (L == 0.0) + return -2; + + return basis.initialize(); +} + + +template +int +RigidFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector3D &e3) const +{ + Matrix3D R = basis.getRotation(); + for (int i = 0; i < 3; i++) { + e1[i] = R(i,0); + e2[i] = R(i,1); + e3[i] = R(i,2); + } + return 0; +} + +template +double +RigidFrameTransf::getInitialLength() +{ + return L; +} + +template +double +RigidFrameTransf::getDeformedLength() +{ + return L; +} + + +// +// Pull +// +template +int +RigidFrameTransf::update() +{ + if (basis.update() < 0) + return -1; + + Matrix3D R = basis.getRotation(); + for (int i=0; igetTrialRotation(); + ur[i] = LogSO3(R^(MatrixFromVersor(q)*R0)); + } + + return 0; +} + +template +Versor +RigidFrameTransf::getNodeRotation(int tag) +{ + return nodes[tag]->getTrialRotation(); +} + + +template +Vector3D +RigidFrameTransf::getNodePosition(int node) +{ +#if 0 + const Vector& ug = nodes[node]->getTrialDisp(); + + Vector3D u; + for (int i=0; i<3; i++) + u[i] = ug[i]; + + if (offsets != nullptr) [[unlikely]] { + u.addVector(1.0, (*offsets)[node], -1.0); + u.addVector(1.0, nodes[node]->getTrialRotation().rotate((*offsets)[node]), 1.0); + } + + u.addVector(1.0, basis.getPosition(), -1.0); +#else + Vector3D u = this->pullPosition<&Node::getTrialDisp>(node) + - basis.getPosition(); +#endif + u += basis.getRotationDelta()^(nodes[node]->getCrds()); + + return u; +} + + +template +Vector3D +RigidFrameTransf::getNodeRotationLogarithm(int node) +{ + return ur[node]; +} + + +template +VectorND +RigidFrameTransf::getStateVariation() +{ + + static VectorND ul; + for (int i=0; igetIncrDeltaDisp(); + for (int j = 0; j < ndf; j++) { + ul[i*ndf+j] = ddu(j); + } + } + + Matrix3D R = basis.getRotation(); + // return RigidFrameTransf::pullVariation(ug, R, offsets, offset_flags); + + + // VectorND ul = ug; + + // (1) Global Offsets + // Do ui -= ri x wi + if constexpr (ndf >= 6) + if (offsets && !(offset_flags&OffsetLocal)) [[unlikely]] { + const std::array& offset = *offsets; + for (int i=0; igetNodePosition(i); + ul.assemble(i*ndf+0, dc, -1.0); + ul.assemble(i*ndf+0, ui.cross(wr), 1.0); + ul.assemble(i*ndf+3, wr, -1.0); + } + } + + // 3) Offsets + if constexpr (ndf >= 6) + if (offsets && (offset_flags&OffsetLocal)) [[unlikely]] { + const std::array& offset = *offsets; + for (int i=0; i +VectorND +RigidFrameTransf::pushResponse(VectorND&p) +{ + VectorND pa = p; + + // 1) Logarithm + if (1) { // !(offset_flags & LogIter)) { + for (int i=0; i A = getProjection(); + pa = A^pa; + + // 3,4) Rotate and joint offsets + auto pg = this->FrameTransform::pushConstant(pa); + + return pg; +} + + +template +MatrixND +RigidFrameTransf::pushResponse(MatrixND&kb, const VectorND&pb) +{ + MatrixND Kb = kb; + VectorND p = pb; + + if (1) {//!(offset_flags & LogIter)) { + for (int i=0; i Kl; + MatrixND A = getProjection(); + Kl.addMatrixTripleProduct(0, A, Kb, 1); + + // + // Kl += -W'*Pn'*A + // + p = A^p; + Kb.zero(); + for (int j=0; j Gj = basis.getRotationGradient(j); + for (int i=0; iFrameTransform::pushConstant(Kl); +} + + +template +FrameTransform * +RigidFrameTransf::getCopy() const +{ + return new RigidFrameTransf(this->getTag(), vz, offsets); +} + + +// +// Sensitivity +// +template +bool +RigidFrameTransf::isShapeSensitivity() +{ + int nodeParameterI = nodes[ 0]->getCrdsSensitivity(); + int nodeParameterJ = nodes[nn-1]->getCrdsSensitivity(); + // TODO(sensitivity): implement dvz + + return (nodeParameterI != 0 || nodeParameterJ != 0); +} + + +template +double +RigidFrameTransf::getLengthGrad() +{ + const int di = nodes[0]->getCrdsSensitivity(); + const int dj = nodes[1]->getCrdsSensitivity(); + + Vector3D dxi{0.0}; + Vector3D dxj{0.0}; + + if (di != 0) + dxi(di-1) = 1.0; + if (dj != 0) + dxj(dj-1) = 1.0; + + return 1/L*(xj - xi).dot(dxj - dxi); +} + +template +double +RigidFrameTransf::getd1overLdh() +{ + return -getLengthGrad()/(L*L); +} + + +template +void +RigidFrameTransf::Print(OPS_Stream &s, int flag) +{ + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << OPS_PRINT_JSON_MATE_INDENT << "{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"RigidFrameTransf\""; + s << ", \"vecxz\": [" + << vz[0] << ", " + << vz[1] << ", " + << vz[2] << "]"; + if (offsets != nullptr) { + s << ", \"offsets\": ["; + for (int i=0; i Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 078/261] add SouzaFrameTransf.hpp --- .../Frame/SouzaFrameTransf.hpp | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 SRC/coordTransformation/Frame/SouzaFrameTransf.hpp diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp new file mode 100644 index 0000000000..e8d2a78a26 --- /dev/null +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp @@ -0,0 +1,149 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Description: This file contains the class definition for +// SouzaFrameTransf. SouzaFrameTransf implements the formulation +// of Crisfield (1990) with the objective of maintaining the +// original "Corotational" implementation by Remo Magalhaes de Souza, within +// the new framework proposed by Perez and Filippou (2024). +// +// Written by : cmp, March 2024 +// +// Adapted from work by: Remo Magalhaes de Souza +// +#ifndef SouzaFrameTransf_hpp +#define SouzaFrameTransf_hpp + +#include +#include "FrameTransform.h" +#include +#include +#include +#include +#include +#include "Orient/CrisfieldTransform.h" + +struct Triad; +using namespace OpenSees; // TODO: Clean namespace use + +template +class SouzaFrameTransf: public FrameTransform +{ +public: + SouzaFrameTransf(int tag, const Vector3D &vecxz, + const std::array *offset=nullptr, + int offset_flags = 0); + + ~SouzaFrameTransf(); + + const char *getClassType() const { + return "SouzaFrameTransf"; + } + + // NOTE: maybe add arg for rotation parameterization + FrameTransform *getCopy() const; + + int initialize(std::array& new_nodes); + int update(); + int commit(); + int revertToLastCommit(); + int revertToStart(); + int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; + virtual const std::array *getRigidOffsets() const { return offsets; } + + double getInitialLength(); + double getDeformedLength(); + + virtual VectorND getStateVariation() final; + virtual Vector3D getNodePosition(int tag) final; + virtual Vector3D getNodeRotationLogarithm(int tag) final; + + virtual VectorND pushResponse(VectorND&pl) final; + virtual MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + + // Sensitivity + double getLengthGrad(); + virtual const Vector &getBasicDisplTotalGrad(int grad); + virtual const Vector &getBasicDisplFixedGrad(); + virtual const Vector &getGlobalResistingForceShapeSensitivity(const Vector &pb, const Vector &p0, int gradNumber); + + // Tagged Object + void Print(OPS_Stream &s, int flag = 0); + +protected: + int addTangent(MatrixND<12,12>& M, const VectorND<12>& pl); + + VectorND<6> pushResponse(const VectorND<6>& pa, int a, int b); + MatrixND<6,6> pushResponse(const MatrixND<6,6>& K, const VectorND<12>& pl, int a, int b); + int addTangent(MatrixND<6,6>& K, const VectorND<6>& p, int a, int b, int c); + +protected: + +private: + constexpr static int n = nn*ndf; + + // compute the transformation matrix + void compTransfMatrixBasicGlobal(const Versor&, const Versor* Q); + + enum { + inx= 0, // axial + iny= 1, // Vy + inz= 2, // Vz + imx= 3, // torsion + imy= 4, // rot y I + imz= 5, // rot z I + + jnx= 6, // axial + jny= 7, + jnz= 8, + jmx= 9, // torsion + jmy=10, // rot y J + jmz=11, // rot z J + }; + + // + // Member data + // + std::array nodes; + + Vector3D xAxis; // local x axis + Vector3D vz; // Vector that lies in local plane xz + Vector3D dX; + + + std::array *offsets; + + + double *nodeIInitialDisp, *nodeJInitialDisp; + bool initialDispChecked; + + double L; // initial element length + double Ln; // current element length (at trial state) + + Versor Q_past[nn]; // commited rotations + Versor Q_pres[nn]; // trial rotations + + Vector3D alphaI; // last trial rotations end i + Vector3D alphaJ; // last trial rotatations end j + + VectorND ul; // local displacements (size=7) + Vector3D vr[nn]; // + VectorND ulcommit; // commited local displacements + VectorND ulpr; // previous local displacements + + OpenSees::MatrixND T; // transformation from local to global system + + OpenSees::Matrix3D R0; // rotation from local to global coordinates + CrisfieldTransform crs; + + // Static workspace variables + Matrix3D A; + MatrixND<12,3> Lr2, Lr3; // auxiliary matrices +}; +#include "SouzaFrameTransf.tpp" +#endif From 8bf467d4134ba629055abc9c53dac9ee755d9869 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 079/261] add SouzaFrameTransf.tpp --- .../Frame/SouzaFrameTransf.tpp | 943 ++++++++++++++++++ 1 file changed, 943 insertions(+) create mode 100644 SRC/coordTransformation/Frame/SouzaFrameTransf.tpp diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp new file mode 100644 index 0000000000..97ec444ade --- /dev/null +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp @@ -0,0 +1,943 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Description: This file contains the implementation for the +// SouzaFrameTransf class. SouzaFrameTransf is a Corotational +// transformation for a spatial frame element between the global +// and basic coordinate systems. +// +// Written: Claudio Perez +// Created: 05/2024 +// +// Adapted from: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) +// +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Orient/CrisfieldTransform.h" + +using namespace OpenSees; + +template +SouzaFrameTransf::SouzaFrameTransf(int tag, const Vector3D &vz, + const std::array *offset, + int offset_flags) + : FrameTransform(tag), + vz(vz), + offsets{nullptr}, + L(0), Ln(0), + nodeIInitialDisp(0), nodeJInitialDisp(0), + initialDispChecked(false) +{ + alphaI.zero(); + alphaJ.zero(); + + // Rigid joint offsets + if (offset != nullptr) { + offsets = new std::array{}; + *offsets = *offset; + } +} + + +template +SouzaFrameTransf::~SouzaFrameTransf() +{ + if (offsets != nullptr) + delete offsets; +} + + +template +double +SouzaFrameTransf::getInitialLength() +{ + return L; +} + + +template +double +SouzaFrameTransf::getDeformedLength() +{ + return Ln; +} + + +template +FrameTransform * +SouzaFrameTransf::getCopy() const +{ + + SouzaFrameTransf *theCopy = + new SouzaFrameTransf(this->getTag(), vz, offsets); + + theCopy->nodes[0] = nodes[0]; + theCopy->nodes[1] = nodes[1]; + theCopy->xAxis = xAxis; + theCopy->L = L; + theCopy->Ln = Ln; + theCopy->R0 = R0; + theCopy->Q_pres[0] = Q_pres[0]; + theCopy->Q_pres[1] = Q_pres[1]; + theCopy->Q_past[0] = Q_past[0]; + theCopy->Q_past[1] = Q_past[1]; + theCopy->ul = ul; + theCopy->ulcommit = ulcommit; + return theCopy; +} + + +template +int +SouzaFrameTransf::revertToStart() +{ + ul.zero(); + Q_pres[0] = VersorFromMatrix(R0); + for (int i=1; iupdate(); + return 0; +} + + +template +int +SouzaFrameTransf::commit() +{ + ulcommit = ul; + Q_past[0] = Q_pres[0]; + Q_past[1] = Q_pres[1]; + return 0; +} + + +template +int +SouzaFrameTransf::revertToLastCommit() +{ + // determine global displacement increments from last iteration + const Vector &dispI = nodes[0]->getTrialDisp(); + const Vector &dispJ = nodes[1]->getTrialDisp(); + + for (int k = 0; k < 3; k++) { + alphaI(k) = dispI(k+3); + alphaJ(k) = dispJ(k+3); + } + + ul = ulcommit; + Q_pres[0] = Q_past[0]; + Q_pres[1] = Q_past[1]; + + this->update(); + + return 0; +} + + +template +int +SouzaFrameTransf::initialize(std::array& new_nodes) +{ + for (int i=0; igetCrds() - nodes[0]->getCrds(); + + // Add initial displacements at nodes + if (initialDispChecked == false) { + const Vector &nodeIDisp = nodes[0]->getDisp(); + const Vector &nodeJDisp = nodes[1]->getDisp(); + for (int i = 0; i<6; i++) + if (nodeIDisp[i] != 0.0) { + nodeIInitialDisp = new double [6]; + for (int j = 0; j<6; j++) + nodeIInitialDisp[j] = nodeIDisp[j]; + i = 6; + } + + for (int j = 0; j<6; j++) + if (nodeJDisp[j] != 0.0) { + nodeJInitialDisp = new double [6]; + for (int i = 0; i<6; i++) + nodeJInitialDisp[i] = nodeJDisp[i]; + j = 6; + } + initialDispChecked = true; + } + + // if (nodeIInitialDisp != nullptr) { + // dX[0] -= nodeIInitialDisp[0]; + // dX[1] -= nodeIInitialDisp[1]; + // dX[2] -= nodeIInitialDisp[2]; + // } + + // if (nodeJInitialDisp != nullptr) { + // dX[0] += nodeJInitialDisp[0]; + // dX[1] += nodeJInitialDisp[1]; + // dX[2] += nodeJInitialDisp[2]; + // } + + + // + // Length and Orientation + // + Vector3D dx; + + dx = nodes[nn-1]->getCrds() - nodes[0]->getCrds(); + + L = dx.norm(); + + if (L == 0.0) { + opserr << "\nSouzaFrameTransf::computeElemtLengthAndOrien: 0 length\n"; + return -2; + } + + // + // Set rotation matrix + // + int error = FrameTransform::Orient(dx, vz, R0); + if (error) + return error; + + // Compute initial pseudo-vectors for nodal triads + Q_pres[0] = Q_pres[1] = VersorFromMatrix(R0); + + ul.zero(); + ulpr.zero(); + + for (int i=0; icommit(); + + return 0; +} + +template +VectorND +SouzaFrameTransf::getStateVariation() +{ + return ul - ulpr; +} + +template +Vector3D +SouzaFrameTransf::getNodePosition(int tag) +{ + Vector3D u; + for (int i=0; i<3; i++) + u[i] = ul[tag*ndf+i]; + return u; +} + +template +Vector3D +SouzaFrameTransf::getNodeRotationLogarithm(int tag) +{ + return vr[tag]; +} + +template +void inline +SouzaFrameTransf::compTransfMatrixBasicGlobal( + const Versor& Qbar, + const Versor* Q_pres) +{ + // extract columns of rotation matrices + const Triad r {MatrixFromVersor(Qbar)}, + rI{MatrixFromVersor(Q_pres[0])}, + rJ{MatrixFromVersor(Q_pres[1])}; + const Vector3D + &e1 = crs.getBasisE1(), // E[1], + &e2 = crs.getBasisE2(), // E[2], + &e3 = crs.getBasisE3(), // E[3], + &r1 = r[1], + &r2 = r[2], + &r3 = r[3], + &rI1 = rI[1], + &rI2 = rI[2], + &rI3 = rI[3], + &rJ1 = rJ[1], + &rJ2 = rJ[2], + &rJ3 = rJ[3]; + + // Compute the transformation matrix from the basic to the + // global system + // A = (1/Ln)*(I - e1*e1'); + // Matrix3D A; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; + + // This must be called up here + CrisfieldTransform::getLMatrix(A, e1, r1, r2, Lr2); + CrisfieldTransform::getLMatrix(A, e1, r1, r3, Lr3); + + // 3 | 3 | 3 | 3 | + // T1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', O', O']'; imx + // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; imz + // T3 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', -(A*rI3)', O']'; imy + // + // T4 = [ O', O', O', ( S(rJ2)*e3 - S(rJ3)*e2 )']'; jmx + // T5 = [(A*rJ2)', O', -(A*rJ2)', ( S(rJ1)*e2 - S(rJ2)*e1 )']'; jmz + // T6 = [(A*rJ3)', O', -(A*rJ3)', ( S(rJ1)*e3 - S(rJ3)*e1 )']'; jmy + + T.zero(); + + // T1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', O', O']'; + + // (-S(rI3)*e2 + S(rI2)*e3) + Vector3D Se = rI2.cross(e3); + Se -= rI3.cross(e2); + for (int i = 0; i < 3; i++) + // T(jmx,i+3) = -Se[i]; + T(imx,i+3) = Se[i]; + + // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; + + Vector3D At = A*rI2; + + // (-S(rI2)*e1 + S(rI1)*e2)' + Se = rI1.cross(e2); + Se -= rI2.cross(e1); + for (int i = 0; i < 3; i++) { + T(imz,i ) = At[i]; + T(imz,i+3) = Se[i]; + T(imz,i+6) = -At[i]; + } + + // T3 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', -(A*rI3)', O']'; + + At = A*rI3; + + // -S(rI3)*e1 + S(rI1)*e3 + Se = rI1.cross(e3); + Se -= rI3.cross(e1); + for (int i = 0; i < 3; i++) { + T(imy,i ) = At[i]*-1; + T(imy,i+3) = Se[i]*-1; + T(imy,i+6) = -At[i]*-1; + } + + // T4 = [ O', O', O', (-S(rJ3)*e2 + S(rJ2)*e3)']'; + Se = rJ2.cross(e3); + Se -= rJ3.cross(e2); + for (int i = 0; i < 3; i++) + T(jmx, i+9) = Se[i]; // S(rJ2)*e3 - S(rJ3)*e2 + + // T5 = [(A*rJ2)', O', -(A*rJ2)', (-S(rJ2)*e1 + S(rJ1)*e2)']'; + At = A*rJ2; + Se = rJ1.cross(e2); + Se -= rJ2.cross(e1); + for (int i = 0; i < 3; i++) { + T(jmz, i ) = At[i]; + T(jmz, i+6) = -At[i]; + T(jmz, i+9) = Se[i]; // (-S(rJ2)*e1 + S(rJ1)*e2) + } + + // T6 = [(A*rJ3)', O', -(A*rJ3)', (-S(rJ3)*e1 + S(rJ1)*e3)']' + At = A*rJ3; + Se = rJ1.cross(e3); // (-S(rJ3)*e1 + S(rJ1)*e3) + Se -= rJ3.cross(e1); + for (int i = 0; i < 3; i++) { + T(jmy,i ) = At[i]*-1; + T(jmy,i+6) = -At[i]*-1; + T(jmy,i+9) = Se[i]*-1; + } + + // + // Second part + // + + // T(:,1) += Lr3*rI2 - Lr2*rI3; + // T(:,2) += Lr2*rI1; z + // T(:,3) += Lr3*rI1 ; y + + // T(:,4) += Lr3*rJ2 - Lr2*rJ3; + // T(:,5) += Lr2*rJ1 ; z // ?????? check sign + // T(:,6) += Lr3*rJ1 ; y // ?????? check sign + + // Bending Z + for (int i = 0; i < 12; i++) { + double T1i = 0; + for (int k=0; k<3; k++) + T1i += Lr2(i,k)*rI1[k]; + T(imz,i) += T1i; + } + + for (int i = 0; i < 12; i++) { + double T4i = 0; + for (int k=0; k<3; k++) + T4i += Lr2(i,k)*rJ1[k]; // Lr[i]; + T(jmz,i) += T4i; + } + + // Torsion + for (int i = 0; i < 12; i++) { + double T0i = 0; + for (int k=0; k<3; k++) + T0i += Lr3(i,k)*rI2[k] - Lr2(i,k)*rI3[k]; + // T(jmx,i) += -T0i; + T(imx,i) += T0i; + } + for (int i = 0; i < 12; i++) { + double T3i = 0; + for (int k=0; k<3; k++) + T3i += Lr3(i,k)*rJ2[k] - Lr2(i,k)*rJ3[k]; + T(jmx,i) += T3i; + } + // Bending Y + for (int i = 0; i < 12; i++) { + double T2i = 0; + for (int k=0; k<3; k++) + T2i += Lr3(i,k)*rI1[k]; // Lr[i]; + T(imy,i) += T2i*-1; // TODO: Check + } + for (int i = 0; i < 12; i++) { + double T5i = 0; + for (int k=0; k<3; k++) + T5i += Lr3(i,k)*rJ1[k]; // Lr[i]; + T(jmy,i) += T5i*-1; // TODO: Check + } + + // + // + // + for (int node=0; node < 2; node++) + for (int j = 0; j < 3; j++) { + const double c = 0.5 / std::cos(ul[(node? jmx : imx) + j]); + for (int i = 0; i < 12; i++) + T((node? jmx : imx) + j, i) *= c; + } + + // Axial + // T(:,7) = [-e1' O' e1' O']'; + for (int i = 0; i < 3; i++) { + T(jnx,i ) = -e1[i]; + T(jnx,i+6) = e1[i]; + } + + // Combine torsion + for (int i=0; i<12; i++) { + T(jmx,i) -= T(imx,i); + T(imx,i) = 0; + } +} + +// +// Set RI,RJ,Rbar, Ln, e and ul +// +template +int +SouzaFrameTransf::update() +{ + // determine global displacement increments from last iteration + + const Vector& dispI = nodes[ 0]->getTrialDisp(); + const Vector& dispJ = nodes[nn-1]->getTrialDisp(); + + // + // Update state + // + // 1.1 Relative translation + Vector3D dx = dX;// dx = dX + dJI; + { + // Relative translation + for (int k = 0; k < 3; k++) + dx[k] += dispJ(k) - dispI(k); + + + // Calculate the deformed length + Ln = dx.norm(); + + if (Ln == 0.0) { + opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; + return -2; + } + } + + // 1.2 Rotational displacement increments + { + Vector3D dAlphaI, dAlphaJ; + + for (int k = 0; k < 3; k++) { + dAlphaI[k] = dispI(k+3) - alphaI[k]; + alphaI[k] = dispI(k+3); + dAlphaJ[k] = dispJ(k+3) - alphaJ[k]; + alphaJ[k] = dispJ(k+3); + } + + // Update the nodal rotations + Q_pres[0] = VersorProduct(Q_pres[0], Versor::from_vector(dAlphaI)); + Q_pres[1] = VersorProduct(Q_pres[1], Versor::from_vector(dAlphaJ)); + } + + // + // 2) Form transformation + // + + crs.update(Q_pres[0], Q_pres[1], dx); + // Form the transformation tangent + this->compTransfMatrixBasicGlobal(crs.getReference(), Q_pres); + + // + // 3) Local deformations + // + + // Save previous state + ulpr = ul; + + // Rotations + { + Matrix3D e = crs.getRotation(); + vr[0] = LogC90(e^MatrixFromVersor(Q_pres[0])); + for (int i=0; i<3; i++) + ul[imx+i] = vr[0][i]; + + vr[1] = LogC90(e^MatrixFromVersor(Q_pres[1])); + for (int i=0; i<3; i++) + ul[jmx+i] = vr[1][i]; + } + + // Axial + ul(inx) = 0; + ul(jnx) = Ln - L; + + return 0; +} + + +template +inline VectorND +SouzaFrameTransf::pushResponse(VectorND&pl) +{ + // return T^pl; + VectorND pg{}; + for (int a = 0; a pa {pl(a*ndf+0), pl(a*ndf+1), pl(a*ndf+2), + pl(a*ndf+3), pl(a*ndf+4), pl(a*ndf+5)}; + + for (int b = 0; b<2; b++) { + VectorND<6> pab = pushResponse(pa, a, b); + pg.assemble(b*6, pab, 1.0); + } + } + return pg; +} + +template +VectorND<6> +SouzaFrameTransf::pushResponse(const VectorND<6>&pa, int a, int b) +{ + VectorND<6> pg{}; + for (int i = 0; i < 6; i++) + for (int j = 0; j < 6; j++) + pg[j] += T(a*6 + i, b*6+j) * pa[i]; + + return pg; +} + +// do +// K = ag'*Km*ag + Kp +// +template +MatrixND +SouzaFrameTransf::pushResponse(MatrixND& kl, const VectorND& pl) +{ + MatrixND<12,12> K; + K.addMatrixTripleProduct(0.0, T, kl, 1.0); + + // Add geometric part kg + this->addTangent(K, pl); + + return K; +} + + +// +// Add geometric part of the transformation tangent +// +// kg += T'*kl*T + ks1 + T * diag(m.*tan(thetal))*T' + ... +// m(4)*(ks2r2t3_u3 + ks2r3u2_t2) + ... +// m(2)*ks2r2t1 + m(3)*ks2r3t1 + ... +// m(5)*ks2r2u1 + m(6)*ks2r3u1 + ... +// ks3 + ks3' + ks4 + ks5; +template +int +SouzaFrameTransf::addTangent(MatrixND<12,12>& kg, const VectorND<12>& pl) +{ + const Triad r {MatrixFromVersor(crs.getReference())}, + rI{MatrixFromVersor(Q_pres[0])}, + rJ{MatrixFromVersor(Q_pres[1])}; + const Vector3D + &e1 = crs.getBasisE1(), // E[1], + &e2 = crs.getBasisE2(), // E[2], + &e3 = crs.getBasisE3(), // E[3], + &r1 = r[1], // .rotate(E1), + &r2 = r[2], // .rotate(E2), + &r3 = r[3], // .rotate(E3), + &rI1 = rI[1], // .rotate(E1), + &rI2 = rI[2], // .rotate(E2), + &rI3 = rI[3], // .rotate(E3), + &rJ1 = rJ[1], // .rotate(E1), + &rJ2 = rJ[2], // .rotate(E2), + &rJ3 = rJ[3]; // .rotate(E3); + + // NOTE[cmp] + // SouzaFrameTransf::compTransfMatrixBasicGlobal must be + // called first to set Lr1, Lr2 and T + + // Matrix3D A; + // for (int i = 0; i < 3; i++) + // for (int j = 0; j < 3; j++) + // A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; + // getLMatrix(A, e1, r1, r2, Lr2); + // getLMatrix(A, e1, r1, r3, Lr3); + + // + // Ksigma1 + // + { + const double N = -pl[0]; // Axial force + // a=0 + kg.assemble(A, 0, 0, N); + kg.assemble(A, 0, 6, -N); + // a=1 + kg.assemble(A, 6, 0, -N); + kg.assemble(A, 6, 6, N); + } + + // + // Ksigma3 + // + // ks3 = [o kbar2 | o kbar4]; + // + // where + // + // kbar2 = -Lr2*(m(3)*S(rI3) + m(1)*S(rI1)) + Lr3*(m(3)*S(rI2) - m(2)*S(rI1)) ; + // + // kbar4 = Lr2*(m(3)*S(rJ3) - m(4)*S(rJ1)) - Lr3*(m(3)*S(rJ2) + m(5)*S(rJ1)); + // + // or + // + // ks3 = [o ka+kb | o kc+kd]; + // = [o ka | o kc] + [o kb | o kd]; + // + // where + // + // ka = -Lr2*S(rI3)*m(3) + // +Lr2*S(rI1)*m(1); + // kb = Lr3*S(rI2)*m(3) + // -Lr3*S(rI1)*m(2); + // + // kc = Lr2*S(rJ3)*m(3) + // -Lr2*S(rJ1)*m(4); + // kd = -Lr3*S(rJ2)*m(3) + // +Lr3*S(rJ1)*m(5); + + VectorND<6> m; + m[0] = 0.5*pl[imx]/std::cos(ul(imx)); + m[2] = -0.5*pl[imy]/std::cos(ul(imy)); + m[1] = 0.5*pl[imz]/std::cos(ul(imz)); + + m[3] = 0.5*pl[jmx]/std::cos(ul(jmx)); + m[5] = -0.5*pl[jmy]/std::cos(ul(jmy)); + m[4] = 0.5*pl[jmz]/std::cos(ul(jmz)); + + + static Matrix3D Sm; + Sm.zero(); + Sm.addSpin(rI3, m[3]); + Sm.addSpin(rI1, m[1]); + static MatrixND<12,3> kbar; + kbar.zero(); + kbar.addMatrixProduct(Lr2, Sm, -1.0); + + Sm.zero(); + Sm.addSpin(rI2, m[3]); + Sm.addSpin(rI1, -m[2]); + kbar.addMatrixProduct(Lr3, Sm, 1.0); + + kg.assemble(kbar, 0, 3, 1.0); + kg.assembleTranspose(kbar, 3, 0, 1.0); + + Sm.zero(); + Sm.addSpin(rJ3, m[3]); + Sm.addSpin(rJ1, -m[4]); + kbar.zero(); + kbar.addMatrixProduct(Lr2, Sm, 1.0); + + Sm.zero(); + Sm.addSpin(rJ2, m[3]); + Sm.addSpin(rJ1, m[5]); + kbar.addMatrixProduct(Lr3, Sm, -1.0); + + kg.assemble(kbar, 0, 9, 1.0); + kg.assembleTranspose(kbar, 9, 0, 1.0); + + + // + // Ksigma4 + // + { + Matrix3D ks33; + ks33.zero(); + ks33.addSpinProduct(e2, rI3, m[3]); + ks33.addSpinProduct(e3, rI2, -m[3]); + ks33.addSpinProduct(e2, rI1, m[1]); + ks33.addSpinProduct(e1, rI2, -m[1]); + ks33.addSpinProduct(e3, rI1, m[2]); + ks33.addSpinProduct(e1, rI3, -m[2]); + kg.assemble(ks33, 3, 3, 1.0); + } + + // + // Ksigma4 + // + { + Matrix3D ks33; + ks33.zero(); + ks33.addSpinProduct(e2, rJ3, -m[3]); + ks33.addSpinProduct(e3, rJ2, m[3]); + ks33.addSpinProduct(e2, rJ1, m[4]); + ks33.addSpinProduct(e1, rJ2, -m[4]); + ks33.addSpinProduct(e3, rJ1, m[5]); + ks33.addSpinProduct(e1, rJ3, -m[5]); + + kg.assemble(ks33, 9, 9, 1.0); + } + + + // + // Ksigma5 + // + // Ks5 = [ Ks5_11 Ks5_12 | -Ks5_11 Ks5_14; + // Ks5_12' O | -Ks5_12' O; + // -Ks5_11 -Ks5_12 | Ks5_11 -Ks5_14; + // Ks5_14t O | -Ks5_14' O]; + // + // + // v = (1/Ln)*(m(2)*rI2 + m(3)*rI3 + m(5)*rJ2 + m(6)*rJ3); + // = 1/Ln * (m[1]*rI2 + m[2]*rI3) + // + 1/Ln * (m[4]*rJ2 + m[5]*rJ3); + // = vi + vj + // + { + Vector3D v; + v.addVector(0.0, rI2, m[1]); + v.addVector(1.0, rI3, m[2]); + v.addVector(1.0, rJ2, m[4]); + v.addVector(1.0, rJ3, m[5]); + v /= Ln; + + // Ks5_11 = A*v*e1' + e1*v'*A + (e1'*v)*A; + // = A*vi*e1' + e1*vi'*A + (e1'*vi)*A + // + A*vj*e1' + e1*vj'*A + (e1'*vj)*A; + // + Matrix3D ks33; + ks33.zero(); + ks33.addMatrix(A, e1.dot(v)); + + static Matrix3D m33; + m33.zero(); + m33.addTensorProduct(v, e1, 1.0); + + ks33.addMatrixProduct(A, m33, 1.0); + + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + m33(i,j) = e1[i]*v[j]; + + ks33.addMatrixProduct(m33, A, 1.0); + + kg.assemble(ks33, 0, 0, 1.0); + kg.assemble(ks33, 0, 6, -1.0); + kg.assemble(ks33, 6, 0, -1.0); + kg.assemble(ks33, 6, 6, 1.0); + } + + // Ks5_12 = -(m(2)*A*S(rI2) + m(3)*A*S(rI3)); + + Matrix3D ks33; + ks33.zero(); + ks33.addMatrixSpinProduct(A, rI2, -m[1]); + ks33.addMatrixSpinProduct(A, rI3, -m[2]); + + kg.assemble(ks33, 0, 3, 1.0); + kg.assemble(ks33, 6, 3, -1.0); + kg.assembleTranspose(ks33, 3, 0, 1.0); + kg.assembleTranspose(ks33, 3, 6, -1.0); + + // Ks5_14 = -(m(5)*A*S(rJ2) + m(6)*A*S(rJ3)); + + ks33.zero(); + ks33.addMatrixSpinProduct(A, rJ2, -m[4]); + ks33.addMatrixSpinProduct(A, rJ3, -m[5]); + + kg.assemble(ks33, 0, 9, 1.0); + kg.assemble(ks33, 6, 9, -1.0); + + kg.assembleTranspose(ks33, 9, 0, 1.0); + kg.assembleTranspose(ks33, 9, 6, -1.0); + + // Ksigma ------------------------------- + Vector3D rm = rI3; + + rm.addVector(1.0, rJ3, -1.0); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rm), m[3]); + +// rm = rJ2; + rm.addVector(0.0, rJ2, -1.0); + rm.addVector(1.0, rI2, -1.0); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rm), m[3]); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rI1), m[1]); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rI1), m[2]); + // + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rJ1), m[4]); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rJ1), m[5]); + + // + // T' * diag (M .* tan(thetal))*T + // + + for (int node=0; node<2; node++) { + for (int k = 0; k < 3; k++) { + const double factor = pl[6*node+3+k] * std::tan(ul[(node ? jmx : imx) + k]); + for (int i = 0; i < 12; i++) { + const double Tki = T((node ? jmx : imx) + k,i); + for (int j = 0; j < 12; j++) + kg(i,j) += Tki * factor * T((node ? jmx : imx) + k, j); + } + } + } + + return 0; +} + + +template +int +SouzaFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector3D &e3) const +{ + for (int i = 0; i < 3; i++) { + e1[i] = R0(i,0); + e2[i] = R0(i,1); + e3[i] = R0(i,2); + } + return 0; +} + + +template +double +SouzaFrameTransf::getLengthGrad() +{ + const int di = nodes[0]->getCrdsSensitivity(); + const int dj = nodes[1]->getCrdsSensitivity(); + + Vector3D dxi{0.0}; + Vector3D dxj{0.0}; + + if (di != 0) + dxi(di-1) = 1.0; + if (dj != 0) + dxj(dj-1) = 1.0; + + return 1/L * dX.dot(dxj - dxi); +} + +template +const Vector & +SouzaFrameTransf::getBasicDisplTotalGrad(int gradNumber) +{ + opserr << "WARNING CrdTransf::getBasicDisplTotalGrad() - this method " + << " should not be called.\n"; + + static Vector dummy(1); + return dummy; +} + +template +const Vector & +SouzaFrameTransf::getBasicDisplFixedGrad() +{ + opserr << "ERROR CrdTransf::getBasicDisplFixedGrad() - has not been" + << " implemented yet for the chosen transformation\n."; + + static Vector dummy(1); + return dummy; +} + + +template +const Vector & +SouzaFrameTransf::getGlobalResistingForceShapeSensitivity(const Vector &pb, + const Vector &p0, + int gradNumber) +{ + opserr << "ERROR CrdTransf::getGlobalResistingForceSensitivity() - has not been" + << " implemented yet for the chosen transformation." << endln; + + static Vector dummy(1); + return dummy; +} + +template +void +SouzaFrameTransf::Print(OPS_Stream &s, int flag) +{ + + if (flag == OPS_PRINT_CURRENTSTATE) { + s << "\nFrameTransform: " << this->getTag() << " Type: SouzaFrameTransf"; + s << "\tvxz: " << Vector(vz); + } + + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << OPS_PRINT_JSON_MATE_INDENT << "{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"SouzaFrameTransf\"" << ", "; + s << "\"vecxz\": [" << vz(0) << ", " << vz(1) << ", " << vz(2) << "]"; + + if (offsets != nullptr) { + s << ", \"offsets\": ["; + for (int i=0; i Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 080/261] add MatrixND.h --- SRC/matrix/MatrixND.h | 908 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 908 insertions(+) create mode 100644 SRC/matrix/MatrixND.h diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h new file mode 100644 index 0000000000..1e2f7849a6 --- /dev/null +++ b/SRC/matrix/MatrixND.h @@ -0,0 +1,908 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// See https://opensees.berkeley.edu/OpenSees/copyright.php for license. +// +//===--- MatrixND.h - Matrix with fixed size ------------------------------===// +// +// Objectives: +// - little to no overhead above C-style arrays +// - value semantics; objects do not decay to pointers; +// +// This code is influenced by the following sources +// List initialization: +// - https://stackoverflow.com/questions/42068882/list-initialization-for-a-matrix-class +// +// Style/practices +// - https://quuxplusone.github.io/blog/2021/04/03/static-constexpr-whittling-knife/ +// +// Operator overloading / semantics +// - https://stackoverflow.com/questions/9851188/does-it-make-sense-to-use-move-semantics-for-operator-and-or-operator/9851423#9851423 +// +// Compile-time template restrictions/concepts: +// - https://codereview.stackexchange.com/questions/259038/compile-time-matrix-class +// (C++ 20) +// - https://github.com/calebzulawski/cotila/ +// (C++ 17) +// +//===----------------------------------------------------------------------===// +// +// Claudio Perez +// +#ifndef MatrixND_H +#define MatrixND_H +#include +#include +#include +#include +#include +#include // overloading << + +#include "VectorND.h" +#include "Matrix.h" +#include "Vector.h" +#include "blasdecl.h" +#include "routines/cmx.h" +#include "routines/SY3.h" + +#if __cplusplus < 202000L +#define consteval +#define requires(X) +#endif + +#define G23_STACK_MAX 10 + +namespace OpenSees { + +template +requires(NR > 0 && NC > 0) +struct MatrixND { + double values[NC][NR]; + +//MatrixND(const MatrixND&) = default; + + // Convert to regular Matrix class + operator Matrix() { return Matrix(&values[0][0], NR, NC);} + operator const Matrix() const { return Matrix(&values[0][0], NR, NC);} + + MatrixND& addDiagonal(const double vol) requires(NR == NC); + + int symeig(VectorND& vals) requires(NR == NC == 3) { + double work[3][3]; + cmx_eigSY3(values, work, vals.values); + return 0; + } + + template + void addMatrix(const MatT& A, const double scale); + + template constexpr MatrixND& + addTensorProduct(const VecA& V, const VecB& W, const double scale); + + template void + addMatrixProduct(const MatrixND &, const MatT&, double scale); + + // += A'B + template void + addMatrixTransposeProduct(double thisFact, const MatrixND &, const MatT&, double scale); + + // += A'BA + template int + addMatrixTripleProduct(double thisFact, + const MatrixND &, + const MatrixND&, + double scale); + + // += A'BC + template int + addMatrixTripleProduct(double thisFact, + const MatrixND &A, + const MatrixND &B, + const MatrixND &C, double otherFact); + + template void map(F func) const; + template void map(F func, MatrixND& destination); + + int invert(MatrixND &) const; + int invert() { + return Matrix(*this).Invert(); + } + + template MatrixND& addSpin(const VecT& V); + template MatrixND& addSpin(const VecT& V, double scale); + template MatrixND& addSpinSquare(const VecT& V, double scale); + template void addSpinProduct(const VecT& a, const VectorND& b, double scale); + template void addMatrixSpinProduct(const MatrixND& A, const VecT& b, double scale); + template void addSpinMatrixProduct(const VectorND& a, const MatT& B, double scale); + +//template +//void addSpinAtRow(const VecT& V, size_t row_index); +//template +//void addSpinAtRow(const VecT& V, size_t vector_index, size_t matrix_row_index); +//template +//MatrixND& addSpin(const VecT& V, double mult) requires(NR == 3); +//template +//void addSpinAtRow(const VecT& V, double mult, size_t row_index); +//template +//void addSpinAtRow(const VecT& V, double mult, size_t vector_index, size_t matrix_row_index); + + // + // Indexing + // + constexpr std::array & + operator[](index_t index) {return values[index];} + + constexpr const std::array & // [i] indexing + operator[](index_t index) const {return values[index];} + + // (i,j) indexing + constexpr T & + operator()(index_t index_r, index_t index_c) { + assert(index_r >= 0 && index_c >= 0); + assert(index_r < NR && index_c < NC); + return values[index_c][index_r]; + } + + inline constexpr const T & + operator()(index_t index_r, index_t index_c) const { + assert(index_r >= 0 && index_c >= 0); + assert(index_r < NR && index_c < NC); + return values[index_c][index_r]; + } + + // + // + // + consteval void zero() { + for (index_t j = 0; j < NC; ++j) { + for (index_t i = 0; i < NR; ++i) { + values[j][i] = 0.0; + } + } + } + + constexpr MatrixND + transpose() const { + MatrixND result = {}; + for (index_t j = 0; j < NC; ++j) { + for (index_t i = 0; i < NR; ++i) { + result.values[i][j] = values[j][i]; + } + } + return result; + } + + constexpr T + trace() const + requires(NR == NC) + { + T sum = 0.0; + for (index_t i = 0; i < NR; ++i) { + sum += values[i][i]; + } + return sum; + } + + constexpr T + determinant() const + requires(NR == NC && NR == 2) + { + return values[0][0] * values[1][1] - values[0][1] * values[1][0]; + } + + int solve(const VectorND &V, VectorND &res) const + requires(NR == NC) + { + MatrixND work = *this; + int pivot_ind[NR]; + int nrhs = 1; + int nr = NR; + int nc = NC; + int info = 0; + res = V; // X will be overwritten with the solution + DGESV(&nr, &nrhs, &work.values[0][0], &nr, pivot_ind, res.values, &nc, &info); + return -abs(info); + } + + int solve(const Vector &V, Vector &res) const + requires(NR == NC) + { + + MatrixND work = *this; + int pivot_ind[NR]; + int nrhs = 1; + int nr = NR; + int nc = NC; + int info = 0; + res = V; // X will be overwritten with the solution + DGESV(&nr, &nrhs, &work.values[0][0], &nr, &pivot_ind[0], res.theData, &nc, &info); + return -abs(info); + } + +//template + int + solve(const Matrix &M, Matrix &res) + { + Matrix slver(*this); + return slver.Solve(M, res); + + MatrixND work = *this; + int pivot_ind[NR]; + int nrhs = M.noCols(); + int nr = NR; + int nc = NC; + int info = 0; + res = M; // M will be overwritten with the solution + DGESV(&nr, &nrhs, &work(0,0), &nr, &pivot_ind[0], &res(0,0), &nc, &info); + return -abs(info); + } + + + template + inline MatrixND + extract() const + { + MatrixND m; + for (int i=0; i + inline MatrixND + extract(int row0, int col0) const + { + MatrixND m; + for (int i=0; i inline void + insert(const MatrixND &M, double fact) + { + + [[maybe_unused]] int final_row = init_row + nr - 1; + [[maybe_unused]] int final_col = init_col + nc - 1; + assert((init_row >= 0) && (final_row < NR) && (init_col >= 0) && (final_col < NC)); + + for (int i=0; i inline void + insert(const MatrixND &M, int init_row, int init_col, double fact) + { + + [[maybe_unused]] int final_row = init_row + nr - 1; + [[maybe_unused]] int final_col = init_col + nc - 1; + assert((init_row >= 0) && (final_row < NR) && (init_col >= 0) && (final_col < NC)); + + for (int i=0; i inline void + assemble(const MatrixND &M, int init_row, int init_col, double fact) + { + + [[maybe_unused]] int final_row = init_row + nr - 1; + [[maybe_unused]] int final_col = init_col + nc - 1; + assert((init_row >= 0) && (final_row < NR) && (init_col >= 0) && (final_col < NC)); + + for (int i=0; i inline void + assemble(const VectorND &v, int init_row, int init_col, double fact) + { + + [[maybe_unused]] int final_row = init_row + nr - 1; + assert((init_row >= 0) && (final_row < NR)); + + for (int j=0; j void + assembleTranspose(const MatrixND &M, int init_row, int init_col, double fact) + { + { + [[maybe_unused]] int final_row = init_row + nc - 1; + [[maybe_unused]] int final_col = init_col + nr - 1; + assert((init_row >= 0) && (final_row < NR) && (init_col >= 0) && (final_col < NC)); + } + + for (int i=0; i void + assembleTranspose(const VectorND &v, int init_row, int init_col, double scale) + { + { + [[maybe_unused]] int final_col = init_col + nr - 1; + assert((init_row >= 0) && (init_col >= 0) && (final_col < NC)); + } + + for (int i=0; i &other) + { + for (index_t j = 0; j < NC; ++j) { + for (index_t i = 0; i < NR; ++i) { + values[j][i] = other.values[j][i]; + } + } + return *this; + } +*/ + + constexpr MatrixND & + operator+=(const double value) { + for (index_t j = 0; j < NC; ++j) { + for (index_t i = 0; i < NR; ++i) { + values[j][i] += value; + } + } + return *this; + } + + constexpr MatrixND & + operator+=(const MatrixND &other) { + for (index_t j = 0; j < NC; ++j) { + for (index_t i = 0; i < NR; ++i) { + values[j][i] += other.values[j][i]; + } + } + return *this; + } + + constexpr MatrixND & + operator-=(const MatrixND &other) { + for (index_t j = 0; j < NC; ++j) + for (index_t i = 0; i < NR; ++i) + values[j][i] -= other.values[j][i]; + + return *this; + } + + constexpr MatrixND & + operator*=(T const scalar) { + for (index_t j = 0; j < NC; ++j) + for (index_t i = 0; i < NR; ++i) + values[j][i] *= scalar; + + return *this; + } + + constexpr MatrixND & + operator/=(T const scalar) { + for (index_t j = 0; j < NC; ++j) + for (index_t i = 0; i < NR; ++i) + values[j][i] /= scalar; + + return *this; + } + + +// Notes on operators: +// - define friend operators inside class for use as header-only library + friend constexpr MatrixND + operator+(MatrixND left, const MatrixND &right) { + left += right; + return left; + } + + friend constexpr MatrixND + operator-(MatrixND left, const MatrixND &right) { + left -= right; + return left; + } + + friend constexpr MatrixND // scalar * Matrix + operator*(T scalar, MatrixND mat) { + mat *= scalar; + return mat; + } + + friend constexpr MatrixND // Matrix * scalar + operator*(MatrixND mat, T scalar) { + mat *= scalar; + return mat; + } + + template + inline constexpr friend MatrixND + operator*(const MatrixND &left, const MatrixND &right) { + MatrixND prod; + for (index_t i = 0; i < NR; ++i) { + for (index_t j = 0; j < J; ++j) { + prod(i, j) = 0.0; + for (index_t k = 0; k < NC; ++k) { + prod(i, j) += left(i,k) * right(k,j); + } + } + } + return prod; + } + + template + inline constexpr friend MatrixND + operator^(const MatrixND &left, const MatrixND &right) { + MatrixND prod; + for (index_t i = 0; i < NC; ++i) { + for (index_t j = 0; j < K; ++j) { + prod(i, j) = 0.0; + for (index_t k = 0; k < NR; ++k) { + prod(i, j) += left(k,i) * right(k,j); + } + } + } + return prod; + } + + VectorND + operator^(const VectorND &V) const + { + VectorND result; + + const double *dataPtr = &values[0][0]; + for (int i=0; i + operator*(const MatrixND &left, const VectorND &right) { + VectorND prod; + for (index_t i = 0; i < NR; ++i) { + prod[i] = 0.0; + for (index_t k = 0; k < NC; ++k) { + prod[i] += left(i,k) * right[k]; + } + } + return prod; + } +#endif + + friend VectorND + operator*(const MatrixND &left, const Vector &right) { + VectorND prod; + for (index_t i = 0; i < NR; ++i) { + prod[i] = 0.0; + for (index_t k = 0; k < NC; ++k) { + prod[i] += left(i,k) * right(k); + } + } + return prod; + } + + + template + friend MatrixND + operator*(const MatrixND &left, const Matrix &right) { + MatrixND prod; + for (index_t i = 0; i < NR; ++i) { + for (index_t j = 0; j < J; ++j) { + prod(i, j) = 0.0; + for (index_t k = 0; k < NC; ++k) { + prod(i, j) += left(i,k) * right(k,j); + } + } + } + return prod; + } + + friend constexpr MatrixND + operator/(MatrixND mat, T scalar) { + mat /= scalar; + return mat; + } + + friend std::ostream & + operator<<(std::ostream &out, MatrixND const &mat) { + out << "{"; + for (int r=0; r +template inline void +MatrixND::map(F func) const +{ + for (int i=0; i +template inline void +MatrixND::map(F func, MatrixND& destination) +{ + for (int i=0; i inline int +template inline int +MatrixND::invert(MatrixND &M) const +{ + static_assert(nr == nc, "Matrix must be square"); + static_assert(nr > 1 && nr < 7, "Matrix must be between 2x2 and 6x6"); + + int status = -1; + if constexpr (nr == 2) { + cmx_inv2(&this->values[0][0], &M.values[0][0], &status); + return status; + } + if constexpr (nr == 3) { + cmx_inv3(&this->values[0][0], &M.values[0][0], &status); + return status; + } + if constexpr (nr == 4) { + cmx_inv4(&this->values[0][0], &M.values[0][0], &status); + return status; + } + if constexpr (nr == 5) { + cmx_inv5(&this->values[0][0], &M.values[0][0], &status); + return status; + } + if constexpr (nr == 6) { + cmx_inv6(&this->values[0][0], &M.values[0][0], &status); + return status; + } + return status; +} + +template inline +MatrixND& +MatrixND::addDiagonal(const double diag) +{ + for (int i=0; i +template inline +void MatrixND::addMatrix(const MatT& A, const double scale) +{ + for (int i=0; i +template +constexpr inline +MatrixND& +MatrixND::addTensorProduct(const VecA& a, const VecB& b, const double scale) +{ + // Chrystal's bun order + for (int j=0; j +template inline +void +MatrixND::addMatrixProduct(const MatrixND& A, const MatT& B, const double scale) +{ + for (int i=0; i +template inline +void +MatrixND::addMatrixTransposeProduct(double thisFact, + const MatrixND& B, + const MatT& C, + const double otherFact) +{ + if (thisFact == 1.0) { + double *aijPtr = &values[0][0]; + for (int j=0; j +template inline +int +MatrixND::addMatrixTripleProduct( + double thisFact, + const MatrixND &T, + const MatrixND &B, + double otherFact) + requires(nr == nc) +{ + if (otherFact == 0.0 && thisFact == 1.0) + return 0; + + MatrixND BT; + BT.zero(); + BT.addMatrixProduct(B, T, otherFact); + this->addMatrixTransposeProduct(thisFact, T, BT, 1.0); + +//{ +// int m = B.numRows, +// n = T.numCols, +// k = B.numCols, +// nrT = T.numRows; +// //k = T.numRows; +// double zero = 0.0, +// one = 1.0; + +// DGEMM ("N", "N", &m , &n , &k,&one , B.data, &m, // m +// T.data, &nrT, // k +// &zero, matrixWork, &m); + +// DGEMM ("T", "N", &numRows, &numCols, &k,&otherFact, T.data, &nrT, +// matrixWork, &m, // k +// &thisFact, data, &numRows); +// return 0; +//} + + return 0; +} + + +template +template inline int +MatrixND::addMatrixTripleProduct(double thisFact, + const MatrixND &A, + const MatrixND &B, + const MatrixND &C, double otherFact) +{ + + if (otherFact == 0.0 && thisFact == 1.0) + return 0; + + MatrixND BC {}; + BC.addMatrixProduct(B, C, otherFact); + this->addMatrixTransposeProduct(thisFact, A, BC, 1.0); + return 0; +} + + +template +MatrixND(const T (&)[nc][nr])->MatrixND; + + +// +// 3D +// + +template +template +inline MatrixND& +MatrixND::addSpin(const VecT& v) requires(NR == 3) +{ + const double v0 = v[0], + v1 = v[1], + v2 = v[2]; + + (*this)(0, 0) += 0.0; (*this)(0, 1) += -v2; (*this)(0, 2) += v1; + (*this)(1, 0) += v2; (*this)(1, 1) += 0.0; (*this)(1, 2) += -v0; + (*this)(2, 0) += -v1; (*this)(2, 1) += v0; (*this)(2, 2) += 0.0; + + return *this; +} + + +template +template +inline MatrixND& +MatrixND::addSpin(const VecT& v, double mult) +{ + const double v0 = mult*v[0], + v1 = mult*v[1], + v2 = mult*v[2]; + + (*this)(0, 0) += 0.0; (*this)(0, 1) += -v2; (*this)(0, 2) += v1; + (*this)(1, 0) += v2; (*this)(1, 1) += 0.00; (*this)(1, 2) += -v0; + (*this)(2, 0) += -v1; (*this)(2, 1) += v0; (*this)(2, 2) += 0.0; + return *this; +} + + +template +template inline +MatrixND& +MatrixND::addSpinSquare(const VecT& v, const double scale) + requires(NR == NC == 3) +{ + const double v1 = v[0], + v2 = v[1], + v3 = v[2]; + + (*this)(0,0) += scale*( -v2*v2 - v3*v3 ); + (*this)(1,1) += scale*( -v1*v1 - v3*v3 ); + (*this)(2,2) += scale*( -v1*v1 - v2*v2 ); + + (*this)(0,1) += scale*( v1*v2 ); + (*this)(1,0) += scale*( v1*v2 ); + (*this)(2,0) += scale*( v1*v3 ); + (*this)(0,2) += scale*( v1*v3 ); + (*this)(1,2) += scale*( v2*v3 ); + (*this)(2,1) += scale*( v2*v3 ); + return *this; +} + + +template +template inline +void MatrixND::addSpinProduct(const VecT& a, const VectorND& b, const double scale) + requires(NR == NC == 3) +{ + // a^b^ = boa - a.b 1 + // where 'o' denotes the tensor product and '.' the dot product + // + this->addTensorProduct(b, a, scale); + this->addDiagonal(-b.dot(a)*scale); +} + +template +template inline +void MatrixND::addMatrixSpinProduct(const MatrixND& A, const VecT& b, const double scale) +{ + // this += s*A*[b^] + // where b^ is the skew-symmetric representation of the three-vector b, s is a scalar, + // and A a 3x3 matrix. + // + (*this)(0, 0) += scale*( A(0,1)*b[2] - A(0,2)*b[1]); + (*this)(0, 1) += scale*(-A(0,0)*b[2] + A(0,2)*b[0]); + (*this)(0, 2) += scale*( A(0,0)*b[1] - A(0,1)*b[0]); + (*this)(1, 0) += scale*( A(1,1)*b[2] - A(1,2)*b[1]); + (*this)(1, 1) += scale*(-A(1,0)*b[2] + A(1,2)*b[0]); + (*this)(1, 2) += scale*( A(1,0)*b[1] - A(1,1)*b[0]); + (*this)(2, 0) += scale*( A(2,1)*b[2] - A(2,2)*b[1]); + (*this)(2, 1) += scale*(-A(2,0)*b[2] + A(2,2)*b[0]); + (*this)(2, 2) += scale*( A(2,0)*b[1] - A(2,1)*b[0]); +} + +template +template inline +void MatrixND::addSpinMatrixProduct(const VectorND& a, const MatT& B, const double scale) + requires(NR == NC == 3) +{ + // this += s*[a^]*B + // where a^ is the skew-symmetric representation of the three-vector a, s is a scalar, + // and B a 3x3 matrix. + // + (*this)(0, 0) += scale*( -B(1,0)*a[2] + B(2,0)*a[1]); + (*this)(0, 1) += scale*( -B(1,1)*a[2] + B(2,1)*a[1]); + (*this)(0, 2) += scale*( -B(1,2)*a[2] + B(2,2)*a[1]); + (*this)(1, 0) += scale*( B(0,0)*a[2] - B(2,0)*a[0]); + (*this)(1, 1) += scale*( B(0,1)*a[2] - B(2,1)*a[0]); + (*this)(1, 2) += scale*( B(0,2)*a[2] - B(2,2)*a[0]); + (*this)(2, 0) += scale*( -B(0,0)*a[1] + B(1,0)*a[0]); + (*this)(2, 1) += scale*( -B(0,1)*a[1] + B(1,1)*a[0]); + (*this)(2, 2) += scale*( -B(0,2)*a[1] + B(1,2)*a[0]); +} + +} // namespace OpenSees + +#endif // MatrixND_H + From 1320686bab84bb08eabc6c0f4639b476b1df733a Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 081/261] add Rotations.hpp --- SRC/matrix/Rotations.hpp | 666 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 666 insertions(+) create mode 100755 SRC/matrix/Rotations.hpp diff --git a/SRC/matrix/Rotations.hpp b/SRC/matrix/Rotations.hpp new file mode 100755 index 0000000000..0a714924c4 --- /dev/null +++ b/SRC/matrix/Rotations.hpp @@ -0,0 +1,666 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Functions related to exponential coordinates on SO(3). The implementation +// follows value semantics with the expectation that RVO will make this +// performant. +// +// Written: cmp +// +// [1] Perez, C. M., and Filippou F. C. (2024) "On Nonlinear Geometric +// Transformations of Finite Elements" +// Int. J. Numer. Meth. Engrg. https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// +#pragma once + +#include +#include +#include "Versor.h" +#include "Matrix3D.h" +#include "Vector3D.h" +using OpenSees::Matrix3D; + + +#define cot(x) std::cos(x)/std::sin(x) + +static constexpr Matrix3D Eye3 {{ + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1} +}}; + + +static inline Vector3D +Vee(const Matrix3D &X) +{ +//===----------------------------------------------------------------------===// +// Return the axial vector x of the given skew-symmetric 3x3 matrix X. +//===----------------------------------------------------------------------===// + return {X(2,1), X(0,2), X(1,0)}; +} + +template +inline constexpr Matrix3D +Hat(const Vec3Type &u) +{ + return Matrix3D {{{ 0 , u[2], -u[1]}, + {-u[2], 0 , u[0]}, + { u[1], -u[0], 0 }}}; +} + +static inline void +GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) +{ +// +// Compute coefficients of the Rodrigues formula and their differentials. +// +// [1,2] | [3] +// ----------+------- +// a1 | +// a2 | c4 +// a3 | c5 +// +// b1 = -c0 | c1 +// b2 | c2 +// b3 | c3 +// +// +// [2] Ritto-Corrêa, M. and Camotim, D. (2002) "On the differentiation of the +// Rodrigues formula and its significance for the vector-like parameterization +// of Reissner-Simo beam theory" +// Int. J. Numer. Meth. Engrg., 55(9), pp. +// 1005–1032. Available at: https://doi.org/10.1002/nme.532. +// +// [3] Ibrahimbegović, A. and Mikdad, M.A. (1998) ‘Finite rotations in dynamics of +// beams and implicit time‐stepping’, 41, pp. 781–814. +// +// [4] Pfister, F. (1998) ‘Bernoulli Numbers and Rotational Kinematics’, +// Journal of Applied Mechanics, 65(3), pp. 758–763. +// Available at: https://doi.org/10.1115/1.2789120. +// +// --------------------------------------------------------------------------- +// Written: cmp 2023 +//===----------------------------------------------------------------------===// +// + double angle2 = vec.dot(vec); + + if (angle2 <= 1e-07) { + // + // Use series formula of Equation (A9) from [1] + // + if (a != nullptr) { + a[0] = 0.0; + a[1] = 1.0 - angle2*(1.0/6.0 - angle2*(1.0/120.0 - angle2/5040.0)); + a[2] = 0.5 - angle2*(1.0/24.0 - angle2*(1.0/720.0 - angle2/40320.0)); + a[3] = 1.0/6.0 - angle2/(1.0/120.0 - angle2/(1.0/5040.0 - angle2/362880.0)); + } + if (b != nullptr) { + b[1] = - 1.0/3.0 + angle2*(1.0/30.0 - angle2*(1.0/840.0 - angle2/45360.0)); + b[2] = - 1.0/12.0 + angle2*(1.0/180.0 - angle2*(1.0/6720.0 - angle2/453600.0)); + b[3] = - 1.0/60.0 + angle2*(1.0/1260.0 - angle2*(1.0/60480 - angle2/4989600.0)); + } + if (c != nullptr) { + c[1] = b[3] - b[2]; + c[2] = 1.0/90.0 - angle2*(1.0/1680.0 - angle2*(1.0/75600.0 - angle2/5987520.0)); + c[3] = 1.0/630.0 - angle2*(1.0/15120.0 - angle2*(1.0/831600.0 - angle2/77837760.0)); + } + + } else { + // + // Use formulas of Equation (A8) from [1] + // + + double angle = vec.norm(); +// double angle = sqrt(angle2); + double sn = std::sin(angle); + double cs = std::cos(angle); + double angle3 = angle*angle2; + double angle4 = angle*angle3; + double angle5 = angle*angle4; +// double angle6 = angle*angle5; + + if (a != nullptr) { + a[0] = cs; + a[1] = sn / angle; + a[2] = ( 1.0 - a[0] ) / angle2; + // a[3] = ( 1.0 - a[1] ) / angle2; + a[3] = (angle - sn)/(angle3); + } + + if (b != nullptr) { + b[1] = ( angle*cs - sn)/angle3; + b[2] = ( angle*sn - 2 + 2*cs)/angle4; + b[3] = ( 3*sn - 2*angle - angle*cs )/angle5; + } + if (c != nullptr) { + c[1] = (3.*sn - angle2*sn - 3.*angle*cs)/(angle5); + c[2] = (8. - 8.*cs - 5.*angle*sn + angle2*cs)/(angle5*angle); + c[3] = (8.*angle + 7.*angle*cs + angle2*sn - 15.*sn)/(angle5*angle2); + } + } +} + +// +// Rotation Conversions +// + +static inline Vector3D +CayleyFromVersor(const Versor &q) +{ + const double q0 = q.scalar; + + Vector3D w; + for (int i = 0; i < 3; i++) + w[i] = 2.0 * q.vector[i]/q0; + + return w; +} + + +static inline Versor +VersorProduct(const Versor &qa, const Versor &qb) +{ + const double qa0 = qa.vector[0], + qa1 = qa.vector[1], + qa2 = qa.vector[2], + qa3 = qa.scalar, + // + qb0 = qb.vector[0], + qb1 = qb.vector[1], + qb2 = qb.vector[2], + qb3 = qb.scalar; + + // Dot product qa.qb + const double qaTqb = qa0*qb0 + qa1*qb1 + qa2*qb2; + + // Cross-product qa x qb + const double + qaxqb0 = qa1*qb2 - qa2*qb1, + qaxqb1 = qa2*qb0 - qa0*qb2, + qaxqb2 = qa0*qb1 - qa1*qb0; + + // + Versor q12; + q12.vector[0] = qa3*qb0 + qb3*qa0 - qaxqb0; + q12.vector[1] = qa3*qb1 + qb3*qa1 - qaxqb1; + q12.vector[2] = qa3*qb2 + qb3*qa2 - qaxqb2; + q12.scalar = qa3*qb3 - qaTqb; + return q12; +} + + +// R = (q0^2 - q' * q)*I + 2 * q * q' + 2*q0*S(q); +static inline Matrix3D +MatrixFromVersor(const Versor &q) +{ + Matrix3D R{}; + + const double factor = q.scalar*q.scalar - q.vector.dot(q.vector); + + for (int i = 0; i < 3; i++) + R(i,i) = factor; + + R.addTensorProduct(q.vector, q.vector, 2.0); + R.addSpin(q.vector, 2.0*q.scalar); + + return R; +} + + +// Form rotation axis vector from a quaternion +static inline Vector3D +VectorFromVersor(const Versor& q) +{ + // Initialize to zero + Vector3D theta{}; + + double q0 = q.scalar; + + // Norm of the vector part + double qn = q.vector.norm(); + + const double* const qv = &q.vector[0]; + + // Return zero-vector + if (qn == 0) + return theta; + + double factor = 1.0; + if (q0 < 0) { + q0 = -q0; + factor = -1.0; + } + + if (qn < q0) + factor *= 2.0*std::asin(qn)/qn; + else + factor *= 2.0*std::acos(q0)/qn; + + + for (int i=0; i<3; i++) + theta[i] = qv[i]*factor; + + return theta; + +} + +static inline Versor +VersorFromMatrix(const Matrix3D &R) +{ + //===--------------------------------------------------------------------===// + // Form a normalised quaternion (Versor) from a proper orthogonal matrix + // using Spurrier's algorithm + //===--------------------------------------------------------------------===// + Versor q; + + // Trace of the rotation R + const double trR = R(0,0) + R(1,1) + R(2,2); + + // a = max([trR R(0,0) R(1,1) R(2,2)]); + double a = trR; + for (int i = 0; i < 3; i++) + if (R(i,i) > a) + a = R(i,i); + + if (a == trR) { + q.scalar = std::sqrt(1.0 + a)*0.5; + + for (int i = 0; i < 3; i++) { + int j = (i+1)%3; + int k = (i+2)%3; + q.vector[i] = (R(k,j) - R(j,k))/(4.0*q.scalar); + } + } + else { + for (int i = 0; i < 3; i++) + if (a == R(i,i)) { + int j = (i+1)%3; + int k = (i+2)%3; + + q.vector[i] = sqrt(a*0.5 + (1.0 - trR)/4.0); + q.scalar = (R(k,j) - R(j,k))/(4.0*q.vector[i]); + q.vector[j] = (R(j,i) + R(i,j))/(4.0*q.vector[i]); + q.vector[k] = (R(k,i) + R(i,k))/(4.0*q.vector[i]); + } + } + return q; +} + + +// +// Exponential Map +// +static inline Matrix3D +ExpSO3(const Vector3D &theta) +{ + //===--------------------------------------------------------------------===// + + // Form the first Gib coefficients + double a[4]; + GibSO3(theta, a); + + Matrix3D R = Eye3; + R.addSpin(theta, a[1]); + R.addSpinSquare(theta, a[2]); + return R; +} + + +static inline Matrix3D +CaySO3(const Vector3D &cayley) +{ + // Cayley map for a rotation matrix given the "tangent-scaled pseudo-vector" + // + // R = I + (S + S*S/2)/(1 + w' * w / 4); + // + //===--------------------------------------------------------------------===// + + const double c = 1.0/(1.0 + cayley.dot(cayley)/4.0); + + Matrix3D R; + R.zero(); + R.addDiagonal(1.0); + R.addSpin(cayley, c); + R.addSpinSquare(cayley, 0.5*c); + + return R; +} + + + +// +// Exponential Differentials +// + +inline Matrix3D +TanSO3(const Vector3D &vec, char repr='L') +{ + // + // Compute right or left differential of the exponential. + // + //===--------------------------------------------------------------------===// + // function by Claudio Perez 2023 + //===--------------------------------------------------------------------===// + double a[4]; + GibSO3(vec, a); + + Matrix3D T; + + // Assemble differential + switch (repr) { + case 'R': + T(0,0) = a[1] + a[3]*vec[0]*vec[0]; + T(0,1) = -vec[2]*a[2] + a[3]*vec[0]*vec[1]; + T(0,2) = vec[1]*a[2] + a[3]*vec[0]*vec[2]; + T(1,0) = vec[2]*a[2] + a[3]*vec[1]*vec[0]; + T(1,1) = a[1] + a[3]*vec[1]*vec[1]; + T(1,2) = -vec[0]*a[2] + a[3]*vec[1]*vec[2]; + T(2,0) = -vec[1]*a[2] + a[3]*vec[2]*vec[0]; + T(2,1) = vec[0]*a[2] + a[3]*vec[2]*vec[1]; + T(2,2) = a[1] + a[3]*vec[2]*vec[2]; + return T; + + case 'L': + default: + T(0,0) = a[1] + a[3]*vec[0]*vec[0]; + T(0,1) = vec[2]*a[2] + a[3]*vec[1]*vec[0]; + T(0,2) = -vec[1]*a[2] + a[3]*vec[2]*vec[0]; + T(1,0) = -vec[2]*a[2] + a[3]*vec[0]*vec[1]; + T(1,1) = a[1] + a[3]*vec[1]*vec[1]; + T(1,2) = vec[0]*a[2] + a[3]*vec[2]*vec[1]; + T(2,0) = vec[1]*a[2] + a[3]*vec[0]*vec[2]; + T(2,1) = -vec[0]*a[2] + a[3]*vec[1]*vec[2]; + T(2,2) = a[1] + a[3]*vec[2]*vec[2]; + return T; + + } +} + + +inline Matrix3D +dExpSO3(const Vector3D &v) +{ +// Compute the right differential of the exponential on SO(3) using the formula in +// Equation (A11) in [1]: +// +// T = a[1]*Eye3 + a[2]*v.hat() + a[3]*v.bun(v); +// +// ========================================================================================= +// function by Claudio Perez 2023 +// ----------------------------------------------------------------------------------------- + + // Form first Gib coefficients + double a[4]; + GibSO3(v, a); + + Matrix3D T{}; + T.addDiagonal(a[1]) + .addSpin(v, a[2]) + .addTensorProduct(v, v, a[3]); + + return T; +} + + +inline Matrix3D +ddTanSO3(const Vector3D &v, const Vector3D &p, const Vector3D &q) +{ + // + // return a[3]*psq + b[1]*p.dot(q)*Eye3 + // + b[2]*(pxq.bun(v) + v.bun(pxq) + vxp.dot(q)*Eye3) + // + b[3]*( v.dot(p)*(q.bun(v) + v.bun(q)) + // + v.dot(q)*(p.bun(v) + v.bun(p)) + // + v.dot(p)*v.dot(q)*Eye3) + // + vov*(c[1]*p.dot(q) + c[2]*(vxp.dot(q)) + c[3]*v.dot(p)*v.dot(q)); + // + // ========================================================================================= + // function by Claudio Perez 2023 + // ----------------------------------------------------------------------------------------- + // + double a[4], b[4], c[4]; + GibSO3(v, a, b, c); + + const Vector3D pxq = p.cross(q); + const Vector3D vxp = v.cross(p); + + Matrix3D dT{}; + + dT.addTensorProduct(p, q, a[3]) + .addTensorProduct(q, p, a[3]) + .addDiagonal(b[1]*p.dot(q)) + .addTensorProduct(pxq, v, b[2]) + .addTensorProduct(v, pxq, b[2]) + .addDiagonal(vxp.dot(q)*b[2]) + + .addTensorProduct(q, v, b[3]*v.dot(p)) + .addTensorProduct(v, q, b[3]*v.dot(p)) + .addTensorProduct(p, v, b[3]*v.dot(q)) + .addTensorProduct(v, p, b[3]*v.dot(q)) + .addDiagonal(v.dot(p)*v.dot(q)*b[3]) + + .addTensorProduct(v, v, c[1]*p.dot(q) + c[2]*(vxp.dot(q)) + c[3]*v.dot(p)*v.dot(q)); + + return dT; +} + + + +inline Matrix3D +dTanSO3(const Vector3D &v, const Vector3D &p, char repr='L') +{ + // Tangents of the right and left exponential differentials using Equations (A13) and (A14), + // respectively from [1]. + // + // repr 'L' or 'R' indicating left or right representation, + // respectively, for the tangent space of SO(3) + // ========================================================================================= + // function by Claudio Perez 2023 + // ----------------------------------------------------------------------------------------- + + + double a[4], b[4]; + GibSO3(v, a, b); + + Matrix3D Xi{}; + Xi.addSpin(p, a[2]*(repr == 'R' ? -1.0 : 1.0)) + .addDiagonal(a[3]*v.dot(p)) + .addTensorProduct(v, p, a[3]) + .addTensorProduct(p, v, b[1]) + .addTensorProduct(v.cross(p), v, b[1]*(repr == 'R' ? 1.0 : -1.0)) + .addTensorProduct(v, v, v.dot(p)*b[2]); + return Xi; +} + + +inline Vector3D +LogSO3(const Matrix3D &R) +{ + //===--------------------------------------------------------------------===// + // + // Inverse of the exponential map on SO(3). + // + // Returns the axial parameters associated with the rotation `R`. The result + // should satisfy the following equality for any 3-vector, `v`: + // + // LogSO3(expm(Hat(v))) == v + // + // where `expm` is matrix exponential, and `Hat` is a function + // which produces the skew-symmetric 3x3 matrix associated with vector `v`. + // + // Parameters + // R (3x3) Rotation (proper orthogonal) matrix. + // + // + // References + // 1. Nurlanov Z (2021) Exploring SO(3) logarithmic map: degeneracies and + // derivatives. + // + //===--------------------------------------------------------------------===// + // function by Claudio Perez 2023 + //===--------------------------------------------------------------------===// + + return VectorFromVersor(VersorFromMatrix(R)); + +} + + +static inline Vector3D +LogC90(const Matrix3D &R) +{ + //===--------------------------------------------------------------------===// + // + // Crisfield M (1990) A consistent co-rotational formulation for non-linear, + // three-dimensional, beam-elements + // + //===--------------------------------------------------------------------===// + // function by Claudio Perez 2024 + //===--------------------------------------------------------------------===// + // Crisfield's approximation to the logarithm on SO(3) + + return Vector3D { + -std::asin(0.5*(R(1,2) - R(2,1))), + std::asin(0.5*(R(0,2) - R(2,0))), + -std::asin(0.5*(R(0,1) - R(1,0))), + }; +} + +static inline Vector3D +LogC90_Skew(const Matrix3D &R) +{ + //===--------------------------------------------------------------------===// + // + // Crisfield M (1990) A consistent co-rotational formulation for non-linear, + // three-dimensional, beam-elements + // + //===--------------------------------------------------------------------===// + // Crisfield's approximation to the logarithm on SO(3) + return Vector3D { + std::asin(0.5*(R(1,2) - R(2,1))), + std::asin(0.5*(R(0,1) - R(1,0))), + std::asin(0.5*(R(0,2) - R(2,0))), + }; +} + + +inline Matrix3D +dLogSO3(const Vector3D &v, double* a=nullptr) +{ +// +// d_R LogSO3(v) +// +// ========================================================================================= +// function by Claudio Perez 2023 +// ----------------------------------------------------------------------------------------- +// + constexpr double tol = 1./20.; + + double angle = v.norm(); + Vector3D u = v; + if (abs(angle) > M_PI/1.01) [[unlikely]] { + u -= 2.0*v/angle*double(floor(angle + M_PI))/2.0; + angle = u.norm(); + } + + double angle2 = angle*angle; + double angle3 = angle*angle2; + double angle4 = angle*angle3; + double angle5 = angle*angle4; + double angle6 = angle*angle5; + + double eta; + if (angle > tol) [[unlikely]] + eta = (1.0 - 0.5*angle*cot(0.5*angle))/angle2; + else + eta = 1./12. + angle2/720. + angle4/30240. + angle6/1209600.; + + Matrix3D dH = Eye3; + dH.addSpin(u, -0.5); + dH.addSpinSquare(u, eta); + return dH; + // return Eye3 - 0.5*Sv + eta*Sv*Sv; +} + +inline Matrix3D +ddLogSO3(const Vector3D& u, const Vector3D& v) +{ +// ========================================================================================= +// function by Claudio Perez 2023 +// ----------------------------------------------------------------------------------------- + + constexpr double tol = 1./20.; + double angle = u.norm(); + + Vector3D th = u; + if (abs(angle) > M_PI/1.01) [[unlikely]] { + th -= 2.0*u/angle*double(floor(angle + M_PI))/2.0; + angle = th.norm(); + } + + double angle2 = angle*angle; + double angle3 = angle*angle2; + double angle4 = angle*angle3; + double angle5 = angle*angle4; + double angle6 = angle*angle5; + + double eta, mu; + if (angle < tol) { + eta = 1./12. + angle2/720. + angle4/30240. + angle6/1209600.; + mu = 1./360. + angle2/7560. + angle4/201600. + angle6/5987520.; + } + else { + double an2 = angle/2.; + double sn = std::sin(an2); + double cs = std::cos(an2); + + eta = (sn - angle2*cs)/(angle2*sn); + mu = (angle*(angle + 2.*sn*cs) - 8.*sn*sn)/(4.*angle4*sn*sn); + } + + Matrix3D St2 = Hat(th); + St2 = St2*St2; + Matrix3D dH{}; // -0.5*Hat(v) + eta*(Eye3*th.dot(v) + th.bun(v) - 2.*v.bun(th)) + mu*St2*v.bun(th); + dH.addSpin(v, -0.5); + dH.addDiagonal( eta*th.dot(v)); + dH.addTensorProduct(th, v, eta); + dH.addTensorProduct(v, th, -2.0*eta); + dH.addMatrixProduct(St2, v.bun(th), mu);; + // dH += mu*St2*v.bun(th); + + return dH*dLogSO3(th); +} + +#if 0 + +class Align { +public: + Align(Vector3D& original, Vector3D& target) + : original(original), target(target) + { + } + + // Align a vector to another vector using the exponential map + static Vector3D + rot(const Vector3D &v, const Vector3D &target) + { + // e3 = r3 - (e1 + r1)*((r3^e1)*0.5); + // e2 = r2 - (e1 + r1)*((r2^e1)*0.5); + Vector3D axis = v.cross(target); + double angle = std::acos(v.dot(target)/(v.norm()*target.norm())); + + if (angle < 1e-10) return v; + + return ExpSO3(axis*angle)*v; + } + + private: + Vector3D original; + Vector3D target; +}; + +#endif \ No newline at end of file From eebd731e15275da86cad9fbb5fcb8213bed994dc Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 082/261] add VectorND.h --- SRC/matrix/VectorND.h | 248 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 SRC/matrix/VectorND.h diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h new file mode 100644 index 0000000000..88366db169 --- /dev/null +++ b/SRC/matrix/VectorND.h @@ -0,0 +1,248 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// +// Objectives: +// - little to no overhead above C-style arrays +// - value semantics; objects do not decay to pointers; +// +// This code is influenced by the following sources +// list initialization: +// - https://stackoverflow.com/questions/42068882/list-initialization-for-a-matrix-class +// +// style/practices +// - https://quuxplusone.github.io/blog/2021/04/03/static-constexpr-whittling-knife/ +// +// Operator overloading / semantics +// - https://stackoverflow.com/questions/9851188/does-it-make-sense-to-use-move-semantics-for-operator-and-or-operator/9851423#9851423 +// +// compile-time template restrictions/concepts: +// - https://codereview.stackexchange.com/questions/259038/compile-time-matrix-class +// (C++ 20) +// - https://github.com/calebzulawski/cotila/ +// (C++ 17) +// +//===----------------------------------------------------------------------===// +// +// Claudio Perez +// +#ifndef VectorND_H +#define VectorND_H +#include +#include +#include +// #include +// #include +#include +#include +#include "blasdecl.h" + +#if __cplusplus < 202000L +# define consteval +# define requires(X) +#endif + +namespace OpenSees { + +typedef int index_t; + +template struct MatrixND; + +template +requires(N > 0) +struct VectorND { + T values[N]; + + operator Vector() { return Vector(values, N);} + + template friend struct MatrixND; + + inline constexpr T& + operator[](index_t index) { + return values[index]; + } + + inline constexpr const T& + operator[](index_t index) const { + return values[index]; + } + + inline constexpr T& + operator()(index_t index) { + return values[index]; + } + + inline constexpr const T& + operator()(index_t index) const noexcept { + return values[index]; + } + + consteval int + size() const { + return N; + } + + + consteval inline void + fill(double value) { + for (T& item : values) + item = value; + } + + consteval inline void + zero() { + for (T& item : values ) + item = 0.0; + } + + template inline + constexpr T + dot(const VecT &other) const noexcept { + T sum = 0.0; + for (index_t i = 0; i < N; ++i) { + sum += values[i] * other[i]; + } + return sum; + } + + // Tensor product, also known as the "bun" product + template + constexpr inline OpenSees::MatrixND + bun(const VectorND &other) const { + if constexpr (N == 3 && nc == 3) + return OpenSees::MatrixND {{ + {values[0]*other[0], values[1]*other[0], values[2]*other[0]}, + {values[0]*other[1], values[1]*other[1], values[2]*other[1]}, + {values[0]*other[2], values[1]*other[2], values[2]*other[2]} + }}; + else { + OpenSees::MatrixND prod; + + for (index_t j = 0; j < other.size(); ++j) + for (index_t i = 0; i < this->size(); ++i) + prod(i,j) = values[i] * other.values[j]; + + return prod; + } + } + + constexpr double + norm() const noexcept { + return std::sqrt(std::fabs(this->dot(*this))); + } + + inline double normalize() { + double n = norm(); + + if (n != 0.0) + for (index_t i=0; i inline + VectorND &operator=(const VecT &right) noexcept { + for (index_t i=0; i< N; i++) + values[i] = right[i]; + return *this; + } + + inline + VectorND &operator/=(const double &right) { + for (index_t i=0; i< N; i++) + values[i] /= right; + return *this; + } + + inline + VectorND operator/(const double &right) const { + VectorND res(*this); + res /= right; + return res; + } + + inline constexpr + VectorND &operator*=(const double &right) noexcept{ + for (int i=0; i< N; i++) + values[i] *= right; + return *this; + } + + inline constexpr + VectorND operator*(const double &right) const noexcept { + VectorND res(*this); + res *= right; + return res; + } + + inline constexpr + VectorND &operator+=(const VectorND &right) noexcept { + for (int i=0; i< N; i++) + values[i] += right[i]; + return *this; + } + + VectorND &operator+=(const Vector &right) { + assert(right.Size() == N); + for (int i=0; i< N; i++) + values[i] += right[i]; + return *this; + } + + template + VectorND operator+(const VecT &right) const noexcept { + VectorND res {*this}; + res += right; + return res; + } + + template + constexpr inline + VectorND &operator-=(const VecT &right) noexcept { + for (int i=0; i< N; i++) + values[i] -= right[i]; + return *this; + } + + template + constexpr inline + VectorND operator-(const VecT &right) const noexcept { + VectorND res {*this}; + res -= right; + return res; + } + + // Return the cross product this vector with another vector, b. + template inline constexpr + void cross(const VecB& b, VecC& c) requires(N==3) const noexcept { + c[0] = values[1] * b[2] - values[2] * b[1]; + c[1] = values[2] * b[0] - values[0] * b[2]; + c[2] = values[0] * b[1] - values[1] * b[0]; + return c; + } + + + template inline constexpr + VectorND cross(const Vec3T& b) const noexcept requires(N==3) { + VectorND<3> c; + c[0] = values[1] * b[2] - values[2] * b[1]; + c[1] = values[2] * b[0] - values[0] * b[2]; + c[2] = values[0] * b[1] - values[1] * b[0]; + return c; + } +#include "VectorND.tpp" + +}; +} // namespace OpenSees + +template +inline OpenSees::VectorND +operator * (double a, const OpenSees::VectorND& b) { + return b * a; +} +#endif + From 5d93d4f09db57ef338590b145a1964711146f560 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 083/261] add VectorND.tpp --- SRC/matrix/VectorND.tpp | 358 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 SRC/matrix/VectorND.tpp diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp new file mode 100644 index 0000000000..82e0559c0e --- /dev/null +++ b/SRC/matrix/VectorND.tpp @@ -0,0 +1,358 @@ + + template inline void + assemble(const VectorND &v, double fact=1) + { + static_assert((ir >= 0) && ((ir + nr - 1) < N)); + + for (int j=0; j void + assemble(int a, const VectorND& v, double scale) noexcept + { + for (int i=0; i inline void + insert(const VectorND &v, double fact=1) + { + static_assert((ir >= 0) && ((ir + nr - 1) < N)); + + for (int j=0; j void + insert(int a, const VectorND& v, double scale) noexcept + { + for (int i=0; i + VectorND + extract(int a) noexcept + { + VectorND v; + for (int i=0; i &other, const T otherFact) + { + if (otherFact == 0.0 && thisFact == 1.0) + return 0; + + else if (thisFact == 1.0) { + // want: this += other * otherFact + double *dataPtr = values; + const double * otherDataPtr = other.values; + if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0 + for (int i=0; i + inline int + addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact) + { + // check the sizes are compatable + assert(NC == v.sz); + + // see if quick return + if (thisFact == 1.0 && otherFact == 0.0) + return 0; + + else { + int incr = 1, + i = N, + n = NC; + DGEMV("N", &i, &n, + &otherFact, + &m.values[0][0], &i, + v.theData, &incr, + &thisFact, + values, + &incr); + + return 0; + } + } + + template + inline int + addMatrixTransposeVector(double thisFact, const MatrixND &m, const Vector &v, double otherFact) + { + // check the sizes are compatable + assert(NR == v.sz); + + + if (thisFact == 1.0 && otherFact == 0.0) + return 0; + + else { + int incr = 1, + i = NR, + n = N; + DGEMV("T", &i, &n, + &otherFact, + &m.values[0][0], &i, + v.theData, &incr, + &thisFact, + values, &incr); + return 0; + } + } + + + + inline int + addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact) + { + // check the sizes are compatable + assert(N == m.noRows()); + assert(m.noCols() == v.sz); + + // see if quick return + if (thisFact == 1.0 && otherFact == 0.0) + return 0; + +#ifdef VECTOR_BLAS + else if (v.sz > 10) { + int incr = 1, + i = m.numRows, + n = m.numCols; + return + DGEMV("N", &i, &n, + &otherFact, + m.data, &i, + v.theData, &incr, + &thisFact, + values, &incr); + } +#endif + + else if (thisFact == 1.0) { + + // want: this += m * v * otherFact + if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0 + int otherSize = v.sz; + double *matrixDataPtr = m.data; + const double *otherDataPtr = v.theData; + for (int i=0; i Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 084/261] add Versor.h --- SRC/matrix/Versor.h | 125 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 SRC/matrix/Versor.h diff --git a/SRC/matrix/Versor.h b/SRC/matrix/Versor.h new file mode 100644 index 0000000000..ea43321b97 --- /dev/null +++ b/SRC/matrix/Versor.h @@ -0,0 +1,125 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +#pragma once +#include +#include + +struct Versor { + Vector3D vector; + double scalar; + + template + inline Vec3T + rotate(const Vec3T& u) const { + return u + 2.0 * vector.cross( scalar*u + vector.cross(u) ); + } + + inline Versor conjugate() const { + Versor c; + c.scalar = scalar; + c.vector = -1.0*vector; // element-wise negation + return c; + } + + inline Versor conj_mult(const Versor& other) const + { + // Equivalent to R_IJ = R_I.T @ R_J, + // i.e. q_IJ = conj(q_I)*q_J. + Versor out; + out.scalar = scalar * other.scalar + vector.dot(other.vector); + out.vector = (other.vector * scalar) - (vector * other.scalar) - vector.cross(other.vector); + return out; + } + + inline Versor mult_conj(const Versor& other) const + { + // Equivalent to R_IJ = R_I @ R_J^T, + // i.e. q_IJ = q_I * conj(q_J). + + // Versor out = *this; + // out *= other.conjugate(); + // return out; + + Versor out; + out.scalar = scalar * other.scalar + vector.dot(other.vector); + out.vector = (vector * other.scalar) + - (other.vector * scalar) + - vector.cross(other.vector); + return out; + } + + template + static inline Versor + from_vector(const Vec3T &theta) + { + + double t = 0.0; // theta.norm(); + for (int i=0; i<3; i++) + t += theta[i]*theta[i]; + + t = std::sqrt(t); + + Versor q; + if (t == 0) + q.vector.zero(); + + else { + const double factor = std::sin(t*0.5) / t; + for (int i = 0; i < 3; i++) + q.vector[i] = theta[i] * factor; + } + + q.scalar = std::cos(t*0.5); + + return q; + } +}; + +#if 1 +inline Versor +operator*(const Versor &qa, const Versor &qb) +{ + const double qa0 = qa.vector[0], + qa1 = qa.vector[1], + qa2 = qa.vector[2], + qa3 = qa.scalar, + qb0 = qb.vector[0], + qb1 = qb.vector[1], + qb2 = qb.vector[2], + qb3 = qb.scalar; + + // Calculate the dot product qa.qb + const double qaTqb = qa0*qb0 + qa1*qb1 + qa2*qb2; + + // Calculate the cross-product qa x qb + const double + qaxqb0 = qa1*qb2 - qa2*qb1, + qaxqb1 = qa2*qb0 - qa0*qb2, + qaxqb2 = qa0*qb1 - qa1*qb0; + + // Calculate the quaternion product + Versor q12; + q12.vector[0] = qa3*qb0 + qb3*qa0 - qaxqb0; + q12.vector[1] = qa3*qb1 + qb3*qa1 - qaxqb1; + q12.vector[2] = qa3*qb2 + qb3*qa2 - qaxqb2; + q12.scalar = qa3*qb3 - qaTqb; + return q12; +} +#else +inline Versor +operator* (const Versor& a, const Versor& b) +{ + return Versor{{ + a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3], + a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2], + a[0]*b[2] + a[2]*b[0] + a[3]*b[1] - a[1]*b[3], + a[0]*b[3] + a[3]*b[0] + a[1]*b[2] - a[2]*b[1] + }}; +} +#endif \ No newline at end of file From 99a2049b83732276d1a0475526940a4fdf82923f Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:27:57 -0700 Subject: [PATCH 085/261] add geomTransf.cpp --- SRC/runtime/commands/modeling/geomTransf.cpp | 459 ++++++++++++++----- 1 file changed, 355 insertions(+), 104 deletions(-) diff --git a/SRC/runtime/commands/modeling/geomTransf.cpp b/SRC/runtime/commands/modeling/geomTransf.cpp index f0656db02f..a8b78dcae1 100644 --- a/SRC/runtime/commands/modeling/geomTransf.cpp +++ b/SRC/runtime/commands/modeling/geomTransf.cpp @@ -1,18 +1,21 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // // Description: Geometric transformation command // // cmp // #include +#include #include #include +#include #include -#include #include #include @@ -20,54 +23,315 @@ #include #include #include -//#include #include #include -#include -#include -#include -// -// Create a coordinate transformation -// -int -TclCommand_addGeomTransf(ClientData clientData, Tcl_Interp *interp, int argc, - const char ** const argv) +#include +#include +int +TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, int argc, + const char ** const argv) { assert(clientData != nullptr); BasicModelBuilder *builder = static_cast(clientData); // Make sure there is a minimum number of arguments - if (argc < 2) { - opserr << G3_ERROR_PROMPT << "insufficient number of geomTransf arguments\n"; - opserr << " Expected: geomTransf type? tag? \n"; + if (argc < 3) { + opserr << OpenSees::PromptValueError << "insufficient number of arguments\n"; return TCL_ERROR; } int ndm = builder->getNDM(); - int ndf = builder->getNDF(); // number of degrees of freedom per node + + if (ndm != 2 && ndm != 3) + return TCL_ERROR; - // create 2d coordinate transformation - if ((ndm == 2 && ndf == 3) || (ndm == 2 && ndf == 4)) { + int tag; + const char *name = argv[1]; + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid tag\n"; + return TCL_ERROR; + } - int crdTransfTag; - Vector jntOffsetI(2), - jntOffsetJ(2); + FrameTransformBuilder& transform = *new FrameTransformBuilder(ndm, tag, name); + + // Parse orientation vector + int argi = 3; + bool parsed_xz = (ndm == 2); + int argxz = 0; + while (argi != argc) { + if (strcmp(argv[argi], "-jntOffset") == 0) { + argi++; + transform.offsets[1].zero(); + for (int i = 0; i < ndm; ++i) { + if (argi == argc || + Tcl_GetDouble(interp, argv[argi++], &transform.offsets[1][i]) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid offset at end I\n"; + return TCL_ERROR; + } + } + + transform.offsets[2].zero(); + for (int i = 0; i < ndm; ++i) { + if (argi == argc || + Tcl_GetDouble(interp, argv[argi++], &transform.offsets[2][i]) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid offset at end J\n"; + return TCL_ERROR; + } + } + } + + else if (strcmp(argv[argi], "-orient") == 0) { + // -orient {x y z} + argi++; + if (parsed_xz) { + opserr << OpenSees::PromptValueError + << "orientation already provided\n"; + return TCL_ERROR; + } + + if (argi == argc) { + opserr << OpenSees::PromptValueError + << "missing orientation vector\n"; + return TCL_ERROR; + } + + const char ** xzarg; + int xznum; + Tcl_SplitList(interp, argv[argi], &xznum, &xzarg); + if (xznum != 3) { + Tcl_Free((char *)xzarg); + opserr << OpenSees::PromptValueError + << "invalid orientation vector\n"; + return TCL_ERROR; + } + for (int i=0; i<3; ++i) + if (Tcl_GetDouble(interp, xzarg[i], &transform.vz[i]) != TCL_OK) { + opserr << OpenSees::PromptValueError << "failed to parse vecxz\n"; + return TCL_ERROR; + } + + Tcl_Free((char *)xzarg); + argi++; + parsed_xz = true; + } + + else if (strcmp(argv[argi], "-pull") == 0) { + // -pull iter|incr|init|default + argi++; + if (argi == argc) { + opserr << OpenSees::PromptValueError + << "missing pull type\n"; + return TCL_ERROR; + } + + if (strcmp(argv[argi], "iter") == 0) { + transform.offset_flags |= LogIter; + } else if (strcmp(argv[argi], "incr") == 0) { + transform.offset_flags |= LogIncr; + } else if (strcmp(argv[argi], "init") == 0) { + transform.offset_flags |= LogInit; + } else if (strcmp(argv[argi], "default") == 0) { + transform.offset_flags |= LogDefault; + } else { + opserr << OpenSees::PromptValueError + << "invalid pull type\n"; + return TCL_ERROR; + } + } + + else if (strcmp(argv[argi], "-offset-local") == 0) { + transform.offset_flags |= OffsetLocal; + argi++; + } + else if (strcmp(argv[argi], "-offset-length") == 0) { + transform.offset_flags |= OffsetNormalized; + argi++; + } + + else if (strcmp(argv[argi], "-offset") == 0) { + // -offset {1 {x y z}; 2 {x y z}} + argi++; + if (argi == argc) { + opserr << OpenSees::PromptValueError << "missing offset block.\n"; + return TCL_ERROR; + } + constexpr static const char * const offset_nodes[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9"}; + constexpr static int MAX_OFFSETS = sizeof(offset_nodes)/sizeof(offset_nodes[0]); + auto TclCommand_addOffset = [](ClientData cd, Tcl_Interp* interp, int oargc, const char** const oargv) ->int { + + FrameTransformBuilder* transform = static_cast(cd); + assert(transform != nullptr); + if (oargc < 2) { + opserr << OpenSees::PromptValueError + << "insufficient number of offset arguments\n"; + return TCL_ERROR; + } + int offset_tag; + if (Tcl_GetInt(interp, oargv[0], &offset_tag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid offset tag\n"; + return TCL_ERROR; + } + if (offset_tag < 1 || offset_tag > MAX_OFFSETS) { + opserr << OpenSees::PromptValueError + << "invalid offset tag\n"; + return TCL_ERROR; + } + if (oargc < 2) { + opserr << OpenSees::PromptValueError + << "missing offset vector\n"; + return TCL_ERROR; + } + + const char ** xzarg; + int xznum; + if (oargc == 2) + Tcl_SplitList(interp, oargv[1], &xznum, &xzarg); + else { + xznum = oargc - 1; + xzarg = oargv + 1; + } + + for (int i=0; ioffsets[offset_tag][i]) != TCL_OK) { + if (oargc == 2) + Tcl_Free((char *)xzarg); + opserr << OpenSees::PromptValueError + << "failed to parse offset vector\n"; + return TCL_ERROR; + } + if (oargc == 2) + Tcl_Free((char *)xzarg); + return TCL_OK; + }; + + for (int i=0; i\n"; + if (Tcl_Eval(interp, argv[argi]) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to parse offset block\n"; + return TCL_ERROR; + } else { + for (int i=0; i= argc) { + opserr << OpenSees::PromptValueError << "missing orientation vector\n"; return TCL_ERROR; } + const char ** xzarg; + int xznum; + Tcl_SplitList(interp, argv[argxz], &xznum, &xzarg); + if (xznum == 3) { + for (int i=0; i<3; ++i) + if (Tcl_GetDouble(interp, xzarg[i], &transform.vz[i]) != TCL_OK) { + Tcl_Free((char *)xzarg); + opserr << OpenSees::PromptValueError + << "Failed to parse vectxz\n"; + return TCL_ERROR; + } + argi++; + parsed_xz = true; + } + Tcl_Free((char *)xzarg); + } - int argi = 2; - if (Tcl_GetInt(interp, argv[argi++], &crdTransfTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid tag\n" - " Expected: geomTransf type? tag? <-jntOffset dXi? dYi? dXj? dYj?>\n"; + if (!parsed_xz) { + if (argxz+3 > argc) { + opserr << OpenSees::PromptValueError + << "missing orientation vector\n"; + return TCL_ERROR; + } + for (int i=0; i<3; i++) + if (Tcl_GetDouble(interp, argv[argxz++], &transform.vz[i]) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid vecxz component\n"; + return TCL_ERROR; + } + } + + if (builder->addTaggedObject(transform) != TCL_OK) + return TCL_ERROR; + + return TCL_OK; +} + + +int +TclCommand_addGeomTransf(ClientData clientData, Tcl_Interp *interp, int argc, + const char ** const argv) + +{ + if (TclCommand_addTransformBuilder(clientData, interp, argc, argv) != TCL_OK) + return TCL_ERROR; + + if (strcmp(argv[0], "transform") == 0) + return TCL_OK; + + + assert(clientData != nullptr); + BasicModelBuilder *builder = static_cast(clientData); + + + // Make sure there is a minimum number of arguments + if (argc < 3) { + opserr << OpenSees::PromptValueError + << "insufficient number of arguments\n"; + return TCL_ERROR; + } + + int tag; + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid tag" + << "\n"; + return TCL_ERROR; + } + + int ndm = builder->getNDM(); + int ndf = builder->getNDF(); + + if (ndm == 3 && !getenv("CRD")) { + auto tb = builder->getTypedObject(tag); + if (tb == nullptr) { + opserr << OpenSees::PromptValueError + << "transformation not found with tag " << tag + << "\n"; return TCL_ERROR; } + CrdTransf* t = new BasicFrameTransf3d(tb->template create<2,6>()); + return builder->addTaggedObject(*t); + } + + // + // 2D Case + // + if ((ndm == 2 && ndf == 3) || (ndm == 2 && ndf == 4)) { + Vector jntOffsetI(2), + jntOffsetJ(2); + + int argi = 3; // Additional options at end of command @@ -77,8 +341,9 @@ TclCommand_addGeomTransf(ClientData clientData, Tcl_Interp *interp, int argc, for (int i = 0; i < 2; ++i) { if (argi == argc || Tcl_GetDouble(interp, argv[argi++], &jntOffsetI(i)) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid jntOffset value\n" - " Expected: geomTransf type? tag? <-jntOffset dXi? dYi? dXj? dYj?>\n"; + opserr << OpenSees::PromptValueError + << "invalid jntOffset value" + << "\n"; return TCL_ERROR; } } @@ -86,75 +351,73 @@ TclCommand_addGeomTransf(ClientData clientData, Tcl_Interp *interp, int argc, for (int i = 0; i < 2; ++i) { if (argi == argc || Tcl_GetDouble(interp, argv[argi++], &jntOffsetJ(i)) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid jntOffset value\n" - " Expected: geomTransf type? tag? <-jntOffset dXi? dYi? dXj? dYj?>\n"; + opserr << OpenSees::PromptValueError + << "invalid jntOffset value" + << "\n"; return TCL_ERROR; } } } else { - opserr << G3_ERROR_PROMPT << "bad command\n Expected: geomTransf type? tag? " - "<-jntOffset dXi? dYi? dXj? dYj?>\n"; - opserr << "invalid: " << argv[argi] << "\n"; + opserr << OpenSees::PromptValueError + << "unexpected argument " << argv[argi] + << "\n"; return TCL_ERROR; } } + // // construct the transformation + // - FrameTransform2d *crdTransf2d = nullptr; + CrdTransf *crdTransf2d = nullptr; if (strcmp(argv[1], "Linear") == 0) -// if (getenv("CRD")) { -// crdTransf2d = new LinearCrdTransf2d02(crdTransfTag, jntOffsetI, jntOffsetJ); -// } else - crdTransf2d = new LinearCrdTransf2d(crdTransfTag, jntOffsetI, jntOffsetJ); + crdTransf2d = new LinearCrdTransf2d(tag, jntOffsetI, jntOffsetJ); else if (strcmp(argv[1], "LinearInt") == 0) crdTransf2d = - new LinearCrdTransf2dInt(crdTransfTag, jntOffsetI, jntOffsetJ); + new LinearCrdTransf2dInt(tag, jntOffsetI, jntOffsetJ); else if (strcmp(argv[1], "PDelta") == 0 || strcmp(argv[1], "LinearWithPDelta") == 0) - crdTransf2d = new PDeltaCrdTransf2d(crdTransfTag, jntOffsetI, jntOffsetJ); + crdTransf2d = new PDeltaCrdTransf2d(tag, jntOffsetI, jntOffsetJ); else if (strcmp(argv[1], "Corotational") == 0 && ndf == 3) - crdTransf2d = new CorotCrdTransf2d(crdTransfTag, jntOffsetI, jntOffsetJ); + crdTransf2d = new CorotCrdTransf2d(tag, jntOffsetI, jntOffsetJ); else if (strcmp(argv[1], "Corotational") == 0 && ndf == 4) crdTransf2d = - new CorotCrdTransfWarping2d(crdTransfTag, jntOffsetI, jntOffsetJ); + new CorotCrdTransfWarping2d(tag, jntOffsetI, jntOffsetJ); else { - opserr << G3_ERROR_PROMPT << "invalid Type\n"; - opserr << argv[1] << "\n"; + opserr << OpenSees::PromptValueError + << "invalid Type: " << argv[1] << "\n"; return TCL_ERROR; } - // add the transformation to the modelBuilder - if (builder->addTaggedObject(*crdTransf2d) != TCL_OK) + // + if (builder->addTaggedObject(*crdTransf2d) != TCL_OK) return TCL_ERROR; + } - } else if (ndm == 3 && ndf == 6) { - int crdTransfTag; - Vector vecxzPlane(3); // vector that defines local xz plane - Vector jntOffsetI(3), jntOffsetJ(3); // joint offsets in global coordinates + else if (ndm == 3 && ndf >= 6) { + // vector that defines local xz plane + Vector vecxzPlane(3); + // joint offsets in global coordinates + Vector jntOffsetI(3), jntOffsetJ(3); if (argc < 6) { - opserr << G3_ERROR_PROMPT - << "insufficient arguments\n" - << " Expected: geomTransf type? tag? " - "vecxzPlaneX? vecxzPlaneY? vecxzPlaneZ? <-jntOffset dXi? dYi? " - "dZi? dXj? dYj? dZj? >\n"; + opserr << OpenSees::PromptValueError + << "insufficient arguments" + << "\n"; return TCL_ERROR; } int argi = 2; - if (Tcl_GetInt(interp, argv[argi++], &crdTransfTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid tag\n Expected: geomTransf type? tag? " - "vecxzPlaneX? vecxzPlaneY? vecxzPlaneZ? <-jntOffset dXi? dYi? " - "dZi? dXj? dYj? dZj? >\n"; + if (Tcl_GetInt(interp, argv[argi++], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid tag\n"; return TCL_ERROR; } @@ -167,7 +430,8 @@ TclCommand_addGeomTransf(ClientData clientData, Tcl_Interp *interp, int argc, if (xznum == 3) { for (int i=0; i<3; ++i) if (Tcl_GetDouble(interp, xzarg[i], &vecxzPlane(i)) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "Failed to parse vectxz\n"; + opserr << OpenSees::PromptValueError + << "Failed to parse vectxz\n"; return TCL_ERROR; } @@ -178,28 +442,27 @@ TclCommand_addGeomTransf(ClientData clientData, Tcl_Interp *interp, int argc, if (!parsed_xz) { if (Tcl_GetDouble(interp, argv[argi++], &vecxzPlane(0)) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid vecxzPlaneX\n Expected: geomTransf type? tag? " - "vecxzPlaneX? vecxzPlaneY? vecxzPlaneZ? <-jntOffset dXi? dYi? " - "dZi? dXj? dYj? dZj? >\n"; + opserr << OpenSees::PromptValueError + << "invalid vecxzPlaneX\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &vecxzPlane(1)) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid vecxzPlaneY\n Expected: geomTransf type? tag? " - "vecxzPlaneX? vecxzPlaneY? vecxzPlaneZ? <-jntOffset dXi? dYi? " - "dZi? dXj? dYj? dZj? >\n"; + opserr << OpenSees::PromptValueError + << "invalid vecxzPlaneY\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &vecxzPlane(2)) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid vecxzPlaneZ\n Expected: geomTransf type? tag? " - "vecxzPlaneX? vecxzPlaneY? vecxzPlaneZ? <-jntOffset dXi? dYi? " - "dZi? dXj? dYj? dZj? >\n"; + opserr << OpenSees::PromptValueError + << "invalid vecxzPlaneZ\n"; return TCL_ERROR; } } - // additional keyword options at end of command + // + // Additional keyword options + // while (argi != argc) { if (strcmp(argv[argi], "-jntOffset") == 0) { @@ -207,9 +470,7 @@ TclCommand_addGeomTransf(ClientData clientData, Tcl_Interp *interp, int argc, for (int i = 0; i < 3; ++i) { if (argi == argc || Tcl_GetDouble(interp, argv[argi++], &jntOffsetI(i)) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid jntOffset value\n Expected: geomTransf " - "type? tag? vecxzPlaneX? vecxzPlaneY? vecxzPlaneZ? " - "<-jntOffset dXi? dYi? dZi? dXj? dYj? dZj? >\n"; + opserr << OpenSees::PromptValueError << "invalid jntOffset\n"; return TCL_ERROR; } } @@ -217,63 +478,53 @@ TclCommand_addGeomTransf(ClientData clientData, Tcl_Interp *interp, int argc, for (int i = 0; i < 3; ++i) { if (argi == argc || Tcl_GetDouble(interp, argv[argi++], &jntOffsetJ(i)) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid jntOffset value\n Expected: geomTransf " - "type? tag? vecxzPlaneX? vecxzPlaneY? vecxzPlaneZ? " - "<-jntOffset dXi? dYi? dZi? dXj? dYj? dZj? >\n"; + opserr << OpenSees::PromptValueError << "invalid jntOffset\n"; return TCL_ERROR; } } } else { - opserr << G3_ERROR_PROMPT << "bad command\n Expected: geomTransf type? tag? " - "vecxzPlaneX? vecxzPlaneY? vecxzPlaneZ? <-jntOffset dXi? " - "dYi? dZi? dXj? dYj? dZj? > \n"; - opserr << " invalid: " << argv[argi] << "\n"; + opserr << OpenSees::PromptValueError << "unexpected argument: " << argv[argi] << "\n"; return TCL_ERROR; } } - // construct the transformation object - FrameTransform3d *crdTransf3d=nullptr; + // + // construct the transformation + // + CrdTransf *crdTransf3d=nullptr; if (strcmp(argv[1], "Linear") == 0) - if (!getenv("CRD")) - crdTransf3d = new LinearFrameTransf3d(crdTransfTag, vecxzPlane, jntOffsetI, jntOffsetJ); - else - crdTransf3d = new LinearCrdTransf3d(crdTransfTag, vecxzPlane, jntOffsetI, jntOffsetJ); + crdTransf3d = new LinearCrdTransf3d(tag, vecxzPlane, jntOffsetI, jntOffsetJ); else if (strcmp(argv[1], "PDelta") == 0 || strcmp(argv[1], "LinearWithPDelta") == 0) - if (!getenv("CRD")) - crdTransf3d = new PDeltaFrameTransf3d(crdTransfTag, vecxzPlane, jntOffsetI, jntOffsetJ); - else - crdTransf3d = new PDeltaCrdTransf3d(crdTransfTag, vecxzPlane, jntOffsetI, jntOffsetJ); + crdTransf3d = new PDeltaCrdTransf3d(tag, vecxzPlane, jntOffsetI, jntOffsetJ); else if (strcmp(argv[1], "Corotational") == 0) - // By default use new faster version - if (!getenv("CRD")) - crdTransf3d = new CorotFrameTransf3d(crdTransfTag, vecxzPlane, jntOffsetI, jntOffsetJ); - else - crdTransf3d = new CorotCrdTransf3d(crdTransfTag, vecxzPlane, jntOffsetI, jntOffsetJ); + crdTransf3d = new CorotCrdTransf3d(tag, vecxzPlane, jntOffsetI, jntOffsetJ); else { - opserr << G3_ERROR_PROMPT << "invalid Type\n"; + opserr << OpenSees::PromptValueError << "invalid Type\n"; return TCL_ERROR; } if (crdTransf3d == nullptr) { - opserr << G3_ERROR_PROMPT << "Failed to create transform\n"; + opserr << OpenSees::PromptValueError << "Failed to create transform\n"; return TCL_ERROR; } // add the transformation to the modelBuilder - if (builder->addTaggedObject(*crdTransf3d) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "could not add " - "geometric transformation to model Builder\n"; + if (builder->addTaggedObject(*crdTransf3d) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Failed to add transformation to model\n"; return TCL_ERROR; } - } else { - opserr << G3_ERROR_PROMPT << "ndm = " << ndm << " and ndf = " << ndf + } + + else { + opserr << OpenSees::PromptValueError + << "ndm = " << ndm << " and ndf = " << ndf << " is incompatible with available frame elements\n"; return TCL_ERROR; } From 28d81db68d2c07f445eeb4cbcba23d6d1f125b81 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:37:40 -0700 Subject: [PATCH 086/261] add FrameTransformBuilder --- .../transform/FrameTransformBuilder.hpp | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp diff --git a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp new file mode 100644 index 0000000000..20a90110bd --- /dev/null +++ b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +#pragma once +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +class FrameTransformBuilder : public TaggedObject { +public: + FrameTransformBuilder(int ndm, int t, const char *n) + : ndm(ndm), + TaggedObject(t), + vz{{0, 0, 0}}, offsets{}, offset_flags(0) { + strncpy(name, n, 128); + // offset_flags |= LogIter; + } + + virtual ~FrameTransformBuilder() {} + + template + FrameTransform * + create() + { + std::array *offset_array = nullptr; + std::array offset_data{}; + + if (offsets.size() > 0) { + offset_array = &offset_data; + for (int i = 0; i < nn; ++i) { + auto it = offsets.find(i+1); + if (it != offsets.end()) + (*offset_array)[i] = it->second; + } + } + + int tag = this->getTag(); + if (strstr(name, "Linear") != nullptr) + return new LinearFrameTransf (tag, vz, offset_array, offset_flags); + + else if (strstr(name, "Corot") != nullptr) { + if constexpr (ndf == 6) + return new SouzaFrameTransf (tag, vz, offset_array, offset_flags); + } + else if (strstr(name, "PDelta") != nullptr) + return new PDeltaFrameTransf (tag, vz, offset_array, offset_flags); + + else if (strcmp(name, "Isometric") == 0 || strstr(name, "Rigid") != nullptr) + return new RigidFrameTransf> (tag, vz, offset_array, offset_flags); + + return nullptr; + } + + virtual void + Print(OPS_Stream&s, int flag) { + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << OPS_PRINT_JSON_MATE_INDENT << "{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"" << name << "\""; + s << ", "; + s << "\"vz\": [" << vz[0] << ", " << vz[1] << ", " << vz[2] << "]"; + if (offsets.size() > 0) { + s << ", \"offsets\": {"; + for (auto it = offsets.begin(); it != offsets.end(); ++it) { + s << it->first << ": [" << it->second[0] << ", " << it->second[1] << ", " << it->second[2] << "]"; + if (std::next(it) != offsets.end()) + s << ", "; + } + } + s << "}"; + } + } + + int ndm; + int tag; + char name[128]; + Vector3D vz; + std::map offsets; + int offset_flags; +}; From 1e5e0e58b0ab2671cafd825b601c9b681abbe0ed Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:40:23 -0700 Subject: [PATCH 087/261] rename `RigidFrameTransf` --- ...dFrameTransf.hpp => EuclidFrameTransf.hpp} | 16 +++--- ...dFrameTransf.tpp => EuclidFrameTransf.tpp} | 54 +++++++++---------- .../transform/FrameTransformBuilder.hpp | 4 +- 3 files changed, 37 insertions(+), 37 deletions(-) rename SRC/coordTransformation/Frame/{RigidFrameTransf.hpp => EuclidFrameTransf.hpp} (91%) rename SRC/coordTransformation/Frame/{RigidFrameTransf.tpp => EuclidFrameTransf.tpp} (85%) diff --git a/SRC/coordTransformation/Frame/RigidFrameTransf.hpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp similarity index 91% rename from SRC/coordTransformation/Frame/RigidFrameTransf.hpp rename to SRC/coordTransformation/Frame/EuclidFrameTransf.hpp index 1f47b58bcf..19b840ded5 100644 --- a/SRC/coordTransformation/Frame/RigidFrameTransf.hpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp @@ -7,15 +7,15 @@ //===----------------------------------------------------------------------===// // // Description: This file contains the class definition for -// RigidFrameTransf.h. RigidFrameTransf provides the +// EuclidFrameTransf.h. EuclidFrameTransf provides the // abstraction of a linear transformation for a spatial frame // between the global and basic coordinate systems // // Written: cmp // Created: 04/2025 // -#ifndef RigidFrameTransf_hpp -#define RigidFrameTransf_hpp +#ifndef EuclidFrameTransf_hpp +#define EuclidFrameTransf_hpp #include #include @@ -23,19 +23,19 @@ #include template -class RigidFrameTransf: public FrameTransform +class EuclidFrameTransf: public FrameTransform { public: constexpr static int n = nn*ndf; - RigidFrameTransf(int tag, + EuclidFrameTransf(int tag, const Vector3D &vecxz, const std::array *offset=nullptr, int offset_flags = 0); - ~RigidFrameTransf(); + ~EuclidFrameTransf(); - const char *getClassType() const {return "RigidFrameTransf";} + const char *getClassType() const {return "EuclidFrameTransf";} virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; @@ -135,6 +135,6 @@ class RigidFrameTransf: public FrameTransform BasisT basis; }; -#include "RigidFrameTransf.tpp" +#include "EuclidFrameTransf.tpp" #endif diff --git a/SRC/coordTransformation/Frame/RigidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp similarity index 85% rename from SRC/coordTransformation/Frame/RigidFrameTransf.tpp rename to SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 3bc5ad1614..e11c827d39 100644 --- a/SRC/coordTransformation/Frame/RigidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // // Description: This file contains the implementation for the -// RigidFrameTransf class. RigidFrameTransf is a nonlinear +// EuclidFrameTransf class. EuclidFrameTransf is a nonlinear // transformation for a space frame // // Written: cmp @@ -21,13 +21,13 @@ #include #include #include -#include +#include using namespace OpenSees; template -RigidFrameTransf::RigidFrameTransf(int tag, +EuclidFrameTransf::EuclidFrameTransf(int tag, const Vector3D &vecxz, const std::array *offset, int offset_flags) @@ -56,7 +56,7 @@ RigidFrameTransf::RigidFrameTransf(int tag, template -RigidFrameTransf::~RigidFrameTransf() +EuclidFrameTransf::~EuclidFrameTransf() { if (offsets != nullptr) delete offsets; @@ -64,21 +64,21 @@ RigidFrameTransf::~RigidFrameTransf() template int -RigidFrameTransf::commit() +EuclidFrameTransf::commit() { return 0; } template int -RigidFrameTransf::revertToLastCommit() +EuclidFrameTransf::revertToLastCommit() { return 0; } template int -RigidFrameTransf::revertToStart() +EuclidFrameTransf::revertToStart() { return 0; } @@ -86,7 +86,7 @@ RigidFrameTransf::revertToStart() template int -RigidFrameTransf::initialize(std::array& new_nodes) +EuclidFrameTransf::initialize(std::array& new_nodes) { for (int i=0; i::initialize(std::array& new_nodes) template int -RigidFrameTransf::computeElemtLengthAndOrient() +EuclidFrameTransf::computeElemtLengthAndOrient() { const Vector &XI = nodes[ 0]->getCrds(); @@ -143,7 +143,7 @@ RigidFrameTransf::computeElemtLengthAndOrient() template int -RigidFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector3D &e3) const +EuclidFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector3D &e3) const { Matrix3D R = basis.getRotation(); for (int i = 0; i < 3; i++) { @@ -156,14 +156,14 @@ RigidFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector template double -RigidFrameTransf::getInitialLength() +EuclidFrameTransf::getInitialLength() { return L; } template double -RigidFrameTransf::getDeformedLength() +EuclidFrameTransf::getDeformedLength() { return L; } @@ -174,7 +174,7 @@ RigidFrameTransf::getDeformedLength() // template int -RigidFrameTransf::update() +EuclidFrameTransf::update() { if (basis.update() < 0) return -1; @@ -190,7 +190,7 @@ RigidFrameTransf::update() template Versor -RigidFrameTransf::getNodeRotation(int tag) +EuclidFrameTransf::getNodeRotation(int tag) { return nodes[tag]->getTrialRotation(); } @@ -198,7 +198,7 @@ RigidFrameTransf::getNodeRotation(int tag) template Vector3D -RigidFrameTransf::getNodePosition(int node) +EuclidFrameTransf::getNodePosition(int node) { #if 0 const Vector& ug = nodes[node]->getTrialDisp(); @@ -225,7 +225,7 @@ RigidFrameTransf::getNodePosition(int node) template Vector3D -RigidFrameTransf::getNodeRotationLogarithm(int node) +EuclidFrameTransf::getNodeRotationLogarithm(int node) { return ur[node]; } @@ -233,7 +233,7 @@ RigidFrameTransf::getNodeRotationLogarithm(int node) template VectorND -RigidFrameTransf::getStateVariation() +EuclidFrameTransf::getStateVariation() { static VectorND ul; @@ -245,7 +245,7 @@ RigidFrameTransf::getStateVariation() } Matrix3D R = basis.getRotation(); - // return RigidFrameTransf::pullVariation(ug, R, offsets, offset_flags); + // return EuclidFrameTransf::pullVariation(ug, R, offsets, offset_flags); // VectorND ul = ug; @@ -315,7 +315,7 @@ RigidFrameTransf::getStateVariation() // template VectorND -RigidFrameTransf::pushResponse(VectorND&p) +EuclidFrameTransf::pushResponse(VectorND&p) { VectorND pa = p; @@ -340,7 +340,7 @@ RigidFrameTransf::pushResponse(VectorND&p) template MatrixND -RigidFrameTransf::pushResponse(MatrixND&kb, const VectorND&pb) +EuclidFrameTransf::pushResponse(MatrixND&kb, const VectorND&pb) { MatrixND Kb = kb; VectorND p = pb; @@ -411,9 +411,9 @@ RigidFrameTransf::pushResponse(MatrixND&kb, const template FrameTransform * -RigidFrameTransf::getCopy() const +EuclidFrameTransf::getCopy() const { - return new RigidFrameTransf(this->getTag(), vz, offsets); + return new EuclidFrameTransf(this->getTag(), vz, offsets); } @@ -422,7 +422,7 @@ RigidFrameTransf::getCopy() const // template bool -RigidFrameTransf::isShapeSensitivity() +EuclidFrameTransf::isShapeSensitivity() { int nodeParameterI = nodes[ 0]->getCrdsSensitivity(); int nodeParameterJ = nodes[nn-1]->getCrdsSensitivity(); @@ -434,7 +434,7 @@ RigidFrameTransf::isShapeSensitivity() template double -RigidFrameTransf::getLengthGrad() +EuclidFrameTransf::getLengthGrad() { const int di = nodes[0]->getCrdsSensitivity(); const int dj = nodes[1]->getCrdsSensitivity(); @@ -452,7 +452,7 @@ RigidFrameTransf::getLengthGrad() template double -RigidFrameTransf::getd1overLdh() +EuclidFrameTransf::getd1overLdh() { return -getLengthGrad()/(L*L); } @@ -460,12 +460,12 @@ RigidFrameTransf::getd1overLdh() template void -RigidFrameTransf::Print(OPS_Stream &s, int flag) +EuclidFrameTransf::Print(OPS_Stream &s, int flag) { if (flag == OPS_PRINT_PRINTMODEL_JSON) { s << OPS_PRINT_JSON_MATE_INDENT << "{"; s << "\"name\": " << this->getTag() << ", "; - s << "\"type\": \"RigidFrameTransf\""; + s << "\"type\": \"EuclidFrameTransf\""; s << ", \"vecxz\": [" << vz[0] << ", " << vz[1] << ", " diff --git a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp index 20a90110bd..3a9aa3f3a4 100644 --- a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp +++ b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include @@ -61,7 +61,7 @@ class FrameTransformBuilder : public TaggedObject { return new PDeltaFrameTransf (tag, vz, offset_array, offset_flags); else if (strcmp(name, "Isometric") == 0 || strstr(name, "Rigid") != nullptr) - return new RigidFrameTransf> (tag, vz, offset_array, offset_flags); + return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); return nullptr; } From f5c580916d3b01166724eefc03602dc6d072b370 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:51:20 -0700 Subject: [PATCH 088/261] implement finite rotations in Node --- SRC/domain/node/Node.cpp | 29 +++++++++++++++++++++++++++++ SRC/domain/node/Node.h | 3 +++ 2 files changed, 32 insertions(+) diff --git a/SRC/domain/node/Node.cpp b/SRC/domain/node/Node.cpp index ccebd571df..2062b8c0e6 100644 --- a/SRC/domain/node/Node.cpp +++ b/SRC/domain/node/Node.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -227,6 +228,7 @@ Node::Node(int theClassTag) trialDisp(0), trialVel(0), trialAccel(0), unbalLoad(0), incrDisp(0), incrDeltaDisp(0), disp(0), vel(0), accel(0), dbTag1(0), dbTag2(0), dbTag3(0), dbTag4(0), + rotation(nullptr), R(0), mass(0), unbalLoadWithInertia(0), alphaM(0.0), theEigenvectors(0), index(-1), reaction(0), displayLocation(0), temperature(0) { @@ -250,6 +252,7 @@ Node::Node(int tag, int theClassTag) trialDisp(0), trialVel(0), trialAccel(0), unbalLoad(0), incrDisp(0), incrDeltaDisp(0), disp(0), vel(0), accel(0), dbTag1(0), dbTag2(0), dbTag3(0), dbTag4(0), + rotation(nullptr), R(0), mass(0), unbalLoadWithInertia(0), alphaM(0.0), theEigenvectors(0), index(-1), reaction(0), displayLocation(0), temperature(0) { @@ -273,6 +276,7 @@ Node::Node(int tag, int ndof, double Crd1, Vector *dLoc) trialDisp(0), trialVel(0), trialAccel(0), unbalLoad(0), incrDisp(0), incrDeltaDisp(0), disp(0), vel(0), accel(0), dbTag1(0), dbTag2(0), dbTag3(0), dbTag4(0), + rotation(nullptr), R(0), mass(0), unbalLoadWithInertia(0), alphaM(0.0), theEigenvectors(0), index(-1), reaction(0), displayLocation(0), temperature(0) { @@ -305,6 +309,7 @@ Node::Node(int tag, int ndof, double Crd1, double Crd2, Vector *dLoc) trialDisp(0), trialVel(0), trialAccel(0), unbalLoad(0), incrDisp(0), incrDeltaDisp(0), disp(0), vel(0), accel(0), dbTag1(0), dbTag2(0), dbTag3(0), dbTag4(0), + rotation(nullptr), R(0), mass(0), unbalLoadWithInertia(0), alphaM(0.0), theEigenvectors(0), reaction(0), displayLocation(0), temperature(0) { @@ -339,6 +344,7 @@ Node::Node(int tag, int ndof, double Crd1, double Crd2, Vector *dLoc) trialDisp(0), trialVel(0), trialAccel(0), unbalLoad(0), incrDisp(0), incrDeltaDisp(0), disp(0), vel(0), accel(0), dbTag1(0), dbTag2(0), dbTag3(0), dbTag4(0), + rotation(nullptr), R(0), mass(0), unbalLoadWithInertia(0), alphaM(0.0), theEigenvectors(0), reaction(0), displayLocation(0), temperature(0) { @@ -374,6 +380,7 @@ Node::Node(const Node &otherNode, bool copyMass) trialDisp(0), trialVel(0), trialAccel(0), unbalLoad(0), incrDisp(0), incrDeltaDisp(0), disp(0), vel(0), accel(0), dbTag1(0), dbTag2(0), dbTag3(0), dbTag4(0), + rotation(nullptr), R(0), mass(0), unbalLoadWithInertia(0), alphaM(0.0), theEigenvectors(0), reaction(0), displayLocation(0), temperature(0) { @@ -482,6 +489,10 @@ Node::~Node() if (trialAccel != 0) delete trialAccel; + if (rotation != nullptr) + delete rotation; + + if (incrDisp != 0) delete incrDisp; @@ -693,6 +704,18 @@ Node::getIncrDeltaDisp(void) return *incrDeltaDisp; } +Versor +Node::getTrialRotation() +{ + if (rotation == nullptr) [[unlikely]] { + if (this->getNumberDOF() < 6) + return Versor(); + else + rotation = new Versor{{0.0, 0.0, 0.0}, 1.0}; + } + + return *rotation; +} int Node::setTrialDisp(double value, int dof) @@ -815,6 +838,10 @@ Node::incrTrialDisp(const Vector &incrDispl) return -2; } + if (rotation != nullptr && this->getNumberDOF() >= 6) + (*rotation) = (*rotation)*Versor::from_vector(&disp[3*numberDOF+3]); + + // create a copy if no trial exists and add committed if (trialDisp == 0) { if (this->createDisp() < 0) { @@ -1147,6 +1174,8 @@ Node::revertToStart() (*unbalLoad) *= 0; + if (rotation != nullptr) + *rotation = Versor{{0.0, 0.0, 0.0}, 1.0}; // AddingSensitivity: BEGIN ///////////////////////////////// diff --git a/SRC/domain/node/Node.h b/SRC/domain/node/Node.h index 8b7a70211f..11263c73c8 100644 --- a/SRC/domain/node/Node.h +++ b/SRC/domain/node/Node.h @@ -44,6 +44,7 @@ class Element; class Vector; class Matrix; +struct Versor; class Channel; class Renderer; @@ -86,6 +87,7 @@ class Node : public DomainComponent virtual const Vector &getTrialDisp(void); virtual const Vector &getTrialVel(void); virtual const Vector &getTrialAccel(void); + virtual Versor getTrialRotation(void); // public methods for updating the trial response quantities virtual int setTrialDisp(double value, int dof); @@ -187,6 +189,7 @@ class Node : public DomainComponent Vector *commitDisp, *commitVel, *commitAccel; // committed quantities Vector *trialDisp, *trialVel, *trialAccel; // trial quantities Vector *unbalLoad; // unbalanced load + Versor *rotation; Vector *incrDisp; Vector *incrDeltaDisp; From 1b7784c6382ca647f1861633ebad883082a07cd7 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Tue, 24 Jun 2025 12:21:05 +0200 Subject: [PATCH 089/261] SendSelf_recSelf_fixes --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 21 ++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index 1b816343bd..64a052bd1d 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -22,9 +22,9 @@ // $Date: 2025-01-03 11:29:01 $ // $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/ASDSteel1DMaterial.cpp,v $ -// Alessia Casalucci - ASDEA Software, Italy +// Alessia Casalucci,Massimo Petracca, Guido Camata - ASDEA Software, Italy // -// todo... +// A unified and efficient plastic-damage material model for steel bars including fracture, bond-slip, and buckling via multiscale homogenization // #include @@ -326,7 +326,6 @@ namespace { constexpr int MAX_ITER = 1000; constexpr double F_REL_TOL = 1.0e-6; constexpr double L_ABS_TOL = 1.0e-8; - //constexpr double K_alpha = 0.8; // base steel response alpha1 = alpha1_commit; alpha2 = alpha2_commit; @@ -470,6 +469,7 @@ namespace { data(pos++) = alpha2_commit; data(pos++) = lambda; data(pos++) = lambda_commit; + data(pos++) = lambda_commit_old; data(pos++) = sg_commit; data(pos++) = strain; data(pos++) = strain_commit; @@ -487,6 +487,7 @@ namespace { alpha2_commit = data(pos++); lambda = data(pos++); lambda_commit = data(pos++); + lambda_commit_old = data(pos++); sg_commit = data(pos++); strain = data(pos++); strain_commit = data(pos++); @@ -626,11 +627,12 @@ namespace { }; int SeriesComponent::serializationDataSize() const { - return 2; + return 2 + steel_material.serializationDataSize(); } void SeriesComponent::serialize(Vector& data, int& pos, int commitTag, Channel& theChannel) { + steel_material.serialize(data, pos); if (slip_material) { data(pos++) = static_cast(slip_material->getClassTag()); int mat_db_tag = slip_material->getDbTag(); @@ -642,13 +644,13 @@ namespace { data(pos++) = static_cast(mat_db_tag); } else { - data(pos++) = -1.0; // classTag data(pos++) = -1.0; // dbTag } } void SeriesComponent::deserialize(Vector& data, int& pos, int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker) { + steel_material.deserialize(data, pos); if (slip_material) { delete slip_material; slip_material = nullptr; @@ -1398,7 +1400,6 @@ namespace { // globals double tolR = params.tolR * params.sy; double tolU = params.tolU * params.length; - //constexpr int max_iter = 200; auto& globals = Globals::instance(); // utility for assembly @@ -1930,7 +1931,6 @@ void* OPS_ASDSteel1DMaterial() params.lch_anchor = lch_anc; params.length = buckling ? lch / 2.0 : 1.0; // consider half distance, the RVE uses symmetry params.radius = r; - //params.radius_frac = r_frac; params.K_alpha = K_alpha; params.max_iter = max_iter; params.tolU = tolU; @@ -2254,10 +2254,11 @@ int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectB int counter; // variable DBL data size - int nv_dbl = nv_dbl = 13 + + int nv_dbl = 13 + params.NDATA + pdata->rve_m.serializationDataSize() + - pdata->steel_comp.serializationDataSize(); + pdata->steel_comp.serializationDataSize() + + pdata->rve_m.e2.section.series.serializationDataSize(); // pdata->rve_m.e0.section.series.serializationDataSize() + pdata->rve_m.e2.section.series.serializationDataSize() + pdata->steel_comp.serializationDataSize(); Vector ddata(nv_dbl); @@ -2282,8 +2283,8 @@ int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectB stress_commit = ddata(counter++); C = ddata(counter++); stress_rve_commit = ddata(counter++); - C_rve = ddata(counter++); stress_rve = ddata(counter++); + C_rve = ddata(counter++); energy = ddata(counter++); //params From 2701bf71e506c4dde737d09dc9f2380121fd8901 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 24 Jun 2025 10:55:22 -0700 Subject: [PATCH 090/261] cleaning up --- .../Frame/BasicFrameTransf.h | 39 +++++++++++-------- .../Frame/BasicFrameTransf.tpp | 11 +++++- .../Frame/EuclidFrameTransf.hpp | 13 ++++--- .../Frame/EuclidFrameTransf.tpp | 18 ++++++--- .../Frame/Isometry/CrisfieldIsometry.tpp | 0 .../{Orient => Isometry}/CrisfieldTransform.h | 6 +-- .../Frame/{Orient => Isometry}/FrameBasis.h | 6 +-- .../Frame/Isometry/RankineIsometry.h | 0 .../Frame/Isometry/RankineIsometry.tpp | 0 .../Frame/LinearFrameTransf.tpp | 10 ++++- .../Frame/PDeltaFrameTransf3d.hpp | 6 +-- .../Frame/PDeltaFrameTransf3d.tpp | 6 +-- .../Frame/SouzaFrameTransf.hpp | 21 +++++----- .../Frame/SouzaFrameTransf.tpp | 2 +- 14 files changed, 85 insertions(+), 53 deletions(-) create mode 100644 SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp rename SRC/coordTransformation/Frame/{Orient => Isometry}/CrisfieldTransform.h (98%) rename SRC/coordTransformation/Frame/{Orient => Isometry}/FrameBasis.h (98%) create mode 100644 SRC/coordTransformation/Frame/Isometry/RankineIsometry.h create mode 100644 SRC/coordTransformation/Frame/Isometry/RankineIsometry.tpp diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.h b/SRC/coordTransformation/Frame/BasicFrameTransf.h index 5fa241eb08..f76f8dab89 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.h +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.h @@ -12,6 +12,14 @@ // // cmp // +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// #ifndef BasicFrameTransf3d_h #define BasicFrameTransf3d_h @@ -30,30 +38,30 @@ class BasicFrameTransf3d: public CrdTransf ~BasicFrameTransf3d(); - virtual int getLocalAxes(Vector &x, Vector &y, Vector &z); + int getLocalAxes(Vector &x, Vector &y, Vector &z) final; - virtual CrdTransf *getCopy3d() final; + CrdTransf *getCopy3d() final; virtual double getInitialLength(); virtual double getDeformedLength(); - virtual int initialize(Node *ni, Node *nj) final; - virtual int update() final; - virtual int commitState() final; - virtual int revertToLastCommit() final; - virtual int revertToStart() final; + int initialize(Node *ni, Node *nj) final; + int update() final; + int commitState() final; + int revertToLastCommit() final; + int revertToStart() final; - virtual const Vector &getBasicTrialDisp() final; - virtual const Vector &getBasicIncrDisp() final; - virtual const Vector &getBasicIncrDeltaDisp() final; - virtual const Vector &getBasicTrialVel() final; + const Vector &getBasicTrialDisp() final; + const Vector &getBasicIncrDisp() final; + const Vector &getBasicIncrDeltaDisp() final; + const Vector &getBasicTrialVel() final; - virtual const Vector &getGlobalResistingForce(const Vector &basicForce, const Vector &p0) final; - virtual const Matrix &getGlobalStiffMatrix(const Matrix &basicStiff, const Vector &basicForce) final; - virtual const Matrix &getInitialGlobalStiffMatrix(const Matrix &basicStiff) final; + const Vector &getGlobalResistingForce(const Vector &basicForce, const Vector &p0) final; + const Matrix &getGlobalStiffMatrix(const Matrix &basicStiff, const Vector &basicForce) final; + const Matrix &getInitialGlobalStiffMatrix(const Matrix &basicStiff) final; // rotate consistent mass matrix - const Matrix &getGlobalMatrixFromLocal(const Matrix &local); + const Matrix &getGlobalMatrixFromLocal(const Matrix &local) final; // methods used in post-processing only const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); @@ -102,7 +110,6 @@ class BasicFrameTransf3d: public CrdTransf }; constexpr static int iq[] = { - // jnx, imz, jmz, imy, jmy, imx inx, iny, inz, imx, imy, imz, jnx, jny, jnz, jmx, jmy, jmz }; diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index 5dd44da0bf..bc2d479a53 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -7,6 +7,14 @@ //===----------------------------------------------------------------------===// // // +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// +// #include #include #include @@ -202,7 +210,7 @@ BasicFrameTransf3d::getGlobalStiffMatrix(const Matrix &kb, const Vector &q_ MatrixND<2*NDF,2*NDF> kl; kl.zero(); -#ifndef DO_BASIC + for (int i=0; i::getGlobalStiffMatrix(const Matrix &kb, const Vector &q_ kl(0*NDF+0, i) = kl(i, 0*NDF+0) = i==0? kl(NDF+0, NDF+0): (i==3? kl(NDF+0, NDF+3) : -kl( NDF+0, i)); kl(0*NDF+3, i) = kl(i, 0*NDF+3) = i==0? kl(NDF+3, NDF+0): (i==3? kl(NDF+3, NDF+3) : -kl( NDF+3, i)); } -#endif static MatrixND<2*NDF,2*NDF> Kg; static Matrix Wrapper(Kg); diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp index 19b840ded5..9b48dddfb7 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp @@ -1,11 +1,14 @@ //===----------------------------------------------------------------------===// // // xara -// -//===----------------------------------------------------------------------===// // https://xara.so //===----------------------------------------------------------------------===// // +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//===----------------------------------------------------------------------===// +// // Description: This file contains the class definition for // EuclidFrameTransf.h. EuclidFrameTransf provides the // abstraction of a linear transformation for a spatial frame @@ -65,12 +68,12 @@ class EuclidFrameTransf: public FrameTransform // Sensitivity // - bool isShapeSensitivity(); - double getLengthGrad(); + bool isShapeSensitivity() final; + double getLengthGrad() final; double getd1overLdh(); // TaggedObject - void Print(OPS_Stream &s, int flag = 0); + void Print(OPS_Stream &s, int flag = 0) override; private: diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index e11c827d39..135864f2cb 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -1,18 +1,26 @@ //===----------------------------------------------------------------------===// // // xara -// -//===----------------------------------------------------------------------===// // https://xara.so //===----------------------------------------------------------------------===// // -// Description: This file contains the implementation for the -// EuclidFrameTransf class. EuclidFrameTransf is a nonlinear -// transformation for a space frame +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//===----------------------------------------------------------------------===// +// +// Description: This file contains the implementation for the +// EuclidFrameTransf class. EuclidFrameTransf is a nonlinear transformation +// for a space frame. +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 // // Written: cmp // Created: 04/2025 // +//===----------------------------------------------------------------------===// #pragma once #include #include diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/SRC/coordTransformation/Frame/Orient/CrisfieldTransform.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h similarity index 98% rename from SRC/coordTransformation/Frame/Orient/CrisfieldTransform.h rename to SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h index 3bca193c16..c4e15872f7 100644 --- a/SRC/coordTransformation/Frame/Orient/CrisfieldTransform.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h @@ -13,6 +13,8 @@ #include #include +namespace OpenSees { + class CrisfieldTransform { public: CrisfieldTransform() {} @@ -268,7 +270,5 @@ class CrisfieldTransform { Vector3D e[3]; double Ln; - // Auxiliary -// Matrix3D A; -// MatrixND<12,3> Lr2, Lr3; // auxiliary matrices }; +} \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Orient/FrameBasis.h b/SRC/coordTransformation/Frame/Isometry/FrameBasis.h similarity index 98% rename from SRC/coordTransformation/Frame/Orient/FrameBasis.h rename to SRC/coordTransformation/Frame/Isometry/FrameBasis.h index e40b917dd5..eb9266ec17 100644 --- a/SRC/coordTransformation/Frame/Orient/FrameBasis.h +++ b/SRC/coordTransformation/Frame/Isometry/FrameBasis.h @@ -19,7 +19,7 @@ #define TRIAD C2 namespace OpenSees { -class FrameBasis +class Isometry { public: virtual int initialize() =0; @@ -40,10 +40,10 @@ class FrameBasis template -class RankineBasis : public FrameBasis +class RankineIsometry : public Isometry { public: - RankineBasis(std::array& nodes, const Vector3D& vecxz) + RankineIsometry(std::array& nodes, const Vector3D& vecxz) : nodes{nodes}, vz(vecxz), Xc{}, c{}, R{} { } diff --git a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h b/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.tpp b/SRC/coordTransformation/Frame/Isometry/RankineIsometry.tpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index 74c41a059b..cb7c3b9527 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// //===----------------------------------------------------------------------===// // // Description: This file contains the implementation for the @@ -14,6 +21,7 @@ // Adapted: Remo Magalhaes de Souza // Created: 04/2000 // +// #pragma once #include #include diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp index f82ead8e7c..943e3509b2 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp @@ -53,15 +53,15 @@ class PDeltaFrameTransf: public FrameTransform virtual VectorND pushResponse(VectorND&pl) final; virtual MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - virtual FrameTransform *getCopy() const; + FrameTransform *getCopy() const final; virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; // Sensitivity - double getLengthGrad(); + double getLengthGrad() final; // Tagged Object - void Print(OPS_Stream &s, int flag = 0); + void Print(OPS_Stream &s, int flag = 0) final; private: int offset_flags; diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp index c7db5e6611..24b65db4b4 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp @@ -1,8 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // // Description: This file contains the implementation for the // PDeltaFrameTransf class. PDeltaFrameTransf is a nonlinear @@ -25,8 +27,6 @@ using OpenSees::Matrix3D; #define THREAD_LOCAL static - - template PDeltaFrameTransf::PDeltaFrameTransf(int tag, const Vector3D &vecxz, diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp index e8d2a78a26..81987ab1db 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp @@ -26,7 +26,7 @@ #include #include #include -#include "Orient/CrisfieldTransform.h" +#include "Isometry/CrisfieldTransform.h" struct Triad; using namespace OpenSees; // TODO: Clean namespace use @@ -59,12 +59,12 @@ class SouzaFrameTransf: public FrameTransform double getInitialLength(); double getDeformedLength(); - virtual VectorND getStateVariation() final; - virtual Vector3D getNodePosition(int tag) final; - virtual Vector3D getNodeRotationLogarithm(int tag) final; + VectorND getStateVariation() final; + Vector3D getNodePosition(int tag) final; + Vector3D getNodeRotationLogarithm(int tag) final; - virtual VectorND pushResponse(VectorND&pl) final; - virtual MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + VectorND pushResponse(VectorND&pl) final; + MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; // Sensitivity double getLengthGrad(); @@ -73,14 +73,14 @@ class SouzaFrameTransf: public FrameTransform virtual const Vector &getGlobalResistingForceShapeSensitivity(const Vector &pb, const Vector &p0, int gradNumber); // Tagged Object - void Print(OPS_Stream &s, int flag = 0); + void Print(OPS_Stream &s, int flag = 0) final; protected: int addTangent(MatrixND<12,12>& M, const VectorND<12>& pl); VectorND<6> pushResponse(const VectorND<6>& pa, int a, int b); - MatrixND<6,6> pushResponse(const MatrixND<6,6>& K, const VectorND<12>& pl, int a, int b); - int addTangent(MatrixND<6,6>& K, const VectorND<6>& p, int a, int b, int c); + // MatrixND<6,6> pushResponse(const MatrixND<6,6>& K, const VectorND<12>& pl, int a, int b); + // int addTangent(MatrixND<6,6>& K, const VectorND<6>& p, int a, int b, int c); protected: @@ -88,7 +88,7 @@ class SouzaFrameTransf: public FrameTransform constexpr static int n = nn*ndf; // compute the transformation matrix - void compTransfMatrixBasicGlobal(const Versor&, const Versor* Q); + void compTransfMatrixBasicGlobal(const Versor&, const Versor*); enum { inx= 0, // axial @@ -114,7 +114,6 @@ class SouzaFrameTransf: public FrameTransform Vector3D xAxis; // local x axis Vector3D vz; // Vector that lies in local plane xz Vector3D dX; - std::array *offsets; diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp index 97ec444ade..1f6e569e45 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp @@ -30,7 +30,7 @@ #include #include #include -#include "Orient/CrisfieldTransform.h" +#include "Isometry/CrisfieldTransform.h" using namespace OpenSees; From 902454198cc95614bb2ac1cdaee55194a9dc66b0 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 24 Jun 2025 11:34:44 -0700 Subject: [PATCH 091/261] update declarations --- .../Frame/SouzaFrameTransf.tpp | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp index 1f6e569e45..aa2428ef06 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp @@ -191,18 +191,19 @@ SouzaFrameTransf::initialize(std::array& new_nodes) initialDispChecked = true; } - // if (nodeIInitialDisp != nullptr) { - // dX[0] -= nodeIInitialDisp[0]; - // dX[1] -= nodeIInitialDisp[1]; - // dX[2] -= nodeIInitialDisp[2]; - // } - - // if (nodeJInitialDisp != nullptr) { - // dX[0] += nodeJInitialDisp[0]; - // dX[1] += nodeJInitialDisp[1]; - // dX[2] += nodeJInitialDisp[2]; - // } +#if 0 + if (nodeIInitialDisp != nullptr) { + dX[0] -= nodeIInitialDisp[0]; + dX[1] -= nodeIInitialDisp[1]; + dX[2] -= nodeIInitialDisp[2]; + } + if (nodeJInitialDisp != nullptr) { + dX[0] += nodeJInitialDisp[0]; + dX[1] += nodeJInitialDisp[1]; + dX[2] += nodeJInitialDisp[2]; + } +#endif // // Length and Orientation From 6a5e4f269c73afe5ad89b6d9fe107aa2270cbe77 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 24 Jun 2025 11:35:28 -0700 Subject: [PATCH 092/261] update virtual declarations --- .../Frame/EuclidFrameTransf.hpp | 7 +++--- .../Frame/LinearFrameTransf.hpp | 24 +++++++++---------- .../Frame/PDeltaFrameTransf3d.hpp | 4 ++-- .../Frame/SouzaFrameTransf.hpp | 16 ++++++------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp index 9b48dddfb7..de7cfc9d90 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp @@ -62,9 +62,10 @@ class EuclidFrameTransf: public FrameTransform VectorND pushResponse(VectorND&pl) final; MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - // // method used to rotate consistent mass matrix - // const Matrix &getGlobalMatrixFromLocal(const Matrix &local); - +#if 0 + // method used to rotate consistent mass matrix + const Matrix &getGlobalMatrixFromLocal(const Matrix &local); +#endif // Sensitivity // diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.hpp b/SRC/coordTransformation/Frame/LinearFrameTransf.hpp index 7a2f3513fd..acb2edef89 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.hpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.hpp @@ -43,15 +43,15 @@ class LinearFrameTransf: public FrameTransform virtual double getDeformedLength(); virtual const std::array *getRigidOffsets() const {return offsets;} - virtual int initialize(std::array& new_nodes) final; - virtual int update() final; - virtual int commit() final; - virtual int revertToLastCommit() final; - virtual int revertToStart() final; + int initialize(std::array& new_nodes) final; + int update() final; + int commit() final; + int revertToLastCommit() final; + int revertToStart() final; - virtual VectorND getStateVariation() final; - virtual Vector3D getNodePosition(int tag) final; - virtual Vector3D getNodeRotationLogarithm(int tag) final; + VectorND getStateVariation() final; + Vector3D getNodePosition(int tag) final; + Vector3D getNodeRotationLogarithm(int tag) final; virtual VectorND pushResponse(VectorND&pl) final; virtual MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; @@ -65,12 +65,12 @@ class LinearFrameTransf: public FrameTransform const Vector & getBasicDisplFixedGrad(); const Vector & getBasicDisplTotalGrad(int gradNumber); const Vector &getGlobalResistingForceShapeSensitivity (const Vector &basicForce, const Vector &p0, int grad); - bool isShapeSensitivity(); - double getLengthGrad(); - double getd1overLdh(); + bool isShapeSensitivity() final; + double getLengthGrad() final; + double getd1overLdh() final; // TaggedObject - void Print(OPS_Stream &s, int flag = 0); + void Print(OPS_Stream &s, int flag = 0) final; // Personal Vector3D getDelta() {return Du;} diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp index 943e3509b2..f2fe843c4b 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp @@ -48,14 +48,14 @@ class PDeltaFrameTransf: public FrameTransform VectorND getStateVariation() final; Vector3D getNodePosition(int tag) final; Vector3D getNodeRotationLogarithm(int tag) final; - virtual const std::array *getRigidOffsets() const { return linear.getRigidOffsets();} + const std::array *getRigidOffsets() const final { return linear.getRigidOffsets();} virtual VectorND pushResponse(VectorND&pl) final; virtual MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; FrameTransform *getCopy() const final; - virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; + int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const final; // Sensitivity double getLengthGrad() final; diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp index 81987ab1db..8940a73821 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp @@ -48,13 +48,13 @@ class SouzaFrameTransf: public FrameTransform // NOTE: maybe add arg for rotation parameterization FrameTransform *getCopy() const; - int initialize(std::array& new_nodes); - int update(); - int commit(); - int revertToLastCommit(); - int revertToStart(); - int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; - virtual const std::array *getRigidOffsets() const { return offsets; } + int initialize(std::array& new_nodes) final; + int update() final; + int commit() final; + int revertToLastCommit() final; + int revertToStart() final; + int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const final; + const std::array *getRigidOffsets() const final { return offsets; } double getInitialLength(); double getDeformedLength(); @@ -67,7 +67,7 @@ class SouzaFrameTransf: public FrameTransform MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; // Sensitivity - double getLengthGrad(); + double getLengthGrad() final; virtual const Vector &getBasicDisplTotalGrad(int grad); virtual const Vector &getBasicDisplFixedGrad(); virtual const Vector &getGlobalResistingForceShapeSensitivity(const Vector &pb, const Vector &p0, int gradNumber); From 2fb5890db9bcba183caf8b6a7354a84666ff5c33 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 24 Jun 2025 11:37:11 -0700 Subject: [PATCH 093/261] add Matrix3D.h --- SRC/matrix/Matrix3D.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 SRC/matrix/Matrix3D.h diff --git a/SRC/matrix/Matrix3D.h b/SRC/matrix/Matrix3D.h new file mode 100644 index 0000000000..5bcd613316 --- /dev/null +++ b/SRC/matrix/Matrix3D.h @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// Claudio Perez +// +#ifndef Matrix3D_H +#define Matrix3D_H + +#include "MatrixND.h" +#include + +namespace OpenSees { + + using Matrix3D = MatrixND<3,3,double>; + + static_assert(std::is_trivially_copyable::value, "Matrix3D is not trivially copyable."); + static_assert(std::is_trivial::value, "Matrix3D is not trivial."); + static_assert(std::is_standard_layout::value, "Matrix3D is not standard layout."); + static_assert(std::is_aggregate::value, "Matrix3D is not an aggregate type."); +} + + +#endif // Matrix3D_H From 47e4dd2b52827960a1d58a5a09c8122e5d81eeae Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 24 Jun 2025 11:42:29 -0700 Subject: [PATCH 094/261] add Vector3D.h --- SRC/matrix/Vector3D.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 SRC/matrix/Vector3D.h diff --git a/SRC/matrix/Vector3D.h b/SRC/matrix/Vector3D.h new file mode 100644 index 0000000000..c45bbd7aaa --- /dev/null +++ b/SRC/matrix/Vector3D.h @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// Implementation of a 3D Vector +// +// Written: cmp +// +#ifndef Vector3D_h +#define Vector3D_h + +#include +#include + +using Vector3D = OpenSees::VectorND<3, double>; + +static_assert(std::is_trivially_copyable::value, "Vector3D is not trivially copyable."); +static_assert(std::is_trivial::value, "Vector3D is not trivial."); +static_assert(std::is_standard_layout::value, "Vector3D is not standard layout."); +static_assert(std::is_aggregate::value, "Vector3D is not an aggregate type."); + +#endif // Vector3D_h From 524ab3752058e7e525cd6279ec855a53900b331e Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 24 Jun 2025 11:56:34 -0700 Subject: [PATCH 095/261] more matrix/vector utilities --- SRC/matrix/Vector3D.h | 19 +++++++-- SRC/matrix/blasdecl.h | 90 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 SRC/matrix/blasdecl.h diff --git a/SRC/matrix/Vector3D.h b/SRC/matrix/Vector3D.h index c45bbd7aaa..eef7ecf5cc 100644 --- a/SRC/matrix/Vector3D.h +++ b/SRC/matrix/Vector3D.h @@ -1,10 +1,17 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // -// Implementation of a 3D Vector +// Implementation of a 3D Vector. The purpose of this file is to ensure that +// the VectorND class is as transparent to the compiler as possible. +// In particular, we want to ensure that the Vector3D class is +// - trivially copyable (i.e., can be copied with memcpy) +// - trivial (i.e., has no user-defined constructors, destructors, or copy) +// - standard layout (i.e., has no virtual functions, no base classes, and no // // Written: cmp // @@ -16,9 +23,13 @@ using Vector3D = OpenSees::VectorND<3, double>; -static_assert(std::is_trivially_copyable::value, "Vector3D is not trivially copyable."); -static_assert(std::is_trivial::value, "Vector3D is not trivial."); static_assert(std::is_standard_layout::value, "Vector3D is not standard layout."); static_assert(std::is_aggregate::value, "Vector3D is not an aggregate type."); +static_assert(std::is_trivially_copyable::value, "Vector3D is not trivially copyable."); +static_assert(std::is_trivially_move_assignable::value, "Vector3D is not trivially move assignable."); +static_assert(std::is_trivial::value, "Vector3D is not trivial."); + +static_assert(std::is_nothrow_constructible::value, "Vector3D is not nothrow constructible."); +static_assert(std::is_nothrow_move_assignable::value, "Vector3D is not nothrow move assignable."); #endif // Vector3D_h diff --git a/SRC/matrix/blasdecl.h b/SRC/matrix/blasdecl.h new file mode 100644 index 0000000000..6b57935b82 --- /dev/null +++ b/SRC/matrix/blasdecl.h @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +#ifndef blasdecl_H +#define blasdecl_H + +#ifndef _WIN32 +# define DAXPY daxpy_ +# define DSCAL dscal_ +# define DGEMV dgemv_ +// Level 3 +# define DGETRF dgetrf_ +# define DGETRI dgetri_ +# define DGEMM dgemm_ +// Lapack +# define DGESV dgesv_ +# define DGETRS dgetrs_ +# define DGBSV dgbsv_ +# define DGBTRS dgbtrs_ +# define DPBSV dpbsv_ +# define DPBTRS dpbtrs_ +#endif +extern "C" { + void DAXPY (int*, double*, double*, const int*, double*, const int*); + void DSCAL (int*, double*, double*, const int*); + void DGEMV (const char* trans, int* M, int* N, + double* alpha, + const double* A, int* lda, + double* X, int* incX, + double* beta, + double* Y, int* incY); +// Level 3 +//void DGESV(int *N, int *NRHS, double *A, int *LDA, +// int *iPiv, double *B, int *LDB, int *INFO); + + void DGETRF(int *M, int *N, double *A, int *LDA, + int *iPiv, int *INFO); + +//void DGETRS(char *TRANS, unsigned int sizeT, +// int *N, int *NRHS, double *A, int *LDA, +// int *iPiv, double *B, int *LDB, int *INFO); + + void DGETRI(int *N, double *A, int *LDA, + int *iPiv, double *Work, int *WORKL, int *INFO); + + void DGEMM(const char* transA, const char* transB, int* M, int* N, int* K, + double* alpha, + double* A, const int* lda, + double* B, const int* ldb, + double* beta, + double* C, const int* ldc); + +// +// Lapack +// +// FullGen +int DGESV(int *N, int *NRHS, double *A, int *LDA, + int *iPiv, double *B, int *LDB, int *INFO); + +int DGETRS(char *TRANS, + int *N, int *NRHS, double *A, int *LDA, + int *iPiv, double *B, int *LDB, int *INFO); + +// BandGen +int DGBSV(int *N, int *KL, int *KU, int *NRHS, double *A, + int *LDA, int *iPiv, double *B, int *LDB, + int *INFO); + +int DGBTRS(char *TRANS, + int *N, int *KL, int *KU, int *NRHS, + double *A, int *LDA, int *iPiv, + double *B, int *LDB, int *INFO); + +// BandSPD +int DPBSV(char *UPLO, + int *N, int *KD, int *NRHS, + double *A, int *LDA, double *B, int *LDB, + int *INFO); + +int DPBTRS(char *UPLO, + int *N, int *KD, int *NRHS, + double *A, int *LDA, double *B, int *LDB, + int *INFO); +} + +#endif // blasdecl_H From 0a3785077c51f0c564764b8dba855c13f5950691 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 24 Jun 2025 18:03:36 -0700 Subject: [PATCH 096/261] add unrolled matrix inverse routines. --- SRC/matrix/routines/cmx.h | 28 + SRC/matrix/routines/invGL2.c | 46 + SRC/matrix/routines/invGL3.c | 54 + SRC/matrix/routines/invGL4.c | 95 + SRC/matrix/routines/invGL5.c | 343 + SRC/matrix/routines/invGL6.c | 13385 +++++++++++++++++++++++++++++++++ 6 files changed, 13951 insertions(+) create mode 100644 SRC/matrix/routines/cmx.h create mode 100644 SRC/matrix/routines/invGL2.c create mode 100644 SRC/matrix/routines/invGL3.c create mode 100644 SRC/matrix/routines/invGL4.c create mode 100644 SRC/matrix/routines/invGL5.c create mode 100644 SRC/matrix/routines/invGL6.c diff --git a/SRC/matrix/routines/cmx.h b/SRC/matrix/routines/cmx.h new file mode 100644 index 0000000000..c9cc19faa7 --- /dev/null +++ b/SRC/matrix/routines/cmx.h @@ -0,0 +1,28 @@ +#ifndef cmx_h +#define cmx_h + +#ifdef __cplusplus +extern "C" { +#endif + +int cmx_inv2 (const double *a, double *ainv, int*ok_flag); +int cmx_inv3 (const double *a, double *ainv, int*ok_flag); +int cmx_inv4 (const double *a, double *ainv, int*ok_flag); +int cmx_inv5 (const double *a, double *ainv, int*ok_flag); +int cmx_inv6 (const double *a, double *ainv, int*ok_flag); +int cmx_inv6_v2(const double *a, double *ainv, int*ok_flag); +int cmx_inv6_v3(const double *a, double *ainv, int*ok_flag); + +#define cmx_inv(a, inv, flag) _Generic(&(a), \ + double(*)[ 4]: cmx_inv2, \ + double(*)[ 9]: cmx_inv3, \ + double(*)[16]: cmx_inv4, \ + double(*)[25]: cmx_inv5, \ + double(*)[36]: cmx_inv6 \ + )(a, inv, flag) + +#ifdef __cplusplus +} +#endif + +#endif // cmx_h diff --git a/SRC/matrix/routines/invGL2.c b/SRC/matrix/routines/invGL2.c new file mode 100644 index 0000000000..305c17c52b --- /dev/null +++ b/SRC/matrix/routines/invGL2.c @@ -0,0 +1,46 @@ +// +// adapted from https://caps.gsfc.nasa.gov/simpson/software/m22inv_f90.txt +// +// David Simpson +// Claudio Perez +// +#include + +int cmx_inv2(double *a, double *ainv, int *ok_flag__) +{ + /* **************************************************************************************** + * m22inv - compute the inverse of a 2x2 matrix. + * + * a : (input) 2x2 matrix to be inverted + * ainv : (output) 2x2 inverse of matrix a + * + * ok_flag: (output) 0 if the input matrix could be inverted, + * and -1 if the input matrix is singular. + * + * ****************************************************************************************/ + + /* Parameter adjustments */ + ainv -= 3; + a -= 3; + + /* Function Body */ + const double eps = 1e-10; + const double det = a[3] * a[6] - a[5] * a[4]; + if (fabs(det) <= eps) { + *ok_flag__ = -1; + } + + double cofactor[4]; + + cofactor[0] = a[6]; + cofactor[2] = -a[4]; + cofactor[1] = -a[5]; + cofactor[3] = a[3]; + + for (int i__ = 1; i__ <= 2; ++i__) + for (int j = 1; j <= 2; ++j) + ainv[j + (i__ << 1)] = cofactor[i__ + (j << 1) - 3] / det; + + *ok_flag__ = 0; + return 0; +} diff --git a/SRC/matrix/routines/invGL3.c b/SRC/matrix/routines/invGL3.c new file mode 100644 index 0000000000..a3a12f87e9 --- /dev/null +++ b/SRC/matrix/routines/invGL3.c @@ -0,0 +1,54 @@ +// +// adapted from https://caps.gsfc.nasa.gov/simpson/software/m33inv_f90.txt +// +#include + + +int cmx_inv3(double *a, double *ainv, int *ok_flag__) +{ +/* **************************************************************************************** */ +/* m33inv - compute the inverse of a 3x3 matrix. */ + +/* a = input 3x3 matrix to be inverted */ +/* ainv = output 3x3 inverse of matrix a */ +/* ok_flag = (output) .true. if the input matrix could be inverted, and */ +/* .false. if the input matrix is singular. */ +/* **************************************************************************************** */ + + + /* Parameter adjustments */ + ainv -= 4; + a -= 4; + + const double det = a[4]*a[8]*a[12] + - a[4]*a[11]*a[9] + - a[7]*a[5]*a[12] + + a[7]*a[11]*a[6] + + a[10]*a[5]*a[9] + - a[10]*a[8]*a[6]; + + const double eps=1e-10; + if (fabs(det) <= eps) { + *ok_flag__ = -1; + // return 0; + } + + double cofactor[9]; + cofactor[0] = a[8]*a[12] - a[11]*a[9]; + cofactor[3] = -(a[5]*a[12] - a[11]*a[6]); + cofactor[6] = a[5]*a[9] - a[8]*a[6]; + cofactor[1] = -(a[7]*a[12] - a[10]*a[9]); + cofactor[4] = a[4]*a[12] - a[10]*a[6]; + cofactor[7] = -(a[4]*a[9] - a[7]*a[6]); + cofactor[2] = a[7]*a[11] - a[10]*a[8]; + cofactor[5] = -(a[4]*a[11] - a[10]*a[5]); + cofactor[8] = a[4]*a[8] - a[7]*a[5]; + + for (int i__ = 1; i__ <= 3; ++i__) + for (int j = 1; j <= 3; ++j) + ainv[j + i__ * 3] = cofactor[i__ + j * 3 - 4] / det; + + *ok_flag__ = 0; + return 0; +} + diff --git a/SRC/matrix/routines/invGL4.c b/SRC/matrix/routines/invGL4.c new file mode 100644 index 0000000000..7060e2d58c --- /dev/null +++ b/SRC/matrix/routines/invGL4.c @@ -0,0 +1,95 @@ +// +// adapted from https://caps.gsfc.nasa.gov/simpson/software/m44inv_f90.txt +// +#include + +int cmx_inv4(double *a, double *ainv, int *ok_flag__) +{ +/* **************************************************************************************** + * m44inv - compute the inverse of a 4x4 matrix. + + * a = input 4x4 matrix to be inverted + * ainv = output 4x4 inverse of matrix a + * ok_flag = (output) .true. if the input matrix could be inverted, and .false. if the input matrix is singular. + * **************************************************************************************** */ + static double cofactor[16]; + static double eps=1e-10; + + /* Parameter adjustments */ + ainv -= 5; + a -= 5; + + const double det = a[ 5]*(a[10]*(a[15]*a[20] - a[19]*a[16]) + + a[14]*(a[19]*a[12] - a[11]*a[20]) + + a[18]*(a[11]*a[16] - a[15]*a[12])) + - a[ 9]*(a[ 6]*(a[15]*a[20] - a[19]*a[16]) + + a[14]*(a[19]*a[ 8] - a[ 7]*a[20]) + + a[18]*(a[ 7]*a[16] - a[15]*a[ 8])) + + a[13]*(a[ 6]*(a[11]*a[20] - a[19]*a[12]) + + a[10]*(a[19]*a[ 8] - a[ 7]*a[20]) + + a[18]*(a[ 7]*a[12] - a[11]*a[ 8])) + - a[17]*(a[ 6]*(a[11]*a[16] - a[15]*a[12]) + + a[10]*(a[15]*a[ 8] - a[ 7]*a[16]) + + a[14]*(a[ 7]*a[12] - a[11]*a[ 8])); + + if (fabs(det) <= eps) { + *ok_flag__ = -1; + } + + cofactor[ 0] = a[10]*(a[15]*a[20] - a[19]*a[16]) + + a[14]*(a[19]*a[12] - a[11]*a[20]) + + a[18]*(a[11]*a[16] - a[15]*a[12]); + cofactor[ 4] = a[ 6]*(a[19]*a[16] - a[15]*a[20]) + + a[14]*(a[ 7]*a[20] - a[19]*a[ 8]) + + a[18]*(a[15]*a[ 8] - a[ 7]*a[16]); + cofactor[ 8] = a[ 6]*(a[11]*a[20] - a[19]*a[12]) + + a[10]*(a[19]*a[ 8] - a[ 7]*a[20]) + + a[18]*(a[ 7]*a[12] - a[11]*a[ 8]); + cofactor[12] = a[ 6]*(a[15]*a[12] - a[11]*a[16]) + + a[10]*(a[ 7]*a[16] - a[15]*a[ 8]) + + a[14]*(a[11]*a[ 8] - a[ 7]*a[12]); + cofactor[ 1] = a[ 9]*(a[19]*a[16] - a[15]*a[20]) + + a[13]*(a[11]*a[20] - a[19]*a[12]) + + a[17]*(a[15]*a[12] - a[11]*a[16]); + cofactor[ 5] = a[ 5]*(a[15]*a[20] - a[19]*a[16]) + + a[13]*(a[19]*a[ 8] - a[ 7]*a[20]) + + a[17]*(a[ 7]*a[16] - a[15]*a[ 8]); + cofactor[ 9] = a[ 5]*(a[19]*a[12] - a[11]*a[20]) + + a[ 9]*(a[ 7]*a[20] - a[19]*a[ 8]) + + a[17]*(a[11]*a[ 8] - a[ 7]*a[12]); + cofactor[13] = a[ 5]*(a[11]*a[16] - a[15]*a[12]) + + a[ 9]*(a[15]*a[ 8] - a[ 7]*a[16]) + + a[13]*(a[ 7]*a[12] - a[11]*a[ 8]); + cofactor[ 2] = a[ 9]*(a[14]*a[20] - a[18]*a[16]) + + a[13]*(a[18]*a[12] - a[10]*a[20]) + + a[17]*(a[10]*a[16] - a[14]*a[12]); + cofactor[ 6] = a[ 5]*(a[18]*a[16] - a[14]*a[20]) + + a[13]*(a[ 6]*a[20] - a[18]*a[ 8]) + + a[17]*(a[14]*a[ 8] - a[ 6]*a[16]); + cofactor[10] = a[ 5]*(a[10]*a[20] - a[18]*a[12]) + + a[ 9]*(a[18]*a[ 8] - a[ 6]*a[20]) + + a[17]*(a[ 6]*a[12] - a[10]*a[ 8]); + cofactor[14] = a[ 5]*(a[14]*a[12] - a[10]*a[16]) + + a[ 9]*(a[ 6]*a[16] - a[14]*a[ 8]) + + a[13]*(a[10]*a[ 8] - a[ 6]*a[12]); + cofactor[ 3] = a[ 9]*(a[18]*a[15] - a[14]*a[19]) + + a[13]*(a[10]*a[19] - a[18]*a[11]) + + a[17]*(a[14]*a[11] - a[10]*a[15]); + cofactor[ 7] = a[ 5]*(a[14]*a[19] - a[18]*a[15]) + + a[13]*(a[18]*a[ 7] - a[ 6]*a[19]) + + a[17]*(a[ 6]*a[15] - a[14]*a[ 7]); + cofactor[11] = a[ 5]*(a[18]*a[11] - a[10]*a[19]) + + a[ 9]*(a[ 6]*a[19] - a[18]*a[ 7]) + + a[17]*(a[10]*a[ 7] - a[ 6]*a[11]); + cofactor[15] = a[ 5]*(a[10]*a[15] - a[14]*a[11]) + + a[ 9]*(a[14]*a[ 7] - a[ 6]*a[15]) + + a[13]*(a[ 6]*a[11] - a[10]*a[ 7]); + + for (int i__ = 1; i__ <= 4; ++i__) + for (int j = 1; j <= 4; ++j) + ainv[j + (i__ << 2)] = cofactor[i__ + (j << 2) - 5] / det; + + *ok_flag__ = 0; + return 0; +} + diff --git a/SRC/matrix/routines/invGL5.c b/SRC/matrix/routines/invGL5.c new file mode 100644 index 0000000000..fe121ccc09 --- /dev/null +++ b/SRC/matrix/routines/invGL5.c @@ -0,0 +1,343 @@ +// +// adapted from https://caps.gsfc.nasa.gov/simpson/software/m55inv_f90.txt +// +#include + +int cmx_inv5(double *a, double *ainv, int *ok_flag__) +{ +/* **************************************************************************************** + * m55inv - compute the inverse of a 5x5 matrix. + + * a = input 5x5 matrix to be inverted + * ainv = output 5x5 inverse of matrix a + * ok_flag = (output) .true. if the input matrix could be inverted, and .false. if the input matrix is singular. + ***************************************************************************************** */ + static double cofactor[25]; + static double a11, a12, a13, a14, a15, a21, a22, a23, a24, a25, a31, + a32, a33, a34, a35, a41, a42, a43, a44, a45, a51, a52, a53, a54, + a55, det; + + const double eps = 1e-10; + + /* Parameter adjustments */ + ainv -= 6; + a -= 6; + + a11 = a[6]; + a12 = a[11]; + a13 = a[16]; + a14 = a[21]; + a15 = a[26]; + a21 = a[7]; + a22 = a[12]; + a23 = a[17]; + a24 = a[22]; + a25 = a[27]; + a31 = a[8]; + a32 = a[13]; + a33 = a[18]; + a34 = a[23]; + a35 = a[28]; + a41 = a[9]; + a42 = a[14]; + a43 = a[19]; + a44 = a[24]; + a45 = a[29]; + a51 = a[10]; + a52 = a[15]; + a53 = a[20]; + a54 = a[25]; + a55 = a[30]; + det = a15*a24*a33*a42*a51 - a14*a25*a33*a42*a51 - a15* + a23*a34*a42*a51 + a13*a25*a34*a42*a51 + a14*a23* + a35*a42*a51 - a13*a24*a35*a42*a51 - a15*a24*a32* + a43*a51 + a14*a25*a32*a43*a51 + a15*a22*a34*a43* + a51 - a12*a25*a34*a43*a51 - a14*a22*a35*a43*a51 + + a12*a24*a35*a43*a51 + a15*a23*a32*a44*a51 - a13* + a25*a32*a44*a51 - a15*a22*a33*a44*a51 + a12*a25* + a33*a44*a51 + a13*a22*a35*a44*a51 - a12*a23*a35* + a44*a51 - a14*a23*a32*a45*a51 + a13*a24*a32*a45* + a51 + a14*a22*a33*a45*a51 - a12*a24*a33*a45*a51 - + a13*a22*a34*a45*a51 + a12*a23*a34*a45*a51 - a15* + a24*a33*a41*a52 + a14*a25*a33*a41*a52 + a15*a23* + a34*a41*a52 - a13*a25*a34*a41*a52 - a14*a23*a35* + a41*a52 + a13*a24*a35*a41*a52 + a15*a24*a31*a43* + a52 - a14*a25*a31*a43*a52 - a15*a21*a34*a43*a52 + + a11*a25*a34*a43*a52 + a14*a21*a35*a43*a52 - a11* + a24*a35*a43*a52 - a15*a23*a31*a44*a52 + a13*a25* + a31*a44*a52 + a15*a21*a33*a44*a52 - a11*a25*a33* + a44*a52 - a13*a21*a35*a44*a52 + a11*a23*a35*a44* + a52 + a14*a23*a31*a45*a52 - a13*a24*a31*a45*a52 - + a14*a21*a33*a45*a52 + a11*a24*a33*a45*a52 + a13* + a21*a34*a45*a52 - a11*a23*a34*a45*a52 + a15*a24* + a32*a41*a53 - a14*a25*a32*a41*a53 - a15*a22*a34* + a41*a53 + a12*a25*a34*a41*a53 + a14*a22*a35*a41* + a53 - a12*a24*a35*a41*a53 - a15*a24*a31*a42*a53 + + a14*a25*a31*a42*a53 + a15*a21*a34*a42*a53 - a11* + a25*a34*a42*a53 - a14*a21*a35*a42*a53 + a11*a24* + a35*a42*a53 + a15*a22*a31*a44*a53 - a12*a25*a31* + a44*a53 - a15*a21*a32*a44*a53 + a11*a25*a32*a44* + a53 + a12*a21*a35*a44*a53 - a11*a22*a35*a44*a53 - + a14*a22*a31*a45*a53 + a12*a24*a31*a45*a53 + a14* + a21*a32*a45*a53 - a11*a24*a32*a45*a53 - a12*a21* + a34*a45*a53 + a11*a22*a34*a45*a53 - a15*a23*a32* + a41*a54 + a13*a25*a32*a41*a54 + a15*a22*a33*a41* + a54 - a12*a25*a33*a41*a54 - a13*a22*a35*a41*a54 + + a12*a23*a35*a41*a54 + a15*a23*a31*a42*a54 - a13* + a25*a31*a42*a54 - a15*a21*a33*a42*a54 + a11*a25* + a33*a42*a54 + a13*a21*a35*a42*a54 - a11*a23*a35* + a42*a54 - a15*a22*a31*a43*a54 + a12*a25*a31*a43* + a54 + a15*a21*a32*a43*a54 - a11*a25*a32*a43*a54 - + a12*a21*a35*a43*a54 + a11*a22*a35*a43*a54 + a13* + a22*a31*a45*a54 - a12*a23*a31*a45*a54 - a13*a21* + a32*a45*a54 + a11*a23*a32*a45*a54 + a12*a21*a33* + a45*a54 - a11*a22*a33*a45*a54 + a14*a23*a32*a41* + a55 - a13*a24*a32*a41*a55 - a14*a22*a33*a41*a55 + + a12*a24*a33*a41*a55 + a13*a22*a34*a41*a55 - a12* + a23*a34*a41*a55 - a14*a23*a31*a42*a55 + a13*a24* + a31*a42*a55 + a14*a21*a33*a42*a55 - a11*a24*a33* + a42*a55 - a13*a21*a34*a42*a55 + a11*a23*a34*a42* + a55 + a14*a22*a31*a43*a55 - a12*a24*a31*a43*a55 - + a14*a21*a32*a43*a55 + a11*a24*a32*a43*a55 + a12* + a21*a34*a43*a55 - a11*a22*a34*a43*a55 - a13*a22* + a31*a44*a55 + a12*a23*a31*a44*a55 + a13*a21*a32* + a44*a55 - a11*a23*a32*a44*a55 - a12*a21*a33*a44* + a55 + a11*a22*a33*a44*a55; + if (fabs(det) <= eps) { + *ok_flag__ = -1; + return 0; + } + cofactor[0] = a25*a34*a43*a52 - a24*a35*a43*a52 - a25*a33* + a44*a52 + a23*a35*a44*a52 + a24*a33*a45*a52 - a23* + a34*a45*a52 - a25*a34*a42*a53 + a24*a35*a42*a53 + + a25*a32*a44*a53 - a22*a35*a44*a53 - a24*a32*a45* + a53 + a22*a34*a45*a53 + a25*a33*a42*a54 - a23*a35* + a42*a54 - a25*a32*a43*a54 + a22*a35*a43*a54 + a23* + a32*a45*a54 - a22*a33*a45*a54 - a24*a33*a42*a55 + + a23*a34*a42*a55 + a24*a32*a43*a55 - a22*a34*a43* + a55 - a23*a32*a44*a55 + a22*a33*a44*a55; + cofactor[1] = -a15*a34*a43*a52 + a14*a35*a43*a52 + a15*a33 * + a44*a52 - a13*a35*a44*a52 - a14*a33*a45*a52 + a13 * + a34*a45*a52 + a15*a34*a42*a53 - a14*a35*a42*a53 + - a15*a32*a44*a53 + a12*a35*a44*a53 + a14*a32*a45 + *a53 - a12*a34*a45*a53 - a15*a33*a42*a54 + a13*a35 + *a42*a54 + a15*a32*a43*a54 - a12*a35*a43*a54 - a13 + *a32*a45*a54 + a12*a33*a45*a54 + a14*a33*a42*a55 + - a13*a34*a42*a55 - a14*a32*a43*a55 + a12*a34*a43 + *a55 + a13*a32*a44*a55 - a12*a33*a44*a55; + cofactor[2] = a15*a24*a43*a52 - a14*a25*a43*a52 - a15*a23* + a44*a52 + a13*a25*a44*a52 + a14*a23*a45*a52 - a13* + a24*a45*a52 - a15*a24*a42*a53 + a14*a25*a42*a53 + + a15*a22*a44*a53 - a12*a25*a44*a53 - a14*a22*a45* + a53 + a12*a24*a45*a53 + a15*a23*a42*a54 - a13*a25* + a42*a54 - a15*a22*a43*a54 + a12*a25*a43*a54 + a13* + a22*a45*a54 - a12*a23*a45*a54 - a14*a23*a42*a55 + + a13*a24*a42*a55 + a14*a22*a43*a55 - a12*a24*a43* + a55 - a13*a22*a44*a55 + a12*a23*a44*a55; + cofactor[3] = -a15*a24*a33*a52 + a14*a25*a33*a52 + a15*a23 * + a34*a52 - a13*a25*a34*a52 - a14*a23*a35*a52 + a13 * + a24*a35*a52 + a15*a24*a32*a53 - a14*a25*a32*a53 + - a15*a22*a34*a53 + a12*a25*a34*a53 + a14*a22*a35 + *a53 - a12*a24*a35*a53 - a15*a23*a32*a54 + a13*a25 + *a32*a54 + a15*a22*a33*a54 - a12*a25*a33*a54 - a13 + *a22*a35*a54 + a12*a23*a35*a54 + a14*a23*a32*a55 + - a13*a24*a32*a55 - a14*a22*a33*a55 + a12*a24*a33 + *a55 + a13*a22*a34*a55 - a12*a23*a34*a55; + cofactor[4] = a15*a24*a33*a42 - a14*a25*a33*a42 - a15*a23* + a34*a42 + a13*a25*a34*a42 + a14*a23*a35*a42 - a13* + a24*a35*a42 - a15*a24*a32*a43 + a14*a25*a32*a43 + + a15*a22*a34*a43 - a12*a25*a34*a43 - a14*a22*a35* + a43 + a12*a24*a35*a43 + a15*a23*a32*a44 - a13*a25* + a32*a44 - a15*a22*a33*a44 + a12*a25*a33*a44 + a13* + a22*a35*a44 - a12*a23*a35*a44 - a14*a23*a32*a45 + + a13*a24*a32*a45 + a14*a22*a33*a45 - a12*a24*a33* + a45 - a13*a22*a34*a45 + a12*a23*a34*a45; + cofactor[5] = -a25*a34*a43*a51 + a24*a35*a43*a51 + a25*a33 * + a44*a51 - a23*a35*a44*a51 - a24*a33*a45*a51 + a23 * + a34*a45*a51 + a25*a34*a41*a53 - a24*a35*a41*a53 + - a25*a31*a44*a53 + a21*a35*a44*a53 + a24*a31*a45 + *a53 - a21*a34*a45*a53 - a25*a33*a41*a54 + a23*a35 + *a41*a54 + a25*a31*a43*a54 - a21*a35*a43*a54 - a23 + *a31*a45*a54 + a21*a33*a45*a54 + a24*a33*a41*a55 + - a23*a34*a41*a55 - a24*a31*a43*a55 + a21*a34*a43 + *a55 + a23*a31*a44*a55 - a21*a33*a44*a55; + cofactor[6] = a15*a34*a43*a51 - a14*a35*a43*a51 - a15*a33* + a44*a51 + a13*a35*a44*a51 + a14*a33*a45*a51 - a13* + a34*a45*a51 - a15*a34*a41*a53 + a14*a35*a41*a53 + + a15*a31*a44*a53 - a11*a35*a44*a53 - a14*a31*a45* + a53 + a11*a34*a45*a53 + a15*a33*a41*a54 - a13*a35* + a41*a54 - a15*a31*a43*a54 + a11*a35*a43*a54 + a13* + a31*a45*a54 - a11*a33*a45*a54 - a14*a33*a41*a55 + + a13*a34*a41*a55 + a14*a31*a43*a55 - a11*a34*a43* + a55 - a13*a31*a44*a55 + a11*a33*a44*a55; + cofactor[7] = -a15*a24*a43*a51 + a14*a25*a43*a51 + a15*a23 * + a44*a51 - a13*a25*a44*a51 - a14*a23*a45*a51 + a13 * + a24*a45*a51 + a15*a24*a41*a53 - a14*a25*a41*a53 + - a15*a21*a44*a53 + a11*a25*a44*a53 + a14*a21*a45 + *a53 - a11*a24*a45*a53 - a15*a23*a41*a54 + a13*a25 + *a41*a54 + a15*a21*a43*a54 - a11*a25*a43*a54 - a13 + *a21*a45*a54 + a11*a23*a45*a54 + a14*a23*a41*a55 + - a13*a24*a41*a55 - a14*a21*a43*a55 + a11*a24*a43 + *a55 + a13*a21*a44*a55 - a11*a23*a44*a55; + cofactor[8] = a15*a24*a33*a51 - a14*a25*a33*a51 - a15*a23* + a34*a51 + a13*a25*a34*a51 + a14*a23*a35*a51 - a13* + a24*a35*a51 - a15*a24*a31*a53 + a14*a25*a31*a53 + + a15*a21*a34*a53 - a11*a25*a34*a53 - a14*a21*a35* + a53 + a11*a24*a35*a53 + a15*a23*a31*a54 - a13*a25* + a31*a54 - a15*a21*a33*a54 + a11*a25*a33*a54 + a13* + a21*a35*a54 - a11*a23*a35*a54 - a14*a23*a31*a55 + + a13*a24*a31*a55 + a14*a21*a33*a55 - a11*a24*a33* + a55 - a13*a21*a34*a55 + a11*a23*a34*a55; + cofactor[9] = -a15*a24*a33*a41 + a14*a25*a33*a41 + a15*a23 * + a34*a41 - a13*a25*a34*a41 - a14*a23*a35*a41 + a13 * + a24*a35*a41 + a15*a24*a31*a43 - a14*a25*a31*a43 + - a15*a21*a34*a43 + a11*a25*a34*a43 + a14*a21*a35 + *a43 - a11*a24*a35*a43 - a15*a23*a31*a44 + a13*a25 + *a31*a44 + a15*a21*a33*a44 - a11*a25*a33*a44 - a13 + *a21*a35*a44 + a11*a23*a35*a44 + a14*a23*a31*a45 + - a13*a24*a31*a45 - a14*a21*a33*a45 + a11*a24*a33 + *a45 + a13*a21*a34*a45 - a11*a23*a34*a45; + cofactor[10] = a25*a34*a42*a51 - a24*a35*a42*a51 - a25*a32 * + a44*a51 + a22*a35*a44*a51 + a24*a32*a45*a51 - a22 * + a34*a45*a51 - a25*a34*a41*a52 + a24*a35*a41*a52 + + a25*a31*a44*a52 - a21*a35*a44*a52 - a24*a31*a45 + *a52 + a21*a34*a45*a52 + a25*a32*a41*a54 - a22*a35 + *a41*a54 - a25*a31*a42*a54 + a21*a35*a42*a54 + a22 + *a31*a45*a54 - a21*a32*a45*a54 - a24*a32*a41*a55 + + a22*a34*a41*a55 + a24*a31*a42*a55 - a21*a34*a42 + *a55 - a22*a31*a44*a55 + a21*a32*a44*a55; + cofactor[11] = -a15*a34*a42*a51 + a14*a35*a42*a51 + a15*a32 + *a44*a51 - a12*a35*a44*a51 - a14*a32*a45*a51 + a12 + *a34*a45*a51 + a15*a34*a41*a52 - a14*a35*a41*a52 + - a15*a31*a44*a52 + a11*a35*a44*a52 + a14*a31*a45 + *a52 - a11*a34*a45*a52 - a15*a32*a41*a54 + a12*a35 + *a41*a54 + a15*a31*a42*a54 - a11*a35*a42*a54 - a12 + *a31*a45*a54 + a11*a32*a45*a54 + a14*a32*a41*a55 + - a12*a34*a41*a55 - a14*a31*a42*a55 + a11*a34*a42 + *a55 + a12*a31*a44*a55 - a11*a32*a44*a55; + cofactor[12] = a15*a24*a42*a51 - a14*a25*a42*a51 - a15*a22 * + a44*a51 + a12*a25*a44*a51 + a14*a22*a45*a51 - a12 * + a24*a45*a51 - a15*a24*a41*a52 + a14*a25*a41*a52 + + a15*a21*a44*a52 - a11*a25*a44*a52 - a14*a21*a45 + *a52 + a11*a24*a45*a52 + a15*a22*a41*a54 - a12*a25 + *a41*a54 - a15*a21*a42*a54 + a11*a25*a42*a54 + a12 + *a21*a45*a54 - a11*a22*a45*a54 - a14*a22*a41*a55 + + a12*a24*a41*a55 + a14*a21*a42*a55 - a11*a24*a42 + *a55 - a12*a21*a44*a55 + a11*a22*a44*a55; + cofactor[13] = -a15*a24*a32*a51 + a14*a25*a32*a51 + a15*a22 + *a34*a51 - a12*a25*a34*a51 - a14*a22*a35*a51 + a12 + *a24*a35*a51 + a15*a24*a31*a52 - a14*a25*a31*a52 + - a15*a21*a34*a52 + a11*a25*a34*a52 + a14*a21*a35 + *a52 - a11*a24*a35*a52 - a15*a22*a31*a54 + a12*a25 + *a31*a54 + a15*a21*a32*a54 - a11*a25*a32*a54 - a12 + *a21*a35*a54 + a11*a22*a35*a54 + a14*a22*a31*a55 + - a12*a24*a31*a55 - a14*a21*a32*a55 + a11*a24*a32 + *a55 + a12*a21*a34*a55 - a11*a22*a34*a55; + cofactor[14] = a15*a24*a32*a41 - a14*a25*a32*a41 - a15*a22 * + a34*a41 + a12*a25*a34*a41 + a14*a22*a35*a41 - a12 * + a24*a35*a41 - a15*a24*a31*a42 + a14*a25*a31*a42 + + a15*a21*a34*a42 - a11*a25*a34*a42 - a14*a21*a35 + *a42 + a11*a24*a35*a42 + a15*a22*a31*a44 - a12*a25 + *a31*a44 - a15*a21*a32*a44 + a11*a25*a32*a44 + a12 + *a21*a35*a44 - a11*a22*a35*a44 - a14*a22*a31*a45 + + a12*a24*a31*a45 + a14*a21*a32*a45 - a11*a24*a32 + *a45 - a12*a21*a34*a45 + a11*a22*a34*a45; + cofactor[15] = -a25*a33*a42*a51 + a23*a35*a42*a51 + a25*a32 + *a43*a51 - a22*a35*a43*a51 - a23*a32*a45*a51 + a22 + *a33*a45*a51 + a25*a33*a41*a52 - a23*a35*a41*a52 + - a25*a31*a43*a52 + a21*a35*a43*a52 + a23*a31*a45 + *a52 - a21*a33*a45*a52 - a25*a32*a41*a53 + a22*a35 + *a41*a53 + a25*a31*a42*a53 - a21*a35*a42*a53 - a22 + *a31*a45*a53 + a21*a32*a45*a53 + a23*a32*a41*a55 + - a22*a33*a41*a55 - a23*a31*a42*a55 + a21*a33*a42 + *a55 + a22*a31*a43*a55 - a21*a32*a43*a55; + cofactor[16] = a15*a33*a42*a51 - a13*a35*a42*a51 - a15*a32 * + a43*a51 + a12*a35*a43*a51 + a13*a32*a45*a51 - a12 * + a33*a45*a51 - a15*a33*a41*a52 + a13*a35*a41*a52 + + a15*a31*a43*a52 - a11*a35*a43*a52 - a13*a31*a45 + *a52 + a11*a33*a45*a52 + a15*a32*a41*a53 - a12*a35 + *a41*a53 - a15*a31*a42*a53 + a11*a35*a42*a53 + a12 + *a31*a45*a53 - a11*a32*a45*a53 - a13*a32*a41*a55 + + a12*a33*a41*a55 + a13*a31*a42*a55 - a11*a33*a42 + *a55 - a12*a31*a43*a55 + a11*a32*a43*a55; + cofactor[17] = -a15*a23*a42*a51 + a13*a25*a42*a51 + a15*a22 + *a43*a51 - a12*a25*a43*a51 - a13*a22*a45*a51 + a12 + *a23*a45*a51 + a15*a23*a41*a52 - a13*a25*a41*a52 + - a15*a21*a43*a52 + a11*a25*a43*a52 + a13*a21*a45 + *a52 - a11*a23*a45*a52 - a15*a22*a41*a53 + a12*a25 + *a41*a53 + a15*a21*a42*a53 - a11*a25*a42*a53 - a12 + *a21*a45*a53 + a11*a22*a45*a53 + a13*a22*a41*a55 + - a12*a23*a41*a55 - a13*a21*a42*a55 + a11*a23*a42 + *a55 + a12*a21*a43*a55 - a11*a22*a43*a55; + cofactor[18] = a15*a23*a32*a51 - a13*a25*a32*a51 - a15*a22 * + a33*a51 + a12*a25*a33*a51 + a13*a22*a35*a51 - a12 * + a23*a35*a51 - a15*a23*a31*a52 + a13*a25*a31*a52 + + a15*a21*a33*a52 - a11*a25*a33*a52 - a13*a21*a35 + *a52 + a11*a23*a35*a52 + a15*a22*a31*a53 - a12*a25 + *a31*a53 - a15*a21*a32*a53 + a11*a25*a32*a53 + a12 + *a21*a35*a53 - a11*a22*a35*a53 - a13*a22*a31*a55 + + a12*a23*a31*a55 + a13*a21*a32*a55 - a11*a23*a32 + *a55 - a12*a21*a33*a55 + a11*a22*a33*a55; + cofactor[19] = -a15*a23*a32*a41 + a13*a25*a32*a41 + a15*a22 + *a33*a41 - a12*a25*a33*a41 - a13*a22*a35*a41 + a12 + *a23*a35*a41 + a15*a23*a31*a42 - a13*a25*a31*a42 + - a15*a21*a33*a42 + a11*a25*a33*a42 + a13*a21*a35 + *a42 - a11*a23*a35*a42 - a15*a22*a31*a43 + a12*a25 + *a31*a43 + a15*a21*a32*a43 - a11*a25*a32*a43 - a12 + *a21*a35*a43 + a11*a22*a35*a43 + a13*a22*a31*a45 + - a12*a23*a31*a45 - a13*a21*a32*a45 + a11*a23*a32 + *a45 + a12*a21*a33*a45 - a11*a22*a33*a45; + cofactor[20] = a24*a33*a42*a51 - a23*a34*a42*a51 - a24*a32 * + a43*a51 + a22*a34*a43*a51 + a23*a32*a44*a51 - a22 * + a33*a44*a51 - a24*a33*a41*a52 + a23*a34*a41*a52 + + a24*a31*a43*a52 - a21*a34*a43*a52 - a23*a31*a44 + *a52 + a21*a33*a44*a52 + a24*a32*a41*a53 - a22*a34 + *a41*a53 - a24*a31*a42*a53 + a21*a34*a42*a53 + a22 + *a31*a44*a53 - a21*a32*a44*a53 - a23*a32*a41*a54 + + a22*a33*a41*a54 + a23*a31*a42*a54 - a21*a33*a42 + *a54 - a22*a31*a43*a54 + a21*a32*a43*a54; + cofactor[21] = -a14*a33*a42*a51 + a13*a34*a42*a51 + a14*a32 + *a43*a51 - a12*a34*a43*a51 - a13*a32*a44*a51 + a12 + *a33*a44*a51 + a14*a33*a41*a52 - a13*a34*a41*a52 + - a14*a31*a43*a52 + a11*a34*a43*a52 + a13*a31*a44 + *a52 - a11*a33*a44*a52 - a14*a32*a41*a53 + a12*a34 + *a41*a53 + a14*a31*a42*a53 - a11*a34*a42*a53 - a12 + *a31*a44*a53 + a11*a32*a44*a53 + a13*a32*a41*a54 + - a12*a33*a41*a54 - a13*a31*a42*a54 + a11*a33*a42 + *a54 + a12*a31*a43*a54 - a11*a32*a43*a54; + cofactor[22] = a14*a23*a42*a51 - a13*a24*a42*a51 - a14*a22 * + a43*a51 + a12*a24*a43*a51 + a13*a22*a44*a51 - a12 * + a23*a44*a51 - a14*a23*a41*a52 + a13*a24*a41*a52 + + a14*a21*a43*a52 - a11*a24*a43*a52 - a13*a21*a44 + *a52 + a11*a23*a44*a52 + a14*a22*a41*a53 - a12*a24 + *a41*a53 - a14*a21*a42*a53 + a11*a24*a42*a53 + a12 + *a21*a44*a53 - a11*a22*a44*a53 - a13*a22*a41*a54 + + a12*a23*a41*a54 + a13*a21*a42*a54 - a11*a23*a42 + *a54 - a12*a21*a43*a54 + a11*a22*a43*a54; + cofactor[23] = -a14*a23*a32*a51 + a13*a24*a32*a51 + a14*a22 + *a33*a51 - a12*a24*a33*a51 - a13*a22*a34*a51 + a12 + *a23*a34*a51 + a14*a23*a31*a52 - a13*a24*a31*a52 + - a14*a21*a33*a52 + a11*a24*a33*a52 + a13*a21*a34 + *a52 - a11*a23*a34*a52 - a14*a22*a31*a53 + a12*a24 + *a31*a53 + a14*a21*a32*a53 - a11*a24*a32*a53 - a12 + *a21*a34*a53 + a11*a22*a34*a53 + a13*a22*a31*a54 + - a12*a23*a31*a54 - a13*a21*a32*a54 + a11*a23*a32 + *a54 + a12*a21*a33*a54 - a11*a22*a33*a54; + cofactor[24] = a14*a23*a32*a41 - a13*a24*a32*a41 - a14*a22 * + a33*a41 + a12*a24*a33*a41 + a13*a22*a34*a41 - a12 * + a23*a34*a41 - a14*a23*a31*a42 + a13*a24*a31*a42 + + a14*a21*a33*a42 - a11*a24*a33*a42 - a13*a21*a34 + *a42 + a11*a23*a34*a42 + a14*a22*a31*a43 - a12*a24 + *a31*a43 - a14*a21*a32*a43 + a11*a24*a32*a43 + a12 + *a21*a34*a43 - a11*a22*a34*a43 - a13*a22*a31*a44 + + a12*a23*a31*a44 + a13*a21*a32*a44 - a11*a23*a32 + *a44 - a12*a21*a33*a44 + a11*a22*a33*a44; + + for (int i__ = 1; i__ <= 5; ++i__) + for (int j = 1; j <= 5; ++j) + ainv[j + i__*5] = cofactor[i__ + j*5 - 6] / det; + + *ok_flag__ = 0; + return 0; +} + diff --git a/SRC/matrix/routines/invGL6.c b/SRC/matrix/routines/invGL6.c new file mode 100644 index 0000000000..ef7477e39d --- /dev/null +++ b/SRC/matrix/routines/invGL6.c @@ -0,0 +1,13385 @@ +// +// adapted from https://caps.gsfc.nasa.gov/simpson/software/m66inv_f90.txt +// +// TODO: Do symmetric version +// +#include + +#if 0 +int cmx_inv6_v0(double *a, double *ainv, int*ok_flag__) +{ +/* **************************************************************************************** * + * m66inv - compute the inverse of a 6x6 matrix. + * + * a = input 6x6 matrix to be inverted + * ainv = output 6x6 inverse of matrix a + * ok_flag = (output) .true. if the input matrix could be inverted, + * and .false. if the input matrix is singular. + * **************************************************************************************** */ + + double cofactor[36] /* was [6][6] */; + double det; + + /* Parameter adjustments */ + ainv -= 7; + a -= 7; + + /* Function Body */ + const double eps = 1e-10; + const double a11 = a[7]; + const double a12 = a[13]; + const double a13 = a[19]; + const double a14 = a[25]; + const double a15 = a[31]; + const double a16 = a[37]; + const double a21 = a[8]; + const double a22 = a[14]; + const double a23 = a[20]; + const double a24 = a[26]; + const double a25 = a[32]; + const double a26 = a[38]; + const double a31 = a[9]; + const double a32 = a[15]; + const double a33 = a[21]; + const double a34 = a[27]; + const double a35 = a[33]; + const double a36 = a[39]; + const double a41 = a[10]; + const double a42 = a[16]; + const double a43 = a[22]; + const double a44 = a[28]; + const double a45 = a[34]; + const double a46 = a[40]; + const double a51 = a[11]; + const double a52 = a[17]; + const double a53 = a[23]; + const double a54 = a[29]; + const double a55 = a[35]; + const double a56 = a[41]; + const double a61 = a[12]; + const double a62 = a[18]; + const double a63 = a[24]; + const double a64 = a[30]; + const double a65 = a[36]; + const double a66 = a[42]; + det = -(a16 * a25 * a34 * a43 * a52 - a15 * a26 * a34 * a43 * a52 - a16 * + a24 * a35 * a43 * a52 + a14 * a26 * a35 * a43 * a52 + a15 * a24 * + a36 * a43 * a52 - a14 * a25 * a36 * a43 * a52 - a16 * a25 * a33 * + a44 * a52 + a15 * a26 * a33 * a44 * a52 + a16 * a23 * a35 * a44 * + a52 - a13 * a26 * a35 * a44 * a52 - a15 * a23 * a36 * a44 * a52 + + a13 * a25 * a36 * a44 * a52 + a16 * a24 * a33 * a45 * a52 - a14 * + a26 * a33 * a45 * a52 - a16 * a23 * a34 * a45 * a52 + a13 * a26 * + a34 * a45 * a52 + a14 * a23 * a36 * a45 * a52 - a13 * a24 * a36 * + a45 * a52 - a15 * a24 * a33 * a46 * a52 + a14 * a25 * a33 * a46 * + a52 + a15 * a23 * a34 * a46 * a52 - a13 * a25 * a34 * a46 * a52 - + a14 * a23 * a35 * a46 * a52 + a13 * a24 * a35 * a46 * a52 - a16 * + a25 * a34 * a42 * a53 + a15 * a26 * a34 * a42 * a53 + a16 * a24 * + a35 * a42 * a53 - a14 * a26 * a35 * a42 * a53 - a15 * a24 * a36 * + a42 * a53 + a14 * a25 * a36 * a42 * a53 + a16 * a25 * a32 * a44 * + a53 - a15 * a26 * a32 * a44 * a53 - a16 * a22 * a35 * a44 * a53 + + a12 * a26 * a35 * a44 * a53 + a15 * a22 * a36 * a44 * a53 - a12 * + a25 * a36 * a44 * a53 - a16 * a24 * a32 * a45 * a53 + a14 * a26 * + a32 * a45 * a53 + a16 * a22 * a34 * a45 * a53 - a12 * a26 * a34 * + a45 * a53 - a14 * a22 * a36 * a45 * a53 + a12 * a24 * a36 * a45 * + a53 + a15 * a24 * a32 * a46 * a53 - a14 * a25 * a32 * a46 * a53 - + a15 * a22 * a34 * a46 * a53 + a12 * a25 * a34 * a46 * a53 + a14 * + a22 * a35 * a46 * a53 - a12 * a24 * a35 * a46 * a53 + a16 * a25 * + a33 * a42 * a54 - a15 * a26 * a33 * a42 * a54 - a16 * a23 * a35 * + a42 * a54 + a13 * a26 * a35 * a42 * a54 + a15 * a23 * a36 * a42 * + a54 - a13 * a25 * a36 * a42 * a54 - a16 * a25 * a32 * a43 * a54 + + a15 * a26 * a32 * a43 * a54 + a16 * a22 * a35 * a43 * a54 - a12 * + a26 * a35 * a43 * a54 - a15 * a22 * a36 * a43 * a54 + a12 * a25 * + a36 * a43 * a54 + a16 * a23 * a32 * a45 * a54 - a13 * a26 * a32 * + a45 * a54 - a16 * a22 * a33 * a45 * a54 + a12 * a26 * a33 * a45 * + a54 + a13 * a22 * a36 * a45 * a54 - a12 * a23 * a36 * a45 * a54 - + a15 * a23 * a32 * a46 * a54 + a13 * a25 * a32 * a46 * a54 + a15 * + a22 * a33 * a46 * a54 - a12 * a25 * a33 * a46 * a54 - a13 * a22 * + a35 * a46 * a54 + a12 * a23 * a35 * a46 * a54 - a16 * a24 * a33 * + a42 * a55 + a14 * a26 * a33 * a42 * a55 + a16 * a23 * a34 * a42 * + a55 - a13 * a26 * a34 * a42 * a55 - a14 * a23 * a36 * a42 * a55 + + a13 * a24 * a36 * a42 * a55 + a16 * a24 * a32 * a43 * a55 - a14 * + a26 * a32 * a43 * a55 - a16 * a22 * a34 * a43 * a55 + a12 * a26 * + a34 * a43 * a55 + a14 * a22 * a36 * a43 * a55 - a12 * a24 * a36 * + a43 * a55 - a16 * a23 * a32 * a44 * a55 + a13 * a26 * a32 * a44 * + a55 + a16 * a22 * a33 * a44 * a55 - a12 * a26 * a33 * a44 * a55 - + a13 * a22 * a36 * a44 * a55 + a12 * a23 * a36 * a44 * a55 + a14 * + a23 * a32 * a46 * a55 - a13 * a24 * a32 * a46 * a55 - a14 * a22 * + a33 * a46 * a55 + a12 * a24 * a33 * a46 * a55 + a13 * a22 * a34 * + a46 * a55 - a12 * a23 * a34 * a46 * a55 + a15 * a24 * a33 * a42 * + a56 - a14 * a25 * a33 * a42 * a56 - a15 * a23 * a34 * a42 * a56 + + a13 * a25 * a34 * a42 * a56 + a14 * a23 * a35 * a42 * a56 - a13 * + a24 * a35 * a42 * a56 - a15 * a24 * a32 * a43 * a56 + a14 * a25 * + a32 * a43 * a56 + a15 * a22 * a34 * a43 * a56 - a12 * a25 * a34 * + a43 * a56 - a14 * a22 * a35 * a43 * a56 + a12 * a24 * a35 * a43 * + a56 + a15 * a23 * a32 * a44 * a56 - a13 * a25 * a32 * a44 * a56 - + a15 * a22 * a33 * a44 * a56 + a12 * a25 * a33 * a44 * a56 + a13 * + a22 * a35 * a44 * a56 - a12 * a23 * a35 * a44 * a56 - a14 * a23 * + a32 * a45 * a56 + a13 * a24 * a32 * a45 * a56 + a14 * a22 * a33 * + a45 * a56 - a12 * a24 * a33 * a45 * a56 - a13 * a22 * a34 * a45 * + a56 + a12 * a23 * a34 * a45 * a56) * a61 + (a16 * a25 * a34 * a43 + * a51 - a15 * a26 * a34 * a43 * a51 - a16 * a24 * a35 * a43 * a51 + + a14 * a26 * a35 * a43 * a51 + a15 * a24 * a36 * a43 * a51 - a14 + * a25 * a36 * a43 * a51 - a16 * a25 * a33 * a44 * a51 + a15 * a26 + * a33 * a44 * a51 + a16 * a23 * a35 * a44 * a51 - a13 * a26 * a35 + * a44 * a51 - a15 * a23 * a36 * a44 * a51 + a13 * a25 * a36 * a44 + * a51 + a16 * a24 * a33 * a45 * a51 - a14 * a26 * a33 * a45 * a51 + - a16 * a23 * a34 * a45 * a51 + a13 * a26 * a34 * a45 * a51 + a14 + * a23 * a36 * a45 * a51 - a13 * a24 * a36 * a45 * a51 - a15 * a24 + * a33 * a46 * a51 + a14 * a25 * a33 * a46 * a51 + a15 * a23 * a34 + * a46 * a51 - a13 * a25 * a34 * a46 * a51 - a14 * a23 * a35 * a46 + * a51 + a13 * a24 * a35 * a46 * a51 - a16 * a25 * a34 * a41 * a53 + + a15 * a26 * a34 * a41 * a53 + a16 * a24 * a35 * a41 * a53 - a14 + * a26 * a35 * a41 * a53 - a15 * a24 * a36 * a41 * a53 + a14 * a25 + * a36 * a41 * a53 + a16 * a25 * a31 * a44 * a53 - a15 * a26 * a31 + * a44 * a53 - a16 * a21 * a35 * a44 * a53 + a11 * a26 * a35 * a44 + * a53 + a15 * a21 * a36 * a44 * a53 - a11 * a25 * a36 * a44 * a53 + - a16 * a24 * a31 * a45 * a53 + a14 * a26 * a31 * a45 * a53 + a16 + * a21 * a34 * a45 * a53 - a11 * a26 * a34 * a45 * a53 - a14 * a21 + * a36 * a45 * a53 + a11 * a24 * a36 * a45 * a53 + a15 * a24 * a31 + * a46 * a53 - a14 * a25 * a31 * a46 * a53 - a15 * a21 * a34 * a46 + * a53 + a11 * a25 * a34 * a46 * a53 + a14 * a21 * a35 * a46 * a53 + - a11 * a24 * a35 * a46 * a53 + a16 * a25 * a33 * a41 * a54 - a15 + * a26 * a33 * a41 * a54 - a16 * a23 * a35 * a41 * a54 + a13 * a26 + * a35 * a41 * a54 + a15 * a23 * a36 * a41 * a54 - a13 * a25 * a36 + * a41 * a54 - a16 * a25 * a31 * a43 * a54 + a15 * a26 * a31 * a43 + * a54 + a16 * a21 * a35 * a43 * a54 - a11 * a26 * a35 * a43 * a54 + - a15 * a21 * a36 * a43 * a54 + a11 * a25 * a36 * a43 * a54 + a16 + * a23 * a31 * a45 * a54 - a13 * a26 * a31 * a45 * a54 - a16 * a21 + * a33 * a45 * a54 + a11 * a26 * a33 * a45 * a54 + a13 * a21 * a36 + * a45 * a54 - a11 * a23 * a36 * a45 * a54 - a15 * a23 * a31 * a46 + * a54 + a13 * a25 * a31 * a46 * a54 + a15 * a21 * a33 * a46 * a54 + - a11 * a25 * a33 * a46 * a54 - a13 * a21 * a35 * a46 * a54 + a11 + * a23 * a35 * a46 * a54 - a16 * a24 * a33 * a41 * a55 + a14 * a26 + * a33 * a41 * a55 + a16 * a23 * a34 * a41 * a55 - a13 * a26 * a34 + * a41 * a55 - a14 * a23 * a36 * a41 * a55 + a13 * a24 * a36 * a41 + * a55 + a16 * a24 * a31 * a43 * a55 - a14 * a26 * a31 * a43 * a55 + - a16 * a21 * a34 * a43 * a55 + a11 * a26 * a34 * a43 * a55 + a14 + * a21 * a36 * a43 * a55 - a11 * a24 * a36 * a43 * a55 - a16 * a23 + * a31 * a44 * a55 + a13 * a26 * a31 * a44 * a55 + a16 * a21 * a33 + * a44 * a55 - a11 * a26 * a33 * a44 * a55 - a13 * a21 * a36 * a44 + * a55 + a11 * a23 * a36 * a44 * a55 + a14 * a23 * a31 * a46 * a55 + - a13 * a24 * a31 * a46 * a55 - a14 * a21 * a33 * a46 * a55 + a11 + * a24 * a33 * a46 * a55 + a13 * a21 * a34 * a46 * a55 - a11 * a23 + * a34 * a46 * a55 + a15 * a24 * a33 * a41 * a56 - a14 * a25 * a33 + * a41 * a56 - a15 * a23 * a34 * a41 * a56 + a13 * a25 * a34 * a41 + * a56 + a14 * a23 * a35 * a41 * a56 - a13 * a24 * a35 * a41 * a56 + - a15 * a24 * a31 * a43 * a56 + a14 * a25 * a31 * a43 * a56 + a15 + * a21 * a34 * a43 * a56 - a11 * a25 * a34 * a43 * a56 - a14 * a21 + * a35 * a43 * a56 + a11 * a24 * a35 * a43 * a56 + a15 * a23 * a31 + * a44 * a56 - a13 * a25 * a31 * a44 * a56 - a15 * a21 * a33 * a44 + * a56 + a11 * a25 * a33 * a44 * a56 + a13 * a21 * a35 * a44 * a56 + - a11 * a23 * a35 * a44 * a56 - a14 * a23 * a31 * a45 * a56 + a13 + * a24 * a31 * a45 * a56 + a14 * a21 * a33 * a45 * a56 - a11 * a24 + * a33 * a45 * a56 - a13 * a21 * a34 * a45 * a56 + a11 * a23 * a34 + * a45 * a56) * a62 - (a16 * a25 * a34 * a42 * a51 - a15 * a26 * + a34 * a42 * a51 - a16 * a24 * a35 * a42 * a51 + a14 * a26 * a35 * + a42 * a51 + a15 * a24 * a36 * a42 * a51 - a14 * a25 * a36 * a42 * + a51 - a16 * a25 * a32 * a44 * a51 + a15 * a26 * a32 * a44 * a51 + + a16 * a22 * a35 * a44 * a51 - a12 * a26 * a35 * a44 * a51 - a15 * + a22 * a36 * a44 * a51 + a12 * a25 * a36 * a44 * a51 + a16 * a24 * + a32 * a45 * a51 - a14 * a26 * a32 * a45 * a51 - a16 * a22 * a34 * + a45 * a51 + a12 * a26 * a34 * a45 * a51 + a14 * a22 * a36 * a45 * + a51 - a12 * a24 * a36 * a45 * a51 - a15 * a24 * a32 * a46 * a51 + + a14 * a25 * a32 * a46 * a51 + a15 * a22 * a34 * a46 * a51 - a12 * + a25 * a34 * a46 * a51 - a14 * a22 * a35 * a46 * a51 + a12 * a24 * + a35 * a46 * a51 - a16 * a25 * a34 * a41 * a52 + a15 * a26 * a34 * + a41 * a52 + a16 * a24 * a35 * a41 * a52 - a14 * a26 * a35 * a41 * + a52 - a15 * a24 * a36 * a41 * a52 + a14 * a25 * a36 * a41 * a52 + + a16 * a25 * a31 * a44 * a52 - a15 * a26 * a31 * a44 * a52 - a16 * + a21 * a35 * a44 * a52 + a11 * a26 * a35 * a44 * a52 + a15 * a21 * + a36 * a44 * a52 - a11 * a25 * a36 * a44 * a52 - a16 * a24 * a31 * + a45 * a52 + a14 * a26 * a31 * a45 * a52 + a16 * a21 * a34 * a45 * + a52 - a11 * a26 * a34 * a45 * a52 - a14 * a21 * a36 * a45 * a52 + + a11 * a24 * a36 * a45 * a52 + a15 * a24 * a31 * a46 * a52 - a14 * + a25 * a31 * a46 * a52 - a15 * a21 * a34 * a46 * a52 + a11 * a25 * + a34 * a46 * a52 + a14 * a21 * a35 * a46 * a52 - a11 * a24 * a35 * + a46 * a52 + a16 * a25 * a32 * a41 * a54 - a15 * a26 * a32 * a41 * + a54 - a16 * a22 * a35 * a41 * a54 + a12 * a26 * a35 * a41 * a54 + + a15 * a22 * a36 * a41 * a54 - a12 * a25 * a36 * a41 * a54 - a16 * + a25 * a31 * a42 * a54 + a15 * a26 * a31 * a42 * a54 + a16 * a21 * + a35 * a42 * a54 - a11 * a26 * a35 * a42 * a54 - a15 * a21 * a36 * + a42 * a54 + a11 * a25 * a36 * a42 * a54 + a16 * a22 * a31 * a45 * + a54 - a12 * a26 * a31 * a45 * a54 - a16 * a21 * a32 * a45 * a54 + + a11 * a26 * a32 * a45 * a54 + a12 * a21 * a36 * a45 * a54 - a11 * + a22 * a36 * a45 * a54 - a15 * a22 * a31 * a46 * a54 + a12 * a25 * + a31 * a46 * a54 + a15 * a21 * a32 * a46 * a54 - a11 * a25 * a32 * + a46 * a54 - a12 * a21 * a35 * a46 * a54 + a11 * a22 * a35 * a46 * + a54 - a16 * a24 * a32 * a41 * a55 + a14 * a26 * a32 * a41 * a55 + + a16 * a22 * a34 * a41 * a55 - a12 * a26 * a34 * a41 * a55 - a14 * + a22 * a36 * a41 * a55 + a12 * a24 * a36 * a41 * a55 + a16 * a24 * + a31 * a42 * a55 - a14 * a26 * a31 * a42 * a55 - a16 * a21 * a34 * + a42 * a55 + a11 * a26 * a34 * a42 * a55 + a14 * a21 * a36 * a42 * + a55 - a11 * a24 * a36 * a42 * a55 - a16 * a22 * a31 * a44 * a55 + + a12 * a26 * a31 * a44 * a55 + a16 * a21 * a32 * a44 * a55 - a11 * + a26 * a32 * a44 * a55 - a12 * a21 * a36 * a44 * a55 + a11 * a22 * + a36 * a44 * a55 + a14 * a22 * a31 * a46 * a55 - a12 * a24 * a31 * + a46 * a55 - a14 * a21 * a32 * a46 * a55 + a11 * a24 * a32 * a46 * + a55 + a12 * a21 * a34 * a46 * a55 - a11 * a22 * a34 * a46 * a55 + + a15 * a24 * a32 * a41 * a56 - a14 * a25 * a32 * a41 * a56 - a15 * + a22 * a34 * a41 * a56 + a12 * a25 * a34 * a41 * a56 + a14 * a22 * + a35 * a41 * a56 - a12 * a24 * a35 * a41 * a56 - a15 * a24 * a31 * + a42 * a56 + a14 * a25 * a31 * a42 * a56 + a15 * a21 * a34 * a42 * + a56 - a11 * a25 * a34 * a42 * a56 - a14 * a21 * a35 * a42 * a56 + + a11 * a24 * a35 * a42 * a56 + a15 * a22 * a31 * a44 * a56 - a12 * + a25 * a31 * a44 * a56 - a15 * a21 * a32 * a44 * a56 + a11 * a25 * + a32 * a44 * a56 + a12 * a21 * a35 * a44 * a56 - a11 * a22 * a35 * + a44 * a56 - a14 * a22 * a31 * a45 * a56 + a12 * a24 * a31 * a45 * + a56 + a14 * a21 * a32 * a45 * a56 - a11 * a24 * a32 * a45 * a56 - + a12 * a21 * a34 * a45 * a56 + a11 * a22 * a34 * a45 * a56) * a63 + + (a16 * a25 * a33 * a42 * a51 - a15 * a26 * a33 * a42 * a51 - + a16 * a23 * a35 * a42 * a51 + a13 * a26 * a35 * a42 * a51 + a15 * + a23 * a36 * a42 * a51 - a13 * a25 * a36 * a42 * a51 - a16 * a25 * + a32 * a43 * a51 + a15 * a26 * a32 * a43 * a51 + a16 * a22 * a35 * + a43 * a51 - a12 * a26 * a35 * a43 * a51 - a15 * a22 * a36 * a43 * + a51 + a12 * a25 * a36 * a43 * a51 + a16 * a23 * a32 * a45 * a51 - + a13 * a26 * a32 * a45 * a51 - a16 * a22 * a33 * a45 * a51 + a12 * + a26 * a33 * a45 * a51 + a13 * a22 * a36 * a45 * a51 - a12 * a23 * + a36 * a45 * a51 - a15 * a23 * a32 * a46 * a51 + a13 * a25 * a32 * + a46 * a51 + a15 * a22 * a33 * a46 * a51 - a12 * a25 * a33 * a46 * + a51 - a13 * a22 * a35 * a46 * a51 + a12 * a23 * a35 * a46 * a51 - + a16 * a25 * a33 * a41 * a52 + a15 * a26 * a33 * a41 * a52 + a16 * + a23 * a35 * a41 * a52 - a13 * a26 * a35 * a41 * a52 - a15 * a23 * + a36 * a41 * a52 + a13 * a25 * a36 * a41 * a52 + a16 * a25 * a31 * + a43 * a52 - a15 * a26 * a31 * a43 * a52 - a16 * a21 * a35 * a43 * + a52 + a11 * a26 * a35 * a43 * a52 + a15 * a21 * a36 * a43 * a52 - + a11 * a25 * a36 * a43 * a52 - a16 * a23 * a31 * a45 * a52 + a13 * + a26 * a31 * a45 * a52 + a16 * a21 * a33 * a45 * a52 - a11 * a26 * + a33 * a45 * a52 - a13 * a21 * a36 * a45 * a52 + a11 * a23 * a36 * + a45 * a52 + a15 * a23 * a31 * a46 * a52 - a13 * a25 * a31 * a46 * + a52 - a15 * a21 * a33 * a46 * a52 + a11 * a25 * a33 * a46 * a52 + + a13 * a21 * a35 * a46 * a52 - a11 * a23 * a35 * a46 * a52 + a16 * + a25 * a32 * a41 * a53 - a15 * a26 * a32 * a41 * a53 - a16 * a22 * + a35 * a41 * a53 + a12 * a26 * a35 * a41 * a53 + a15 * a22 * a36 * + a41 * a53 - a12 * a25 * a36 * a41 * a53 - a16 * a25 * a31 * a42 * + a53 + a15 * a26 * a31 * a42 * a53 + a16 * a21 * a35 * a42 * a53 - + a11 * a26 * a35 * a42 * a53 - a15 * a21 * a36 * a42 * a53 + a11 * + a25 * a36 * a42 * a53 + a16 * a22 * a31 * a45 * a53 - a12 * a26 * + a31 * a45 * a53 - a16 * a21 * a32 * a45 * a53 + a11 * a26 * a32 * + a45 * a53 + a12 * a21 * a36 * a45 * a53 - a11 * a22 * a36 * a45 * + a53 - a15 * a22 * a31 * a46 * a53 + a12 * a25 * a31 * a46 * a53 + + a15 * a21 * a32 * a46 * a53 - a11 * a25 * a32 * a46 * a53 - a12 * + a21 * a35 * a46 * a53 + a11 * a22 * a35 * a46 * a53 - a16 * a23 * + a32 * a41 * a55 + a13 * a26 * a32 * a41 * a55 + a16 * a22 * a33 * + a41 * a55 - a12 * a26 * a33 * a41 * a55 - a13 * a22 * a36 * a41 * + a55 + a12 * a23 * a36 * a41 * a55 + a16 * a23 * a31 * a42 * a55 - + a13 * a26 * a31 * a42 * a55 - a16 * a21 * a33 * a42 * a55 + a11 * + a26 * a33 * a42 * a55 + a13 * a21 * a36 * a42 * a55 - a11 * a23 * + a36 * a42 * a55 - a16 * a22 * a31 * a43 * a55 + a12 * a26 * a31 * + a43 * a55 + a16 * a21 * a32 * a43 * a55 - a11 * a26 * a32 * a43 * + a55 - a12 * a21 * a36 * a43 * a55 + a11 * a22 * a36 * a43 * a55 + + a13 * a22 * a31 * a46 * a55 - a12 * a23 * a31 * a46 * a55 - a13 * + a21 * a32 * a46 * a55 + a11 * a23 * a32 * a46 * a55 + a12 * a21 * + a33 * a46 * a55 - a11 * a22 * a33 * a46 * a55 + a15 * a23 * a32 * + a41 * a56 - a13 * a25 * a32 * a41 * a56 - a15 * a22 * a33 * a41 * + a56 + a12 * a25 * a33 * a41 * a56 + a13 * a22 * a35 * a41 * a56 - + a12 * a23 * a35 * a41 * a56 - a15 * a23 * a31 * a42 * a56 + a13 * + a25 * a31 * a42 * a56 + a15 * a21 * a33 * a42 * a56 - a11 * a25 * + a33 * a42 * a56 - a13 * a21 * a35 * a42 * a56 + a11 * a23 * a35 * + a42 * a56 + a15 * a22 * a31 * a43 * a56 - a12 * a25 * a31 * a43 * + a56 - a15 * a21 * a32 * a43 * a56 + a11 * a25 * a32 * a43 * a56 + + a12 * a21 * a35 * a43 * a56 - a11 * a22 * a35 * a43 * a56 - a13 * + a22 * a31 * a45 * a56 + a12 * a23 * a31 * a45 * a56 + a13 * a21 * + a32 * a45 * a56 - a11 * a23 * a32 * a45 * a56 - a12 * a21 * a33 * + a45 * a56 + a11 * a22 * a33 * a45 * a56) * a64 - (a16 * a24 * a33 + * a42 * a51 - a14 * a26 * a33 * a42 * a51 - a16 * a23 * a34 * a42 + * a51 + a13 * a26 * a34 * a42 * a51 + a14 * a23 * a36 * a42 * a51 + - a13 * a24 * a36 * a42 * a51 - a16 * a24 * a32 * a43 * a51 + a14 + * a26 * a32 * a43 * a51 + a16 * a22 * a34 * a43 * a51 - a12 * a26 + * a34 * a43 * a51 - a14 * a22 * a36 * a43 * a51 + a12 * a24 * a36 + * a43 * a51 + a16 * a23 * a32 * a44 * a51 - a13 * a26 * a32 * a44 + * a51 - a16 * a22 * a33 * a44 * a51 + a12 * a26 * a33 * a44 * a51 + + a13 * a22 * a36 * a44 * a51 - a12 * a23 * a36 * a44 * a51 - a14 + * a23 * a32 * a46 * a51 + a13 * a24 * a32 * a46 * a51 + a14 * a22 + * a33 * a46 * a51 - a12 * a24 * a33 * a46 * a51 - a13 * a22 * a34 + * a46 * a51 + a12 * a23 * a34 * a46 * a51 - a16 * a24 * a33 * a41 + * a52 + a14 * a26 * a33 * a41 * a52 + a16 * a23 * a34 * a41 * a52 + - a13 * a26 * a34 * a41 * a52 - a14 * a23 * a36 * a41 * a52 + a13 + * a24 * a36 * a41 * a52 + a16 * a24 * a31 * a43 * a52 - a14 * a26 + * a31 * a43 * a52 - a16 * a21 * a34 * a43 * a52 + a11 * a26 * a34 + * a43 * a52 + a14 * a21 * a36 * a43 * a52 - a11 * a24 * a36 * a43 + * a52 - a16 * a23 * a31 * a44 * a52 + a13 * a26 * a31 * a44 * a52 + + a16 * a21 * a33 * a44 * a52 - a11 * a26 * a33 * a44 * a52 - a13 + * a21 * a36 * a44 * a52 + a11 * a23 * a36 * a44 * a52 + a14 * a23 + * a31 * a46 * a52 - a13 * a24 * a31 * a46 * a52 - a14 * a21 * a33 + * a46 * a52 + a11 * a24 * a33 * a46 * a52 + a13 * a21 * a34 * a46 + * a52 - a11 * a23 * a34 * a46 * a52 + a16 * a24 * a32 * a41 * a53 + - a14 * a26 * a32 * a41 * a53 - a16 * a22 * a34 * a41 * a53 + a12 + * a26 * a34 * a41 * a53 + a14 * a22 * a36 * a41 * a53 - a12 * a24 + * a36 * a41 * a53 - a16 * a24 * a31 * a42 * a53 + a14 * a26 * a31 + * a42 * a53 + a16 * a21 * a34 * a42 * a53 - a11 * a26 * a34 * a42 + * a53 - a14 * a21 * a36 * a42 * a53 + a11 * a24 * a36 * a42 * a53 + + a16 * a22 * a31 * a44 * a53 - a12 * a26 * a31 * a44 * a53 - a16 + * a21 * a32 * a44 * a53 + a11 * a26 * a32 * a44 * a53 + a12 * a21 + * a36 * a44 * a53 - a11 * a22 * a36 * a44 * a53 - a14 * a22 * a31 + * a46 * a53 + a12 * a24 * a31 * a46 * a53 + a14 * a21 * a32 * a46 + * a53 - a11 * a24 * a32 * a46 * a53 - a12 * a21 * a34 * a46 * a53 + + a11 * a22 * a34 * a46 * a53 - a16 * a23 * a32 * a41 * a54 + a13 + * a26 * a32 * a41 * a54 + a16 * a22 * a33 * a41 * a54 - a12 * a26 + * a33 * a41 * a54 - a13 * a22 * a36 * a41 * a54 + a12 * a23 * a36 + * a41 * a54 + a16 * a23 * a31 * a42 * a54 - a13 * a26 * a31 * a42 + * a54 - a16 * a21 * a33 * a42 * a54 + a11 * a26 * a33 * a42 * a54 + + a13 * a21 * a36 * a42 * a54 - a11 * a23 * a36 * a42 * a54 - a16 + * a22 * a31 * a43 * a54 + a12 * a26 * a31 * a43 * a54 + a16 * a21 + * a32 * a43 * a54 - a11 * a26 * a32 * a43 * a54 - a12 * a21 * a36 + * a43 * a54 + a11 * a22 * a36 * a43 * a54 + a13 * a22 * a31 * a46 + * a54 - a12 * a23 * a31 * a46 * a54 - a13 * a21 * a32 * a46 * a54 + + a11 * a23 * a32 * a46 * a54 + a12 * a21 * a33 * a46 * a54 - a11 + * a22 * a33 * a46 * a54 + a14 * a23 * a32 * a41 * a56 - a13 * a24 + * a32 * a41 * a56 - a14 * a22 * a33 * a41 * a56 + a12 * a24 * a33 + * a41 * a56 + a13 * a22 * a34 * a41 * a56 - a12 * a23 * a34 * a41 + * a56 - a14 * a23 * a31 * a42 * a56 + a13 * a24 * a31 * a42 * a56 + + a14 * a21 * a33 * a42 * a56 - a11 * a24 * a33 * a42 * a56 - a13 + * a21 * a34 * a42 * a56 + a11 * a23 * a34 * a42 * a56 + a14 * a22 + * a31 * a43 * a56 - a12 * a24 * a31 * a43 * a56 - a14 * a21 * a32 + * a43 * a56 + a11 * a24 * a32 * a43 * a56 + a12 * a21 * a34 * a43 + * a56 - a11 * a22 * a34 * a43 * a56 - a13 * a22 * a31 * a44 * a56 + + a12 * a23 * a31 * a44 * a56 + a13 * a21 * a32 * a44 * a56 - a11 + * a23 * a32 * a44 * a56 - a12 * a21 * a33 * a44 * a56 + a11 * a22 + * a33 * a44 * a56) * a65 + (a15 * a24 * a33 * a42 * a51 - a14 * + a25 * a33 * a42 * a51 - a15 * a23 * a34 * a42 * a51 + a13 * a25 * + a34 * a42 * a51 + a14 * a23 * a35 * a42 * a51 - a13 * a24 * a35 * + a42 * a51 - a15 * a24 * a32 * a43 * a51 + a14 * a25 * a32 * a43 * + a51 + a15 * a22 * a34 * a43 * a51 - a12 * a25 * a34 * a43 * a51 - + a14 * a22 * a35 * a43 * a51 + a12 * a24 * a35 * a43 * a51 + a15 * + a23 * a32 * a44 * a51 - a13 * a25 * a32 * a44 * a51 - a15 * a22 * + a33 * a44 * a51 + a12 * a25 * a33 * a44 * a51 + a13 * a22 * a35 * + a44 * a51 - a12 * a23 * a35 * a44 * a51 - a14 * a23 * a32 * a45 * + a51 + a13 * a24 * a32 * a45 * a51 + a14 * a22 * a33 * a45 * a51 - + a12 * a24 * a33 * a45 * a51 - a13 * a22 * a34 * a45 * a51 + a12 * + a23 * a34 * a45 * a51 - a15 * a24 * a33 * a41 * a52 + a14 * a25 * + a33 * a41 * a52 + a15 * a23 * a34 * a41 * a52 - a13 * a25 * a34 * + a41 * a52 - a14 * a23 * a35 * a41 * a52 + a13 * a24 * a35 * a41 * + a52 + a15 * a24 * a31 * a43 * a52 - a14 * a25 * a31 * a43 * a52 - + a15 * a21 * a34 * a43 * a52 + a11 * a25 * a34 * a43 * a52 + a14 * + a21 * a35 * a43 * a52 - a11 * a24 * a35 * a43 * a52 - a15 * a23 * + a31 * a44 * a52 + a13 * a25 * a31 * a44 * a52 + a15 * a21 * a33 * + a44 * a52 - a11 * a25 * a33 * a44 * a52 - a13 * a21 * a35 * a44 * + a52 + a11 * a23 * a35 * a44 * a52 + a14 * a23 * a31 * a45 * a52 - + a13 * a24 * a31 * a45 * a52 - a14 * a21 * a33 * a45 * a52 + a11 * + a24 * a33 * a45 * a52 + a13 * a21 * a34 * a45 * a52 - a11 * a23 * + a34 * a45 * a52 + a15 * a24 * a32 * a41 * a53 - a14 * a25 * a32 * + a41 * a53 - a15 * a22 * a34 * a41 * a53 + a12 * a25 * a34 * a41 * + a53 + a14 * a22 * a35 * a41 * a53 - a12 * a24 * a35 * a41 * a53 - + a15 * a24 * a31 * a42 * a53 + a14 * a25 * a31 * a42 * a53 + a15 * + a21 * a34 * a42 * a53 - a11 * a25 * a34 * a42 * a53 - a14 * a21 * + a35 * a42 * a53 + a11 * a24 * a35 * a42 * a53 + a15 * a22 * a31 * + a44 * a53 - a12 * a25 * a31 * a44 * a53 - a15 * a21 * a32 * a44 * + a53 + a11 * a25 * a32 * a44 * a53 + a12 * a21 * a35 * a44 * a53 - + a11 * a22 * a35 * a44 * a53 - a14 * a22 * a31 * a45 * a53 + a12 * + a24 * a31 * a45 * a53 + a14 * a21 * a32 * a45 * a53 - a11 * a24 * + a32 * a45 * a53 - a12 * a21 * a34 * a45 * a53 + a11 * a22 * a34 * + a45 * a53 - a15 * a23 * a32 * a41 * a54 + a13 * a25 * a32 * a41 * + a54 + a15 * a22 * a33 * a41 * a54 - a12 * a25 * a33 * a41 * a54 - + a13 * a22 * a35 * a41 * a54 + a12 * a23 * a35 * a41 * a54 + a15 * + a23 * a31 * a42 * a54 - a13 * a25 * a31 * a42 * a54 - a15 * a21 * + a33 * a42 * a54 + a11 * a25 * a33 * a42 * a54 + a13 * a21 * a35 * + a42 * a54 - a11 * a23 * a35 * a42 * a54 - a15 * a22 * a31 * a43 * + a54 + a12 * a25 * a31 * a43 * a54 + a15 * a21 * a32 * a43 * a54 - + a11 * a25 * a32 * a43 * a54 - a12 * a21 * a35 * a43 * a54 + a11 * + a22 * a35 * a43 * a54 + a13 * a22 * a31 * a45 * a54 - a12 * a23 * + a31 * a45 * a54 - a13 * a21 * a32 * a45 * a54 + a11 * a23 * a32 * + a45 * a54 + a12 * a21 * a33 * a45 * a54 - a11 * a22 * a33 * a45 * + a54 + a14 * a23 * a32 * a41 * a55 - a13 * a24 * a32 * a41 * a55 - + a14 * a22 * a33 * a41 * a55 + a12 * a24 * a33 * a41 * a55 + a13 * + a22 * a34 * a41 * a55 - a12 * a23 * a34 * a41 * a55 - a14 * a23 * + a31 * a42 * a55 + a13 * a24 * a31 * a42 * a55 + a14 * a21 * a33 * + a42 * a55 - a11 * a24 * a33 * a42 * a55 - a13 * a21 * a34 * a42 * + a55 + a11 * a23 * a34 * a42 * a55 + a14 * a22 * a31 * a43 * a55 - + a12 * a24 * a31 * a43 * a55 - a14 * a21 * a32 * a43 * a55 + a11 * + a24 * a32 * a43 * a55 + a12 * a21 * a34 * a43 * a55 - a11 * a22 * + a34 * a43 * a55 - a13 * a22 * a31 * a44 * a55 + a12 * a23 * a31 * + a44 * a55 + a13 * a21 * a32 * a44 * a55 - a11 * a23 * a32 * a44 * + a55 - a12 * a21 * a33 * a44 * a55 + a11 * a22 * a33 * a44 * a55) * + a66; + + if (fabs(det) <= eps) { +/* ainv = 0.0d0 */ + *ok_flag__ = -1; + return 0; + } + cofactor[0] = a26 * a35 * a44 * a53 * a62 - a25 * a36 * a44 * a53 * a62 - + a26 * a34 * a45 * a53 * a62 + a24 * a36 * a45 * a53 * a62 + a25 * + a34 * a46 * a53 * a62 - a24 * a35 * a46 * a53 * a62 - a26 * a35 * + a43 * a54 * a62 + a25 * a36 * a43 * a54 * a62 + a26 * a33 * a45 * + a54 * a62 - a23 * a36 * a45 * a54 * a62 - a25 * a33 * a46 * a54 * + a62 + a23 * a35 * a46 * a54 * a62 + a26 * a34 * a43 * a55 * a62 - + a24 * a36 * a43 * a55 * a62 - a26 * a33 * a44 * a55 * a62 + a23 * + a36 * a44 * a55 * a62 + a24 * a33 * a46 * a55 * a62 - a23 * a34 * + a46 * a55 * a62 - a25 * a34 * a43 * a56 * a62 + a24 * a35 * a43 * + a56 * a62 + a25 * a33 * a44 * a56 * a62 - a23 * a35 * a44 * a56 * + a62 - a24 * a33 * a45 * a56 * a62 + a23 * a34 * a45 * a56 * a62 - + a26 * a35 * a44 * a52 * a63 + a25 * a36 * a44 * a52 * a63 + a26 * + a34 * a45 * a52 * a63 - a24 * a36 * a45 * a52 * a63 - a25 * a34 * + a46 * a52 * a63 + a24 * a35 * a46 * a52 * a63 + a26 * a35 * a42 * + a54 * a63 - a25 * a36 * a42 * a54 * a63 - a26 * a32 * a45 * a54 * + a63 + a22 * a36 * a45 * a54 * a63 + a25 * a32 * a46 * a54 * a63 - + a22 * a35 * a46 * a54 * a63 - a26 * a34 * a42 * a55 * a63 + a24 * + a36 * a42 * a55 * a63 + a26 * a32 * a44 * a55 * a63 - a22 * a36 * + a44 * a55 * a63 - a24 * a32 * a46 * a55 * a63 + a22 * a34 * a46 * + a55 * a63 + a25 * a34 * a42 * a56 * a63 - a24 * a35 * a42 * a56 * + a63 - a25 * a32 * a44 * a56 * a63 + a22 * a35 * a44 * a56 * a63 + + a24 * a32 * a45 * a56 * a63 - a22 * a34 * a45 * a56 * a63 + a26 * + a35 * a43 * a52 * a64 - a25 * a36 * a43 * a52 * a64 - a26 * a33 * + a45 * a52 * a64 + a23 * a36 * a45 * a52 * a64 + a25 * a33 * a46 * + a52 * a64 - a23 * a35 * a46 * a52 * a64 - a26 * a35 * a42 * a53 * + a64 + a25 * a36 * a42 * a53 * a64 + a26 * a32 * a45 * a53 * a64 - + a22 * a36 * a45 * a53 * a64 - a25 * a32 * a46 * a53 * a64 + a22 * + a35 * a46 * a53 * a64 + a26 * a33 * a42 * a55 * a64 - a23 * a36 * + a42 * a55 * a64 - a26 * a32 * a43 * a55 * a64 + a22 * a36 * a43 * + a55 * a64 + a23 * a32 * a46 * a55 * a64 - a22 * a33 * a46 * a55 * + a64 - a25 * a33 * a42 * a56 * a64 + a23 * a35 * a42 * a56 * a64 + + a25 * a32 * a43 * a56 * a64 - a22 * a35 * a43 * a56 * a64 - a23 * + a32 * a45 * a56 * a64 + a22 * a33 * a45 * a56 * a64 - a26 * a34 * + a43 * a52 * a65 + a24 * a36 * a43 * a52 * a65 + a26 * a33 * a44 * + a52 * a65 - a23 * a36 * a44 * a52 * a65 - a24 * a33 * a46 * a52 * + a65 + a23 * a34 * a46 * a52 * a65 + a26 * a34 * a42 * a53 * a65 - + a24 * a36 * a42 * a53 * a65 - a26 * a32 * a44 * a53 * a65 + a22 * + a36 * a44 * a53 * a65 + a24 * a32 * a46 * a53 * a65 - a22 * a34 * + a46 * a53 * a65 - a26 * a33 * a42 * a54 * a65 + a23 * a36 * a42 * + a54 * a65 + a26 * a32 * a43 * a54 * a65 - a22 * a36 * a43 * a54 * + a65 - a23 * a32 * a46 * a54 * a65 + a22 * a33 * a46 * a54 * a65 + + a24 * a33 * a42 * a56 * a65 - a23 * a34 * a42 * a56 * a65 - a24 * + a32 * a43 * a56 * a65 + a22 * a34 * a43 * a56 * a65 + a23 * a32 * + a44 * a56 * a65 - a22 * a33 * a44 * a56 * a65 + a25 * a34 * a43 * + a52 * a66 - a24 * a35 * a43 * a52 * a66 - a25 * a33 * a44 * a52 * + a66 + a23 * a35 * a44 * a52 * a66 + a24 * a33 * a45 * a52 * a66 - + a23 * a34 * a45 * a52 * a66 - a25 * a34 * a42 * a53 * a66 + a24 * + a35 * a42 * a53 * a66 + a25 * a32 * a44 * a53 * a66 - a22 * a35 * + a44 * a53 * a66 - a24 * a32 * a45 * a53 * a66 + a22 * a34 * a45 * + a53 * a66 + a25 * a33 * a42 * a54 * a66 - a23 * a35 * a42 * a54 * + a66 - a25 * a32 * a43 * a54 * a66 + a22 * a35 * a43 * a54 * a66 + + a23 * a32 * a45 * a54 * a66 - a22 * a33 * a45 * a54 * a66 - a24 * + a33 * a42 * a55 * a66 + a23 * a34 * a42 * a55 * a66 + a24 * a32 * + a43 * a55 * a66 - a22 * a34 * a43 * a55 * a66 - a23 * a32 * a44 * + a55 * a66 + a22 * a33 * a44 * a55 * a66; + cofactor[1] = -a16 * a35 * a44 * a53 * a62 + a15 * a36 * a44 * a53 * a62 + + a16 * a34 * a45 * a53 * a62 - a14 * a36 * a45 * a53 * a62 - a15 + * a34 * a46 * a53 * a62 + a14 * a35 * a46 * a53 * a62 + a16 * a35 + * a43 * a54 * a62 - a15 * a36 * a43 * a54 * a62 - a16 * a33 * a45 + * a54 * a62 + a13 * a36 * a45 * a54 * a62 + a15 * a33 * a46 * a54 + * a62 - a13 * a35 * a46 * a54 * a62 - a16 * a34 * a43 * a55 * a62 + + a14 * a36 * a43 * a55 * a62 + a16 * a33 * a44 * a55 * a62 - a13 + * a36 * a44 * a55 * a62 - a14 * a33 * a46 * a55 * a62 + a13 * a34 + * a46 * a55 * a62 + a15 * a34 * a43 * a56 * a62 - a14 * a35 * a43 + * a56 * a62 - a15 * a33 * a44 * a56 * a62 + a13 * a35 * a44 * a56 + * a62 + a14 * a33 * a45 * a56 * a62 - a13 * a34 * a45 * a56 * a62 + + a16 * a35 * a44 * a52 * a63 - a15 * a36 * a44 * a52 * a63 - a16 + * a34 * a45 * a52 * a63 + a14 * a36 * a45 * a52 * a63 + a15 * a34 + * a46 * a52 * a63 - a14 * a35 * a46 * a52 * a63 - a16 * a35 * a42 + * a54 * a63 + a15 * a36 * a42 * a54 * a63 + a16 * a32 * a45 * a54 + * a63 - a12 * a36 * a45 * a54 * a63 - a15 * a32 * a46 * a54 * a63 + + a12 * a35 * a46 * a54 * a63 + a16 * a34 * a42 * a55 * a63 - a14 + * a36 * a42 * a55 * a63 - a16 * a32 * a44 * a55 * a63 + a12 * a36 + * a44 * a55 * a63 + a14 * a32 * a46 * a55 * a63 - a12 * a34 * a46 + * a55 * a63 - a15 * a34 * a42 * a56 * a63 + a14 * a35 * a42 * a56 + * a63 + a15 * a32 * a44 * a56 * a63 - a12 * a35 * a44 * a56 * a63 + - a14 * a32 * a45 * a56 * a63 + a12 * a34 * a45 * a56 * a63 - a16 + * a35 * a43 * a52 * a64 + a15 * a36 * a43 * a52 * a64 + a16 * a33 + * a45 * a52 * a64 - a13 * a36 * a45 * a52 * a64 - a15 * a33 * a46 + * a52 * a64 + a13 * a35 * a46 * a52 * a64 + a16 * a35 * a42 * a53 + * a64 - a15 * a36 * a42 * a53 * a64 - a16 * a32 * a45 * a53 * a64 + + a12 * a36 * a45 * a53 * a64 + a15 * a32 * a46 * a53 * a64 - a12 + * a35 * a46 * a53 * a64 - a16 * a33 * a42 * a55 * a64 + a13 * a36 + * a42 * a55 * a64 + a16 * a32 * a43 * a55 * a64 - a12 * a36 * a43 + * a55 * a64 - a13 * a32 * a46 * a55 * a64 + a12 * a33 * a46 * a55 + * a64 + a15 * a33 * a42 * a56 * a64 - a13 * a35 * a42 * a56 * a64 + - a15 * a32 * a43 * a56 * a64 + a12 * a35 * a43 * a56 * a64 + a13 + * a32 * a45 * a56 * a64 - a12 * a33 * a45 * a56 * a64 + a16 * a34 + * a43 * a52 * a65 - a14 * a36 * a43 * a52 * a65 - a16 * a33 * a44 + * a52 * a65 + a13 * a36 * a44 * a52 * a65 + a14 * a33 * a46 * a52 + * a65 - a13 * a34 * a46 * a52 * a65 - a16 * a34 * a42 * a53 * a65 + + a14 * a36 * a42 * a53 * a65 + a16 * a32 * a44 * a53 * a65 - a12 + * a36 * a44 * a53 * a65 - a14 * a32 * a46 * a53 * a65 + a12 * a34 + * a46 * a53 * a65 + a16 * a33 * a42 * a54 * a65 - a13 * a36 * a42 + * a54 * a65 - a16 * a32 * a43 * a54 * a65 + a12 * a36 * a43 * a54 + * a65 + a13 * a32 * a46 * a54 * a65 - a12 * a33 * a46 * a54 * a65 + - a14 * a33 * a42 * a56 * a65 + a13 * a34 * a42 * a56 * a65 + a14 + * a32 * a43 * a56 * a65 - a12 * a34 * a43 * a56 * a65 - a13 * a32 + * a44 * a56 * a65 + a12 * a33 * a44 * a56 * a65 - a15 * a34 * a43 + * a52 * a66 + a14 * a35 * a43 * a52 * a66 + a15 * a33 * a44 * a52 + * a66 - a13 * a35 * a44 * a52 * a66 - a14 * a33 * a45 * a52 * a66 + + a13 * a34 * a45 * a52 * a66 + a15 * a34 * a42 * a53 * a66 - a14 + * a35 * a42 * a53 * a66 - a15 * a32 * a44 * a53 * a66 + a12 * a35 + * a44 * a53 * a66 + a14 * a32 * a45 * a53 * a66 - a12 * a34 * a45 + * a53 * a66 - a15 * a33 * a42 * a54 * a66 + a13 * a35 * a42 * a54 + * a66 + a15 * a32 * a43 * a54 * a66 - a12 * a35 * a43 * a54 * a66 + - a13 * a32 * a45 * a54 * a66 + a12 * a33 * a45 * a54 * a66 + a14 + * a33 * a42 * a55 * a66 - a13 * a34 * a42 * a55 * a66 - a14 * a32 + * a43 * a55 * a66 + a12 * a34 * a43 * a55 * a66 + a13 * a32 * a44 + * a55 * a66 - a12 * a33 * a44 * a55 * a66; + cofactor[2] = a16 * a25 * a44 * a53 * a62 - a15 * a26 * a44 * a53 * a62 - + a16 * a24 * a45 * a53 * a62 + a14 * a26 * a45 * a53 * a62 + a15 * + a24 * a46 * a53 * a62 - a14 * a25 * a46 * a53 * a62 - a16 * a25 * + a43 * a54 * a62 + a15 * a26 * a43 * a54 * a62 + a16 * a23 * a45 * + a54 * a62 - a13 * a26 * a45 * a54 * a62 - a15 * a23 * a46 * a54 * + a62 + a13 * a25 * a46 * a54 * a62 + a16 * a24 * a43 * a55 * a62 - + a14 * a26 * a43 * a55 * a62 - a16 * a23 * a44 * a55 * a62 + a13 * + a26 * a44 * a55 * a62 + a14 * a23 * a46 * a55 * a62 - a13 * a24 * + a46 * a55 * a62 - a15 * a24 * a43 * a56 * a62 + a14 * a25 * a43 * + a56 * a62 + a15 * a23 * a44 * a56 * a62 - a13 * a25 * a44 * a56 * + a62 - a14 * a23 * a45 * a56 * a62 + a13 * a24 * a45 * a56 * a62 - + a16 * a25 * a44 * a52 * a63 + a15 * a26 * a44 * a52 * a63 + a16 * + a24 * a45 * a52 * a63 - a14 * a26 * a45 * a52 * a63 - a15 * a24 * + a46 * a52 * a63 + a14 * a25 * a46 * a52 * a63 + a16 * a25 * a42 * + a54 * a63 - a15 * a26 * a42 * a54 * a63 - a16 * a22 * a45 * a54 * + a63 + a12 * a26 * a45 * a54 * a63 + a15 * a22 * a46 * a54 * a63 - + a12 * a25 * a46 * a54 * a63 - a16 * a24 * a42 * a55 * a63 + a14 * + a26 * a42 * a55 * a63 + a16 * a22 * a44 * a55 * a63 - a12 * a26 * + a44 * a55 * a63 - a14 * a22 * a46 * a55 * a63 + a12 * a24 * a46 * + a55 * a63 + a15 * a24 * a42 * a56 * a63 - a14 * a25 * a42 * a56 * + a63 - a15 * a22 * a44 * a56 * a63 + a12 * a25 * a44 * a56 * a63 + + a14 * a22 * a45 * a56 * a63 - a12 * a24 * a45 * a56 * a63 + a16 * + a25 * a43 * a52 * a64 - a15 * a26 * a43 * a52 * a64 - a16 * a23 * + a45 * a52 * a64 + a13 * a26 * a45 * a52 * a64 + a15 * a23 * a46 * + a52 * a64 - a13 * a25 * a46 * a52 * a64 - a16 * a25 * a42 * a53 * + a64 + a15 * a26 * a42 * a53 * a64 + a16 * a22 * a45 * a53 * a64 - + a12 * a26 * a45 * a53 * a64 - a15 * a22 * a46 * a53 * a64 + a12 * + a25 * a46 * a53 * a64 + a16 * a23 * a42 * a55 * a64 - a13 * a26 * + a42 * a55 * a64 - a16 * a22 * a43 * a55 * a64 + a12 * a26 * a43 * + a55 * a64 + a13 * a22 * a46 * a55 * a64 - a12 * a23 * a46 * a55 * + a64 - a15 * a23 * a42 * a56 * a64 + a13 * a25 * a42 * a56 * a64 + + a15 * a22 * a43 * a56 * a64 - a12 * a25 * a43 * a56 * a64 - a13 * + a22 * a45 * a56 * a64 + a12 * a23 * a45 * a56 * a64 - a16 * a24 * + a43 * a52 * a65 + a14 * a26 * a43 * a52 * a65 + a16 * a23 * a44 * + a52 * a65 - a13 * a26 * a44 * a52 * a65 - a14 * a23 * a46 * a52 * + a65 + a13 * a24 * a46 * a52 * a65 + a16 * a24 * a42 * a53 * a65 - + a14 * a26 * a42 * a53 * a65 - a16 * a22 * a44 * a53 * a65 + a12 * + a26 * a44 * a53 * a65 + a14 * a22 * a46 * a53 * a65 - a12 * a24 * + a46 * a53 * a65 - a16 * a23 * a42 * a54 * a65 + a13 * a26 * a42 * + a54 * a65 + a16 * a22 * a43 * a54 * a65 - a12 * a26 * a43 * a54 * + a65 - a13 * a22 * a46 * a54 * a65 + a12 * a23 * a46 * a54 * a65 + + a14 * a23 * a42 * a56 * a65 - a13 * a24 * a42 * a56 * a65 - a14 * + a22 * a43 * a56 * a65 + a12 * a24 * a43 * a56 * a65 + a13 * a22 * + a44 * a56 * a65 - a12 * a23 * a44 * a56 * a65 + a15 * a24 * a43 * + a52 * a66 - a14 * a25 * a43 * a52 * a66 - a15 * a23 * a44 * a52 * + a66 + a13 * a25 * a44 * a52 * a66 + a14 * a23 * a45 * a52 * a66 - + a13 * a24 * a45 * a52 * a66 - a15 * a24 * a42 * a53 * a66 + a14 * + a25 * a42 * a53 * a66 + a15 * a22 * a44 * a53 * a66 - a12 * a25 * + a44 * a53 * a66 - a14 * a22 * a45 * a53 * a66 + a12 * a24 * a45 * + a53 * a66 + a15 * a23 * a42 * a54 * a66 - a13 * a25 * a42 * a54 * + a66 - a15 * a22 * a43 * a54 * a66 + a12 * a25 * a43 * a54 * a66 + + a13 * a22 * a45 * a54 * a66 - a12 * a23 * a45 * a54 * a66 - a14 * + a23 * a42 * a55 * a66 + a13 * a24 * a42 * a55 * a66 + a14 * a22 * + a43 * a55 * a66 - a12 * a24 * a43 * a55 * a66 - a13 * a22 * a44 * + a55 * a66 + a12 * a23 * a44 * a55 * a66; + cofactor[3] = -a16 * a25 * a34 * a53 * a62 + a15 * a26 * a34 * a53 * a62 + + a16 * a24 * a35 * a53 * a62 - a14 * a26 * a35 * a53 * a62 - a15 + * a24 * a36 * a53 * a62 + a14 * a25 * a36 * a53 * a62 + a16 * a25 + * a33 * a54 * a62 - a15 * a26 * a33 * a54 * a62 - a16 * a23 * a35 + * a54 * a62 + a13 * a26 * a35 * a54 * a62 + a15 * a23 * a36 * a54 + * a62 - a13 * a25 * a36 * a54 * a62 - a16 * a24 * a33 * a55 * a62 + + a14 * a26 * a33 * a55 * a62 + a16 * a23 * a34 * a55 * a62 - a13 + * a26 * a34 * a55 * a62 - a14 * a23 * a36 * a55 * a62 + a13 * a24 + * a36 * a55 * a62 + a15 * a24 * a33 * a56 * a62 - a14 * a25 * a33 + * a56 * a62 - a15 * a23 * a34 * a56 * a62 + a13 * a25 * a34 * a56 + * a62 + a14 * a23 * a35 * a56 * a62 - a13 * a24 * a35 * a56 * a62 + + a16 * a25 * a34 * a52 * a63 - a15 * a26 * a34 * a52 * a63 - a16 + * a24 * a35 * a52 * a63 + a14 * a26 * a35 * a52 * a63 + a15 * a24 + * a36 * a52 * a63 - a14 * a25 * a36 * a52 * a63 - a16 * a25 * a32 + * a54 * a63 + a15 * a26 * a32 * a54 * a63 + a16 * a22 * a35 * a54 + * a63 - a12 * a26 * a35 * a54 * a63 - a15 * a22 * a36 * a54 * a63 + + a12 * a25 * a36 * a54 * a63 + a16 * a24 * a32 * a55 * a63 - a14 + * a26 * a32 * a55 * a63 - a16 * a22 * a34 * a55 * a63 + a12 * a26 + * a34 * a55 * a63 + a14 * a22 * a36 * a55 * a63 - a12 * a24 * a36 + * a55 * a63 - a15 * a24 * a32 * a56 * a63 + a14 * a25 * a32 * a56 + * a63 + a15 * a22 * a34 * a56 * a63 - a12 * a25 * a34 * a56 * a63 + - a14 * a22 * a35 * a56 * a63 + a12 * a24 * a35 * a56 * a63 - a16 + * a25 * a33 * a52 * a64 + a15 * a26 * a33 * a52 * a64 + a16 * a23 + * a35 * a52 * a64 - a13 * a26 * a35 * a52 * a64 - a15 * a23 * a36 + * a52 * a64 + a13 * a25 * a36 * a52 * a64 + a16 * a25 * a32 * a53 + * a64 - a15 * a26 * a32 * a53 * a64 - a16 * a22 * a35 * a53 * a64 + + a12 * a26 * a35 * a53 * a64 + a15 * a22 * a36 * a53 * a64 - a12 + * a25 * a36 * a53 * a64 - a16 * a23 * a32 * a55 * a64 + a13 * a26 + * a32 * a55 * a64 + a16 * a22 * a33 * a55 * a64 - a12 * a26 * a33 + * a55 * a64 - a13 * a22 * a36 * a55 * a64 + a12 * a23 * a36 * a55 + * a64 + a15 * a23 * a32 * a56 * a64 - a13 * a25 * a32 * a56 * a64 + - a15 * a22 * a33 * a56 * a64 + a12 * a25 * a33 * a56 * a64 + a13 + * a22 * a35 * a56 * a64 - a12 * a23 * a35 * a56 * a64 + a16 * a24 + * a33 * a52 * a65 - a14 * a26 * a33 * a52 * a65 - a16 * a23 * a34 + * a52 * a65 + a13 * a26 * a34 * a52 * a65 + a14 * a23 * a36 * a52 + * a65 - a13 * a24 * a36 * a52 * a65 - a16 * a24 * a32 * a53 * a65 + + a14 * a26 * a32 * a53 * a65 + a16 * a22 * a34 * a53 * a65 - a12 + * a26 * a34 * a53 * a65 - a14 * a22 * a36 * a53 * a65 + a12 * a24 + * a36 * a53 * a65 + a16 * a23 * a32 * a54 * a65 - a13 * a26 * a32 + * a54 * a65 - a16 * a22 * a33 * a54 * a65 + a12 * a26 * a33 * a54 + * a65 + a13 * a22 * a36 * a54 * a65 - a12 * a23 * a36 * a54 * a65 + - a14 * a23 * a32 * a56 * a65 + a13 * a24 * a32 * a56 * a65 + a14 + * a22 * a33 * a56 * a65 - a12 * a24 * a33 * a56 * a65 - a13 * a22 + * a34 * a56 * a65 + a12 * a23 * a34 * a56 * a65 - a15 * a24 * a33 + * a52 * a66 + a14 * a25 * a33 * a52 * a66 + a15 * a23 * a34 * a52 + * a66 - a13 * a25 * a34 * a52 * a66 - a14 * a23 * a35 * a52 * a66 + + a13 * a24 * a35 * a52 * a66 + a15 * a24 * a32 * a53 * a66 - a14 + * a25 * a32 * a53 * a66 - a15 * a22 * a34 * a53 * a66 + a12 * a25 + * a34 * a53 * a66 + a14 * a22 * a35 * a53 * a66 - a12 * a24 * a35 + * a53 * a66 - a15 * a23 * a32 * a54 * a66 + a13 * a25 * a32 * a54 + * a66 + a15 * a22 * a33 * a54 * a66 - a12 * a25 * a33 * a54 * a66 + - a13 * a22 * a35 * a54 * a66 + a12 * a23 * a35 * a54 * a66 + a14 + * a23 * a32 * a55 * a66 - a13 * a24 * a32 * a55 * a66 - a14 * a22 + * a33 * a55 * a66 + a12 * a24 * a33 * a55 * a66 + a13 * a22 * a34 + * a55 * a66 - a12 * a23 * a34 * a55 * a66; + cofactor[4] = a16 * a25 * a34 * a43 * a62 - a15 * a26 * a34 * a43 * a62 - + a16 * a24 * a35 * a43 * a62 + a14 * a26 * a35 * a43 * a62 + a15 * + a24 * a36 * a43 * a62 - a14 * a25 * a36 * a43 * a62 - a16 * a25 * + a33 * a44 * a62 + a15 * a26 * a33 * a44 * a62 + a16 * a23 * a35 * + a44 * a62 - a13 * a26 * a35 * a44 * a62 - a15 * a23 * a36 * a44 * + a62 + a13 * a25 * a36 * a44 * a62 + a16 * a24 * a33 * a45 * a62 - + a14 * a26 * a33 * a45 * a62 - a16 * a23 * a34 * a45 * a62 + a13 * + a26 * a34 * a45 * a62 + a14 * a23 * a36 * a45 * a62 - a13 * a24 * + a36 * a45 * a62 - a15 * a24 * a33 * a46 * a62 + a14 * a25 * a33 * + a46 * a62 + a15 * a23 * a34 * a46 * a62 - a13 * a25 * a34 * a46 * + a62 - a14 * a23 * a35 * a46 * a62 + a13 * a24 * a35 * a46 * a62 - + a16 * a25 * a34 * a42 * a63 + a15 * a26 * a34 * a42 * a63 + a16 * + a24 * a35 * a42 * a63 - a14 * a26 * a35 * a42 * a63 - a15 * a24 * + a36 * a42 * a63 + a14 * a25 * a36 * a42 * a63 + a16 * a25 * a32 * + a44 * a63 - a15 * a26 * a32 * a44 * a63 - a16 * a22 * a35 * a44 * + a63 + a12 * a26 * a35 * a44 * a63 + a15 * a22 * a36 * a44 * a63 - + a12 * a25 * a36 * a44 * a63 - a16 * a24 * a32 * a45 * a63 + a14 * + a26 * a32 * a45 * a63 + a16 * a22 * a34 * a45 * a63 - a12 * a26 * + a34 * a45 * a63 - a14 * a22 * a36 * a45 * a63 + a12 * a24 * a36 * + a45 * a63 + a15 * a24 * a32 * a46 * a63 - a14 * a25 * a32 * a46 * + a63 - a15 * a22 * a34 * a46 * a63 + a12 * a25 * a34 * a46 * a63 + + a14 * a22 * a35 * a46 * a63 - a12 * a24 * a35 * a46 * a63 + a16 * + a25 * a33 * a42 * a64 - a15 * a26 * a33 * a42 * a64 - a16 * a23 * + a35 * a42 * a64 + a13 * a26 * a35 * a42 * a64 + a15 * a23 * a36 * + a42 * a64 - a13 * a25 * a36 * a42 * a64 - a16 * a25 * a32 * a43 * + a64 + a15 * a26 * a32 * a43 * a64 + a16 * a22 * a35 * a43 * a64 - + a12 * a26 * a35 * a43 * a64 - a15 * a22 * a36 * a43 * a64 + a12 * + a25 * a36 * a43 * a64 + a16 * a23 * a32 * a45 * a64 - a13 * a26 * + a32 * a45 * a64 - a16 * a22 * a33 * a45 * a64 + a12 * a26 * a33 * + a45 * a64 + a13 * a22 * a36 * a45 * a64 - a12 * a23 * a36 * a45 * + a64 - a15 * a23 * a32 * a46 * a64 + a13 * a25 * a32 * a46 * a64 + + a15 * a22 * a33 * a46 * a64 - a12 * a25 * a33 * a46 * a64 - a13 * + a22 * a35 * a46 * a64 + a12 * a23 * a35 * a46 * a64 - a16 * a24 * + a33 * a42 * a65 + a14 * a26 * a33 * a42 * a65 + a16 * a23 * a34 * + a42 * a65 - a13 * a26 * a34 * a42 * a65 - a14 * a23 * a36 * a42 * + a65 + a13 * a24 * a36 * a42 * a65 + a16 * a24 * a32 * a43 * a65 - + a14 * a26 * a32 * a43 * a65 - a16 * a22 * a34 * a43 * a65 + a12 * + a26 * a34 * a43 * a65 + a14 * a22 * a36 * a43 * a65 - a12 * a24 * + a36 * a43 * a65 - a16 * a23 * a32 * a44 * a65 + a13 * a26 * a32 * + a44 * a65 + a16 * a22 * a33 * a44 * a65 - a12 * a26 * a33 * a44 * + a65 - a13 * a22 * a36 * a44 * a65 + a12 * a23 * a36 * a44 * a65 + + a14 * a23 * a32 * a46 * a65 - a13 * a24 * a32 * a46 * a65 - a14 * + a22 * a33 * a46 * a65 + a12 * a24 * a33 * a46 * a65 + a13 * a22 * + a34 * a46 * a65 - a12 * a23 * a34 * a46 * a65 + a15 * a24 * a33 * + a42 * a66 - a14 * a25 * a33 * a42 * a66 - a15 * a23 * a34 * a42 * + a66 + a13 * a25 * a34 * a42 * a66 + a14 * a23 * a35 * a42 * a66 - + a13 * a24 * a35 * a42 * a66 - a15 * a24 * a32 * a43 * a66 + a14 * + a25 * a32 * a43 * a66 + a15 * a22 * a34 * a43 * a66 - a12 * a25 * + a34 * a43 * a66 - a14 * a22 * a35 * a43 * a66 + a12 * a24 * a35 * + a43 * a66 + a15 * a23 * a32 * a44 * a66 - a13 * a25 * a32 * a44 * + a66 - a15 * a22 * a33 * a44 * a66 + a12 * a25 * a33 * a44 * a66 + + a13 * a22 * a35 * a44 * a66 - a12 * a23 * a35 * a44 * a66 - a14 * + a23 * a32 * a45 * a66 + a13 * a24 * a32 * a45 * a66 + a14 * a22 * + a33 * a45 * a66 - a12 * a24 * a33 * a45 * a66 - a13 * a22 * a34 * + a45 * a66 + a12 * a23 * a34 * a45 * a66; + cofactor[5] = -a16 * a25 * a34 * a43 * a52 + a15 * a26 * a34 * a43 * a52 + + a16 * a24 * a35 * a43 * a52 - a14 * a26 * a35 * a43 * a52 - a15 + * a24 * a36 * a43 * a52 + a14 * a25 * a36 * a43 * a52 + a16 * a25 + * a33 * a44 * a52 - a15 * a26 * a33 * a44 * a52 - a16 * a23 * a35 + * a44 * a52 + a13 * a26 * a35 * a44 * a52 + a15 * a23 * a36 * a44 + * a52 - a13 * a25 * a36 * a44 * a52 - a16 * a24 * a33 * a45 * a52 + + a14 * a26 * a33 * a45 * a52 + a16 * a23 * a34 * a45 * a52 - a13 + * a26 * a34 * a45 * a52 - a14 * a23 * a36 * a45 * a52 + a13 * a24 + * a36 * a45 * a52 + a15 * a24 * a33 * a46 * a52 - a14 * a25 * a33 + * a46 * a52 - a15 * a23 * a34 * a46 * a52 + a13 * a25 * a34 * a46 + * a52 + a14 * a23 * a35 * a46 * a52 - a13 * a24 * a35 * a46 * a52 + + a16 * a25 * a34 * a42 * a53 - a15 * a26 * a34 * a42 * a53 - a16 + * a24 * a35 * a42 * a53 + a14 * a26 * a35 * a42 * a53 + a15 * a24 + * a36 * a42 * a53 - a14 * a25 * a36 * a42 * a53 - a16 * a25 * a32 + * a44 * a53 + a15 * a26 * a32 * a44 * a53 + a16 * a22 * a35 * a44 + * a53 - a12 * a26 * a35 * a44 * a53 - a15 * a22 * a36 * a44 * a53 + + a12 * a25 * a36 * a44 * a53 + a16 * a24 * a32 * a45 * a53 - a14 + * a26 * a32 * a45 * a53 - a16 * a22 * a34 * a45 * a53 + a12 * a26 + * a34 * a45 * a53 + a14 * a22 * a36 * a45 * a53 - a12 * a24 * a36 + * a45 * a53 - a15 * a24 * a32 * a46 * a53 + a14 * a25 * a32 * a46 + * a53 + a15 * a22 * a34 * a46 * a53 - a12 * a25 * a34 * a46 * a53 + - a14 * a22 * a35 * a46 * a53 + a12 * a24 * a35 * a46 * a53 - a16 + * a25 * a33 * a42 * a54 + a15 * a26 * a33 * a42 * a54 + a16 * a23 + * a35 * a42 * a54 - a13 * a26 * a35 * a42 * a54 - a15 * a23 * a36 + * a42 * a54 + a13 * a25 * a36 * a42 * a54 + a16 * a25 * a32 * a43 + * a54 - a15 * a26 * a32 * a43 * a54 - a16 * a22 * a35 * a43 * a54 + + a12 * a26 * a35 * a43 * a54 + a15 * a22 * a36 * a43 * a54 - a12 + * a25 * a36 * a43 * a54 - a16 * a23 * a32 * a45 * a54 + a13 * a26 + * a32 * a45 * a54 + a16 * a22 * a33 * a45 * a54 - a12 * a26 * a33 + * a45 * a54 - a13 * a22 * a36 * a45 * a54 + a12 * a23 * a36 * a45 + * a54 + a15 * a23 * a32 * a46 * a54 - a13 * a25 * a32 * a46 * a54 + - a15 * a22 * a33 * a46 * a54 + a12 * a25 * a33 * a46 * a54 + a13 + * a22 * a35 * a46 * a54 - a12 * a23 * a35 * a46 * a54 + a16 * a24 + * a33 * a42 * a55 - a14 * a26 * a33 * a42 * a55 - a16 * a23 * a34 + * a42 * a55 + a13 * a26 * a34 * a42 * a55 + a14 * a23 * a36 * a42 + * a55 - a13 * a24 * a36 * a42 * a55 - a16 * a24 * a32 * a43 * a55 + + a14 * a26 * a32 * a43 * a55 + a16 * a22 * a34 * a43 * a55 - a12 + * a26 * a34 * a43 * a55 - a14 * a22 * a36 * a43 * a55 + a12 * a24 + * a36 * a43 * a55 + a16 * a23 * a32 * a44 * a55 - a13 * a26 * a32 + * a44 * a55 - a16 * a22 * a33 * a44 * a55 + a12 * a26 * a33 * a44 + * a55 + a13 * a22 * a36 * a44 * a55 - a12 * a23 * a36 * a44 * a55 + - a14 * a23 * a32 * a46 * a55 + a13 * a24 * a32 * a46 * a55 + a14 + * a22 * a33 * a46 * a55 - a12 * a24 * a33 * a46 * a55 - a13 * a22 + * a34 * a46 * a55 + a12 * a23 * a34 * a46 * a55 - a15 * a24 * a33 + * a42 * a56 + a14 * a25 * a33 * a42 * a56 + a15 * a23 * a34 * a42 + * a56 - a13 * a25 * a34 * a42 * a56 - a14 * a23 * a35 * a42 * a56 + + a13 * a24 * a35 * a42 * a56 + a15 * a24 * a32 * a43 * a56 - a14 + * a25 * a32 * a43 * a56 - a15 * a22 * a34 * a43 * a56 + a12 * a25 + * a34 * a43 * a56 + a14 * a22 * a35 * a43 * a56 - a12 * a24 * a35 + * a43 * a56 - a15 * a23 * a32 * a44 * a56 + a13 * a25 * a32 * a44 + * a56 + a15 * a22 * a33 * a44 * a56 - a12 * a25 * a33 * a44 * a56 + - a13 * a22 * a35 * a44 * a56 + a12 * a23 * a35 * a44 * a56 + a14 + * a23 * a32 * a45 * a56 - a13 * a24 * a32 * a45 * a56 - a14 * a22 + * a33 * a45 * a56 + a12 * a24 * a33 * a45 * a56 + a13 * a22 * a34 + * a45 * a56 - a12 * a23 * a34 * a45 * a56; + cofactor[6] = -a26 * a35 * a44 * a53 * a61 + a25 * a36 * a44 * a53 * a61 + + a26 * a34 * a45 * a53 * a61 - a24 * a36 * a45 * a53 * a61 - a25 + * a34 * a46 * a53 * a61 + a24 * a35 * a46 * a53 * a61 + a26 * a35 + * a43 * a54 * a61 - a25 * a36 * a43 * a54 * a61 - a26 * a33 * a45 + * a54 * a61 + a23 * a36 * a45 * a54 * a61 + a25 * a33 * a46 * a54 + * a61 - a23 * a35 * a46 * a54 * a61 - a26 * a34 * a43 * a55 * a61 + + a24 * a36 * a43 * a55 * a61 + a26 * a33 * a44 * a55 * a61 - a23 + * a36 * a44 * a55 * a61 - a24 * a33 * a46 * a55 * a61 + a23 * a34 + * a46 * a55 * a61 + a25 * a34 * a43 * a56 * a61 - a24 * a35 * a43 + * a56 * a61 - a25 * a33 * a44 * a56 * a61 + a23 * a35 * a44 * a56 + * a61 + a24 * a33 * a45 * a56 * a61 - a23 * a34 * a45 * a56 * a61 + + a26 * a35 * a44 * a51 * a63 - a25 * a36 * a44 * a51 * a63 - a26 + * a34 * a45 * a51 * a63 + a24 * a36 * a45 * a51 * a63 + a25 * a34 + * a46 * a51 * a63 - a24 * a35 * a46 * a51 * a63 - a26 * a35 * a41 + * a54 * a63 + a25 * a36 * a41 * a54 * a63 + a26 * a31 * a45 * a54 + * a63 - a21 * a36 * a45 * a54 * a63 - a25 * a31 * a46 * a54 * a63 + + a21 * a35 * a46 * a54 * a63 + a26 * a34 * a41 * a55 * a63 - a24 + * a36 * a41 * a55 * a63 - a26 * a31 * a44 * a55 * a63 + a21 * a36 + * a44 * a55 * a63 + a24 * a31 * a46 * a55 * a63 - a21 * a34 * a46 + * a55 * a63 - a25 * a34 * a41 * a56 * a63 + a24 * a35 * a41 * a56 + * a63 + a25 * a31 * a44 * a56 * a63 - a21 * a35 * a44 * a56 * a63 + - a24 * a31 * a45 * a56 * a63 + a21 * a34 * a45 * a56 * a63 - a26 + * a35 * a43 * a51 * a64 + a25 * a36 * a43 * a51 * a64 + a26 * a33 + * a45 * a51 * a64 - a23 * a36 * a45 * a51 * a64 - a25 * a33 * a46 + * a51 * a64 + a23 * a35 * a46 * a51 * a64 + a26 * a35 * a41 * a53 + * a64 - a25 * a36 * a41 * a53 * a64 - a26 * a31 * a45 * a53 * a64 + + a21 * a36 * a45 * a53 * a64 + a25 * a31 * a46 * a53 * a64 - a21 + * a35 * a46 * a53 * a64 - a26 * a33 * a41 * a55 * a64 + a23 * a36 + * a41 * a55 * a64 + a26 * a31 * a43 * a55 * a64 - a21 * a36 * a43 + * a55 * a64 - a23 * a31 * a46 * a55 * a64 + a21 * a33 * a46 * a55 + * a64 + a25 * a33 * a41 * a56 * a64 - a23 * a35 * a41 * a56 * a64 + - a25 * a31 * a43 * a56 * a64 + a21 * a35 * a43 * a56 * a64 + a23 + * a31 * a45 * a56 * a64 - a21 * a33 * a45 * a56 * a64 + a26 * a34 + * a43 * a51 * a65 - a24 * a36 * a43 * a51 * a65 - a26 * a33 * a44 + * a51 * a65 + a23 * a36 * a44 * a51 * a65 + a24 * a33 * a46 * a51 + * a65 - a23 * a34 * a46 * a51 * a65 - a26 * a34 * a41 * a53 * a65 + + a24 * a36 * a41 * a53 * a65 + a26 * a31 * a44 * a53 * a65 - a21 + * a36 * a44 * a53 * a65 - a24 * a31 * a46 * a53 * a65 + a21 * a34 + * a46 * a53 * a65 + a26 * a33 * a41 * a54 * a65 - a23 * a36 * a41 + * a54 * a65 - a26 * a31 * a43 * a54 * a65 + a21 * a36 * a43 * a54 + * a65 + a23 * a31 * a46 * a54 * a65 - a21 * a33 * a46 * a54 * a65 + - a24 * a33 * a41 * a56 * a65 + a23 * a34 * a41 * a56 * a65 + a24 + * a31 * a43 * a56 * a65 - a21 * a34 * a43 * a56 * a65 - a23 * a31 + * a44 * a56 * a65 + a21 * a33 * a44 * a56 * a65 - a25 * a34 * a43 + * a51 * a66 + a24 * a35 * a43 * a51 * a66 + a25 * a33 * a44 * a51 + * a66 - a23 * a35 * a44 * a51 * a66 - a24 * a33 * a45 * a51 * a66 + + a23 * a34 * a45 * a51 * a66 + a25 * a34 * a41 * a53 * a66 - a24 + * a35 * a41 * a53 * a66 - a25 * a31 * a44 * a53 * a66 + a21 * a35 + * a44 * a53 * a66 + a24 * a31 * a45 * a53 * a66 - a21 * a34 * a45 + * a53 * a66 - a25 * a33 * a41 * a54 * a66 + a23 * a35 * a41 * a54 + * a66 + a25 * a31 * a43 * a54 * a66 - a21 * a35 * a43 * a54 * a66 + - a23 * a31 * a45 * a54 * a66 + a21 * a33 * a45 * a54 * a66 + a24 + * a33 * a41 * a55 * a66 - a23 * a34 * a41 * a55 * a66 - a24 * a31 + * a43 * a55 * a66 + a21 * a34 * a43 * a55 * a66 + a23 * a31 * a44 + * a55 * a66 - a21 * a33 * a44 * a55 * a66; + cofactor[7] = a16 * a35 * a44 * a53 * a61 - a15 * a36 * a44 * a53 * a61 - + a16 * a34 * a45 * a53 * a61 + a14 * a36 * a45 * a53 * a61 + a15 * + a34 * a46 * a53 * a61 - a14 * a35 * a46 * a53 * a61 - a16 * a35 * + a43 * a54 * a61 + a15 * a36 * a43 * a54 * a61 + a16 * a33 * a45 * + a54 * a61 - a13 * a36 * a45 * a54 * a61 - a15 * a33 * a46 * a54 * + a61 + a13 * a35 * a46 * a54 * a61 + a16 * a34 * a43 * a55 * a61 - + a14 * a36 * a43 * a55 * a61 - a16 * a33 * a44 * a55 * a61 + a13 * + a36 * a44 * a55 * a61 + a14 * a33 * a46 * a55 * a61 - a13 * a34 * + a46 * a55 * a61 - a15 * a34 * a43 * a56 * a61 + a14 * a35 * a43 * + a56 * a61 + a15 * a33 * a44 * a56 * a61 - a13 * a35 * a44 * a56 * + a61 - a14 * a33 * a45 * a56 * a61 + a13 * a34 * a45 * a56 * a61 - + a16 * a35 * a44 * a51 * a63 + a15 * a36 * a44 * a51 * a63 + a16 * + a34 * a45 * a51 * a63 - a14 * a36 * a45 * a51 * a63 - a15 * a34 * + a46 * a51 * a63 + a14 * a35 * a46 * a51 * a63 + a16 * a35 * a41 * + a54 * a63 - a15 * a36 * a41 * a54 * a63 - a16 * a31 * a45 * a54 * + a63 + a11 * a36 * a45 * a54 * a63 + a15 * a31 * a46 * a54 * a63 - + a11 * a35 * a46 * a54 * a63 - a16 * a34 * a41 * a55 * a63 + a14 * + a36 * a41 * a55 * a63 + a16 * a31 * a44 * a55 * a63 - a11 * a36 * + a44 * a55 * a63 - a14 * a31 * a46 * a55 * a63 + a11 * a34 * a46 * + a55 * a63 + a15 * a34 * a41 * a56 * a63 - a14 * a35 * a41 * a56 * + a63 - a15 * a31 * a44 * a56 * a63 + a11 * a35 * a44 * a56 * a63 + + a14 * a31 * a45 * a56 * a63 - a11 * a34 * a45 * a56 * a63 + a16 * + a35 * a43 * a51 * a64 - a15 * a36 * a43 * a51 * a64 - a16 * a33 * + a45 * a51 * a64 + a13 * a36 * a45 * a51 * a64 + a15 * a33 * a46 * + a51 * a64 - a13 * a35 * a46 * a51 * a64 - a16 * a35 * a41 * a53 * + a64 + a15 * a36 * a41 * a53 * a64 + a16 * a31 * a45 * a53 * a64 - + a11 * a36 * a45 * a53 * a64 - a15 * a31 * a46 * a53 * a64 + a11 * + a35 * a46 * a53 * a64 + a16 * a33 * a41 * a55 * a64 - a13 * a36 * + a41 * a55 * a64 - a16 * a31 * a43 * a55 * a64 + a11 * a36 * a43 * + a55 * a64 + a13 * a31 * a46 * a55 * a64 - a11 * a33 * a46 * a55 * + a64 - a15 * a33 * a41 * a56 * a64 + a13 * a35 * a41 * a56 * a64 + + a15 * a31 * a43 * a56 * a64 - a11 * a35 * a43 * a56 * a64 - a13 * + a31 * a45 * a56 * a64 + a11 * a33 * a45 * a56 * a64 - a16 * a34 * + a43 * a51 * a65 + a14 * a36 * a43 * a51 * a65 + a16 * a33 * a44 * + a51 * a65 - a13 * a36 * a44 * a51 * a65 - a14 * a33 * a46 * a51 * + a65 + a13 * a34 * a46 * a51 * a65 + a16 * a34 * a41 * a53 * a65 - + a14 * a36 * a41 * a53 * a65 - a16 * a31 * a44 * a53 * a65 + a11 * + a36 * a44 * a53 * a65 + a14 * a31 * a46 * a53 * a65 - a11 * a34 * + a46 * a53 * a65 - a16 * a33 * a41 * a54 * a65 + a13 * a36 * a41 * + a54 * a65 + a16 * a31 * a43 * a54 * a65 - a11 * a36 * a43 * a54 * + a65 - a13 * a31 * a46 * a54 * a65 + a11 * a33 * a46 * a54 * a65 + + a14 * a33 * a41 * a56 * a65 - a13 * a34 * a41 * a56 * a65 - a14 * + a31 * a43 * a56 * a65 + a11 * a34 * a43 * a56 * a65 + a13 * a31 * + a44 * a56 * a65 - a11 * a33 * a44 * a56 * a65 + a15 * a34 * a43 * + a51 * a66 - a14 * a35 * a43 * a51 * a66 - a15 * a33 * a44 * a51 * + a66 + a13 * a35 * a44 * a51 * a66 + a14 * a33 * a45 * a51 * a66 - + a13 * a34 * a45 * a51 * a66 - a15 * a34 * a41 * a53 * a66 + a14 * + a35 * a41 * a53 * a66 + a15 * a31 * a44 * a53 * a66 - a11 * a35 * + a44 * a53 * a66 - a14 * a31 * a45 * a53 * a66 + a11 * a34 * a45 * + a53 * a66 + a15 * a33 * a41 * a54 * a66 - a13 * a35 * a41 * a54 * + a66 - a15 * a31 * a43 * a54 * a66 + a11 * a35 * a43 * a54 * a66 + + a13 * a31 * a45 * a54 * a66 - a11 * a33 * a45 * a54 * a66 - a14 * + a33 * a41 * a55 * a66 + a13 * a34 * a41 * a55 * a66 + a14 * a31 * + a43 * a55 * a66 - a11 * a34 * a43 * a55 * a66 - a13 * a31 * a44 * + a55 * a66 + a11 * a33 * a44 * a55 * a66; + cofactor[8] = -a16 * a25 * a44 * a53 * a61 + a15 * a26 * a44 * a53 * a61 + + a16 * a24 * a45 * a53 * a61 - a14 * a26 * a45 * a53 * a61 - a15 + * a24 * a46 * a53 * a61 + a14 * a25 * a46 * a53 * a61 + a16 * a25 + * a43 * a54 * a61 - a15 * a26 * a43 * a54 * a61 - a16 * a23 * a45 + * a54 * a61 + a13 * a26 * a45 * a54 * a61 + a15 * a23 * a46 * a54 + * a61 - a13 * a25 * a46 * a54 * a61 - a16 * a24 * a43 * a55 * a61 + + a14 * a26 * a43 * a55 * a61 + a16 * a23 * a44 * a55 * a61 - a13 + * a26 * a44 * a55 * a61 - a14 * a23 * a46 * a55 * a61 + a13 * a24 + * a46 * a55 * a61 + a15 * a24 * a43 * a56 * a61 - a14 * a25 * a43 + * a56 * a61 - a15 * a23 * a44 * a56 * a61 + a13 * a25 * a44 * a56 + * a61 + a14 * a23 * a45 * a56 * a61 - a13 * a24 * a45 * a56 * a61 + + a16 * a25 * a44 * a51 * a63 - a15 * a26 * a44 * a51 * a63 - a16 + * a24 * a45 * a51 * a63 + a14 * a26 * a45 * a51 * a63 + a15 * a24 + * a46 * a51 * a63 - a14 * a25 * a46 * a51 * a63 - a16 * a25 * a41 + * a54 * a63 + a15 * a26 * a41 * a54 * a63 + a16 * a21 * a45 * a54 + * a63 - a11 * a26 * a45 * a54 * a63 - a15 * a21 * a46 * a54 * a63 + + a11 * a25 * a46 * a54 * a63 + a16 * a24 * a41 * a55 * a63 - a14 + * a26 * a41 * a55 * a63 - a16 * a21 * a44 * a55 * a63 + a11 * a26 + * a44 * a55 * a63 + a14 * a21 * a46 * a55 * a63 - a11 * a24 * a46 + * a55 * a63 - a15 * a24 * a41 * a56 * a63 + a14 * a25 * a41 * a56 + * a63 + a15 * a21 * a44 * a56 * a63 - a11 * a25 * a44 * a56 * a63 + - a14 * a21 * a45 * a56 * a63 + a11 * a24 * a45 * a56 * a63 - a16 + * a25 * a43 * a51 * a64 + a15 * a26 * a43 * a51 * a64 + a16 * a23 + * a45 * a51 * a64 - a13 * a26 * a45 * a51 * a64 - a15 * a23 * a46 + * a51 * a64 + a13 * a25 * a46 * a51 * a64 + a16 * a25 * a41 * a53 + * a64 - a15 * a26 * a41 * a53 * a64 - a16 * a21 * a45 * a53 * a64 + + a11 * a26 * a45 * a53 * a64 + a15 * a21 * a46 * a53 * a64 - a11 + * a25 * a46 * a53 * a64 - a16 * a23 * a41 * a55 * a64 + a13 * a26 + * a41 * a55 * a64 + a16 * a21 * a43 * a55 * a64 - a11 * a26 * a43 + * a55 * a64 - a13 * a21 * a46 * a55 * a64 + a11 * a23 * a46 * a55 + * a64 + a15 * a23 * a41 * a56 * a64 - a13 * a25 * a41 * a56 * a64 + - a15 * a21 * a43 * a56 * a64 + a11 * a25 * a43 * a56 * a64 + a13 + * a21 * a45 * a56 * a64 - a11 * a23 * a45 * a56 * a64 + a16 * a24 + * a43 * a51 * a65 - a14 * a26 * a43 * a51 * a65 - a16 * a23 * a44 + * a51 * a65 + a13 * a26 * a44 * a51 * a65 + a14 * a23 * a46 * a51 + * a65 - a13 * a24 * a46 * a51 * a65 - a16 * a24 * a41 * a53 * a65 + + a14 * a26 * a41 * a53 * a65 + a16 * a21 * a44 * a53 * a65 - a11 + * a26 * a44 * a53 * a65 - a14 * a21 * a46 * a53 * a65 + a11 * a24 + * a46 * a53 * a65 + a16 * a23 * a41 * a54 * a65 - a13 * a26 * a41 + * a54 * a65 - a16 * a21 * a43 * a54 * a65 + a11 * a26 * a43 * a54 + * a65 + a13 * a21 * a46 * a54 * a65 - a11 * a23 * a46 * a54 * a65 + - a14 * a23 * a41 * a56 * a65 + a13 * a24 * a41 * a56 * a65 + a14 + * a21 * a43 * a56 * a65 - a11 * a24 * a43 * a56 * a65 - a13 * a21 + * a44 * a56 * a65 + a11 * a23 * a44 * a56 * a65 - a15 * a24 * a43 + * a51 * a66 + a14 * a25 * a43 * a51 * a66 + a15 * a23 * a44 * a51 + * a66 - a13 * a25 * a44 * a51 * a66 - a14 * a23 * a45 * a51 * a66 + + a13 * a24 * a45 * a51 * a66 + a15 * a24 * a41 * a53 * a66 - a14 + * a25 * a41 * a53 * a66 - a15 * a21 * a44 * a53 * a66 + a11 * a25 + * a44 * a53 * a66 + a14 * a21 * a45 * a53 * a66 - a11 * a24 * a45 + * a53 * a66 - a15 * a23 * a41 * a54 * a66 + a13 * a25 * a41 * a54 + * a66 + a15 * a21 * a43 * a54 * a66 - a11 * a25 * a43 * a54 * a66 + - a13 * a21 * a45 * a54 * a66 + a11 * a23 * a45 * a54 * a66 + a14 + * a23 * a41 * a55 * a66 - a13 * a24 * a41 * a55 * a66 - a14 * a21 + * a43 * a55 * a66 + a11 * a24 * a43 * a55 * a66 + a13 * a21 * a44 + * a55 * a66 - a11 * a23 * a44 * a55 * a66; + cofactor[9] = a16 * a25 * a34 * a53 * a61 - a15 * a26 * a34 * a53 * a61 - + a16 * a24 * a35 * a53 * a61 + a14 * a26 * a35 * a53 * a61 + a15 * + a24 * a36 * a53 * a61 - a14 * a25 * a36 * a53 * a61 - a16 * a25 * + a33 * a54 * a61 + a15 * a26 * a33 * a54 * a61 + a16 * a23 * a35 * + a54 * a61 - a13 * a26 * a35 * a54 * a61 - a15 * a23 * a36 * a54 * + a61 + a13 * a25 * a36 * a54 * a61 + a16 * a24 * a33 * a55 * a61 - + a14 * a26 * a33 * a55 * a61 - a16 * a23 * a34 * a55 * a61 + a13 * + a26 * a34 * a55 * a61 + a14 * a23 * a36 * a55 * a61 - a13 * a24 * + a36 * a55 * a61 - a15 * a24 * a33 * a56 * a61 + a14 * a25 * a33 * + a56 * a61 + a15 * a23 * a34 * a56 * a61 - a13 * a25 * a34 * a56 * + a61 - a14 * a23 * a35 * a56 * a61 + a13 * a24 * a35 * a56 * a61 - + a16 * a25 * a34 * a51 * a63 + a15 * a26 * a34 * a51 * a63 + a16 * + a24 * a35 * a51 * a63 - a14 * a26 * a35 * a51 * a63 - a15 * a24 * + a36 * a51 * a63 + a14 * a25 * a36 * a51 * a63 + a16 * a25 * a31 * + a54 * a63 - a15 * a26 * a31 * a54 * a63 - a16 * a21 * a35 * a54 * + a63 + a11 * a26 * a35 * a54 * a63 + a15 * a21 * a36 * a54 * a63 - + a11 * a25 * a36 * a54 * a63 - a16 * a24 * a31 * a55 * a63 + a14 * + a26 * a31 * a55 * a63 + a16 * a21 * a34 * a55 * a63 - a11 * a26 * + a34 * a55 * a63 - a14 * a21 * a36 * a55 * a63 + a11 * a24 * a36 * + a55 * a63 + a15 * a24 * a31 * a56 * a63 - a14 * a25 * a31 * a56 * + a63 - a15 * a21 * a34 * a56 * a63 + a11 * a25 * a34 * a56 * a63 + + a14 * a21 * a35 * a56 * a63 - a11 * a24 * a35 * a56 * a63 + a16 * + a25 * a33 * a51 * a64 - a15 * a26 * a33 * a51 * a64 - a16 * a23 * + a35 * a51 * a64 + a13 * a26 * a35 * a51 * a64 + a15 * a23 * a36 * + a51 * a64 - a13 * a25 * a36 * a51 * a64 - a16 * a25 * a31 * a53 * + a64 + a15 * a26 * a31 * a53 * a64 + a16 * a21 * a35 * a53 * a64 - + a11 * a26 * a35 * a53 * a64 - a15 * a21 * a36 * a53 * a64 + a11 * + a25 * a36 * a53 * a64 + a16 * a23 * a31 * a55 * a64 - a13 * a26 * + a31 * a55 * a64 - a16 * a21 * a33 * a55 * a64 + a11 * a26 * a33 * + a55 * a64 + a13 * a21 * a36 * a55 * a64 - a11 * a23 * a36 * a55 * + a64 - a15 * a23 * a31 * a56 * a64 + a13 * a25 * a31 * a56 * a64 + + a15 * a21 * a33 * a56 * a64 - a11 * a25 * a33 * a56 * a64 - a13 * + a21 * a35 * a56 * a64 + a11 * a23 * a35 * a56 * a64 - a16 * a24 * + a33 * a51 * a65 + a14 * a26 * a33 * a51 * a65 + a16 * a23 * a34 * + a51 * a65 - a13 * a26 * a34 * a51 * a65 - a14 * a23 * a36 * a51 * + a65 + a13 * a24 * a36 * a51 * a65 + a16 * a24 * a31 * a53 * a65 - + a14 * a26 * a31 * a53 * a65 - a16 * a21 * a34 * a53 * a65 + a11 * + a26 * a34 * a53 * a65 + a14 * a21 * a36 * a53 * a65 - a11 * a24 * + a36 * a53 * a65 - a16 * a23 * a31 * a54 * a65 + a13 * a26 * a31 * + a54 * a65 + a16 * a21 * a33 * a54 * a65 - a11 * a26 * a33 * a54 * + a65 - a13 * a21 * a36 * a54 * a65 + a11 * a23 * a36 * a54 * a65 + + a14 * a23 * a31 * a56 * a65 - a13 * a24 * a31 * a56 * a65 - a14 * + a21 * a33 * a56 * a65 + a11 * a24 * a33 * a56 * a65 + a13 * a21 * + a34 * a56 * a65 - a11 * a23 * a34 * a56 * a65 + a15 * a24 * a33 * + a51 * a66 - a14 * a25 * a33 * a51 * a66 - a15 * a23 * a34 * a51 * + a66 + a13 * a25 * a34 * a51 * a66 + a14 * a23 * a35 * a51 * a66 - + a13 * a24 * a35 * a51 * a66 - a15 * a24 * a31 * a53 * a66 + a14 * + a25 * a31 * a53 * a66 + a15 * a21 * a34 * a53 * a66 - a11 * a25 * + a34 * a53 * a66 - a14 * a21 * a35 * a53 * a66 + a11 * a24 * a35 * + a53 * a66 + a15 * a23 * a31 * a54 * a66 - a13 * a25 * a31 * a54 * + a66 - a15 * a21 * a33 * a54 * a66 + a11 * a25 * a33 * a54 * a66 + + a13 * a21 * a35 * a54 * a66 - a11 * a23 * a35 * a54 * a66 - a14 * + a23 * a31 * a55 * a66 + a13 * a24 * a31 * a55 * a66 + a14 * a21 * + a33 * a55 * a66 - a11 * a24 * a33 * a55 * a66 - a13 * a21 * a34 * + a55 * a66 + a11 * a23 * a34 * a55 * a66; + cofactor[10] = -a16 * a25 * a34 * a43 * a61 + a15 * a26 * a34 * a43 * a61 + + a16 * a24 * a35 * a43 * a61 - a14 * a26 * a35 * a43 * a61 - a15 + * a24 * a36 * a43 * a61 + a14 * a25 * a36 * a43 * a61 + a16 * a25 + * a33 * a44 * a61 - a15 * a26 * a33 * a44 * a61 - a16 * a23 * a35 + * a44 * a61 + a13 * a26 * a35 * a44 * a61 + a15 * a23 * a36 * a44 + * a61 - a13 * a25 * a36 * a44 * a61 - a16 * a24 * a33 * a45 * a61 + + a14 * a26 * a33 * a45 * a61 + a16 * a23 * a34 * a45 * a61 - a13 + * a26 * a34 * a45 * a61 - a14 * a23 * a36 * a45 * a61 + a13 * a24 + * a36 * a45 * a61 + a15 * a24 * a33 * a46 * a61 - a14 * a25 * a33 + * a46 * a61 - a15 * a23 * a34 * a46 * a61 + a13 * a25 * a34 * a46 + * a61 + a14 * a23 * a35 * a46 * a61 - a13 * a24 * a35 * a46 * a61 + + a16 * a25 * a34 * a41 * a63 - a15 * a26 * a34 * a41 * a63 - a16 + * a24 * a35 * a41 * a63 + a14 * a26 * a35 * a41 * a63 + a15 * a24 + * a36 * a41 * a63 - a14 * a25 * a36 * a41 * a63 - a16 * a25 * a31 + * a44 * a63 + a15 * a26 * a31 * a44 * a63 + a16 * a21 * a35 * a44 + * a63 - a11 * a26 * a35 * a44 * a63 - a15 * a21 * a36 * a44 * a63 + + a11 * a25 * a36 * a44 * a63 + a16 * a24 * a31 * a45 * a63 - a14 + * a26 * a31 * a45 * a63 - a16 * a21 * a34 * a45 * a63 + a11 * a26 + * a34 * a45 * a63 + a14 * a21 * a36 * a45 * a63 - a11 * a24 * a36 + * a45 * a63 - a15 * a24 * a31 * a46 * a63 + a14 * a25 * a31 * a46 + * a63 + a15 * a21 * a34 * a46 * a63 - a11 * a25 * a34 * a46 * a63 + - a14 * a21 * a35 * a46 * a63 + a11 * a24 * a35 * a46 * a63 - a16 + * a25 * a33 * a41 * a64 + a15 * a26 * a33 * a41 * a64 + a16 * a23 + * a35 * a41 * a64 - a13 * a26 * a35 * a41 * a64 - a15 * a23 * a36 + * a41 * a64 + a13 * a25 * a36 * a41 * a64 + a16 * a25 * a31 * a43 + * a64 - a15 * a26 * a31 * a43 * a64 - a16 * a21 * a35 * a43 * a64 + + a11 * a26 * a35 * a43 * a64 + a15 * a21 * a36 * a43 * a64 - a11 + * a25 * a36 * a43 * a64 - a16 * a23 * a31 * a45 * a64 + a13 * a26 + * a31 * a45 * a64 + a16 * a21 * a33 * a45 * a64 - a11 * a26 * a33 + * a45 * a64 - a13 * a21 * a36 * a45 * a64 + a11 * a23 * a36 * a45 + * a64 + a15 * a23 * a31 * a46 * a64 - a13 * a25 * a31 * a46 * a64 + - a15 * a21 * a33 * a46 * a64 + a11 * a25 * a33 * a46 * a64 + a13 + * a21 * a35 * a46 * a64 - a11 * a23 * a35 * a46 * a64 + a16 * a24 + * a33 * a41 * a65 - a14 * a26 * a33 * a41 * a65 - a16 * a23 * a34 + * a41 * a65 + a13 * a26 * a34 * a41 * a65 + a14 * a23 * a36 * a41 + * a65 - a13 * a24 * a36 * a41 * a65 - a16 * a24 * a31 * a43 * a65 + + a14 * a26 * a31 * a43 * a65 + a16 * a21 * a34 * a43 * a65 - a11 + * a26 * a34 * a43 * a65 - a14 * a21 * a36 * a43 * a65 + a11 * a24 + * a36 * a43 * a65 + a16 * a23 * a31 * a44 * a65 - a13 * a26 * a31 + * a44 * a65 - a16 * a21 * a33 * a44 * a65 + a11 * a26 * a33 * a44 + * a65 + a13 * a21 * a36 * a44 * a65 - a11 * a23 * a36 * a44 * a65 + - a14 * a23 * a31 * a46 * a65 + a13 * a24 * a31 * a46 * a65 + a14 + * a21 * a33 * a46 * a65 - a11 * a24 * a33 * a46 * a65 - a13 * a21 + * a34 * a46 * a65 + a11 * a23 * a34 * a46 * a65 - a15 * a24 * a33 + * a41 * a66 + a14 * a25 * a33 * a41 * a66 + a15 * a23 * a34 * a41 + * a66 - a13 * a25 * a34 * a41 * a66 - a14 * a23 * a35 * a41 * a66 + + a13 * a24 * a35 * a41 * a66 + a15 * a24 * a31 * a43 * a66 - a14 + * a25 * a31 * a43 * a66 - a15 * a21 * a34 * a43 * a66 + a11 * a25 + * a34 * a43 * a66 + a14 * a21 * a35 * a43 * a66 - a11 * a24 * a35 + * a43 * a66 - a15 * a23 * a31 * a44 * a66 + a13 * a25 * a31 * a44 + * a66 + a15 * a21 * a33 * a44 * a66 - a11 * a25 * a33 * a44 * a66 + - a13 * a21 * a35 * a44 * a66 + a11 * a23 * a35 * a44 * a66 + a14 + * a23 * a31 * a45 * a66 - a13 * a24 * a31 * a45 * a66 - a14 * a21 + * a33 * a45 * a66 + a11 * a24 * a33 * a45 * a66 + a13 * a21 * a34 + * a45 * a66 - a11 * a23 * a34 * a45 * a66; + cofactor[11] = a16 * a25 * a34 * a43 * a51 - a15 * a26 * a34 * a43 * a51 + - a16 * a24 * a35 * a43 * a51 + a14 * a26 * a35 * a43 * a51 + a15 + * a24 * a36 * a43 * a51 - a14 * a25 * a36 * a43 * a51 - a16 * a25 + * a33 * a44 * a51 + a15 * a26 * a33 * a44 * a51 + a16 * a23 * a35 + * a44 * a51 - a13 * a26 * a35 * a44 * a51 - a15 * a23 * a36 * a44 + * a51 + a13 * a25 * a36 * a44 * a51 + a16 * a24 * a33 * a45 * a51 + - a14 * a26 * a33 * a45 * a51 - a16 * a23 * a34 * a45 * a51 + a13 + * a26 * a34 * a45 * a51 + a14 * a23 * a36 * a45 * a51 - a13 * a24 + * a36 * a45 * a51 - a15 * a24 * a33 * a46 * a51 + a14 * a25 * a33 + * a46 * a51 + a15 * a23 * a34 * a46 * a51 - a13 * a25 * a34 * a46 + * a51 - a14 * a23 * a35 * a46 * a51 + a13 * a24 * a35 * a46 * a51 + - a16 * a25 * a34 * a41 * a53 + a15 * a26 * a34 * a41 * a53 + a16 + * a24 * a35 * a41 * a53 - a14 * a26 * a35 * a41 * a53 - a15 * a24 + * a36 * a41 * a53 + a14 * a25 * a36 * a41 * a53 + a16 * a25 * a31 + * a44 * a53 - a15 * a26 * a31 * a44 * a53 - a16 * a21 * a35 * a44 + * a53 + a11 * a26 * a35 * a44 * a53 + a15 * a21 * a36 * a44 * a53 + - a11 * a25 * a36 * a44 * a53 - a16 * a24 * a31 * a45 * a53 + a14 + * a26 * a31 * a45 * a53 + a16 * a21 * a34 * a45 * a53 - a11 * a26 + * a34 * a45 * a53 - a14 * a21 * a36 * a45 * a53 + a11 * a24 * a36 + * a45 * a53 + a15 * a24 * a31 * a46 * a53 - a14 * a25 * a31 * a46 + * a53 - a15 * a21 * a34 * a46 * a53 + a11 * a25 * a34 * a46 * a53 + + a14 * a21 * a35 * a46 * a53 - a11 * a24 * a35 * a46 * a53 + a16 + * a25 * a33 * a41 * a54 - a15 * a26 * a33 * a41 * a54 - a16 * a23 + * a35 * a41 * a54 + a13 * a26 * a35 * a41 * a54 + a15 * a23 * a36 + * a41 * a54 - a13 * a25 * a36 * a41 * a54 - a16 * a25 * a31 * a43 + * a54 + a15 * a26 * a31 * a43 * a54 + a16 * a21 * a35 * a43 * a54 + - a11 * a26 * a35 * a43 * a54 - a15 * a21 * a36 * a43 * a54 + a11 + * a25 * a36 * a43 * a54 + a16 * a23 * a31 * a45 * a54 - a13 * a26 + * a31 * a45 * a54 - a16 * a21 * a33 * a45 * a54 + a11 * a26 * a33 + * a45 * a54 + a13 * a21 * a36 * a45 * a54 - a11 * a23 * a36 * a45 + * a54 - a15 * a23 * a31 * a46 * a54 + a13 * a25 * a31 * a46 * a54 + + a15 * a21 * a33 * a46 * a54 - a11 * a25 * a33 * a46 * a54 - a13 + * a21 * a35 * a46 * a54 + a11 * a23 * a35 * a46 * a54 - a16 * a24 + * a33 * a41 * a55 + a14 * a26 * a33 * a41 * a55 + a16 * a23 * a34 + * a41 * a55 - a13 * a26 * a34 * a41 * a55 - a14 * a23 * a36 * a41 + * a55 + a13 * a24 * a36 * a41 * a55 + a16 * a24 * a31 * a43 * a55 + - a14 * a26 * a31 * a43 * a55 - a16 * a21 * a34 * a43 * a55 + a11 + * a26 * a34 * a43 * a55 + a14 * a21 * a36 * a43 * a55 - a11 * a24 + * a36 * a43 * a55 - a16 * a23 * a31 * a44 * a55 + a13 * a26 * a31 + * a44 * a55 + a16 * a21 * a33 * a44 * a55 - a11 * a26 * a33 * a44 + * a55 - a13 * a21 * a36 * a44 * a55 + a11 * a23 * a36 * a44 * a55 + + a14 * a23 * a31 * a46 * a55 - a13 * a24 * a31 * a46 * a55 - a14 + * a21 * a33 * a46 * a55 + a11 * a24 * a33 * a46 * a55 + a13 * a21 + * a34 * a46 * a55 - a11 * a23 * a34 * a46 * a55 + a15 * a24 * a33 + * a41 * a56 - a14 * a25 * a33 * a41 * a56 - a15 * a23 * a34 * a41 + * a56 + a13 * a25 * a34 * a41 * a56 + a14 * a23 * a35 * a41 * a56 + - a13 * a24 * a35 * a41 * a56 - a15 * a24 * a31 * a43 * a56 + a14 + * a25 * a31 * a43 * a56 + a15 * a21 * a34 * a43 * a56 - a11 * a25 + * a34 * a43 * a56 - a14 * a21 * a35 * a43 * a56 + a11 * a24 * a35 + * a43 * a56 + a15 * a23 * a31 * a44 * a56 - a13 * a25 * a31 * a44 + * a56 - a15 * a21 * a33 * a44 * a56 + a11 * a25 * a33 * a44 * a56 + + a13 * a21 * a35 * a44 * a56 - a11 * a23 * a35 * a44 * a56 - a14 + * a23 * a31 * a45 * a56 + a13 * a24 * a31 * a45 * a56 + a14 * a21 + * a33 * a45 * a56 - a11 * a24 * a33 * a45 * a56 - a13 * a21 * a34 + * a45 * a56 + a11 * a23 * a34 * a45 * a56; + cofactor[12] = a26 * a35 * a44 * a52 * a61 - a25 * a36 * a44 * a52 * a61 + - a26 * a34 * a45 * a52 * a61 + a24 * a36 * a45 * a52 * a61 + a25 + * a34 * a46 * a52 * a61 - a24 * a35 * a46 * a52 * a61 - a26 * a35 + * a42 * a54 * a61 + a25 * a36 * a42 * a54 * a61 + a26 * a32 * a45 + * a54 * a61 - a22 * a36 * a45 * a54 * a61 - a25 * a32 * a46 * a54 + * a61 + a22 * a35 * a46 * a54 * a61 + a26 * a34 * a42 * a55 * a61 + - a24 * a36 * a42 * a55 * a61 - a26 * a32 * a44 * a55 * a61 + a22 + * a36 * a44 * a55 * a61 + a24 * a32 * a46 * a55 * a61 - a22 * a34 + * a46 * a55 * a61 - a25 * a34 * a42 * a56 * a61 + a24 * a35 * a42 + * a56 * a61 + a25 * a32 * a44 * a56 * a61 - a22 * a35 * a44 * a56 + * a61 - a24 * a32 * a45 * a56 * a61 + a22 * a34 * a45 * a56 * a61 + - a26 * a35 * a44 * a51 * a62 + a25 * a36 * a44 * a51 * a62 + a26 + * a34 * a45 * a51 * a62 - a24 * a36 * a45 * a51 * a62 - a25 * a34 + * a46 * a51 * a62 + a24 * a35 * a46 * a51 * a62 + a26 * a35 * a41 + * a54 * a62 - a25 * a36 * a41 * a54 * a62 - a26 * a31 * a45 * a54 + * a62 + a21 * a36 * a45 * a54 * a62 + a25 * a31 * a46 * a54 * a62 + - a21 * a35 * a46 * a54 * a62 - a26 * a34 * a41 * a55 * a62 + a24 + * a36 * a41 * a55 * a62 + a26 * a31 * a44 * a55 * a62 - a21 * a36 + * a44 * a55 * a62 - a24 * a31 * a46 * a55 * a62 + a21 * a34 * a46 + * a55 * a62 + a25 * a34 * a41 * a56 * a62 - a24 * a35 * a41 * a56 + * a62 - a25 * a31 * a44 * a56 * a62 + a21 * a35 * a44 * a56 * a62 + + a24 * a31 * a45 * a56 * a62 - a21 * a34 * a45 * a56 * a62 + a26 + * a35 * a42 * a51 * a64 - a25 * a36 * a42 * a51 * a64 - a26 * a32 + * a45 * a51 * a64 + a22 * a36 * a45 * a51 * a64 + a25 * a32 * a46 + * a51 * a64 - a22 * a35 * a46 * a51 * a64 - a26 * a35 * a41 * a52 + * a64 + a25 * a36 * a41 * a52 * a64 + a26 * a31 * a45 * a52 * a64 + - a21 * a36 * a45 * a52 * a64 - a25 * a31 * a46 * a52 * a64 + a21 + * a35 * a46 * a52 * a64 + a26 * a32 * a41 * a55 * a64 - a22 * a36 + * a41 * a55 * a64 - a26 * a31 * a42 * a55 * a64 + a21 * a36 * a42 + * a55 * a64 + a22 * a31 * a46 * a55 * a64 - a21 * a32 * a46 * a55 + * a64 - a25 * a32 * a41 * a56 * a64 + a22 * a35 * a41 * a56 * a64 + + a25 * a31 * a42 * a56 * a64 - a21 * a35 * a42 * a56 * a64 - a22 + * a31 * a45 * a56 * a64 + a21 * a32 * a45 * a56 * a64 - a26 * a34 + * a42 * a51 * a65 + a24 * a36 * a42 * a51 * a65 + a26 * a32 * a44 + * a51 * a65 - a22 * a36 * a44 * a51 * a65 - a24 * a32 * a46 * a51 + * a65 + a22 * a34 * a46 * a51 * a65 + a26 * a34 * a41 * a52 * a65 + - a24 * a36 * a41 * a52 * a65 - a26 * a31 * a44 * a52 * a65 + a21 + * a36 * a44 * a52 * a65 + a24 * a31 * a46 * a52 * a65 - a21 * a34 + * a46 * a52 * a65 - a26 * a32 * a41 * a54 * a65 + a22 * a36 * a41 + * a54 * a65 + a26 * a31 * a42 * a54 * a65 - a21 * a36 * a42 * a54 + * a65 - a22 * a31 * a46 * a54 * a65 + a21 * a32 * a46 * a54 * a65 + + a24 * a32 * a41 * a56 * a65 - a22 * a34 * a41 * a56 * a65 - a24 + * a31 * a42 * a56 * a65 + a21 * a34 * a42 * a56 * a65 + a22 * a31 + * a44 * a56 * a65 - a21 * a32 * a44 * a56 * a65 + a25 * a34 * a42 + * a51 * a66 - a24 * a35 * a42 * a51 * a66 - a25 * a32 * a44 * a51 + * a66 + a22 * a35 * a44 * a51 * a66 + a24 * a32 * a45 * a51 * a66 + - a22 * a34 * a45 * a51 * a66 - a25 * a34 * a41 * a52 * a66 + a24 + * a35 * a41 * a52 * a66 + a25 * a31 * a44 * a52 * a66 - a21 * a35 + * a44 * a52 * a66 - a24 * a31 * a45 * a52 * a66 + a21 * a34 * a45 + * a52 * a66 + a25 * a32 * a41 * a54 * a66 - a22 * a35 * a41 * a54 + * a66 - a25 * a31 * a42 * a54 * a66 + a21 * a35 * a42 * a54 * a66 + + a22 * a31 * a45 * a54 * a66 - a21 * a32 * a45 * a54 * a66 - a24 + * a32 * a41 * a55 * a66 + a22 * a34 * a41 * a55 * a66 + a24 * a31 + * a42 * a55 * a66 - a21 * a34 * a42 * a55 * a66 - a22 * a31 * a44 + * a55 * a66 + a21 * a32 * a44 * a55 * a66; + cofactor[13] = -a16 * a35 * a44 * a52 * a61 + a15 * a36 * a44 * a52 * a61 + + a16 * a34 * a45 * a52 * a61 - a14 * a36 * a45 * a52 * a61 - a15 + * a34 * a46 * a52 * a61 + a14 * a35 * a46 * a52 * a61 + a16 * a35 + * a42 * a54 * a61 - a15 * a36 * a42 * a54 * a61 - a16 * a32 * a45 + * a54 * a61 + a12 * a36 * a45 * a54 * a61 + a15 * a32 * a46 * a54 + * a61 - a12 * a35 * a46 * a54 * a61 - a16 * a34 * a42 * a55 * a61 + + a14 * a36 * a42 * a55 * a61 + a16 * a32 * a44 * a55 * a61 - a12 + * a36 * a44 * a55 * a61 - a14 * a32 * a46 * a55 * a61 + a12 * a34 + * a46 * a55 * a61 + a15 * a34 * a42 * a56 * a61 - a14 * a35 * a42 + * a56 * a61 - a15 * a32 * a44 * a56 * a61 + a12 * a35 * a44 * a56 + * a61 + a14 * a32 * a45 * a56 * a61 - a12 * a34 * a45 * a56 * a61 + + a16 * a35 * a44 * a51 * a62 - a15 * a36 * a44 * a51 * a62 - a16 + * a34 * a45 * a51 * a62 + a14 * a36 * a45 * a51 * a62 + a15 * a34 + * a46 * a51 * a62 - a14 * a35 * a46 * a51 * a62 - a16 * a35 * a41 + * a54 * a62 + a15 * a36 * a41 * a54 * a62 + a16 * a31 * a45 * a54 + * a62 - a11 * a36 * a45 * a54 * a62 - a15 * a31 * a46 * a54 * a62 + + a11 * a35 * a46 * a54 * a62 + a16 * a34 * a41 * a55 * a62 - a14 + * a36 * a41 * a55 * a62 - a16 * a31 * a44 * a55 * a62 + a11 * a36 + * a44 * a55 * a62 + a14 * a31 * a46 * a55 * a62 - a11 * a34 * a46 + * a55 * a62 - a15 * a34 * a41 * a56 * a62 + a14 * a35 * a41 * a56 + * a62 + a15 * a31 * a44 * a56 * a62 - a11 * a35 * a44 * a56 * a62 + - a14 * a31 * a45 * a56 * a62 + a11 * a34 * a45 * a56 * a62 - a16 + * a35 * a42 * a51 * a64 + a15 * a36 * a42 * a51 * a64 + a16 * a32 + * a45 * a51 * a64 - a12 * a36 * a45 * a51 * a64 - a15 * a32 * a46 + * a51 * a64 + a12 * a35 * a46 * a51 * a64 + a16 * a35 * a41 * a52 + * a64 - a15 * a36 * a41 * a52 * a64 - a16 * a31 * a45 * a52 * a64 + + a11 * a36 * a45 * a52 * a64 + a15 * a31 * a46 * a52 * a64 - a11 + * a35 * a46 * a52 * a64 - a16 * a32 * a41 * a55 * a64 + a12 * a36 + * a41 * a55 * a64 + a16 * a31 * a42 * a55 * a64 - a11 * a36 * a42 + * a55 * a64 - a12 * a31 * a46 * a55 * a64 + a11 * a32 * a46 * a55 + * a64 + a15 * a32 * a41 * a56 * a64 - a12 * a35 * a41 * a56 * a64 + - a15 * a31 * a42 * a56 * a64 + a11 * a35 * a42 * a56 * a64 + a12 + * a31 * a45 * a56 * a64 - a11 * a32 * a45 * a56 * a64 + a16 * a34 + * a42 * a51 * a65 - a14 * a36 * a42 * a51 * a65 - a16 * a32 * a44 + * a51 * a65 + a12 * a36 * a44 * a51 * a65 + a14 * a32 * a46 * a51 + * a65 - a12 * a34 * a46 * a51 * a65 - a16 * a34 * a41 * a52 * a65 + + a14 * a36 * a41 * a52 * a65 + a16 * a31 * a44 * a52 * a65 - a11 + * a36 * a44 * a52 * a65 - a14 * a31 * a46 * a52 * a65 + a11 * a34 + * a46 * a52 * a65 + a16 * a32 * a41 * a54 * a65 - a12 * a36 * a41 + * a54 * a65 - a16 * a31 * a42 * a54 * a65 + a11 * a36 * a42 * a54 + * a65 + a12 * a31 * a46 * a54 * a65 - a11 * a32 * a46 * a54 * a65 + - a14 * a32 * a41 * a56 * a65 + a12 * a34 * a41 * a56 * a65 + a14 + * a31 * a42 * a56 * a65 - a11 * a34 * a42 * a56 * a65 - a12 * a31 + * a44 * a56 * a65 + a11 * a32 * a44 * a56 * a65 - a15 * a34 * a42 + * a51 * a66 + a14 * a35 * a42 * a51 * a66 + a15 * a32 * a44 * a51 + * a66 - a12 * a35 * a44 * a51 * a66 - a14 * a32 * a45 * a51 * a66 + + a12 * a34 * a45 * a51 * a66 + a15 * a34 * a41 * a52 * a66 - a14 + * a35 * a41 * a52 * a66 - a15 * a31 * a44 * a52 * a66 + a11 * a35 + * a44 * a52 * a66 + a14 * a31 * a45 * a52 * a66 - a11 * a34 * a45 + * a52 * a66 - a15 * a32 * a41 * a54 * a66 + a12 * a35 * a41 * a54 + * a66 + a15 * a31 * a42 * a54 * a66 - a11 * a35 * a42 * a54 * a66 + - a12 * a31 * a45 * a54 * a66 + a11 * a32 * a45 * a54 * a66 + a14 + * a32 * a41 * a55 * a66 - a12 * a34 * a41 * a55 * a66 - a14 * a31 + * a42 * a55 * a66 + a11 * a34 * a42 * a55 * a66 + a12 * a31 * a44 + * a55 * a66 - a11 * a32 * a44 * a55 * a66; + cofactor[14] = a16 * a25 * a44 * a52 * a61 - a15 * a26 * a44 * a52 * a61 + - a16 * a24 * a45 * a52 * a61 + a14 * a26 * a45 * a52 * a61 + a15 + * a24 * a46 * a52 * a61 - a14 * a25 * a46 * a52 * a61 - a16 * a25 + * a42 * a54 * a61 + a15 * a26 * a42 * a54 * a61 + a16 * a22 * a45 + * a54 * a61 - a12 * a26 * a45 * a54 * a61 - a15 * a22 * a46 * a54 + * a61 + a12 * a25 * a46 * a54 * a61 + a16 * a24 * a42 * a55 * a61 + - a14 * a26 * a42 * a55 * a61 - a16 * a22 * a44 * a55 * a61 + a12 + * a26 * a44 * a55 * a61 + a14 * a22 * a46 * a55 * a61 - a12 * a24 + * a46 * a55 * a61 - a15 * a24 * a42 * a56 * a61 + a14 * a25 * a42 + * a56 * a61 + a15 * a22 * a44 * a56 * a61 - a12 * a25 * a44 * a56 + * a61 - a14 * a22 * a45 * a56 * a61 + a12 * a24 * a45 * a56 * a61 + - a16 * a25 * a44 * a51 * a62 + a15 * a26 * a44 * a51 * a62 + a16 + * a24 * a45 * a51 * a62 - a14 * a26 * a45 * a51 * a62 - a15 * a24 + * a46 * a51 * a62 + a14 * a25 * a46 * a51 * a62 + a16 * a25 * a41 + * a54 * a62 - a15 * a26 * a41 * a54 * a62 - a16 * a21 * a45 * a54 + * a62 + a11 * a26 * a45 * a54 * a62 + a15 * a21 * a46 * a54 * a62 + - a11 * a25 * a46 * a54 * a62 - a16 * a24 * a41 * a55 * a62 + a14 + * a26 * a41 * a55 * a62 + a16 * a21 * a44 * a55 * a62 - a11 * a26 + * a44 * a55 * a62 - a14 * a21 * a46 * a55 * a62 + a11 * a24 * a46 + * a55 * a62 + a15 * a24 * a41 * a56 * a62 - a14 * a25 * a41 * a56 + * a62 - a15 * a21 * a44 * a56 * a62 + a11 * a25 * a44 * a56 * a62 + + a14 * a21 * a45 * a56 * a62 - a11 * a24 * a45 * a56 * a62 + a16 + * a25 * a42 * a51 * a64 - a15 * a26 * a42 * a51 * a64 - a16 * a22 + * a45 * a51 * a64 + a12 * a26 * a45 * a51 * a64 + a15 * a22 * a46 + * a51 * a64 - a12 * a25 * a46 * a51 * a64 - a16 * a25 * a41 * a52 + * a64 + a15 * a26 * a41 * a52 * a64 + a16 * a21 * a45 * a52 * a64 + - a11 * a26 * a45 * a52 * a64 - a15 * a21 * a46 * a52 * a64 + a11 + * a25 * a46 * a52 * a64 + a16 * a22 * a41 * a55 * a64 - a12 * a26 + * a41 * a55 * a64 - a16 * a21 * a42 * a55 * a64 + a11 * a26 * a42 + * a55 * a64 + a12 * a21 * a46 * a55 * a64 - a11 * a22 * a46 * a55 + * a64 - a15 * a22 * a41 * a56 * a64 + a12 * a25 * a41 * a56 * a64 + + a15 * a21 * a42 * a56 * a64 - a11 * a25 * a42 * a56 * a64 - a12 + * a21 * a45 * a56 * a64 + a11 * a22 * a45 * a56 * a64 - a16 * a24 + * a42 * a51 * a65 + a14 * a26 * a42 * a51 * a65 + a16 * a22 * a44 + * a51 * a65 - a12 * a26 * a44 * a51 * a65 - a14 * a22 * a46 * a51 + * a65 + a12 * a24 * a46 * a51 * a65 + a16 * a24 * a41 * a52 * a65 + - a14 * a26 * a41 * a52 * a65 - a16 * a21 * a44 * a52 * a65 + a11 + * a26 * a44 * a52 * a65 + a14 * a21 * a46 * a52 * a65 - a11 * a24 + * a46 * a52 * a65 - a16 * a22 * a41 * a54 * a65 + a12 * a26 * a41 + * a54 * a65 + a16 * a21 * a42 * a54 * a65 - a11 * a26 * a42 * a54 + * a65 - a12 * a21 * a46 * a54 * a65 + a11 * a22 * a46 * a54 * a65 + + a14 * a22 * a41 * a56 * a65 - a12 * a24 * a41 * a56 * a65 - a14 + * a21 * a42 * a56 * a65 + a11 * a24 * a42 * a56 * a65 + a12 * a21 + * a44 * a56 * a65 - a11 * a22 * a44 * a56 * a65 + a15 * a24 * a42 + * a51 * a66 - a14 * a25 * a42 * a51 * a66 - a15 * a22 * a44 * a51 + * a66 + a12 * a25 * a44 * a51 * a66 + a14 * a22 * a45 * a51 * a66 + - a12 * a24 * a45 * a51 * a66 - a15 * a24 * a41 * a52 * a66 + a14 + * a25 * a41 * a52 * a66 + a15 * a21 * a44 * a52 * a66 - a11 * a25 + * a44 * a52 * a66 - a14 * a21 * a45 * a52 * a66 + a11 * a24 * a45 + * a52 * a66 + a15 * a22 * a41 * a54 * a66 - a12 * a25 * a41 * a54 + * a66 - a15 * a21 * a42 * a54 * a66 + a11 * a25 * a42 * a54 * a66 + + a12 * a21 * a45 * a54 * a66 - a11 * a22 * a45 * a54 * a66 - a14 + * a22 * a41 * a55 * a66 + a12 * a24 * a41 * a55 * a66 + a14 * a21 + * a42 * a55 * a66 - a11 * a24 * a42 * a55 * a66 - a12 * a21 * a44 + * a55 * a66 + a11 * a22 * a44 * a55 * a66; + cofactor[15] = -a16 * a25 * a34 * a52 * a61 + a15 * a26 * a34 * a52 * a61 + + a16 * a24 * a35 * a52 * a61 - a14 * a26 * a35 * a52 * a61 - a15 + * a24 * a36 * a52 * a61 + a14 * a25 * a36 * a52 * a61 + a16 * a25 + * a32 * a54 * a61 - a15 * a26 * a32 * a54 * a61 - a16 * a22 * a35 + * a54 * a61 + a12 * a26 * a35 * a54 * a61 + a15 * a22 * a36 * a54 + * a61 - a12 * a25 * a36 * a54 * a61 - a16 * a24 * a32 * a55 * a61 + + a14 * a26 * a32 * a55 * a61 + a16 * a22 * a34 * a55 * a61 - a12 + * a26 * a34 * a55 * a61 - a14 * a22 * a36 * a55 * a61 + a12 * a24 + * a36 * a55 * a61 + a15 * a24 * a32 * a56 * a61 - a14 * a25 * a32 + * a56 * a61 - a15 * a22 * a34 * a56 * a61 + a12 * a25 * a34 * a56 + * a61 + a14 * a22 * a35 * a56 * a61 - a12 * a24 * a35 * a56 * a61 + + a16 * a25 * a34 * a51 * a62 - a15 * a26 * a34 * a51 * a62 - a16 + * a24 * a35 * a51 * a62 + a14 * a26 * a35 * a51 * a62 + a15 * a24 + * a36 * a51 * a62 - a14 * a25 * a36 * a51 * a62 - a16 * a25 * a31 + * a54 * a62 + a15 * a26 * a31 * a54 * a62 + a16 * a21 * a35 * a54 + * a62 - a11 * a26 * a35 * a54 * a62 - a15 * a21 * a36 * a54 * a62 + + a11 * a25 * a36 * a54 * a62 + a16 * a24 * a31 * a55 * a62 - a14 + * a26 * a31 * a55 * a62 - a16 * a21 * a34 * a55 * a62 + a11 * a26 + * a34 * a55 * a62 + a14 * a21 * a36 * a55 * a62 - a11 * a24 * a36 + * a55 * a62 - a15 * a24 * a31 * a56 * a62 + a14 * a25 * a31 * a56 + * a62 + a15 * a21 * a34 * a56 * a62 - a11 * a25 * a34 * a56 * a62 + - a14 * a21 * a35 * a56 * a62 + a11 * a24 * a35 * a56 * a62 - a16 + * a25 * a32 * a51 * a64 + a15 * a26 * a32 * a51 * a64 + a16 * a22 + * a35 * a51 * a64 - a12 * a26 * a35 * a51 * a64 - a15 * a22 * a36 + * a51 * a64 + a12 * a25 * a36 * a51 * a64 + a16 * a25 * a31 * a52 + * a64 - a15 * a26 * a31 * a52 * a64 - a16 * a21 * a35 * a52 * a64 + + a11 * a26 * a35 * a52 * a64 + a15 * a21 * a36 * a52 * a64 - a11 + * a25 * a36 * a52 * a64 - a16 * a22 * a31 * a55 * a64 + a12 * a26 + * a31 * a55 * a64 + a16 * a21 * a32 * a55 * a64 - a11 * a26 * a32 + * a55 * a64 - a12 * a21 * a36 * a55 * a64 + a11 * a22 * a36 * a55 + * a64 + a15 * a22 * a31 * a56 * a64 - a12 * a25 * a31 * a56 * a64 + - a15 * a21 * a32 * a56 * a64 + a11 * a25 * a32 * a56 * a64 + a12 + * a21 * a35 * a56 * a64 - a11 * a22 * a35 * a56 * a64 + a16 * a24 + * a32 * a51 * a65 - a14 * a26 * a32 * a51 * a65 - a16 * a22 * a34 + * a51 * a65 + a12 * a26 * a34 * a51 * a65 + a14 * a22 * a36 * a51 + * a65 - a12 * a24 * a36 * a51 * a65 - a16 * a24 * a31 * a52 * a65 + + a14 * a26 * a31 * a52 * a65 + a16 * a21 * a34 * a52 * a65 - a11 + * a26 * a34 * a52 * a65 - a14 * a21 * a36 * a52 * a65 + a11 * a24 + * a36 * a52 * a65 + a16 * a22 * a31 * a54 * a65 - a12 * a26 * a31 + * a54 * a65 - a16 * a21 * a32 * a54 * a65 + a11 * a26 * a32 * a54 + * a65 + a12 * a21 * a36 * a54 * a65 - a11 * a22 * a36 * a54 * a65 + - a14 * a22 * a31 * a56 * a65 + a12 * a24 * a31 * a56 * a65 + a14 + * a21 * a32 * a56 * a65 - a11 * a24 * a32 * a56 * a65 - a12 * a21 + * a34 * a56 * a65 + a11 * a22 * a34 * a56 * a65 - a15 * a24 * a32 + * a51 * a66 + a14 * a25 * a32 * a51 * a66 + a15 * a22 * a34 * a51 + * a66 - a12 * a25 * a34 * a51 * a66 - a14 * a22 * a35 * a51 * a66 + + a12 * a24 * a35 * a51 * a66 + a15 * a24 * a31 * a52 * a66 - a14 + * a25 * a31 * a52 * a66 - a15 * a21 * a34 * a52 * a66 + a11 * a25 + * a34 * a52 * a66 + a14 * a21 * a35 * a52 * a66 - a11 * a24 * a35 + * a52 * a66 - a15 * a22 * a31 * a54 * a66 + a12 * a25 * a31 * a54 + * a66 + a15 * a21 * a32 * a54 * a66 - a11 * a25 * a32 * a54 * a66 + - a12 * a21 * a35 * a54 * a66 + a11 * a22 * a35 * a54 * a66 + a14 + * a22 * a31 * a55 * a66 - a12 * a24 * a31 * a55 * a66 - a14 * a21 + * a32 * a55 * a66 + a11 * a24 * a32 * a55 * a66 + a12 * a21 * a34 + * a55 * a66 - a11 * a22 * a34 * a55 * a66; + cofactor[16] = a16 * a25 * a34 * a42 * a61 - a15 * a26 * a34 * a42 * a61 + - a16 * a24 * a35 * a42 * a61 + a14 * a26 * a35 * a42 * a61 + a15 + * a24 * a36 * a42 * a61 - a14 * a25 * a36 * a42 * a61 - a16 * a25 + * a32 * a44 * a61 + a15 * a26 * a32 * a44 * a61 + a16 * a22 * a35 + * a44 * a61 - a12 * a26 * a35 * a44 * a61 - a15 * a22 * a36 * a44 + * a61 + a12 * a25 * a36 * a44 * a61 + a16 * a24 * a32 * a45 * a61 + - a14 * a26 * a32 * a45 * a61 - a16 * a22 * a34 * a45 * a61 + a12 + * a26 * a34 * a45 * a61 + a14 * a22 * a36 * a45 * a61 - a12 * a24 + * a36 * a45 * a61 - a15 * a24 * a32 * a46 * a61 + a14 * a25 * a32 + * a46 * a61 + a15 * a22 * a34 * a46 * a61 - a12 * a25 * a34 * a46 + * a61 - a14 * a22 * a35 * a46 * a61 + a12 * a24 * a35 * a46 * a61 + - a16 * a25 * a34 * a41 * a62 + a15 * a26 * a34 * a41 * a62 + a16 + * a24 * a35 * a41 * a62 - a14 * a26 * a35 * a41 * a62 - a15 * a24 + * a36 * a41 * a62 + a14 * a25 * a36 * a41 * a62 + a16 * a25 * a31 + * a44 * a62 - a15 * a26 * a31 * a44 * a62 - a16 * a21 * a35 * a44 + * a62 + a11 * a26 * a35 * a44 * a62 + a15 * a21 * a36 * a44 * a62 + - a11 * a25 * a36 * a44 * a62 - a16 * a24 * a31 * a45 * a62 + a14 + * a26 * a31 * a45 * a62 + a16 * a21 * a34 * a45 * a62 - a11 * a26 + * a34 * a45 * a62 - a14 * a21 * a36 * a45 * a62 + a11 * a24 * a36 + * a45 * a62 + a15 * a24 * a31 * a46 * a62 - a14 * a25 * a31 * a46 + * a62 - a15 * a21 * a34 * a46 * a62 + a11 * a25 * a34 * a46 * a62 + + a14 * a21 * a35 * a46 * a62 - a11 * a24 * a35 * a46 * a62 + a16 + * a25 * a32 * a41 * a64 - a15 * a26 * a32 * a41 * a64 - a16 * a22 + * a35 * a41 * a64 + a12 * a26 * a35 * a41 * a64 + a15 * a22 * a36 + * a41 * a64 - a12 * a25 * a36 * a41 * a64 - a16 * a25 * a31 * a42 + * a64 + a15 * a26 * a31 * a42 * a64 + a16 * a21 * a35 * a42 * a64 + - a11 * a26 * a35 * a42 * a64 - a15 * a21 * a36 * a42 * a64 + a11 + * a25 * a36 * a42 * a64 + a16 * a22 * a31 * a45 * a64 - a12 * a26 + * a31 * a45 * a64 - a16 * a21 * a32 * a45 * a64 + a11 * a26 * a32 + * a45 * a64 + a12 * a21 * a36 * a45 * a64 - a11 * a22 * a36 * a45 + * a64 - a15 * a22 * a31 * a46 * a64 + a12 * a25 * a31 * a46 * a64 + + a15 * a21 * a32 * a46 * a64 - a11 * a25 * a32 * a46 * a64 - a12 + * a21 * a35 * a46 * a64 + a11 * a22 * a35 * a46 * a64 - a16 * a24 + * a32 * a41 * a65 + a14 * a26 * a32 * a41 * a65 + a16 * a22 * a34 + * a41 * a65 - a12 * a26 * a34 * a41 * a65 - a14 * a22 * a36 * a41 + * a65 + a12 * a24 * a36 * a41 * a65 + a16 * a24 * a31 * a42 * a65 + - a14 * a26 * a31 * a42 * a65 - a16 * a21 * a34 * a42 * a65 + a11 + * a26 * a34 * a42 * a65 + a14 * a21 * a36 * a42 * a65 - a11 * a24 + * a36 * a42 * a65 - a16 * a22 * a31 * a44 * a65 + a12 * a26 * a31 + * a44 * a65 + a16 * a21 * a32 * a44 * a65 - a11 * a26 * a32 * a44 + * a65 - a12 * a21 * a36 * a44 * a65 + a11 * a22 * a36 * a44 * a65 + + a14 * a22 * a31 * a46 * a65 - a12 * a24 * a31 * a46 * a65 - a14 + * a21 * a32 * a46 * a65 + a11 * a24 * a32 * a46 * a65 + a12 * a21 + * a34 * a46 * a65 - a11 * a22 * a34 * a46 * a65 + a15 * a24 * a32 + * a41 * a66 - a14 * a25 * a32 * a41 * a66 - a15 * a22 * a34 * a41 + * a66 + a12 * a25 * a34 * a41 * a66 + a14 * a22 * a35 * a41 * a66 + - a12 * a24 * a35 * a41 * a66 - a15 * a24 * a31 * a42 * a66 + a14 + * a25 * a31 * a42 * a66 + a15 * a21 * a34 * a42 * a66 - a11 * a25 + * a34 * a42 * a66 - a14 * a21 * a35 * a42 * a66 + a11 * a24 * a35 + * a42 * a66 + a15 * a22 * a31 * a44 * a66 - a12 * a25 * a31 * a44 + * a66 - a15 * a21 * a32 * a44 * a66 + a11 * a25 * a32 * a44 * a66 + + a12 * a21 * a35 * a44 * a66 - a11 * a22 * a35 * a44 * a66 - a14 + * a22 * a31 * a45 * a66 + a12 * a24 * a31 * a45 * a66 + a14 * a21 + * a32 * a45 * a66 - a11 * a24 * a32 * a45 * a66 - a12 * a21 * a34 + * a45 * a66 + a11 * a22 * a34 * a45 * a66; + cofactor[17] = -a16 * a25 * a34 * a42 * a51 + a15 * a26 * a34 * a42 * a51 + + a16 * a24 * a35 * a42 * a51 - a14 * a26 * a35 * a42 * a51 - a15 + * a24 * a36 * a42 * a51 + a14 * a25 * a36 * a42 * a51 + a16 * a25 + * a32 * a44 * a51 - a15 * a26 * a32 * a44 * a51 - a16 * a22 * a35 + * a44 * a51 + a12 * a26 * a35 * a44 * a51 + a15 * a22 * a36 * a44 + * a51 - a12 * a25 * a36 * a44 * a51 - a16 * a24 * a32 * a45 * a51 + + a14 * a26 * a32 * a45 * a51 + a16 * a22 * a34 * a45 * a51 - a12 + * a26 * a34 * a45 * a51 - a14 * a22 * a36 * a45 * a51 + a12 * a24 + * a36 * a45 * a51 + a15 * a24 * a32 * a46 * a51 - a14 * a25 * a32 + * a46 * a51 - a15 * a22 * a34 * a46 * a51 + a12 * a25 * a34 * a46 + * a51 + a14 * a22 * a35 * a46 * a51 - a12 * a24 * a35 * a46 * a51 + + a16 * a25 * a34 * a41 * a52 - a15 * a26 * a34 * a41 * a52 - a16 + * a24 * a35 * a41 * a52 + a14 * a26 * a35 * a41 * a52 + a15 * a24 + * a36 * a41 * a52 - a14 * a25 * a36 * a41 * a52 - a16 * a25 * a31 + * a44 * a52 + a15 * a26 * a31 * a44 * a52 + a16 * a21 * a35 * a44 + * a52 - a11 * a26 * a35 * a44 * a52 - a15 * a21 * a36 * a44 * a52 + + a11 * a25 * a36 * a44 * a52 + a16 * a24 * a31 * a45 * a52 - a14 + * a26 * a31 * a45 * a52 - a16 * a21 * a34 * a45 * a52 + a11 * a26 + * a34 * a45 * a52 + a14 * a21 * a36 * a45 * a52 - a11 * a24 * a36 + * a45 * a52 - a15 * a24 * a31 * a46 * a52 + a14 * a25 * a31 * a46 + * a52 + a15 * a21 * a34 * a46 * a52 - a11 * a25 * a34 * a46 * a52 + - a14 * a21 * a35 * a46 * a52 + a11 * a24 * a35 * a46 * a52 - a16 + * a25 * a32 * a41 * a54 + a15 * a26 * a32 * a41 * a54 + a16 * a22 + * a35 * a41 * a54 - a12 * a26 * a35 * a41 * a54 - a15 * a22 * a36 + * a41 * a54 + a12 * a25 * a36 * a41 * a54 + a16 * a25 * a31 * a42 + * a54 - a15 * a26 * a31 * a42 * a54 - a16 * a21 * a35 * a42 * a54 + + a11 * a26 * a35 * a42 * a54 + a15 * a21 * a36 * a42 * a54 - a11 + * a25 * a36 * a42 * a54 - a16 * a22 * a31 * a45 * a54 + a12 * a26 + * a31 * a45 * a54 + a16 * a21 * a32 * a45 * a54 - a11 * a26 * a32 + * a45 * a54 - a12 * a21 * a36 * a45 * a54 + a11 * a22 * a36 * a45 + * a54 + a15 * a22 * a31 * a46 * a54 - a12 * a25 * a31 * a46 * a54 + - a15 * a21 * a32 * a46 * a54 + a11 * a25 * a32 * a46 * a54 + a12 + * a21 * a35 * a46 * a54 - a11 * a22 * a35 * a46 * a54 + a16 * a24 + * a32 * a41 * a55 - a14 * a26 * a32 * a41 * a55 - a16 * a22 * a34 + * a41 * a55 + a12 * a26 * a34 * a41 * a55 + a14 * a22 * a36 * a41 + * a55 - a12 * a24 * a36 * a41 * a55 - a16 * a24 * a31 * a42 * a55 + + a14 * a26 * a31 * a42 * a55 + a16 * a21 * a34 * a42 * a55 - a11 + * a26 * a34 * a42 * a55 - a14 * a21 * a36 * a42 * a55 + a11 * a24 + * a36 * a42 * a55 + a16 * a22 * a31 * a44 * a55 - a12 * a26 * a31 + * a44 * a55 - a16 * a21 * a32 * a44 * a55 + a11 * a26 * a32 * a44 + * a55 + a12 * a21 * a36 * a44 * a55 - a11 * a22 * a36 * a44 * a55 + - a14 * a22 * a31 * a46 * a55 + a12 * a24 * a31 * a46 * a55 + a14 + * a21 * a32 * a46 * a55 - a11 * a24 * a32 * a46 * a55 - a12 * a21 + * a34 * a46 * a55 + a11 * a22 * a34 * a46 * a55 - a15 * a24 * a32 + * a41 * a56 + a14 * a25 * a32 * a41 * a56 + a15 * a22 * a34 * a41 + * a56 - a12 * a25 * a34 * a41 * a56 - a14 * a22 * a35 * a41 * a56 + + a12 * a24 * a35 * a41 * a56 + a15 * a24 * a31 * a42 * a56 - a14 + * a25 * a31 * a42 * a56 - a15 * a21 * a34 * a42 * a56 + a11 * a25 + * a34 * a42 * a56 + a14 * a21 * a35 * a42 * a56 - a11 * a24 * a35 + * a42 * a56 - a15 * a22 * a31 * a44 * a56 + a12 * a25 * a31 * a44 + * a56 + a15 * a21 * a32 * a44 * a56 - a11 * a25 * a32 * a44 * a56 + - a12 * a21 * a35 * a44 * a56 + a11 * a22 * a35 * a44 * a56 + a14 + * a22 * a31 * a45 * a56 - a12 * a24 * a31 * a45 * a56 - a14 * a21 + * a32 * a45 * a56 + a11 * a24 * a32 * a45 * a56 + a12 * a21 * a34 + * a45 * a56 - a11 * a22 * a34 * a45 * a56; + cofactor[18] = -a26 * a35 * a43 * a52 * a61 + a25 * a36 * a43 * a52 * a61 + + a26 * a33 * a45 * a52 * a61 - a23 * a36 * a45 * a52 * a61 - a25 + * a33 * a46 * a52 * a61 + a23 * a35 * a46 * a52 * a61 + a26 * a35 + * a42 * a53 * a61 - a25 * a36 * a42 * a53 * a61 - a26 * a32 * a45 + * a53 * a61 + a22 * a36 * a45 * a53 * a61 + a25 * a32 * a46 * a53 + * a61 - a22 * a35 * a46 * a53 * a61 - a26 * a33 * a42 * a55 * a61 + + a23 * a36 * a42 * a55 * a61 + a26 * a32 * a43 * a55 * a61 - a22 + * a36 * a43 * a55 * a61 - a23 * a32 * a46 * a55 * a61 + a22 * a33 + * a46 * a55 * a61 + a25 * a33 * a42 * a56 * a61 - a23 * a35 * a42 + * a56 * a61 - a25 * a32 * a43 * a56 * a61 + a22 * a35 * a43 * a56 + * a61 + a23 * a32 * a45 * a56 * a61 - a22 * a33 * a45 * a56 * a61 + + a26 * a35 * a43 * a51 * a62 - a25 * a36 * a43 * a51 * a62 - a26 + * a33 * a45 * a51 * a62 + a23 * a36 * a45 * a51 * a62 + a25 * a33 + * a46 * a51 * a62 - a23 * a35 * a46 * a51 * a62 - a26 * a35 * a41 + * a53 * a62 + a25 * a36 * a41 * a53 * a62 + a26 * a31 * a45 * a53 + * a62 - a21 * a36 * a45 * a53 * a62 - a25 * a31 * a46 * a53 * a62 + + a21 * a35 * a46 * a53 * a62 + a26 * a33 * a41 * a55 * a62 - a23 + * a36 * a41 * a55 * a62 - a26 * a31 * a43 * a55 * a62 + a21 * a36 + * a43 * a55 * a62 + a23 * a31 * a46 * a55 * a62 - a21 * a33 * a46 + * a55 * a62 - a25 * a33 * a41 * a56 * a62 + a23 * a35 * a41 * a56 + * a62 + a25 * a31 * a43 * a56 * a62 - a21 * a35 * a43 * a56 * a62 + - a23 * a31 * a45 * a56 * a62 + a21 * a33 * a45 * a56 * a62 - a26 + * a35 * a42 * a51 * a63 + a25 * a36 * a42 * a51 * a63 + a26 * a32 + * a45 * a51 * a63 - a22 * a36 * a45 * a51 * a63 - a25 * a32 * a46 + * a51 * a63 + a22 * a35 * a46 * a51 * a63 + a26 * a35 * a41 * a52 + * a63 - a25 * a36 * a41 * a52 * a63 - a26 * a31 * a45 * a52 * a63 + + a21 * a36 * a45 * a52 * a63 + a25 * a31 * a46 * a52 * a63 - a21 + * a35 * a46 * a52 * a63 - a26 * a32 * a41 * a55 * a63 + a22 * a36 + * a41 * a55 * a63 + a26 * a31 * a42 * a55 * a63 - a21 * a36 * a42 + * a55 * a63 - a22 * a31 * a46 * a55 * a63 + a21 * a32 * a46 * a55 + * a63 + a25 * a32 * a41 * a56 * a63 - a22 * a35 * a41 * a56 * a63 + - a25 * a31 * a42 * a56 * a63 + a21 * a35 * a42 * a56 * a63 + a22 + * a31 * a45 * a56 * a63 - a21 * a32 * a45 * a56 * a63 + a26 * a33 + * a42 * a51 * a65 - a23 * a36 * a42 * a51 * a65 - a26 * a32 * a43 + * a51 * a65 + a22 * a36 * a43 * a51 * a65 + a23 * a32 * a46 * a51 + * a65 - a22 * a33 * a46 * a51 * a65 - a26 * a33 * a41 * a52 * a65 + + a23 * a36 * a41 * a52 * a65 + a26 * a31 * a43 * a52 * a65 - a21 + * a36 * a43 * a52 * a65 - a23 * a31 * a46 * a52 * a65 + a21 * a33 + * a46 * a52 * a65 + a26 * a32 * a41 * a53 * a65 - a22 * a36 * a41 + * a53 * a65 - a26 * a31 * a42 * a53 * a65 + a21 * a36 * a42 * a53 + * a65 + a22 * a31 * a46 * a53 * a65 - a21 * a32 * a46 * a53 * a65 + - a23 * a32 * a41 * a56 * a65 + a22 * a33 * a41 * a56 * a65 + a23 + * a31 * a42 * a56 * a65 - a21 * a33 * a42 * a56 * a65 - a22 * a31 + * a43 * a56 * a65 + a21 * a32 * a43 * a56 * a65 - a25 * a33 * a42 + * a51 * a66 + a23 * a35 * a42 * a51 * a66 + a25 * a32 * a43 * a51 + * a66 - a22 * a35 * a43 * a51 * a66 - a23 * a32 * a45 * a51 * a66 + + a22 * a33 * a45 * a51 * a66 + a25 * a33 * a41 * a52 * a66 - a23 + * a35 * a41 * a52 * a66 - a25 * a31 * a43 * a52 * a66 + a21 * a35 + * a43 * a52 * a66 + a23 * a31 * a45 * a52 * a66 - a21 * a33 * a45 + * a52 * a66 - a25 * a32 * a41 * a53 * a66 + a22 * a35 * a41 * a53 + * a66 + a25 * a31 * a42 * a53 * a66 - a21 * a35 * a42 * a53 * a66 + - a22 * a31 * a45 * a53 * a66 + a21 * a32 * a45 * a53 * a66 + a23 + * a32 * a41 * a55 * a66 - a22 * a33 * a41 * a55 * a66 - a23 * a31 + * a42 * a55 * a66 + a21 * a33 * a42 * a55 * a66 + a22 * a31 * a43 + * a55 * a66 - a21 * a32 * a43 * a55 * a66; + cofactor[19] = a16 * a35 * a43 * a52 * a61 - a15 * a36 * a43 * a52 * a61 + - a16 * a33 * a45 * a52 * a61 + a13 * a36 * a45 * a52 * a61 + a15 + * a33 * a46 * a52 * a61 - a13 * a35 * a46 * a52 * a61 - a16 * a35 + * a42 * a53 * a61 + a15 * a36 * a42 * a53 * a61 + a16 * a32 * a45 + * a53 * a61 - a12 * a36 * a45 * a53 * a61 - a15 * a32 * a46 * a53 + * a61 + a12 * a35 * a46 * a53 * a61 + a16 * a33 * a42 * a55 * a61 + - a13 * a36 * a42 * a55 * a61 - a16 * a32 * a43 * a55 * a61 + a12 + * a36 * a43 * a55 * a61 + a13 * a32 * a46 * a55 * a61 - a12 * a33 + * a46 * a55 * a61 - a15 * a33 * a42 * a56 * a61 + a13 * a35 * a42 + * a56 * a61 + a15 * a32 * a43 * a56 * a61 - a12 * a35 * a43 * a56 + * a61 - a13 * a32 * a45 * a56 * a61 + a12 * a33 * a45 * a56 * a61 + - a16 * a35 * a43 * a51 * a62 + a15 * a36 * a43 * a51 * a62 + a16 + * a33 * a45 * a51 * a62 - a13 * a36 * a45 * a51 * a62 - a15 * a33 + * a46 * a51 * a62 + a13 * a35 * a46 * a51 * a62 + a16 * a35 * a41 + * a53 * a62 - a15 * a36 * a41 * a53 * a62 - a16 * a31 * a45 * a53 + * a62 + a11 * a36 * a45 * a53 * a62 + a15 * a31 * a46 * a53 * a62 + - a11 * a35 * a46 * a53 * a62 - a16 * a33 * a41 * a55 * a62 + a13 + * a36 * a41 * a55 * a62 + a16 * a31 * a43 * a55 * a62 - a11 * a36 + * a43 * a55 * a62 - a13 * a31 * a46 * a55 * a62 + a11 * a33 * a46 + * a55 * a62 + a15 * a33 * a41 * a56 * a62 - a13 * a35 * a41 * a56 + * a62 - a15 * a31 * a43 * a56 * a62 + a11 * a35 * a43 * a56 * a62 + + a13 * a31 * a45 * a56 * a62 - a11 * a33 * a45 * a56 * a62 + a16 + * a35 * a42 * a51 * a63 - a15 * a36 * a42 * a51 * a63 - a16 * a32 + * a45 * a51 * a63 + a12 * a36 * a45 * a51 * a63 + a15 * a32 * a46 + * a51 * a63 - a12 * a35 * a46 * a51 * a63 - a16 * a35 * a41 * a52 + * a63 + a15 * a36 * a41 * a52 * a63 + a16 * a31 * a45 * a52 * a63 + - a11 * a36 * a45 * a52 * a63 - a15 * a31 * a46 * a52 * a63 + a11 + * a35 * a46 * a52 * a63 + a16 * a32 * a41 * a55 * a63 - a12 * a36 + * a41 * a55 * a63 - a16 * a31 * a42 * a55 * a63 + a11 * a36 * a42 + * a55 * a63 + a12 * a31 * a46 * a55 * a63 - a11 * a32 * a46 * a55 + * a63 - a15 * a32 * a41 * a56 * a63 + a12 * a35 * a41 * a56 * a63 + + a15 * a31 * a42 * a56 * a63 - a11 * a35 * a42 * a56 * a63 - a12 + * a31 * a45 * a56 * a63 + a11 * a32 * a45 * a56 * a63 - a16 * a33 + * a42 * a51 * a65 + a13 * a36 * a42 * a51 * a65 + a16 * a32 * a43 + * a51 * a65 - a12 * a36 * a43 * a51 * a65 - a13 * a32 * a46 * a51 + * a65 + a12 * a33 * a46 * a51 * a65 + a16 * a33 * a41 * a52 * a65 + - a13 * a36 * a41 * a52 * a65 - a16 * a31 * a43 * a52 * a65 + a11 + * a36 * a43 * a52 * a65 + a13 * a31 * a46 * a52 * a65 - a11 * a33 + * a46 * a52 * a65 - a16 * a32 * a41 * a53 * a65 + a12 * a36 * a41 + * a53 * a65 + a16 * a31 * a42 * a53 * a65 - a11 * a36 * a42 * a53 + * a65 - a12 * a31 * a46 * a53 * a65 + a11 * a32 * a46 * a53 * a65 + + a13 * a32 * a41 * a56 * a65 - a12 * a33 * a41 * a56 * a65 - a13 + * a31 * a42 * a56 * a65 + a11 * a33 * a42 * a56 * a65 + a12 * a31 + * a43 * a56 * a65 - a11 * a32 * a43 * a56 * a65 + a15 * a33 * a42 + * a51 * a66 - a13 * a35 * a42 * a51 * a66 - a15 * a32 * a43 * a51 + * a66 + a12 * a35 * a43 * a51 * a66 + a13 * a32 * a45 * a51 * a66 + - a12 * a33 * a45 * a51 * a66 - a15 * a33 * a41 * a52 * a66 + a13 + * a35 * a41 * a52 * a66 + a15 * a31 * a43 * a52 * a66 - a11 * a35 + * a43 * a52 * a66 - a13 * a31 * a45 * a52 * a66 + a11 * a33 * a45 + * a52 * a66 + a15 * a32 * a41 * a53 * a66 - a12 * a35 * a41 * a53 + * a66 - a15 * a31 * a42 * a53 * a66 + a11 * a35 * a42 * a53 * a66 + + a12 * a31 * a45 * a53 * a66 - a11 * a32 * a45 * a53 * a66 - a13 + * a32 * a41 * a55 * a66 + a12 * a33 * a41 * a55 * a66 + a13 * a31 + * a42 * a55 * a66 - a11 * a33 * a42 * a55 * a66 - a12 * a31 * a43 + * a55 * a66 + a11 * a32 * a43 * a55 * a66; + cofactor[20] = -a16 * a25 * a43 * a52 * a61 + a15 * a26 * a43 * a52 * a61 + + a16 * a23 * a45 * a52 * a61 - a13 * a26 * a45 * a52 * a61 - a15 + * a23 * a46 * a52 * a61 + a13 * a25 * a46 * a52 * a61 + a16 * a25 + * a42 * a53 * a61 - a15 * a26 * a42 * a53 * a61 - a16 * a22 * a45 + * a53 * a61 + a12 * a26 * a45 * a53 * a61 + a15 * a22 * a46 * a53 + * a61 - a12 * a25 * a46 * a53 * a61 - a16 * a23 * a42 * a55 * a61 + + a13 * a26 * a42 * a55 * a61 + a16 * a22 * a43 * a55 * a61 - a12 + * a26 * a43 * a55 * a61 - a13 * a22 * a46 * a55 * a61 + a12 * a23 + * a46 * a55 * a61 + a15 * a23 * a42 * a56 * a61 - a13 * a25 * a42 + * a56 * a61 - a15 * a22 * a43 * a56 * a61 + a12 * a25 * a43 * a56 + * a61 + a13 * a22 * a45 * a56 * a61 - a12 * a23 * a45 * a56 * a61 + + a16 * a25 * a43 * a51 * a62 - a15 * a26 * a43 * a51 * a62 - a16 + * a23 * a45 * a51 * a62 + a13 * a26 * a45 * a51 * a62 + a15 * a23 + * a46 * a51 * a62 - a13 * a25 * a46 * a51 * a62 - a16 * a25 * a41 + * a53 * a62 + a15 * a26 * a41 * a53 * a62 + a16 * a21 * a45 * a53 + * a62 - a11 * a26 * a45 * a53 * a62 - a15 * a21 * a46 * a53 * a62 + + a11 * a25 * a46 * a53 * a62 + a16 * a23 * a41 * a55 * a62 - a13 + * a26 * a41 * a55 * a62 - a16 * a21 * a43 * a55 * a62 + a11 * a26 + * a43 * a55 * a62 + a13 * a21 * a46 * a55 * a62 - a11 * a23 * a46 + * a55 * a62 - a15 * a23 * a41 * a56 * a62 + a13 * a25 * a41 * a56 + * a62 + a15 * a21 * a43 * a56 * a62 - a11 * a25 * a43 * a56 * a62 + - a13 * a21 * a45 * a56 * a62 + a11 * a23 * a45 * a56 * a62 - a16 + * a25 * a42 * a51 * a63 + a15 * a26 * a42 * a51 * a63 + a16 * a22 + * a45 * a51 * a63 - a12 * a26 * a45 * a51 * a63 - a15 * a22 * a46 + * a51 * a63 + a12 * a25 * a46 * a51 * a63 + a16 * a25 * a41 * a52 + * a63 - a15 * a26 * a41 * a52 * a63 - a16 * a21 * a45 * a52 * a63 + + a11 * a26 * a45 * a52 * a63 + a15 * a21 * a46 * a52 * a63 - a11 + * a25 * a46 * a52 * a63 - a16 * a22 * a41 * a55 * a63 + a12 * a26 + * a41 * a55 * a63 + a16 * a21 * a42 * a55 * a63 - a11 * a26 * a42 + * a55 * a63 - a12 * a21 * a46 * a55 * a63 + a11 * a22 * a46 * a55 + * a63 + a15 * a22 * a41 * a56 * a63 - a12 * a25 * a41 * a56 * a63 + - a15 * a21 * a42 * a56 * a63 + a11 * a25 * a42 * a56 * a63 + a12 + * a21 * a45 * a56 * a63 - a11 * a22 * a45 * a56 * a63 + a16 * a23 + * a42 * a51 * a65 - a13 * a26 * a42 * a51 * a65 - a16 * a22 * a43 + * a51 * a65 + a12 * a26 * a43 * a51 * a65 + a13 * a22 * a46 * a51 + * a65 - a12 * a23 * a46 * a51 * a65 - a16 * a23 * a41 * a52 * a65 + + a13 * a26 * a41 * a52 * a65 + a16 * a21 * a43 * a52 * a65 - a11 + * a26 * a43 * a52 * a65 - a13 * a21 * a46 * a52 * a65 + a11 * a23 + * a46 * a52 * a65 + a16 * a22 * a41 * a53 * a65 - a12 * a26 * a41 + * a53 * a65 - a16 * a21 * a42 * a53 * a65 + a11 * a26 * a42 * a53 + * a65 + a12 * a21 * a46 * a53 * a65 - a11 * a22 * a46 * a53 * a65 + - a13 * a22 * a41 * a56 * a65 + a12 * a23 * a41 * a56 * a65 + a13 + * a21 * a42 * a56 * a65 - a11 * a23 * a42 * a56 * a65 - a12 * a21 + * a43 * a56 * a65 + a11 * a22 * a43 * a56 * a65 - a15 * a23 * a42 + * a51 * a66 + a13 * a25 * a42 * a51 * a66 + a15 * a22 * a43 * a51 + * a66 - a12 * a25 * a43 * a51 * a66 - a13 * a22 * a45 * a51 * a66 + + a12 * a23 * a45 * a51 * a66 + a15 * a23 * a41 * a52 * a66 - a13 + * a25 * a41 * a52 * a66 - a15 * a21 * a43 * a52 * a66 + a11 * a25 + * a43 * a52 * a66 + a13 * a21 * a45 * a52 * a66 - a11 * a23 * a45 + * a52 * a66 - a15 * a22 * a41 * a53 * a66 + a12 * a25 * a41 * a53 + * a66 + a15 * a21 * a42 * a53 * a66 - a11 * a25 * a42 * a53 * a66 + - a12 * a21 * a45 * a53 * a66 + a11 * a22 * a45 * a53 * a66 + a13 + * a22 * a41 * a55 * a66 - a12 * a23 * a41 * a55 * a66 - a13 * a21 + * a42 * a55 * a66 + a11 * a23 * a42 * a55 * a66 + a12 * a21 * a43 + * a55 * a66 - a11 * a22 * a43 * a55 * a66; + cofactor[21] = a16 * a25 * a33 * a52 * a61 - a15 * a26 * a33 * a52 * a61 + - a16 * a23 * a35 * a52 * a61 + a13 * a26 * a35 * a52 * a61 + a15 + * a23 * a36 * a52 * a61 - a13 * a25 * a36 * a52 * a61 - a16 * a25 + * a32 * a53 * a61 + a15 * a26 * a32 * a53 * a61 + a16 * a22 * a35 + * a53 * a61 - a12 * a26 * a35 * a53 * a61 - a15 * a22 * a36 * a53 + * a61 + a12 * a25 * a36 * a53 * a61 + a16 * a23 * a32 * a55 * a61 + - a13 * a26 * a32 * a55 * a61 - a16 * a22 * a33 * a55 * a61 + a12 + * a26 * a33 * a55 * a61 + a13 * a22 * a36 * a55 * a61 - a12 * a23 + * a36 * a55 * a61 - a15 * a23 * a32 * a56 * a61 + a13 * a25 * a32 + * a56 * a61 + a15 * a22 * a33 * a56 * a61 - a12 * a25 * a33 * a56 + * a61 - a13 * a22 * a35 * a56 * a61 + a12 * a23 * a35 * a56 * a61 + - a16 * a25 * a33 * a51 * a62 + a15 * a26 * a33 * a51 * a62 + a16 + * a23 * a35 * a51 * a62 - a13 * a26 * a35 * a51 * a62 - a15 * a23 + * a36 * a51 * a62 + a13 * a25 * a36 * a51 * a62 + a16 * a25 * a31 + * a53 * a62 - a15 * a26 * a31 * a53 * a62 - a16 * a21 * a35 * a53 + * a62 + a11 * a26 * a35 * a53 * a62 + a15 * a21 * a36 * a53 * a62 + - a11 * a25 * a36 * a53 * a62 - a16 * a23 * a31 * a55 * a62 + a13 + * a26 * a31 * a55 * a62 + a16 * a21 * a33 * a55 * a62 - a11 * a26 + * a33 * a55 * a62 - a13 * a21 * a36 * a55 * a62 + a11 * a23 * a36 + * a55 * a62 + a15 * a23 * a31 * a56 * a62 - a13 * a25 * a31 * a56 + * a62 - a15 * a21 * a33 * a56 * a62 + a11 * a25 * a33 * a56 * a62 + + a13 * a21 * a35 * a56 * a62 - a11 * a23 * a35 * a56 * a62 + a16 + * a25 * a32 * a51 * a63 - a15 * a26 * a32 * a51 * a63 - a16 * a22 + * a35 * a51 * a63 + a12 * a26 * a35 * a51 * a63 + a15 * a22 * a36 + * a51 * a63 - a12 * a25 * a36 * a51 * a63 - a16 * a25 * a31 * a52 + * a63 + a15 * a26 * a31 * a52 * a63 + a16 * a21 * a35 * a52 * a63 + - a11 * a26 * a35 * a52 * a63 - a15 * a21 * a36 * a52 * a63 + a11 + * a25 * a36 * a52 * a63 + a16 * a22 * a31 * a55 * a63 - a12 * a26 + * a31 * a55 * a63 - a16 * a21 * a32 * a55 * a63 + a11 * a26 * a32 + * a55 * a63 + a12 * a21 * a36 * a55 * a63 - a11 * a22 * a36 * a55 + * a63 - a15 * a22 * a31 * a56 * a63 + a12 * a25 * a31 * a56 * a63 + + a15 * a21 * a32 * a56 * a63 - a11 * a25 * a32 * a56 * a63 - a12 + * a21 * a35 * a56 * a63 + a11 * a22 * a35 * a56 * a63 - a16 * a23 + * a32 * a51 * a65 + a13 * a26 * a32 * a51 * a65 + a16 * a22 * a33 + * a51 * a65 - a12 * a26 * a33 * a51 * a65 - a13 * a22 * a36 * a51 + * a65 + a12 * a23 * a36 * a51 * a65 + a16 * a23 * a31 * a52 * a65 + - a13 * a26 * a31 * a52 * a65 - a16 * a21 * a33 * a52 * a65 + a11 + * a26 * a33 * a52 * a65 + a13 * a21 * a36 * a52 * a65 - a11 * a23 + * a36 * a52 * a65 - a16 * a22 * a31 * a53 * a65 + a12 * a26 * a31 + * a53 * a65 + a16 * a21 * a32 * a53 * a65 - a11 * a26 * a32 * a53 + * a65 - a12 * a21 * a36 * a53 * a65 + a11 * a22 * a36 * a53 * a65 + + a13 * a22 * a31 * a56 * a65 - a12 * a23 * a31 * a56 * a65 - a13 + * a21 * a32 * a56 * a65 + a11 * a23 * a32 * a56 * a65 + a12 * a21 + * a33 * a56 * a65 - a11 * a22 * a33 * a56 * a65 + a15 * a23 * a32 + * a51 * a66 - a13 * a25 * a32 * a51 * a66 - a15 * a22 * a33 * a51 + * a66 + a12 * a25 * a33 * a51 * a66 + a13 * a22 * a35 * a51 * a66 + - a12 * a23 * a35 * a51 * a66 - a15 * a23 * a31 * a52 * a66 + a13 + * a25 * a31 * a52 * a66 + a15 * a21 * a33 * a52 * a66 - a11 * a25 + * a33 * a52 * a66 - a13 * a21 * a35 * a52 * a66 + a11 * a23 * a35 + * a52 * a66 + a15 * a22 * a31 * a53 * a66 - a12 * a25 * a31 * a53 + * a66 - a15 * a21 * a32 * a53 * a66 + a11 * a25 * a32 * a53 * a66 + + a12 * a21 * a35 * a53 * a66 - a11 * a22 * a35 * a53 * a66 - a13 + * a22 * a31 * a55 * a66 + a12 * a23 * a31 * a55 * a66 + a13 * a21 + * a32 * a55 * a66 - a11 * a23 * a32 * a55 * a66 - a12 * a21 * a33 + * a55 * a66 + a11 * a22 * a33 * a55 * a66; + cofactor[22] = -a16 * a25 * a33 * a42 * a61 + a15 * a26 * a33 * a42 * a61 + + a16 * a23 * a35 * a42 * a61 - a13 * a26 * a35 * a42 * a61 - a15 + * a23 * a36 * a42 * a61 + a13 * a25 * a36 * a42 * a61 + a16 * a25 + * a32 * a43 * a61 - a15 * a26 * a32 * a43 * a61 - a16 * a22 * a35 + * a43 * a61 + a12 * a26 * a35 * a43 * a61 + a15 * a22 * a36 * a43 + * a61 - a12 * a25 * a36 * a43 * a61 - a16 * a23 * a32 * a45 * a61 + + a13 * a26 * a32 * a45 * a61 + a16 * a22 * a33 * a45 * a61 - a12 + * a26 * a33 * a45 * a61 - a13 * a22 * a36 * a45 * a61 + a12 * a23 + * a36 * a45 * a61 + a15 * a23 * a32 * a46 * a61 - a13 * a25 * a32 + * a46 * a61 - a15 * a22 * a33 * a46 * a61 + a12 * a25 * a33 * a46 + * a61 + a13 * a22 * a35 * a46 * a61 - a12 * a23 * a35 * a46 * a61 + + a16 * a25 * a33 * a41 * a62 - a15 * a26 * a33 * a41 * a62 - a16 + * a23 * a35 * a41 * a62 + a13 * a26 * a35 * a41 * a62 + a15 * a23 + * a36 * a41 * a62 - a13 * a25 * a36 * a41 * a62 - a16 * a25 * a31 + * a43 * a62 + a15 * a26 * a31 * a43 * a62 + a16 * a21 * a35 * a43 + * a62 - a11 * a26 * a35 * a43 * a62 - a15 * a21 * a36 * a43 * a62 + + a11 * a25 * a36 * a43 * a62 + a16 * a23 * a31 * a45 * a62 - a13 + * a26 * a31 * a45 * a62 - a16 * a21 * a33 * a45 * a62 + a11 * a26 + * a33 * a45 * a62 + a13 * a21 * a36 * a45 * a62 - a11 * a23 * a36 + * a45 * a62 - a15 * a23 * a31 * a46 * a62 + a13 * a25 * a31 * a46 + * a62 + a15 * a21 * a33 * a46 * a62 - a11 * a25 * a33 * a46 * a62 + - a13 * a21 * a35 * a46 * a62 + a11 * a23 * a35 * a46 * a62 - a16 + * a25 * a32 * a41 * a63 + a15 * a26 * a32 * a41 * a63 + a16 * a22 + * a35 * a41 * a63 - a12 * a26 * a35 * a41 * a63 - a15 * a22 * a36 + * a41 * a63 + a12 * a25 * a36 * a41 * a63 + a16 * a25 * a31 * a42 + * a63 - a15 * a26 * a31 * a42 * a63 - a16 * a21 * a35 * a42 * a63 + + a11 * a26 * a35 * a42 * a63 + a15 * a21 * a36 * a42 * a63 - a11 + * a25 * a36 * a42 * a63 - a16 * a22 * a31 * a45 * a63 + a12 * a26 + * a31 * a45 * a63 + a16 * a21 * a32 * a45 * a63 - a11 * a26 * a32 + * a45 * a63 - a12 * a21 * a36 * a45 * a63 + a11 * a22 * a36 * a45 + * a63 + a15 * a22 * a31 * a46 * a63 - a12 * a25 * a31 * a46 * a63 + - a15 * a21 * a32 * a46 * a63 + a11 * a25 * a32 * a46 * a63 + a12 + * a21 * a35 * a46 * a63 - a11 * a22 * a35 * a46 * a63 + a16 * a23 + * a32 * a41 * a65 - a13 * a26 * a32 * a41 * a65 - a16 * a22 * a33 + * a41 * a65 + a12 * a26 * a33 * a41 * a65 + a13 * a22 * a36 * a41 + * a65 - a12 * a23 * a36 * a41 * a65 - a16 * a23 * a31 * a42 * a65 + + a13 * a26 * a31 * a42 * a65 + a16 * a21 * a33 * a42 * a65 - a11 + * a26 * a33 * a42 * a65 - a13 * a21 * a36 * a42 * a65 + a11 * a23 + * a36 * a42 * a65 + a16 * a22 * a31 * a43 * a65 - a12 * a26 * a31 + * a43 * a65 - a16 * a21 * a32 * a43 * a65 + a11 * a26 * a32 * a43 + * a65 + a12 * a21 * a36 * a43 * a65 - a11 * a22 * a36 * a43 * a65 + - a13 * a22 * a31 * a46 * a65 + a12 * a23 * a31 * a46 * a65 + a13 + * a21 * a32 * a46 * a65 - a11 * a23 * a32 * a46 * a65 - a12 * a21 + * a33 * a46 * a65 + a11 * a22 * a33 * a46 * a65 - a15 * a23 * a32 + * a41 * a66 + a13 * a25 * a32 * a41 * a66 + a15 * a22 * a33 * a41 + * a66 - a12 * a25 * a33 * a41 * a66 - a13 * a22 * a35 * a41 * a66 + + a12 * a23 * a35 * a41 * a66 + a15 * a23 * a31 * a42 * a66 - a13 + * a25 * a31 * a42 * a66 - a15 * a21 * a33 * a42 * a66 + a11 * a25 + * a33 * a42 * a66 + a13 * a21 * a35 * a42 * a66 - a11 * a23 * a35 + * a42 * a66 - a15 * a22 * a31 * a43 * a66 + a12 * a25 * a31 * a43 + * a66 + a15 * a21 * a32 * a43 * a66 - a11 * a25 * a32 * a43 * a66 + - a12 * a21 * a35 * a43 * a66 + a11 * a22 * a35 * a43 * a66 + a13 + * a22 * a31 * a45 * a66 - a12 * a23 * a31 * a45 * a66 - a13 * a21 + * a32 * a45 * a66 + a11 * a23 * a32 * a45 * a66 + a12 * a21 * a33 + * a45 * a66 - a11 * a22 * a33 * a45 * a66; + cofactor[23] = a16 * a25 * a33 * a42 * a51 - a15 * a26 * a33 * a42 * a51 + - a16 * a23 * a35 * a42 * a51 + a13 * a26 * a35 * a42 * a51 + a15 + * a23 * a36 * a42 * a51 - a13 * a25 * a36 * a42 * a51 - a16 * a25 + * a32 * a43 * a51 + a15 * a26 * a32 * a43 * a51 + a16 * a22 * a35 + * a43 * a51 - a12 * a26 * a35 * a43 * a51 - a15 * a22 * a36 * a43 + * a51 + a12 * a25 * a36 * a43 * a51 + a16 * a23 * a32 * a45 * a51 + - a13 * a26 * a32 * a45 * a51 - a16 * a22 * a33 * a45 * a51 + a12 + * a26 * a33 * a45 * a51 + a13 * a22 * a36 * a45 * a51 - a12 * a23 + * a36 * a45 * a51 - a15 * a23 * a32 * a46 * a51 + a13 * a25 * a32 + * a46 * a51 + a15 * a22 * a33 * a46 * a51 - a12 * a25 * a33 * a46 + * a51 - a13 * a22 * a35 * a46 * a51 + a12 * a23 * a35 * a46 * a51 + - a16 * a25 * a33 * a41 * a52 + a15 * a26 * a33 * a41 * a52 + a16 + * a23 * a35 * a41 * a52 - a13 * a26 * a35 * a41 * a52 - a15 * a23 + * a36 * a41 * a52 + a13 * a25 * a36 * a41 * a52 + a16 * a25 * a31 + * a43 * a52 - a15 * a26 * a31 * a43 * a52 - a16 * a21 * a35 * a43 + * a52 + a11 * a26 * a35 * a43 * a52 + a15 * a21 * a36 * a43 * a52 + - a11 * a25 * a36 * a43 * a52 - a16 * a23 * a31 * a45 * a52 + a13 + * a26 * a31 * a45 * a52 + a16 * a21 * a33 * a45 * a52 - a11 * a26 + * a33 * a45 * a52 - a13 * a21 * a36 * a45 * a52 + a11 * a23 * a36 + * a45 * a52 + a15 * a23 * a31 * a46 * a52 - a13 * a25 * a31 * a46 + * a52 - a15 * a21 * a33 * a46 * a52 + a11 * a25 * a33 * a46 * a52 + + a13 * a21 * a35 * a46 * a52 - a11 * a23 * a35 * a46 * a52 + a16 + * a25 * a32 * a41 * a53 - a15 * a26 * a32 * a41 * a53 - a16 * a22 + * a35 * a41 * a53 + a12 * a26 * a35 * a41 * a53 + a15 * a22 * a36 + * a41 * a53 - a12 * a25 * a36 * a41 * a53 - a16 * a25 * a31 * a42 + * a53 + a15 * a26 * a31 * a42 * a53 + a16 * a21 * a35 * a42 * a53 + - a11 * a26 * a35 * a42 * a53 - a15 * a21 * a36 * a42 * a53 + a11 + * a25 * a36 * a42 * a53 + a16 * a22 * a31 * a45 * a53 - a12 * a26 + * a31 * a45 * a53 - a16 * a21 * a32 * a45 * a53 + a11 * a26 * a32 + * a45 * a53 + a12 * a21 * a36 * a45 * a53 - a11 * a22 * a36 * a45 + * a53 - a15 * a22 * a31 * a46 * a53 + a12 * a25 * a31 * a46 * a53 + + a15 * a21 * a32 * a46 * a53 - a11 * a25 * a32 * a46 * a53 - a12 + * a21 * a35 * a46 * a53 + a11 * a22 * a35 * a46 * a53 - a16 * a23 + * a32 * a41 * a55 + a13 * a26 * a32 * a41 * a55 + a16 * a22 * a33 + * a41 * a55 - a12 * a26 * a33 * a41 * a55 - a13 * a22 * a36 * a41 + * a55 + a12 * a23 * a36 * a41 * a55 + a16 * a23 * a31 * a42 * a55 + - a13 * a26 * a31 * a42 * a55 - a16 * a21 * a33 * a42 * a55 + a11 + * a26 * a33 * a42 * a55 + a13 * a21 * a36 * a42 * a55 - a11 * a23 + * a36 * a42 * a55 - a16 * a22 * a31 * a43 * a55 + a12 * a26 * a31 + * a43 * a55 + a16 * a21 * a32 * a43 * a55 - a11 * a26 * a32 * a43 + * a55 - a12 * a21 * a36 * a43 * a55 + a11 * a22 * a36 * a43 * a55 + + a13 * a22 * a31 * a46 * a55 - a12 * a23 * a31 * a46 * a55 - a13 + * a21 * a32 * a46 * a55 + a11 * a23 * a32 * a46 * a55 + a12 * a21 + * a33 * a46 * a55 - a11 * a22 * a33 * a46 * a55 + a15 * a23 * a32 + * a41 * a56 - a13 * a25 * a32 * a41 * a56 - a15 * a22 * a33 * a41 + * a56 + a12 * a25 * a33 * a41 * a56 + a13 * a22 * a35 * a41 * a56 + - a12 * a23 * a35 * a41 * a56 - a15 * a23 * a31 * a42 * a56 + a13 + * a25 * a31 * a42 * a56 + a15 * a21 * a33 * a42 * a56 - a11 * a25 + * a33 * a42 * a56 - a13 * a21 * a35 * a42 * a56 + a11 * a23 * a35 + * a42 * a56 + a15 * a22 * a31 * a43 * a56 - a12 * a25 * a31 * a43 + * a56 - a15 * a21 * a32 * a43 * a56 + a11 * a25 * a32 * a43 * a56 + + a12 * a21 * a35 * a43 * a56 - a11 * a22 * a35 * a43 * a56 - a13 + * a22 * a31 * a45 * a56 + a12 * a23 * a31 * a45 * a56 + a13 * a21 + * a32 * a45 * a56 - a11 * a23 * a32 * a45 * a56 - a12 * a21 * a33 + * a45 * a56 + a11 * a22 * a33 * a45 * a56; + cofactor[24] = a26 * a34 * a43 * a52 * a61 - a24 * a36 * a43 * a52 * a61 + - a26 * a33 * a44 * a52 * a61 + a23 * a36 * a44 * a52 * a61 + a24 + * a33 * a46 * a52 * a61 - a23 * a34 * a46 * a52 * a61 - a26 * a34 + * a42 * a53 * a61 + a24 * a36 * a42 * a53 * a61 + a26 * a32 * a44 + * a53 * a61 - a22 * a36 * a44 * a53 * a61 - a24 * a32 * a46 * a53 + * a61 + a22 * a34 * a46 * a53 * a61 + a26 * a33 * a42 * a54 * a61 + - a23 * a36 * a42 * a54 * a61 - a26 * a32 * a43 * a54 * a61 + a22 + * a36 * a43 * a54 * a61 + a23 * a32 * a46 * a54 * a61 - a22 * a33 + * a46 * a54 * a61 - a24 * a33 * a42 * a56 * a61 + a23 * a34 * a42 + * a56 * a61 + a24 * a32 * a43 * a56 * a61 - a22 * a34 * a43 * a56 + * a61 - a23 * a32 * a44 * a56 * a61 + a22 * a33 * a44 * a56 * a61 + - a26 * a34 * a43 * a51 * a62 + a24 * a36 * a43 * a51 * a62 + a26 + * a33 * a44 * a51 * a62 - a23 * a36 * a44 * a51 * a62 - a24 * a33 + * a46 * a51 * a62 + a23 * a34 * a46 * a51 * a62 + a26 * a34 * a41 + * a53 * a62 - a24 * a36 * a41 * a53 * a62 - a26 * a31 * a44 * a53 + * a62 + a21 * a36 * a44 * a53 * a62 + a24 * a31 * a46 * a53 * a62 + - a21 * a34 * a46 * a53 * a62 - a26 * a33 * a41 * a54 * a62 + a23 + * a36 * a41 * a54 * a62 + a26 * a31 * a43 * a54 * a62 - a21 * a36 + * a43 * a54 * a62 - a23 * a31 * a46 * a54 * a62 + a21 * a33 * a46 + * a54 * a62 + a24 * a33 * a41 * a56 * a62 - a23 * a34 * a41 * a56 + * a62 - a24 * a31 * a43 * a56 * a62 + a21 * a34 * a43 * a56 * a62 + + a23 * a31 * a44 * a56 * a62 - a21 * a33 * a44 * a56 * a62 + a26 + * a34 * a42 * a51 * a63 - a24 * a36 * a42 * a51 * a63 - a26 * a32 + * a44 * a51 * a63 + a22 * a36 * a44 * a51 * a63 + a24 * a32 * a46 + * a51 * a63 - a22 * a34 * a46 * a51 * a63 - a26 * a34 * a41 * a52 + * a63 + a24 * a36 * a41 * a52 * a63 + a26 * a31 * a44 * a52 * a63 + - a21 * a36 * a44 * a52 * a63 - a24 * a31 * a46 * a52 * a63 + a21 + * a34 * a46 * a52 * a63 + a26 * a32 * a41 * a54 * a63 - a22 * a36 + * a41 * a54 * a63 - a26 * a31 * a42 * a54 * a63 + a21 * a36 * a42 + * a54 * a63 + a22 * a31 * a46 * a54 * a63 - a21 * a32 * a46 * a54 + * a63 - a24 * a32 * a41 * a56 * a63 + a22 * a34 * a41 * a56 * a63 + + a24 * a31 * a42 * a56 * a63 - a21 * a34 * a42 * a56 * a63 - a22 + * a31 * a44 * a56 * a63 + a21 * a32 * a44 * a56 * a63 - a26 * a33 + * a42 * a51 * a64 + a23 * a36 * a42 * a51 * a64 + a26 * a32 * a43 + * a51 * a64 - a22 * a36 * a43 * a51 * a64 - a23 * a32 * a46 * a51 + * a64 + a22 * a33 * a46 * a51 * a64 + a26 * a33 * a41 * a52 * a64 + - a23 * a36 * a41 * a52 * a64 - a26 * a31 * a43 * a52 * a64 + a21 + * a36 * a43 * a52 * a64 + a23 * a31 * a46 * a52 * a64 - a21 * a33 + * a46 * a52 * a64 - a26 * a32 * a41 * a53 * a64 + a22 * a36 * a41 + * a53 * a64 + a26 * a31 * a42 * a53 * a64 - a21 * a36 * a42 * a53 + * a64 - a22 * a31 * a46 * a53 * a64 + a21 * a32 * a46 * a53 * a64 + + a23 * a32 * a41 * a56 * a64 - a22 * a33 * a41 * a56 * a64 - a23 + * a31 * a42 * a56 * a64 + a21 * a33 * a42 * a56 * a64 + a22 * a31 + * a43 * a56 * a64 - a21 * a32 * a43 * a56 * a64 + a24 * a33 * a42 + * a51 * a66 - a23 * a34 * a42 * a51 * a66 - a24 * a32 * a43 * a51 + * a66 + a22 * a34 * a43 * a51 * a66 + a23 * a32 * a44 * a51 * a66 + - a22 * a33 * a44 * a51 * a66 - a24 * a33 * a41 * a52 * a66 + a23 + * a34 * a41 * a52 * a66 + a24 * a31 * a43 * a52 * a66 - a21 * a34 + * a43 * a52 * a66 - a23 * a31 * a44 * a52 * a66 + a21 * a33 * a44 + * a52 * a66 + a24 * a32 * a41 * a53 * a66 - a22 * a34 * a41 * a53 + * a66 - a24 * a31 * a42 * a53 * a66 + a21 * a34 * a42 * a53 * a66 + + a22 * a31 * a44 * a53 * a66 - a21 * a32 * a44 * a53 * a66 - a23 + * a32 * a41 * a54 * a66 + a22 * a33 * a41 * a54 * a66 + a23 * a31 + * a42 * a54 * a66 - a21 * a33 * a42 * a54 * a66 - a22 * a31 * a43 + * a54 * a66 + a21 * a32 * a43 * a54 * a66; + cofactor[25] = -a16 * a34 * a43 * a52 * a61 + a14 * a36 * a43 * a52 * a61 + + a16 * a33 * a44 * a52 * a61 - a13 * a36 * a44 * a52 * a61 - a14 + * a33 * a46 * a52 * a61 + a13 * a34 * a46 * a52 * a61 + a16 * a34 + * a42 * a53 * a61 - a14 * a36 * a42 * a53 * a61 - a16 * a32 * a44 + * a53 * a61 + a12 * a36 * a44 * a53 * a61 + a14 * a32 * a46 * a53 + * a61 - a12 * a34 * a46 * a53 * a61 - a16 * a33 * a42 * a54 * a61 + + a13 * a36 * a42 * a54 * a61 + a16 * a32 * a43 * a54 * a61 - a12 + * a36 * a43 * a54 * a61 - a13 * a32 * a46 * a54 * a61 + a12 * a33 + * a46 * a54 * a61 + a14 * a33 * a42 * a56 * a61 - a13 * a34 * a42 + * a56 * a61 - a14 * a32 * a43 * a56 * a61 + a12 * a34 * a43 * a56 + * a61 + a13 * a32 * a44 * a56 * a61 - a12 * a33 * a44 * a56 * a61 + + a16 * a34 * a43 * a51 * a62 - a14 * a36 * a43 * a51 * a62 - a16 + * a33 * a44 * a51 * a62 + a13 * a36 * a44 * a51 * a62 + a14 * a33 + * a46 * a51 * a62 - a13 * a34 * a46 * a51 * a62 - a16 * a34 * a41 + * a53 * a62 + a14 * a36 * a41 * a53 * a62 + a16 * a31 * a44 * a53 + * a62 - a11 * a36 * a44 * a53 * a62 - a14 * a31 * a46 * a53 * a62 + + a11 * a34 * a46 * a53 * a62 + a16 * a33 * a41 * a54 * a62 - a13 + * a36 * a41 * a54 * a62 - a16 * a31 * a43 * a54 * a62 + a11 * a36 + * a43 * a54 * a62 + a13 * a31 * a46 * a54 * a62 - a11 * a33 * a46 + * a54 * a62 - a14 * a33 * a41 * a56 * a62 + a13 * a34 * a41 * a56 + * a62 + a14 * a31 * a43 * a56 * a62 - a11 * a34 * a43 * a56 * a62 + - a13 * a31 * a44 * a56 * a62 + a11 * a33 * a44 * a56 * a62 - a16 + * a34 * a42 * a51 * a63 + a14 * a36 * a42 * a51 * a63 + a16 * a32 + * a44 * a51 * a63 - a12 * a36 * a44 * a51 * a63 - a14 * a32 * a46 + * a51 * a63 + a12 * a34 * a46 * a51 * a63 + a16 * a34 * a41 * a52 + * a63 - a14 * a36 * a41 * a52 * a63 - a16 * a31 * a44 * a52 * a63 + + a11 * a36 * a44 * a52 * a63 + a14 * a31 * a46 * a52 * a63 - a11 + * a34 * a46 * a52 * a63 - a16 * a32 * a41 * a54 * a63 + a12 * a36 + * a41 * a54 * a63 + a16 * a31 * a42 * a54 * a63 - a11 * a36 * a42 + * a54 * a63 - a12 * a31 * a46 * a54 * a63 + a11 * a32 * a46 * a54 + * a63 + a14 * a32 * a41 * a56 * a63 - a12 * a34 * a41 * a56 * a63 + - a14 * a31 * a42 * a56 * a63 + a11 * a34 * a42 * a56 * a63 + a12 + * a31 * a44 * a56 * a63 - a11 * a32 * a44 * a56 * a63 + a16 * a33 + * a42 * a51 * a64 - a13 * a36 * a42 * a51 * a64 - a16 * a32 * a43 + * a51 * a64 + a12 * a36 * a43 * a51 * a64 + a13 * a32 * a46 * a51 + * a64 - a12 * a33 * a46 * a51 * a64 - a16 * a33 * a41 * a52 * a64 + + a13 * a36 * a41 * a52 * a64 + a16 * a31 * a43 * a52 * a64 - a11 + * a36 * a43 * a52 * a64 - a13 * a31 * a46 * a52 * a64 + a11 * a33 + * a46 * a52 * a64 + a16 * a32 * a41 * a53 * a64 - a12 * a36 * a41 + * a53 * a64 - a16 * a31 * a42 * a53 * a64 + a11 * a36 * a42 * a53 + * a64 + a12 * a31 * a46 * a53 * a64 - a11 * a32 * a46 * a53 * a64 + - a13 * a32 * a41 * a56 * a64 + a12 * a33 * a41 * a56 * a64 + a13 + * a31 * a42 * a56 * a64 - a11 * a33 * a42 * a56 * a64 - a12 * a31 + * a43 * a56 * a64 + a11 * a32 * a43 * a56 * a64 - a14 * a33 * a42 + * a51 * a66 + a13 * a34 * a42 * a51 * a66 + a14 * a32 * a43 * a51 + * a66 - a12 * a34 * a43 * a51 * a66 - a13 * a32 * a44 * a51 * a66 + + a12 * a33 * a44 * a51 * a66 + a14 * a33 * a41 * a52 * a66 - a13 + * a34 * a41 * a52 * a66 - a14 * a31 * a43 * a52 * a66 + a11 * a34 + * a43 * a52 * a66 + a13 * a31 * a44 * a52 * a66 - a11 * a33 * a44 + * a52 * a66 - a14 * a32 * a41 * a53 * a66 + a12 * a34 * a41 * a53 + * a66 + a14 * a31 * a42 * a53 * a66 - a11 * a34 * a42 * a53 * a66 + - a12 * a31 * a44 * a53 * a66 + a11 * a32 * a44 * a53 * a66 + a13 + * a32 * a41 * a54 * a66 - a12 * a33 * a41 * a54 * a66 - a13 * a31 + * a42 * a54 * a66 + a11 * a33 * a42 * a54 * a66 + a12 * a31 * a43 + * a54 * a66 - a11 * a32 * a43 * a54 * a66; + cofactor[26] = a16 * a24 * a43 * a52 * a61 - a14 * a26 * a43 * a52 * a61 + - a16 * a23 * a44 * a52 * a61 + a13 * a26 * a44 * a52 * a61 + a14 + * a23 * a46 * a52 * a61 - a13 * a24 * a46 * a52 * a61 - a16 * a24 + * a42 * a53 * a61 + a14 * a26 * a42 * a53 * a61 + a16 * a22 * a44 + * a53 * a61 - a12 * a26 * a44 * a53 * a61 - a14 * a22 * a46 * a53 + * a61 + a12 * a24 * a46 * a53 * a61 + a16 * a23 * a42 * a54 * a61 + - a13 * a26 * a42 * a54 * a61 - a16 * a22 * a43 * a54 * a61 + a12 + * a26 * a43 * a54 * a61 + a13 * a22 * a46 * a54 * a61 - a12 * a23 + * a46 * a54 * a61 - a14 * a23 * a42 * a56 * a61 + a13 * a24 * a42 + * a56 * a61 + a14 * a22 * a43 * a56 * a61 - a12 * a24 * a43 * a56 + * a61 - a13 * a22 * a44 * a56 * a61 + a12 * a23 * a44 * a56 * a61 + - a16 * a24 * a43 * a51 * a62 + a14 * a26 * a43 * a51 * a62 + a16 + * a23 * a44 * a51 * a62 - a13 * a26 * a44 * a51 * a62 - a14 * a23 + * a46 * a51 * a62 + a13 * a24 * a46 * a51 * a62 + a16 * a24 * a41 + * a53 * a62 - a14 * a26 * a41 * a53 * a62 - a16 * a21 * a44 * a53 + * a62 + a11 * a26 * a44 * a53 * a62 + a14 * a21 * a46 * a53 * a62 + - a11 * a24 * a46 * a53 * a62 - a16 * a23 * a41 * a54 * a62 + a13 + * a26 * a41 * a54 * a62 + a16 * a21 * a43 * a54 * a62 - a11 * a26 + * a43 * a54 * a62 - a13 * a21 * a46 * a54 * a62 + a11 * a23 * a46 + * a54 * a62 + a14 * a23 * a41 * a56 * a62 - a13 * a24 * a41 * a56 + * a62 - a14 * a21 * a43 * a56 * a62 + a11 * a24 * a43 * a56 * a62 + + a13 * a21 * a44 * a56 * a62 - a11 * a23 * a44 * a56 * a62 + a16 + * a24 * a42 * a51 * a63 - a14 * a26 * a42 * a51 * a63 - a16 * a22 + * a44 * a51 * a63 + a12 * a26 * a44 * a51 * a63 + a14 * a22 * a46 + * a51 * a63 - a12 * a24 * a46 * a51 * a63 - a16 * a24 * a41 * a52 + * a63 + a14 * a26 * a41 * a52 * a63 + a16 * a21 * a44 * a52 * a63 + - a11 * a26 * a44 * a52 * a63 - a14 * a21 * a46 * a52 * a63 + a11 + * a24 * a46 * a52 * a63 + a16 * a22 * a41 * a54 * a63 - a12 * a26 + * a41 * a54 * a63 - a16 * a21 * a42 * a54 * a63 + a11 * a26 * a42 + * a54 * a63 + a12 * a21 * a46 * a54 * a63 - a11 * a22 * a46 * a54 + * a63 - a14 * a22 * a41 * a56 * a63 + a12 * a24 * a41 * a56 * a63 + + a14 * a21 * a42 * a56 * a63 - a11 * a24 * a42 * a56 * a63 - a12 + * a21 * a44 * a56 * a63 + a11 * a22 * a44 * a56 * a63 - a16 * a23 + * a42 * a51 * a64 + a13 * a26 * a42 * a51 * a64 + a16 * a22 * a43 + * a51 * a64 - a12 * a26 * a43 * a51 * a64 - a13 * a22 * a46 * a51 + * a64 + a12 * a23 * a46 * a51 * a64 + a16 * a23 * a41 * a52 * a64 + - a13 * a26 * a41 * a52 * a64 - a16 * a21 * a43 * a52 * a64 + a11 + * a26 * a43 * a52 * a64 + a13 * a21 * a46 * a52 * a64 - a11 * a23 + * a46 * a52 * a64 - a16 * a22 * a41 * a53 * a64 + a12 * a26 * a41 + * a53 * a64 + a16 * a21 * a42 * a53 * a64 - a11 * a26 * a42 * a53 + * a64 - a12 * a21 * a46 * a53 * a64 + a11 * a22 * a46 * a53 * a64 + + a13 * a22 * a41 * a56 * a64 - a12 * a23 * a41 * a56 * a64 - a13 + * a21 * a42 * a56 * a64 + a11 * a23 * a42 * a56 * a64 + a12 * a21 + * a43 * a56 * a64 - a11 * a22 * a43 * a56 * a64 + a14 * a23 * a42 + * a51 * a66 - a13 * a24 * a42 * a51 * a66 - a14 * a22 * a43 * a51 + * a66 + a12 * a24 * a43 * a51 * a66 + a13 * a22 * a44 * a51 * a66 + - a12 * a23 * a44 * a51 * a66 - a14 * a23 * a41 * a52 * a66 + a13 + * a24 * a41 * a52 * a66 + a14 * a21 * a43 * a52 * a66 - a11 * a24 + * a43 * a52 * a66 - a13 * a21 * a44 * a52 * a66 + a11 * a23 * a44 + * a52 * a66 + a14 * a22 * a41 * a53 * a66 - a12 * a24 * a41 * a53 + * a66 - a14 * a21 * a42 * a53 * a66 + a11 * a24 * a42 * a53 * a66 + + a12 * a21 * a44 * a53 * a66 - a11 * a22 * a44 * a53 * a66 - a13 + * a22 * a41 * a54 * a66 + a12 * a23 * a41 * a54 * a66 + a13 * a21 + * a42 * a54 * a66 - a11 * a23 * a42 * a54 * a66 - a12 * a21 * a43 + * a54 * a66 + a11 * a22 * a43 * a54 * a66; + cofactor[27] = -a16 * a24 * a33 * a52 * a61 + a14 * a26 * a33 * a52 * a61 + + a16 * a23 * a34 * a52 * a61 - a13 * a26 * a34 * a52 * a61 - a14 + * a23 * a36 * a52 * a61 + a13 * a24 * a36 * a52 * a61 + a16 * a24 + * a32 * a53 * a61 - a14 * a26 * a32 * a53 * a61 - a16 * a22 * a34 + * a53 * a61 + a12 * a26 * a34 * a53 * a61 + a14 * a22 * a36 * a53 + * a61 - a12 * a24 * a36 * a53 * a61 - a16 * a23 * a32 * a54 * a61 + + a13 * a26 * a32 * a54 * a61 + a16 * a22 * a33 * a54 * a61 - a12 + * a26 * a33 * a54 * a61 - a13 * a22 * a36 * a54 * a61 + a12 * a23 + * a36 * a54 * a61 + a14 * a23 * a32 * a56 * a61 - a13 * a24 * a32 + * a56 * a61 - a14 * a22 * a33 * a56 * a61 + a12 * a24 * a33 * a56 + * a61 + a13 * a22 * a34 * a56 * a61 - a12 * a23 * a34 * a56 * a61 + + a16 * a24 * a33 * a51 * a62 - a14 * a26 * a33 * a51 * a62 - a16 + * a23 * a34 * a51 * a62 + a13 * a26 * a34 * a51 * a62 + a14 * a23 + * a36 * a51 * a62 - a13 * a24 * a36 * a51 * a62 - a16 * a24 * a31 + * a53 * a62 + a14 * a26 * a31 * a53 * a62 + a16 * a21 * a34 * a53 + * a62 - a11 * a26 * a34 * a53 * a62 - a14 * a21 * a36 * a53 * a62 + + a11 * a24 * a36 * a53 * a62 + a16 * a23 * a31 * a54 * a62 - a13 + * a26 * a31 * a54 * a62 - a16 * a21 * a33 * a54 * a62 + a11 * a26 + * a33 * a54 * a62 + a13 * a21 * a36 * a54 * a62 - a11 * a23 * a36 + * a54 * a62 - a14 * a23 * a31 * a56 * a62 + a13 * a24 * a31 * a56 + * a62 + a14 * a21 * a33 * a56 * a62 - a11 * a24 * a33 * a56 * a62 + - a13 * a21 * a34 * a56 * a62 + a11 * a23 * a34 * a56 * a62 - a16 + * a24 * a32 * a51 * a63 + a14 * a26 * a32 * a51 * a63 + a16 * a22 + * a34 * a51 * a63 - a12 * a26 * a34 * a51 * a63 - a14 * a22 * a36 + * a51 * a63 + a12 * a24 * a36 * a51 * a63 + a16 * a24 * a31 * a52 + * a63 - a14 * a26 * a31 * a52 * a63 - a16 * a21 * a34 * a52 * a63 + + a11 * a26 * a34 * a52 * a63 + a14 * a21 * a36 * a52 * a63 - a11 + * a24 * a36 * a52 * a63 - a16 * a22 * a31 * a54 * a63 + a12 * a26 + * a31 * a54 * a63 + a16 * a21 * a32 * a54 * a63 - a11 * a26 * a32 + * a54 * a63 - a12 * a21 * a36 * a54 * a63 + a11 * a22 * a36 * a54 + * a63 + a14 * a22 * a31 * a56 * a63 - a12 * a24 * a31 * a56 * a63 + - a14 * a21 * a32 * a56 * a63 + a11 * a24 * a32 * a56 * a63 + a12 + * a21 * a34 * a56 * a63 - a11 * a22 * a34 * a56 * a63 + a16 * a23 + * a32 * a51 * a64 - a13 * a26 * a32 * a51 * a64 - a16 * a22 * a33 + * a51 * a64 + a12 * a26 * a33 * a51 * a64 + a13 * a22 * a36 * a51 + * a64 - a12 * a23 * a36 * a51 * a64 - a16 * a23 * a31 * a52 * a64 + + a13 * a26 * a31 * a52 * a64 + a16 * a21 * a33 * a52 * a64 - a11 + * a26 * a33 * a52 * a64 - a13 * a21 * a36 * a52 * a64 + a11 * a23 + * a36 * a52 * a64 + a16 * a22 * a31 * a53 * a64 - a12 * a26 * a31 + * a53 * a64 - a16 * a21 * a32 * a53 * a64 + a11 * a26 * a32 * a53 + * a64 + a12 * a21 * a36 * a53 * a64 - a11 * a22 * a36 * a53 * a64 + - a13 * a22 * a31 * a56 * a64 + a12 * a23 * a31 * a56 * a64 + a13 + * a21 * a32 * a56 * a64 - a11 * a23 * a32 * a56 * a64 - a12 * a21 + * a33 * a56 * a64 + a11 * a22 * a33 * a56 * a64 - a14 * a23 * a32 + * a51 * a66 + a13 * a24 * a32 * a51 * a66 + a14 * a22 * a33 * a51 + * a66 - a12 * a24 * a33 * a51 * a66 - a13 * a22 * a34 * a51 * a66 + + a12 * a23 * a34 * a51 * a66 + a14 * a23 * a31 * a52 * a66 - a13 + * a24 * a31 * a52 * a66 - a14 * a21 * a33 * a52 * a66 + a11 * a24 + * a33 * a52 * a66 + a13 * a21 * a34 * a52 * a66 - a11 * a23 * a34 + * a52 * a66 - a14 * a22 * a31 * a53 * a66 + a12 * a24 * a31 * a53 + * a66 + a14 * a21 * a32 * a53 * a66 - a11 * a24 * a32 * a53 * a66 + - a12 * a21 * a34 * a53 * a66 + a11 * a22 * a34 * a53 * a66 + a13 + * a22 * a31 * a54 * a66 - a12 * a23 * a31 * a54 * a66 - a13 * a21 + * a32 * a54 * a66 + a11 * a23 * a32 * a54 * a66 + a12 * a21 * a33 + * a54 * a66 - a11 * a22 * a33 * a54 * a66; + cofactor[28] = a16 * a24 * a33 * a42 * a61 - a14 * a26 * a33 * a42 * a61 + - a16 * a23 * a34 * a42 * a61 + a13 * a26 * a34 * a42 * a61 + a14 + * a23 * a36 * a42 * a61 - a13 * a24 * a36 * a42 * a61 - a16 * a24 + * a32 * a43 * a61 + a14 * a26 * a32 * a43 * a61 + a16 * a22 * a34 + * a43 * a61 - a12 * a26 * a34 * a43 * a61 - a14 * a22 * a36 * a43 + * a61 + a12 * a24 * a36 * a43 * a61 + a16 * a23 * a32 * a44 * a61 + - a13 * a26 * a32 * a44 * a61 - a16 * a22 * a33 * a44 * a61 + a12 + * a26 * a33 * a44 * a61 + a13 * a22 * a36 * a44 * a61 - a12 * a23 + * a36 * a44 * a61 - a14 * a23 * a32 * a46 * a61 + a13 * a24 * a32 + * a46 * a61 + a14 * a22 * a33 * a46 * a61 - a12 * a24 * a33 * a46 + * a61 - a13 * a22 * a34 * a46 * a61 + a12 * a23 * a34 * a46 * a61 + - a16 * a24 * a33 * a41 * a62 + a14 * a26 * a33 * a41 * a62 + a16 + * a23 * a34 * a41 * a62 - a13 * a26 * a34 * a41 * a62 - a14 * a23 + * a36 * a41 * a62 + a13 * a24 * a36 * a41 * a62 + a16 * a24 * a31 + * a43 * a62 - a14 * a26 * a31 * a43 * a62 - a16 * a21 * a34 * a43 + * a62 + a11 * a26 * a34 * a43 * a62 + a14 * a21 * a36 * a43 * a62 + - a11 * a24 * a36 * a43 * a62 - a16 * a23 * a31 * a44 * a62 + a13 + * a26 * a31 * a44 * a62 + a16 * a21 * a33 * a44 * a62 - a11 * a26 + * a33 * a44 * a62 - a13 * a21 * a36 * a44 * a62 + a11 * a23 * a36 + * a44 * a62 + a14 * a23 * a31 * a46 * a62 - a13 * a24 * a31 * a46 + * a62 - a14 * a21 * a33 * a46 * a62 + a11 * a24 * a33 * a46 * a62 + + a13 * a21 * a34 * a46 * a62 - a11 * a23 * a34 * a46 * a62 + a16 + * a24 * a32 * a41 * a63 - a14 * a26 * a32 * a41 * a63 - a16 * a22 + * a34 * a41 * a63 + a12 * a26 * a34 * a41 * a63 + a14 * a22 * a36 + * a41 * a63 - a12 * a24 * a36 * a41 * a63 - a16 * a24 * a31 * a42 + * a63 + a14 * a26 * a31 * a42 * a63 + a16 * a21 * a34 * a42 * a63 + - a11 * a26 * a34 * a42 * a63 - a14 * a21 * a36 * a42 * a63 + a11 + * a24 * a36 * a42 * a63 + a16 * a22 * a31 * a44 * a63 - a12 * a26 + * a31 * a44 * a63 - a16 * a21 * a32 * a44 * a63 + a11 * a26 * a32 + * a44 * a63 + a12 * a21 * a36 * a44 * a63 - a11 * a22 * a36 * a44 + * a63 - a14 * a22 * a31 * a46 * a63 + a12 * a24 * a31 * a46 * a63 + + a14 * a21 * a32 * a46 * a63 - a11 * a24 * a32 * a46 * a63 - a12 + * a21 * a34 * a46 * a63 + a11 * a22 * a34 * a46 * a63 - a16 * a23 + * a32 * a41 * a64 + a13 * a26 * a32 * a41 * a64 + a16 * a22 * a33 + * a41 * a64 - a12 * a26 * a33 * a41 * a64 - a13 * a22 * a36 * a41 + * a64 + a12 * a23 * a36 * a41 * a64 + a16 * a23 * a31 * a42 * a64 + - a13 * a26 * a31 * a42 * a64 - a16 * a21 * a33 * a42 * a64 + a11 + * a26 * a33 * a42 * a64 + a13 * a21 * a36 * a42 * a64 - a11 * a23 + * a36 * a42 * a64 - a16 * a22 * a31 * a43 * a64 + a12 * a26 * a31 + * a43 * a64 + a16 * a21 * a32 * a43 * a64 - a11 * a26 * a32 * a43 + * a64 - a12 * a21 * a36 * a43 * a64 + a11 * a22 * a36 * a43 * a64 + + a13 * a22 * a31 * a46 * a64 - a12 * a23 * a31 * a46 * a64 - a13 + * a21 * a32 * a46 * a64 + a11 * a23 * a32 * a46 * a64 + a12 * a21 + * a33 * a46 * a64 - a11 * a22 * a33 * a46 * a64 + a14 * a23 * a32 + * a41 * a66 - a13 * a24 * a32 * a41 * a66 - a14 * a22 * a33 * a41 + * a66 + a12 * a24 * a33 * a41 * a66 + a13 * a22 * a34 * a41 * a66 + - a12 * a23 * a34 * a41 * a66 - a14 * a23 * a31 * a42 * a66 + a13 + * a24 * a31 * a42 * a66 + a14 * a21 * a33 * a42 * a66 - a11 * a24 + * a33 * a42 * a66 - a13 * a21 * a34 * a42 * a66 + a11 * a23 * a34 + * a42 * a66 + a14 * a22 * a31 * a43 * a66 - a12 * a24 * a31 * a43 + * a66 - a14 * a21 * a32 * a43 * a66 + a11 * a24 * a32 * a43 * a66 + + a12 * a21 * a34 * a43 * a66 - a11 * a22 * a34 * a43 * a66 - a13 + * a22 * a31 * a44 * a66 + a12 * a23 * a31 * a44 * a66 + a13 * a21 + * a32 * a44 * a66 - a11 * a23 * a32 * a44 * a66 - a12 * a21 * a33 + * a44 * a66 + a11 * a22 * a33 * a44 * a66; + cofactor[29] = -a16 * a24 * a33 * a42 * a51 + a14 * a26 * a33 * a42 * a51 + + a16 * a23 * a34 * a42 * a51 - a13 * a26 * a34 * a42 * a51 - a14 + * a23 * a36 * a42 * a51 + a13 * a24 * a36 * a42 * a51 + a16 * a24 + * a32 * a43 * a51 - a14 * a26 * a32 * a43 * a51 - a16 * a22 * a34 + * a43 * a51 + a12 * a26 * a34 * a43 * a51 + a14 * a22 * a36 * a43 + * a51 - a12 * a24 * a36 * a43 * a51 - a16 * a23 * a32 * a44 * a51 + + a13 * a26 * a32 * a44 * a51 + a16 * a22 * a33 * a44 * a51 - a12 + * a26 * a33 * a44 * a51 - a13 * a22 * a36 * a44 * a51 + a12 * a23 + * a36 * a44 * a51 + a14 * a23 * a32 * a46 * a51 - a13 * a24 * a32 + * a46 * a51 - a14 * a22 * a33 * a46 * a51 + a12 * a24 * a33 * a46 + * a51 + a13 * a22 * a34 * a46 * a51 - a12 * a23 * a34 * a46 * a51 + + a16 * a24 * a33 * a41 * a52 - a14 * a26 * a33 * a41 * a52 - a16 + * a23 * a34 * a41 * a52 + a13 * a26 * a34 * a41 * a52 + a14 * a23 + * a36 * a41 * a52 - a13 * a24 * a36 * a41 * a52 - a16 * a24 * a31 + * a43 * a52 + a14 * a26 * a31 * a43 * a52 + a16 * a21 * a34 * a43 + * a52 - a11 * a26 * a34 * a43 * a52 - a14 * a21 * a36 * a43 * a52 + + a11 * a24 * a36 * a43 * a52 + a16 * a23 * a31 * a44 * a52 - a13 + * a26 * a31 * a44 * a52 - a16 * a21 * a33 * a44 * a52 + a11 * a26 + * a33 * a44 * a52 + a13 * a21 * a36 * a44 * a52 - a11 * a23 * a36 + * a44 * a52 - a14 * a23 * a31 * a46 * a52 + a13 * a24 * a31 * a46 + * a52 + a14 * a21 * a33 * a46 * a52 - a11 * a24 * a33 * a46 * a52 + - a13 * a21 * a34 * a46 * a52 + a11 * a23 * a34 * a46 * a52 - a16 + * a24 * a32 * a41 * a53 + a14 * a26 * a32 * a41 * a53 + a16 * a22 + * a34 * a41 * a53 - a12 * a26 * a34 * a41 * a53 - a14 * a22 * a36 + * a41 * a53 + a12 * a24 * a36 * a41 * a53 + a16 * a24 * a31 * a42 + * a53 - a14 * a26 * a31 * a42 * a53 - a16 * a21 * a34 * a42 * a53 + + a11 * a26 * a34 * a42 * a53 + a14 * a21 * a36 * a42 * a53 - a11 + * a24 * a36 * a42 * a53 - a16 * a22 * a31 * a44 * a53 + a12 * a26 + * a31 * a44 * a53 + a16 * a21 * a32 * a44 * a53 - a11 * a26 * a32 + * a44 * a53 - a12 * a21 * a36 * a44 * a53 + a11 * a22 * a36 * a44 + * a53 + a14 * a22 * a31 * a46 * a53 - a12 * a24 * a31 * a46 * a53 + - a14 * a21 * a32 * a46 * a53 + a11 * a24 * a32 * a46 * a53 + a12 + * a21 * a34 * a46 * a53 - a11 * a22 * a34 * a46 * a53 + a16 * a23 + * a32 * a41 * a54 - a13 * a26 * a32 * a41 * a54 - a16 * a22 * a33 + * a41 * a54 + a12 * a26 * a33 * a41 * a54 + a13 * a22 * a36 * a41 + * a54 - a12 * a23 * a36 * a41 * a54 - a16 * a23 * a31 * a42 * a54 + + a13 * a26 * a31 * a42 * a54 + a16 * a21 * a33 * a42 * a54 - a11 + * a26 * a33 * a42 * a54 - a13 * a21 * a36 * a42 * a54 + a11 * a23 + * a36 * a42 * a54 + a16 * a22 * a31 * a43 * a54 - a12 * a26 * a31 + * a43 * a54 - a16 * a21 * a32 * a43 * a54 + a11 * a26 * a32 * a43 + * a54 + a12 * a21 * a36 * a43 * a54 - a11 * a22 * a36 * a43 * a54 + - a13 * a22 * a31 * a46 * a54 + a12 * a23 * a31 * a46 * a54 + a13 + * a21 * a32 * a46 * a54 - a11 * a23 * a32 * a46 * a54 - a12 * a21 + * a33 * a46 * a54 + a11 * a22 * a33 * a46 * a54 - a14 * a23 * a32 + * a41 * a56 + a13 * a24 * a32 * a41 * a56 + a14 * a22 * a33 * a41 + * a56 - a12 * a24 * a33 * a41 * a56 - a13 * a22 * a34 * a41 * a56 + + a12 * a23 * a34 * a41 * a56 + a14 * a23 * a31 * a42 * a56 - a13 + * a24 * a31 * a42 * a56 - a14 * a21 * a33 * a42 * a56 + a11 * a24 + * a33 * a42 * a56 + a13 * a21 * a34 * a42 * a56 - a11 * a23 * a34 + * a42 * a56 - a14 * a22 * a31 * a43 * a56 + a12 * a24 * a31 * a43 + * a56 + a14 * a21 * a32 * a43 * a56 - a11 * a24 * a32 * a43 * a56 + - a12 * a21 * a34 * a43 * a56 + a11 * a22 * a34 * a43 * a56 + a13 + * a22 * a31 * a44 * a56 - a12 * a23 * a31 * a44 * a56 - a13 * a21 + * a32 * a44 * a56 + a11 * a23 * a32 * a44 * a56 + a12 * a21 * a33 + * a44 * a56 - a11 * a22 * a33 * a44 * a56; + cofactor[30] = -a25 * a34 * a43 * a52 * a61 + a24 * a35 * a43 * a52 * a61 + + a25 * a33 * a44 * a52 * a61 - a23 * a35 * a44 * a52 * a61 - a24 + * a33 * a45 * a52 * a61 + a23 * a34 * a45 * a52 * a61 + a25 * a34 + * a42 * a53 * a61 - a24 * a35 * a42 * a53 * a61 - a25 * a32 * a44 + * a53 * a61 + a22 * a35 * a44 * a53 * a61 + a24 * a32 * a45 * a53 + * a61 - a22 * a34 * a45 * a53 * a61 - a25 * a33 * a42 * a54 * a61 + + a23 * a35 * a42 * a54 * a61 + a25 * a32 * a43 * a54 * a61 - a22 + * a35 * a43 * a54 * a61 - a23 * a32 * a45 * a54 * a61 + a22 * a33 + * a45 * a54 * a61 + a24 * a33 * a42 * a55 * a61 - a23 * a34 * a42 + * a55 * a61 - a24 * a32 * a43 * a55 * a61 + a22 * a34 * a43 * a55 + * a61 + a23 * a32 * a44 * a55 * a61 - a22 * a33 * a44 * a55 * a61 + + a25 * a34 * a43 * a51 * a62 - a24 * a35 * a43 * a51 * a62 - a25 + * a33 * a44 * a51 * a62 + a23 * a35 * a44 * a51 * a62 + a24 * a33 + * a45 * a51 * a62 - a23 * a34 * a45 * a51 * a62 - a25 * a34 * a41 + * a53 * a62 + a24 * a35 * a41 * a53 * a62 + a25 * a31 * a44 * a53 + * a62 - a21 * a35 * a44 * a53 * a62 - a24 * a31 * a45 * a53 * a62 + + a21 * a34 * a45 * a53 * a62 + a25 * a33 * a41 * a54 * a62 - a23 + * a35 * a41 * a54 * a62 - a25 * a31 * a43 * a54 * a62 + a21 * a35 + * a43 * a54 * a62 + a23 * a31 * a45 * a54 * a62 - a21 * a33 * a45 + * a54 * a62 - a24 * a33 * a41 * a55 * a62 + a23 * a34 * a41 * a55 + * a62 + a24 * a31 * a43 * a55 * a62 - a21 * a34 * a43 * a55 * a62 + - a23 * a31 * a44 * a55 * a62 + a21 * a33 * a44 * a55 * a62 - a25 + * a34 * a42 * a51 * a63 + a24 * a35 * a42 * a51 * a63 + a25 * a32 + * a44 * a51 * a63 - a22 * a35 * a44 * a51 * a63 - a24 * a32 * a45 + * a51 * a63 + a22 * a34 * a45 * a51 * a63 + a25 * a34 * a41 * a52 + * a63 - a24 * a35 * a41 * a52 * a63 - a25 * a31 * a44 * a52 * a63 + + a21 * a35 * a44 * a52 * a63 + a24 * a31 * a45 * a52 * a63 - a21 + * a34 * a45 * a52 * a63 - a25 * a32 * a41 * a54 * a63 + a22 * a35 + * a41 * a54 * a63 + a25 * a31 * a42 * a54 * a63 - a21 * a35 * a42 + * a54 * a63 - a22 * a31 * a45 * a54 * a63 + a21 * a32 * a45 * a54 + * a63 + a24 * a32 * a41 * a55 * a63 - a22 * a34 * a41 * a55 * a63 + - a24 * a31 * a42 * a55 * a63 + a21 * a34 * a42 * a55 * a63 + a22 + * a31 * a44 * a55 * a63 - a21 * a32 * a44 * a55 * a63 + a25 * a33 + * a42 * a51 * a64 - a23 * a35 * a42 * a51 * a64 - a25 * a32 * a43 + * a51 * a64 + a22 * a35 * a43 * a51 * a64 + a23 * a32 * a45 * a51 + * a64 - a22 * a33 * a45 * a51 * a64 - a25 * a33 * a41 * a52 * a64 + + a23 * a35 * a41 * a52 * a64 + a25 * a31 * a43 * a52 * a64 - a21 + * a35 * a43 * a52 * a64 - a23 * a31 * a45 * a52 * a64 + a21 * a33 + * a45 * a52 * a64 + a25 * a32 * a41 * a53 * a64 - a22 * a35 * a41 + * a53 * a64 - a25 * a31 * a42 * a53 * a64 + a21 * a35 * a42 * a53 + * a64 + a22 * a31 * a45 * a53 * a64 - a21 * a32 * a45 * a53 * a64 + - a23 * a32 * a41 * a55 * a64 + a22 * a33 * a41 * a55 * a64 + a23 + * a31 * a42 * a55 * a64 - a21 * a33 * a42 * a55 * a64 - a22 * a31 + * a43 * a55 * a64 + a21 * a32 * a43 * a55 * a64 - a24 * a33 * a42 + * a51 * a65 + a23 * a34 * a42 * a51 * a65 + a24 * a32 * a43 * a51 + * a65 - a22 * a34 * a43 * a51 * a65 - a23 * a32 * a44 * a51 * a65 + + a22 * a33 * a44 * a51 * a65 + a24 * a33 * a41 * a52 * a65 - a23 + * a34 * a41 * a52 * a65 - a24 * a31 * a43 * a52 * a65 + a21 * a34 + * a43 * a52 * a65 + a23 * a31 * a44 * a52 * a65 - a21 * a33 * a44 + * a52 * a65 - a24 * a32 * a41 * a53 * a65 + a22 * a34 * a41 * a53 + * a65 + a24 * a31 * a42 * a53 * a65 - a21 * a34 * a42 * a53 * a65 + - a22 * a31 * a44 * a53 * a65 + a21 * a32 * a44 * a53 * a65 + a23 + * a32 * a41 * a54 * a65 - a22 * a33 * a41 * a54 * a65 - a23 * a31 + * a42 * a54 * a65 + a21 * a33 * a42 * a54 * a65 + a22 * a31 * a43 + * a54 * a65 - a21 * a32 * a43 * a54 * a65; + cofactor[31] = a15 * a34 * a43 * a52 * a61 - a14 * a35 * a43 * a52 * a61 + - a15 * a33 * a44 * a52 * a61 + a13 * a35 * a44 * a52 * a61 + a14 + * a33 * a45 * a52 * a61 - a13 * a34 * a45 * a52 * a61 - a15 * a34 + * a42 * a53 * a61 + a14 * a35 * a42 * a53 * a61 + a15 * a32 * a44 + * a53 * a61 - a12 * a35 * a44 * a53 * a61 - a14 * a32 * a45 * a53 + * a61 + a12 * a34 * a45 * a53 * a61 + a15 * a33 * a42 * a54 * a61 + - a13 * a35 * a42 * a54 * a61 - a15 * a32 * a43 * a54 * a61 + a12 + * a35 * a43 * a54 * a61 + a13 * a32 * a45 * a54 * a61 - a12 * a33 + * a45 * a54 * a61 - a14 * a33 * a42 * a55 * a61 + a13 * a34 * a42 + * a55 * a61 + a14 * a32 * a43 * a55 * a61 - a12 * a34 * a43 * a55 + * a61 - a13 * a32 * a44 * a55 * a61 + a12 * a33 * a44 * a55 * a61 + - a15 * a34 * a43 * a51 * a62 + a14 * a35 * a43 * a51 * a62 + a15 + * a33 * a44 * a51 * a62 - a13 * a35 * a44 * a51 * a62 - a14 * a33 + * a45 * a51 * a62 + a13 * a34 * a45 * a51 * a62 + a15 * a34 * a41 + * a53 * a62 - a14 * a35 * a41 * a53 * a62 - a15 * a31 * a44 * a53 + * a62 + a11 * a35 * a44 * a53 * a62 + a14 * a31 * a45 * a53 * a62 + - a11 * a34 * a45 * a53 * a62 - a15 * a33 * a41 * a54 * a62 + a13 + * a35 * a41 * a54 * a62 + a15 * a31 * a43 * a54 * a62 - a11 * a35 + * a43 * a54 * a62 - a13 * a31 * a45 * a54 * a62 + a11 * a33 * a45 + * a54 * a62 + a14 * a33 * a41 * a55 * a62 - a13 * a34 * a41 * a55 + * a62 - a14 * a31 * a43 * a55 * a62 + a11 * a34 * a43 * a55 * a62 + + a13 * a31 * a44 * a55 * a62 - a11 * a33 * a44 * a55 * a62 + a15 + * a34 * a42 * a51 * a63 - a14 * a35 * a42 * a51 * a63 - a15 * a32 + * a44 * a51 * a63 + a12 * a35 * a44 * a51 * a63 + a14 * a32 * a45 + * a51 * a63 - a12 * a34 * a45 * a51 * a63 - a15 * a34 * a41 * a52 + * a63 + a14 * a35 * a41 * a52 * a63 + a15 * a31 * a44 * a52 * a63 + - a11 * a35 * a44 * a52 * a63 - a14 * a31 * a45 * a52 * a63 + a11 + * a34 * a45 * a52 * a63 + a15 * a32 * a41 * a54 * a63 - a12 * a35 + * a41 * a54 * a63 - a15 * a31 * a42 * a54 * a63 + a11 * a35 * a42 + * a54 * a63 + a12 * a31 * a45 * a54 * a63 - a11 * a32 * a45 * a54 + * a63 - a14 * a32 * a41 * a55 * a63 + a12 * a34 * a41 * a55 * a63 + + a14 * a31 * a42 * a55 * a63 - a11 * a34 * a42 * a55 * a63 - a12 + * a31 * a44 * a55 * a63 + a11 * a32 * a44 * a55 * a63 - a15 * a33 + * a42 * a51 * a64 + a13 * a35 * a42 * a51 * a64 + a15 * a32 * a43 + * a51 * a64 - a12 * a35 * a43 * a51 * a64 - a13 * a32 * a45 * a51 + * a64 + a12 * a33 * a45 * a51 * a64 + a15 * a33 * a41 * a52 * a64 + - a13 * a35 * a41 * a52 * a64 - a15 * a31 * a43 * a52 * a64 + a11 + * a35 * a43 * a52 * a64 + a13 * a31 * a45 * a52 * a64 - a11 * a33 + * a45 * a52 * a64 - a15 * a32 * a41 * a53 * a64 + a12 * a35 * a41 + * a53 * a64 + a15 * a31 * a42 * a53 * a64 - a11 * a35 * a42 * a53 + * a64 - a12 * a31 * a45 * a53 * a64 + a11 * a32 * a45 * a53 * a64 + + a13 * a32 * a41 * a55 * a64 - a12 * a33 * a41 * a55 * a64 - a13 + * a31 * a42 * a55 * a64 + a11 * a33 * a42 * a55 * a64 + a12 * a31 + * a43 * a55 * a64 - a11 * a32 * a43 * a55 * a64 + a14 * a33 * a42 + * a51 * a65 - a13 * a34 * a42 * a51 * a65 - a14 * a32 * a43 * a51 + * a65 + a12 * a34 * a43 * a51 * a65 + a13 * a32 * a44 * a51 * a65 + - a12 * a33 * a44 * a51 * a65 - a14 * a33 * a41 * a52 * a65 + a13 + * a34 * a41 * a52 * a65 + a14 * a31 * a43 * a52 * a65 - a11 * a34 + * a43 * a52 * a65 - a13 * a31 * a44 * a52 * a65 + a11 * a33 * a44 + * a52 * a65 + a14 * a32 * a41 * a53 * a65 - a12 * a34 * a41 * a53 + * a65 - a14 * a31 * a42 * a53 * a65 + a11 * a34 * a42 * a53 * a65 + + a12 * a31 * a44 * a53 * a65 - a11 * a32 * a44 * a53 * a65 - a13 + * a32 * a41 * a54 * a65 + a12 * a33 * a41 * a54 * a65 + a13 * a31 + * a42 * a54 * a65 - a11 * a33 * a42 * a54 * a65 - a12 * a31 * a43 + * a54 * a65 + a11 * a32 * a43 * a54 * a65; + cofactor[32] = -a15 * a24 * a43 * a52 * a61 + a14 * a25 * a43 * a52 * a61 + + a15 * a23 * a44 * a52 * a61 - a13 * a25 * a44 * a52 * a61 - a14 + * a23 * a45 * a52 * a61 + a13 * a24 * a45 * a52 * a61 + a15 * a24 + * a42 * a53 * a61 - a14 * a25 * a42 * a53 * a61 - a15 * a22 * a44 + * a53 * a61 + a12 * a25 * a44 * a53 * a61 + a14 * a22 * a45 * a53 + * a61 - a12 * a24 * a45 * a53 * a61 - a15 * a23 * a42 * a54 * a61 + + a13 * a25 * a42 * a54 * a61 + a15 * a22 * a43 * a54 * a61 - a12 + * a25 * a43 * a54 * a61 - a13 * a22 * a45 * a54 * a61 + a12 * a23 + * a45 * a54 * a61 + a14 * a23 * a42 * a55 * a61 - a13 * a24 * a42 + * a55 * a61 - a14 * a22 * a43 * a55 * a61 + a12 * a24 * a43 * a55 + * a61 + a13 * a22 * a44 * a55 * a61 - a12 * a23 * a44 * a55 * a61 + + a15 * a24 * a43 * a51 * a62 - a14 * a25 * a43 * a51 * a62 - a15 + * a23 * a44 * a51 * a62 + a13 * a25 * a44 * a51 * a62 + a14 * a23 + * a45 * a51 * a62 - a13 * a24 * a45 * a51 * a62 - a15 * a24 * a41 + * a53 * a62 + a14 * a25 * a41 * a53 * a62 + a15 * a21 * a44 * a53 + * a62 - a11 * a25 * a44 * a53 * a62 - a14 * a21 * a45 * a53 * a62 + + a11 * a24 * a45 * a53 * a62 + a15 * a23 * a41 * a54 * a62 - a13 + * a25 * a41 * a54 * a62 - a15 * a21 * a43 * a54 * a62 + a11 * a25 + * a43 * a54 * a62 + a13 * a21 * a45 * a54 * a62 - a11 * a23 * a45 + * a54 * a62 - a14 * a23 * a41 * a55 * a62 + a13 * a24 * a41 * a55 + * a62 + a14 * a21 * a43 * a55 * a62 - a11 * a24 * a43 * a55 * a62 + - a13 * a21 * a44 * a55 * a62 + a11 * a23 * a44 * a55 * a62 - a15 + * a24 * a42 * a51 * a63 + a14 * a25 * a42 * a51 * a63 + a15 * a22 + * a44 * a51 * a63 - a12 * a25 * a44 * a51 * a63 - a14 * a22 * a45 + * a51 * a63 + a12 * a24 * a45 * a51 * a63 + a15 * a24 * a41 * a52 + * a63 - a14 * a25 * a41 * a52 * a63 - a15 * a21 * a44 * a52 * a63 + + a11 * a25 * a44 * a52 * a63 + a14 * a21 * a45 * a52 * a63 - a11 + * a24 * a45 * a52 * a63 - a15 * a22 * a41 * a54 * a63 + a12 * a25 + * a41 * a54 * a63 + a15 * a21 * a42 * a54 * a63 - a11 * a25 * a42 + * a54 * a63 - a12 * a21 * a45 * a54 * a63 + a11 * a22 * a45 * a54 + * a63 + a14 * a22 * a41 * a55 * a63 - a12 * a24 * a41 * a55 * a63 + - a14 * a21 * a42 * a55 * a63 + a11 * a24 * a42 * a55 * a63 + a12 + * a21 * a44 * a55 * a63 - a11 * a22 * a44 * a55 * a63 + a15 * a23 + * a42 * a51 * a64 - a13 * a25 * a42 * a51 * a64 - a15 * a22 * a43 + * a51 * a64 + a12 * a25 * a43 * a51 * a64 + a13 * a22 * a45 * a51 + * a64 - a12 * a23 * a45 * a51 * a64 - a15 * a23 * a41 * a52 * a64 + + a13 * a25 * a41 * a52 * a64 + a15 * a21 * a43 * a52 * a64 - a11 + * a25 * a43 * a52 * a64 - a13 * a21 * a45 * a52 * a64 + a11 * a23 + * a45 * a52 * a64 + a15 * a22 * a41 * a53 * a64 - a12 * a25 * a41 + * a53 * a64 - a15 * a21 * a42 * a53 * a64 + a11 * a25 * a42 * a53 + * a64 + a12 * a21 * a45 * a53 * a64 - a11 * a22 * a45 * a53 * a64 + - a13 * a22 * a41 * a55 * a64 + a12 * a23 * a41 * a55 * a64 + a13 + * a21 * a42 * a55 * a64 - a11 * a23 * a42 * a55 * a64 - a12 * a21 + * a43 * a55 * a64 + a11 * a22 * a43 * a55 * a64 - a14 * a23 * a42 + * a51 * a65 + a13 * a24 * a42 * a51 * a65 + a14 * a22 * a43 * a51 + * a65 - a12 * a24 * a43 * a51 * a65 - a13 * a22 * a44 * a51 * a65 + + a12 * a23 * a44 * a51 * a65 + a14 * a23 * a41 * a52 * a65 - a13 + * a24 * a41 * a52 * a65 - a14 * a21 * a43 * a52 * a65 + a11 * a24 + * a43 * a52 * a65 + a13 * a21 * a44 * a52 * a65 - a11 * a23 * a44 + * a52 * a65 - a14 * a22 * a41 * a53 * a65 + a12 * a24 * a41 * a53 + * a65 + a14 * a21 * a42 * a53 * a65 - a11 * a24 * a42 * a53 * a65 + - a12 * a21 * a44 * a53 * a65 + a11 * a22 * a44 * a53 * a65 + a13 + * a22 * a41 * a54 * a65 - a12 * a23 * a41 * a54 * a65 - a13 * a21 + * a42 * a54 * a65 + a11 * a23 * a42 * a54 * a65 + a12 * a21 * a43 + * a54 * a65 - a11 * a22 * a43 * a54 * a65; + cofactor[33] = a15 * a24 * a33 * a52 * a61 - a14 * a25 * a33 * a52 * a61 + - a15 * a23 * a34 * a52 * a61 + a13 * a25 * a34 * a52 * a61 + a14 + * a23 * a35 * a52 * a61 - a13 * a24 * a35 * a52 * a61 - a15 * a24 + * a32 * a53 * a61 + a14 * a25 * a32 * a53 * a61 + a15 * a22 * a34 + * a53 * a61 - a12 * a25 * a34 * a53 * a61 - a14 * a22 * a35 * a53 + * a61 + a12 * a24 * a35 * a53 * a61 + a15 * a23 * a32 * a54 * a61 + - a13 * a25 * a32 * a54 * a61 - a15 * a22 * a33 * a54 * a61 + a12 + * a25 * a33 * a54 * a61 + a13 * a22 * a35 * a54 * a61 - a12 * a23 + * a35 * a54 * a61 - a14 * a23 * a32 * a55 * a61 + a13 * a24 * a32 + * a55 * a61 + a14 * a22 * a33 * a55 * a61 - a12 * a24 * a33 * a55 + * a61 - a13 * a22 * a34 * a55 * a61 + a12 * a23 * a34 * a55 * a61 + - a15 * a24 * a33 * a51 * a62 + a14 * a25 * a33 * a51 * a62 + a15 + * a23 * a34 * a51 * a62 - a13 * a25 * a34 * a51 * a62 - a14 * a23 + * a35 * a51 * a62 + a13 * a24 * a35 * a51 * a62 + a15 * a24 * a31 + * a53 * a62 - a14 * a25 * a31 * a53 * a62 - a15 * a21 * a34 * a53 + * a62 + a11 * a25 * a34 * a53 * a62 + a14 * a21 * a35 * a53 * a62 + - a11 * a24 * a35 * a53 * a62 - a15 * a23 * a31 * a54 * a62 + a13 + * a25 * a31 * a54 * a62 + a15 * a21 * a33 * a54 * a62 - a11 * a25 + * a33 * a54 * a62 - a13 * a21 * a35 * a54 * a62 + a11 * a23 * a35 + * a54 * a62 + a14 * a23 * a31 * a55 * a62 - a13 * a24 * a31 * a55 + * a62 - a14 * a21 * a33 * a55 * a62 + a11 * a24 * a33 * a55 * a62 + + a13 * a21 * a34 * a55 * a62 - a11 * a23 * a34 * a55 * a62 + a15 + * a24 * a32 * a51 * a63 - a14 * a25 * a32 * a51 * a63 - a15 * a22 + * a34 * a51 * a63 + a12 * a25 * a34 * a51 * a63 + a14 * a22 * a35 + * a51 * a63 - a12 * a24 * a35 * a51 * a63 - a15 * a24 * a31 * a52 + * a63 + a14 * a25 * a31 * a52 * a63 + a15 * a21 * a34 * a52 * a63 + - a11 * a25 * a34 * a52 * a63 - a14 * a21 * a35 * a52 * a63 + a11 + * a24 * a35 * a52 * a63 + a15 * a22 * a31 * a54 * a63 - a12 * a25 + * a31 * a54 * a63 - a15 * a21 * a32 * a54 * a63 + a11 * a25 * a32 + * a54 * a63 + a12 * a21 * a35 * a54 * a63 - a11 * a22 * a35 * a54 + * a63 - a14 * a22 * a31 * a55 * a63 + a12 * a24 * a31 * a55 * a63 + + a14 * a21 * a32 * a55 * a63 - a11 * a24 * a32 * a55 * a63 - a12 + * a21 * a34 * a55 * a63 + a11 * a22 * a34 * a55 * a63 - a15 * a23 + * a32 * a51 * a64 + a13 * a25 * a32 * a51 * a64 + a15 * a22 * a33 + * a51 * a64 - a12 * a25 * a33 * a51 * a64 - a13 * a22 * a35 * a51 + * a64 + a12 * a23 * a35 * a51 * a64 + a15 * a23 * a31 * a52 * a64 + - a13 * a25 * a31 * a52 * a64 - a15 * a21 * a33 * a52 * a64 + a11 + * a25 * a33 * a52 * a64 + a13 * a21 * a35 * a52 * a64 - a11 * a23 + * a35 * a52 * a64 - a15 * a22 * a31 * a53 * a64 + a12 * a25 * a31 + * a53 * a64 + a15 * a21 * a32 * a53 * a64 - a11 * a25 * a32 * a53 + * a64 - a12 * a21 * a35 * a53 * a64 + a11 * a22 * a35 * a53 * a64 + + a13 * a22 * a31 * a55 * a64 - a12 * a23 * a31 * a55 * a64 - a13 + * a21 * a32 * a55 * a64 + a11 * a23 * a32 * a55 * a64 + a12 * a21 + * a33 * a55 * a64 - a11 * a22 * a33 * a55 * a64 + a14 * a23 * a32 + * a51 * a65 - a13 * a24 * a32 * a51 * a65 - a14 * a22 * a33 * a51 + * a65 + a12 * a24 * a33 * a51 * a65 + a13 * a22 * a34 * a51 * a65 + - a12 * a23 * a34 * a51 * a65 - a14 * a23 * a31 * a52 * a65 + a13 + * a24 * a31 * a52 * a65 + a14 * a21 * a33 * a52 * a65 - a11 * a24 + * a33 * a52 * a65 - a13 * a21 * a34 * a52 * a65 + a11 * a23 * a34 + * a52 * a65 + a14 * a22 * a31 * a53 * a65 - a12 * a24 * a31 * a53 + * a65 - a14 * a21 * a32 * a53 * a65 + a11 * a24 * a32 * a53 * a65 + + a12 * a21 * a34 * a53 * a65 - a11 * a22 * a34 * a53 * a65 - a13 + * a22 * a31 * a54 * a65 + a12 * a23 * a31 * a54 * a65 + a13 * a21 + * a32 * a54 * a65 - a11 * a23 * a32 * a54 * a65 - a12 * a21 * a33 + * a54 * a65 + a11 * a22 * a33 * a54 * a65; + cofactor[34] = -a15 * a24 * a33 * a42 * a61 + a14 * a25 * a33 * a42 * a61 + + a15 * a23 * a34 * a42 * a61 - a13 * a25 * a34 * a42 * a61 - a14 + * a23 * a35 * a42 * a61 + a13 * a24 * a35 * a42 * a61 + a15 * a24 + * a32 * a43 * a61 - a14 * a25 * a32 * a43 * a61 - a15 * a22 * a34 + * a43 * a61 + a12 * a25 * a34 * a43 * a61 + a14 * a22 * a35 * a43 + * a61 - a12 * a24 * a35 * a43 * a61 - a15 * a23 * a32 * a44 * a61 + + a13 * a25 * a32 * a44 * a61 + a15 * a22 * a33 * a44 * a61 - a12 + * a25 * a33 * a44 * a61 - a13 * a22 * a35 * a44 * a61 + a12 * a23 + * a35 * a44 * a61 + a14 * a23 * a32 * a45 * a61 - a13 * a24 * a32 + * a45 * a61 - a14 * a22 * a33 * a45 * a61 + a12 * a24 * a33 * a45 + * a61 + a13 * a22 * a34 * a45 * a61 - a12 * a23 * a34 * a45 * a61 + + a15 * a24 * a33 * a41 * a62 - a14 * a25 * a33 * a41 * a62 - a15 + * a23 * a34 * a41 * a62 + a13 * a25 * a34 * a41 * a62 + a14 * a23 + * a35 * a41 * a62 - a13 * a24 * a35 * a41 * a62 - a15 * a24 * a31 + * a43 * a62 + a14 * a25 * a31 * a43 * a62 + a15 * a21 * a34 * a43 + * a62 - a11 * a25 * a34 * a43 * a62 - a14 * a21 * a35 * a43 * a62 + + a11 * a24 * a35 * a43 * a62 + a15 * a23 * a31 * a44 * a62 - a13 + * a25 * a31 * a44 * a62 - a15 * a21 * a33 * a44 * a62 + a11 * a25 + * a33 * a44 * a62 + a13 * a21 * a35 * a44 * a62 - a11 * a23 * a35 + * a44 * a62 - a14 * a23 * a31 * a45 * a62 + a13 * a24 * a31 * a45 + * a62 + a14 * a21 * a33 * a45 * a62 - a11 * a24 * a33 * a45 * a62 + - a13 * a21 * a34 * a45 * a62 + a11 * a23 * a34 * a45 * a62 - a15 + * a24 * a32 * a41 * a63 + a14 * a25 * a32 * a41 * a63 + a15 * a22 + * a34 * a41 * a63 - a12 * a25 * a34 * a41 * a63 - a14 * a22 * a35 + * a41 * a63 + a12 * a24 * a35 * a41 * a63 + a15 * a24 * a31 * a42 + * a63 - a14 * a25 * a31 * a42 * a63 - a15 * a21 * a34 * a42 * a63 + + a11 * a25 * a34 * a42 * a63 + a14 * a21 * a35 * a42 * a63 - a11 + * a24 * a35 * a42 * a63 - a15 * a22 * a31 * a44 * a63 + a12 * a25 + * a31 * a44 * a63 + a15 * a21 * a32 * a44 * a63 - a11 * a25 * a32 + * a44 * a63 - a12 * a21 * a35 * a44 * a63 + a11 * a22 * a35 * a44 + * a63 + a14 * a22 * a31 * a45 * a63 - a12 * a24 * a31 * a45 * a63 + - a14 * a21 * a32 * a45 * a63 + a11 * a24 * a32 * a45 * a63 + a12 + * a21 * a34 * a45 * a63 - a11 * a22 * a34 * a45 * a63 + a15 * a23 + * a32 * a41 * a64 - a13 * a25 * a32 * a41 * a64 - a15 * a22 * a33 + * a41 * a64 + a12 * a25 * a33 * a41 * a64 + a13 * a22 * a35 * a41 + * a64 - a12 * a23 * a35 * a41 * a64 - a15 * a23 * a31 * a42 * a64 + + a13 * a25 * a31 * a42 * a64 + a15 * a21 * a33 * a42 * a64 - a11 + * a25 * a33 * a42 * a64 - a13 * a21 * a35 * a42 * a64 + a11 * a23 + * a35 * a42 * a64 + a15 * a22 * a31 * a43 * a64 - a12 * a25 * a31 + * a43 * a64 - a15 * a21 * a32 * a43 * a64 + a11 * a25 * a32 * a43 + * a64 + a12 * a21 * a35 * a43 * a64 - a11 * a22 * a35 * a43 * a64 + - a13 * a22 * a31 * a45 * a64 + a12 * a23 * a31 * a45 * a64 + a13 + * a21 * a32 * a45 * a64 - a11 * a23 * a32 * a45 * a64 - a12 * a21 + * a33 * a45 * a64 + a11 * a22 * a33 * a45 * a64 - a14 * a23 * a32 + * a41 * a65 + a13 * a24 * a32 * a41 * a65 + a14 * a22 * a33 * a41 + * a65 - a12 * a24 * a33 * a41 * a65 - a13 * a22 * a34 * a41 * a65 + + a12 * a23 * a34 * a41 * a65 + a14 * a23 * a31 * a42 * a65 - a13 + * a24 * a31 * a42 * a65 - a14 * a21 * a33 * a42 * a65 + a11 * a24 + * a33 * a42 * a65 + a13 * a21 * a34 * a42 * a65 - a11 * a23 * a34 + * a42 * a65 - a14 * a22 * a31 * a43 * a65 + a12 * a24 * a31 * a43 + * a65 + a14 * a21 * a32 * a43 * a65 - a11 * a24 * a32 * a43 * a65 + - a12 * a21 * a34 * a43 * a65 + a11 * a22 * a34 * a43 * a65 + a13 + * a22 * a31 * a44 * a65 - a12 * a23 * a31 * a44 * a65 - a13 * a21 + * a32 * a44 * a65 + a11 * a23 * a32 * a44 * a65 + a12 * a21 * a33 + * a44 * a65 - a11 * a22 * a33 * a44 * a65; + cofactor[35] = a15 * a24 * a33 * a42 * a51 - a14 * a25 * a33 * a42 * a51 + - a15 * a23 * a34 * a42 * a51 + a13 * a25 * a34 * a42 * a51 + a14 + * a23 * a35 * a42 * a51 - a13 * a24 * a35 * a42 * a51 - a15 * a24 + * a32 * a43 * a51 + a14 * a25 * a32 * a43 * a51 + a15 * a22 * a34 + * a43 * a51 - a12 * a25 * a34 * a43 * a51 - a14 * a22 * a35 * a43 + * a51 + a12 * a24 * a35 * a43 * a51 + a15 * a23 * a32 * a44 * a51 + - a13 * a25 * a32 * a44 * a51 - a15 * a22 * a33 * a44 * a51 + a12 + * a25 * a33 * a44 * a51 + a13 * a22 * a35 * a44 * a51 - a12 * a23 + * a35 * a44 * a51 - a14 * a23 * a32 * a45 * a51 + a13 * a24 * a32 + * a45 * a51 + a14 * a22 * a33 * a45 * a51 - a12 * a24 * a33 * a45 + * a51 - a13 * a22 * a34 * a45 * a51 + a12 * a23 * a34 * a45 * a51 + - a15 * a24 * a33 * a41 * a52 + a14 * a25 * a33 * a41 * a52 + a15 + * a23 * a34 * a41 * a52 - a13 * a25 * a34 * a41 * a52 - a14 * a23 + * a35 * a41 * a52 + a13 * a24 * a35 * a41 * a52 + a15 * a24 * a31 + * a43 * a52 - a14 * a25 * a31 * a43 * a52 - a15 * a21 * a34 * a43 + * a52 + a11 * a25 * a34 * a43 * a52 + a14 * a21 * a35 * a43 * a52 + - a11 * a24 * a35 * a43 * a52 - a15 * a23 * a31 * a44 * a52 + a13 + * a25 * a31 * a44 * a52 + a15 * a21 * a33 * a44 * a52 - a11 * a25 + * a33 * a44 * a52 - a13 * a21 * a35 * a44 * a52 + a11 * a23 * a35 + * a44 * a52 + a14 * a23 * a31 * a45 * a52 - a13 * a24 * a31 * a45 + * a52 - a14 * a21 * a33 * a45 * a52 + a11 * a24 * a33 * a45 * a52 + + a13 * a21 * a34 * a45 * a52 - a11 * a23 * a34 * a45 * a52 + a15 + * a24 * a32 * a41 * a53 - a14 * a25 * a32 * a41 * a53 - a15 * a22 + * a34 * a41 * a53 + a12 * a25 * a34 * a41 * a53 + a14 * a22 * a35 + * a41 * a53 - a12 * a24 * a35 * a41 * a53 - a15 * a24 * a31 * a42 + * a53 + a14 * a25 * a31 * a42 * a53 + a15 * a21 * a34 * a42 * a53 + - a11 * a25 * a34 * a42 * a53 - a14 * a21 * a35 * a42 * a53 + a11 + * a24 * a35 * a42 * a53 + a15 * a22 * a31 * a44 * a53 - a12 * a25 + * a31 * a44 * a53 - a15 * a21 * a32 * a44 * a53 + a11 * a25 * a32 + * a44 * a53 + a12 * a21 * a35 * a44 * a53 - a11 * a22 * a35 * a44 + * a53 - a14 * a22 * a31 * a45 * a53 + a12 * a24 * a31 * a45 * a53 + + a14 * a21 * a32 * a45 * a53 - a11 * a24 * a32 * a45 * a53 - a12 + * a21 * a34 * a45 * a53 + a11 * a22 * a34 * a45 * a53 - a15 * a23 + * a32 * a41 * a54 + a13 * a25 * a32 * a41 * a54 + a15 * a22 * a33 + * a41 * a54 - a12 * a25 * a33 * a41 * a54 - a13 * a22 * a35 * a41 + * a54 + a12 * a23 * a35 * a41 * a54 + a15 * a23 * a31 * a42 * a54 + - a13 * a25 * a31 * a42 * a54 - a15 * a21 * a33 * a42 * a54 + a11 + * a25 * a33 * a42 * a54 + a13 * a21 * a35 * a42 * a54 - a11 * a23 + * a35 * a42 * a54 - a15 * a22 * a31 * a43 * a54 + a12 * a25 * a31 + * a43 * a54 + a15 * a21 * a32 * a43 * a54 - a11 * a25 * a32 * a43 + * a54 - a12 * a21 * a35 * a43 * a54 + a11 * a22 * a35 * a43 * a54 + + a13 * a22 * a31 * a45 * a54 - a12 * a23 * a31 * a45 * a54 - a13 + * a21 * a32 * a45 * a54 + a11 * a23 * a32 * a45 * a54 + a12 * a21 + * a33 * a45 * a54 - a11 * a22 * a33 * a45 * a54 + a14 * a23 * a32 + * a41 * a55 - a13 * a24 * a32 * a41 * a55 - a14 * a22 * a33 * a41 + * a55 + a12 * a24 * a33 * a41 * a55 + a13 * a22 * a34 * a41 * a55 + - a12 * a23 * a34 * a41 * a55 - a14 * a23 * a31 * a42 * a55 + a13 + * a24 * a31 * a42 * a55 + a14 * a21 * a33 * a42 * a55 - a11 * a24 + * a33 * a42 * a55 - a13 * a21 * a34 * a42 * a55 + a11 * a23 * a34 + * a42 * a55 + a14 * a22 * a31 * a43 * a55 - a12 * a24 * a31 * a43 + * a55 - a14 * a21 * a32 * a43 * a55 + a11 * a24 * a32 * a43 * a55 + + a12 * a21 * a34 * a43 * a55 - a11 * a22 * a34 * a43 * a55 - a13 + * a22 * a31 * a44 * a55 + a12 * a23 * a31 * a44 * a55 + a13 * a21 + * a32 * a44 * a55 - a11 * a23 * a32 * a44 * a55 - a12 * a21 * a33 + * a44 * a55 + a11 * a22 * a33 * a44 * a55; + + for (int i = 1; i <= 6; ++i) { + for (int j = 1; j <= 6; ++j) { + ainv[j + i * 6] = cofactor[i + j * 6 - 7] / det; + } + } +/* ainv = transpose(cofactor) ! / det */ + *ok_flag__ = 0; + return 0; +} + +int cmx_inv6_v1(const double const a[6][6], double *ainv, int*ok_flag__) +{ + double cofactor[36] /* was [6][6] */; + + /* Parameter adjustments */ + ainv -= 7; +// a -= 7; + + /* Function Body */ + const double eps = 1e-10; + const double + det = -(a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][6-1]* + a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]* + a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]* + a[4-1][4-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]* + a[5-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] + + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][4-1]* + a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][6-1]* + a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]* + a[4-1][5-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]* + a[5-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] + - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][6-1]* + a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][4-1]* + a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]* + a[4-1][2-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]* + a[5-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] + + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][2-1]* + a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][6-1]* + a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]* + a[4-1][5-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]* + a[5-1][3-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] + - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][4-1]* + a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][5-1]* + a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]* + a[4-1][2-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]* + a[5-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] + + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][2-1]* + a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]* + a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]* + a[4-1][5-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]* + a[5-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] + - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][5-1]* + a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][2-1]* + a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]* + a[4-1][2-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]* + a[5-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] + + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][4-1]* + a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][6-1]* + a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]* + a[4-1][3-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]* + a[5-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] + - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][4-1]* + a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][2-1]* + a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]* + a[4-1][6-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]* + a[5-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] + + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][3-1]* + a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][5-1]* + a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]* + a[4-1][3-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]* + a[5-1][6-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] + - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][3-1]* + a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][3-1]* + a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]* + a[4-1][5-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]* + a[5-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1])*a[6-1][1-1] + + (a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1])*a[6-1][2-1] + - (a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]* + a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]* + a[4-1][2-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]* + a[5-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] + + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][5-1]* + a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]* + a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]* + a[4-1][5-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]* + a[5-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] + + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][2-1]* + a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]* + a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]* + a[4-1][1-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]* + a[5-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] + + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][6-1]* + a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]* + a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]* + a[4-1][5-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]* + a[5-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] + + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][4-1]* + a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]* + a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]* + a[4-1][6-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]* + a[5-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] + + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][6-1]* + a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]* + a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]* + a[4-1][2-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]* + a[5-1][4-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] + + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][1-1]* + a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]* + a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]* + a[4-1][6-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]* + a[5-1][4-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] + + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][4-1]* + a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][4-1]* + a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]* + a[4-1][2-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]* + a[5-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] + + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][1-1]* + a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]* + a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]* + a[4-1][6-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]* + a[5-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] + + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][5-1]* + a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]* + a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]* + a[4-1][2-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]* + a[5-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] + + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][2-1]* + a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]* + a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]* + a[4-1][4-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]* + a[5-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] + - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1])*a[6-1][3-1] + + (a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] + - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][5-1]* + a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]* + a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]* + a[4-1][3-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]* + a[5-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] + - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][2-1]* + a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]* + a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]* + a[4-1][6-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]* + a[5-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] + - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][6-1]* + a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]* + a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]* + a[4-1][3-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]* + a[5-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] + - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][3-1]* + a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]* + a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]* + a[4-1][5-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]* + a[5-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] + + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][6-1]* + a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]* + a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]* + a[4-1][1-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]* + a[5-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] + - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][1-1]* + a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]* + a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]* + a[4-1][5-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]* + a[5-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] + + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][2-1]* + a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][3-1]* + a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]* + a[4-1][1-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]* + a[5-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] + - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][1-1]* + a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]* + a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]* + a[4-1][3-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]* + a[5-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] + + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][3-1]* + a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]* + a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]* + a[4-1][1-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]* + a[5-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] + - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][3-1]* + a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]* + a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]* + a[4-1][2-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]* + a[5-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] + + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][3-1]* + a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]* + a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]* + a[4-1][5-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1])*a[6-1][4-1] + - (a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1])*a[6-1][5-1] + + (a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][4-1]* + a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]* + a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]* + a[4-1][2-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]* + a[5-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] + - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][5-1]* + a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]* + a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]* + a[4-1][4-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]* + a[5-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] + - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][2-1]* + a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]* + a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]* + a[4-1][1-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]* + a[5-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] + - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][4-1]* + a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]* + a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]* + a[4-1][4-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]* + a[5-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] + - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][1-1]* + a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]* + a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]* + a[4-1][1-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]* + a[5-1][3-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] + - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][5-1]* + a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]* + a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]* + a[4-1][4-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]* + a[5-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] + - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][2-1]* + a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]* + a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]* + a[4-1][5-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]* + a[5-1][4-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] + - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][5-1]* + a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]* + a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]* + a[4-1][2-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]* + a[5-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] + - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][1-1]* + a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]* + a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]* + a[4-1][5-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]* + a[5-1][4-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] + - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][3-1]* + a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]* + a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]* + a[4-1][2-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]* + a[5-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] + - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][1-1]* + a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]* + a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]* + a[4-1][4-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]* + a[5-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]) * + a[6-1][6-1]; + + if (fabs(det) <= eps) { + *ok_flag__ = -1; + return 0; + } + cofactor[0] = a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + - + a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + + a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + + a[2-1][5-1]* + a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + - a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + - a[2-1][6-1]*a[3-1][5-1]* + a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + + a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + + a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]* + a[5-1][4-1]*a[6-1][2-1] + - a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]* + a[6-1][2-1] + + a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + + a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + - a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + + a[2-1][3-1]* + a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + + a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + - a[2-1][3-1]*a[3-1][4-1]* + a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + + a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]* + a[5-1][6-1]*a[6-1][2-1] + + a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + - a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]* + a[6-1][2-1] + - a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + + a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + - + a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + + a[2-1][6-1]* + a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + - a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + - a[2-1][5-1]*a[3-1][4-1]* + a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + + a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + + a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]* + a[5-1][4-1]*a[6-1][3-1] + - a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + - a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]* + a[6-1][3-1] + + a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + - + a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + - a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + + a[2-1][4-1]* + a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + + a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + - a[2-1][2-1]*a[3-1][6-1]* + a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + - a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + + a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]* + a[5-1][5-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + - a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]* + a[6-1][3-1] + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + + a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + + + a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + - a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + + a[2-1][6-1]* + a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + - a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + - a[2-1][6-1]*a[3-1][3-1]* + a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + + a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + + a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]* + a[5-1][2-1]*a[6-1][4-1] + - a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + - a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]* + a[6-1][4-1] + + a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + + a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + - + a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + + a[2-1][2-1]* + a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + + a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + - a[2-1][3-1]*a[3-1][6-1]* + a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + - a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + + a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]* + a[5-1][5-1]*a[6-1][4-1] + + a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + - a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]* + a[6-1][4-1] + - a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + + a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + + + a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + - a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + - a[2-1][3-1]* + a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + + a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + - a[2-1][6-1]*a[3-1][4-1]* + a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + + a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + + a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]* + a[5-1][2-1]*a[6-1][5-1] + - a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + - a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]* + a[6-1][5-1] + + a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + + a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + - a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + + a[2-1][2-1]* + a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + + a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + - a[2-1][2-1]*a[3-1][4-1]* + a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + - a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + + a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]* + a[5-1][4-1]*a[6-1][5-1] + + a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + - a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]* + a[6-1][5-1] + - a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + + a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + + + a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + - a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + - a[2-1][4-1]* + a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + + a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + + a[2-1][3-1]*a[3-1][2-1]* + a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + - a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + + a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]* + a[5-1][2-1]*a[6-1][6-1] + - a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + - a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]* + a[6-1][6-1] + + a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + + a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + - a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + + a[2-1][4-1]* + a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + + a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + - a[2-1][2-1]*a[3-1][5-1]* + a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + - a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + + a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]* + a[5-1][3-1]*a[6-1][6-1] + + a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + - a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]* + a[6-1][6-1] + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + + a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + + + a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + - a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + - a[2-1][4-1]* + a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + + a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + + a[2-1][4-1]*a[3-1][2-1]* + a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + - a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + - a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]* + a[5-1][5-1]*a[6-1][6-1] + + a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[1] = -a[1-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[2] = a[1-1][6-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + - + a[1-1][6-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][5-1]* + a[2-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][5-1]* + a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[4-1][5-1]* + a[5-1][4-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][4-1]* + a[6-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][3-1]* + a[2-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]* + a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[4-1][3-1]* + a[5-1][6-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][6-1]* + a[6-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + - + a[1-1][6-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][6-1]* + a[2-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][4-1]* + a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][5-1]*a[4-1][2-1]* + a[5-1][4-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][4-1]* + a[6-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + - + a[1-1][2-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][4-1]* + a[2-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]* + a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[4-1][6-1]* + a[5-1][5-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][6-1]* + a[6-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + + + a[1-1][4-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][6-1]* + a[2-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][3-1]* + a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][3-1]*a[4-1][6-1]* + a[5-1][2-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][3-1]* + a[6-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + - + a[1-1][2-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][2-1]* + a[2-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]* + a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[4-1][3-1]* + a[5-1][5-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][5-1]* + a[6-1][4-1] + - a[1-1][5-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + + + a[1-1][5-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][3-1]* + a[2-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][4-1]* + a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[4-1][4-1]* + a[5-1][2-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][2-1]* + a[6-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][2-1]* + a[2-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]* + a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[4-1][2-1]* + a[5-1][4-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][4-1]* + a[6-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + + + a[1-1][4-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][4-1]* + a[2-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]* + a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][5-1]*a[2-1][4-1]*a[4-1][3-1]* + a[5-1][2-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][2-1]* + a[6-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][4-1]* + a[2-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]* + a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[4-1][5-1]* + a[5-1][3-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][4-1]* + a[6-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + + + a[1-1][3-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][4-1]* + a[2-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]* + a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[4-1][4-1]* + a[5-1][5-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[3] = -a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[4] = a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][2-1] + - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][2-1] + + a[1-1][5-1]* + a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][5-1]* + a[3-1][3-1]*a[4-1][4-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]* + a[4-1][4-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]* + a[6-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][2-1] + - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][2-1] + + a[1-1][3-1]* + a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]* + a[3-1][6-1]*a[4-1][5-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]* + a[4-1][6-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]* + a[6-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][2-1] + - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][3-1] + + a[1-1][6-1]* + a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][4-1]* + a[3-1][6-1]*a[4-1][2-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]* + a[4-1][4-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]* + a[6-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][3-1] + - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][3-1] + + a[1-1][4-1]* + a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]* + a[3-1][4-1]*a[4-1][5-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]* + a[4-1][5-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]* + a[6-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][3-1] + + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][3-1] + + a[1-1][6-1]* + a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][3-1]* + a[3-1][5-1]*a[4-1][2-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]* + a[4-1][2-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]* + a[6-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][4-1] + - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][4-1] + + a[1-1][2-1]* + a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]* + a[3-1][2-1]*a[4-1][5-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]* + a[4-1][5-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]* + a[6-1][4-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][4-1] + + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][4-1] + - a[1-1][3-1]* + a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][4-1]* + a[3-1][3-1]*a[4-1][2-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]* + a[4-1][2-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]* + a[6-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][5-1] + - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][5-1] + + a[1-1][2-1]* + a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]* + a[3-1][6-1]*a[4-1][3-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]* + a[4-1][4-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]* + a[6-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][5-1] + + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][5-1] + - a[1-1][4-1]* + a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]* + a[3-1][4-1]*a[4-1][6-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][5-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]* + a[4-1][2-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]* + a[6-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][6-1] + - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][6-1] + + a[1-1][4-1]* + a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]* + a[3-1][4-1]*a[4-1][3-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]* + a[4-1][3-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]* + a[6-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][6-1] + + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][6-1] + - a[1-1][4-1]* + a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]* + a[3-1][3-1]*a[4-1][5-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]* + a[4-1][5-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][6-1]; + cofactor[5] = -a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]; + cofactor[6] = -a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + + a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + - a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + - a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + + a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + + a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + - a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + - a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + + a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + - a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + - a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + - a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + - a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + - a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + - a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + + a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + + a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + - a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + + a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + - a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + - a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + + a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + - a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + - a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + + a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + - a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + - a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + + a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + + a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + - a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + - a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + + a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + + a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + - a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + - a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + + a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + - a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + - a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + + a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + - a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + + a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + + a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + - a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + - a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + + a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + + a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + - a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + - a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + + a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + + a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + - a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + - a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + + a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + + a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + - a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + - a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + + a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + + a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + - a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + - a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + + a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + + a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + - a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + + a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + - a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + - a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + + a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + + a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + - a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + - a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + + a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + + a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + - a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + - a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + + a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + + a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + - a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + - a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + + a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + + a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + - a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + - a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + + a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + + a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + - a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + - a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + + a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + - a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + + a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + + a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + - a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + - a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + + a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + + a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + - a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + - a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + + a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + + a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + - a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + - a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + + a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + + a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + - a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + - a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + + a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + + a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + - a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + - a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + + a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + + a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1] + - a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[7] = a[1-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + - + a[1-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][5-1]* + a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][6-1]*a[3-1][5-1]* + a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][6-1]*a[3-1][3-1]*a[4-1][5-1]* + a[5-1][4-1]*a[6-1][1-1] + - a[1-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]* + a[6-1][1-1] + + a[1-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][3-1]* + a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][3-1]*a[3-1][4-1]* + a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][4-1]*a[3-1][5-1]*a[4-1][3-1]* + a[5-1][6-1]*a[6-1][1-1] + + a[1-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]* + a[6-1][1-1] + - a[1-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + - + a[1-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][6-1]* + a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][5-1]*a[3-1][4-1]* + a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][6-1]*a[3-1][5-1]*a[4-1][1-1]* + a[5-1][4-1]*a[6-1][3-1] + - a[1-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]* + a[6-1][3-1] + + a[1-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + - + a[1-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][4-1]* + a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][1-1]*a[3-1][6-1]* + a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][1-1]*a[3-1][4-1]*a[4-1][6-1]* + a[5-1][5-1]*a[6-1][3-1] + + a[1-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]* + a[6-1][3-1] + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + + + a[1-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][6-1]* + a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][6-1]*a[3-1][3-1]* + a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][5-1]*a[3-1][3-1]*a[4-1][6-1]* + a[5-1][1-1]*a[6-1][4-1] + - a[1-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]* + a[6-1][4-1] + + a[1-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + - + a[1-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][1-1]* + a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][3-1]*a[3-1][6-1]* + a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][1-1]*a[3-1][6-1]*a[4-1][3-1]* + a[5-1][5-1]*a[6-1][4-1] + + a[1-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]* + a[6-1][4-1] + - a[1-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + + + a[1-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][3-1]* + a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][6-1]*a[3-1][4-1]* + a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][6-1]*a[3-1][3-1]*a[4-1][4-1]* + a[5-1][1-1]*a[6-1][5-1] + - a[1-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]* + a[6-1][5-1] + + a[1-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][1-1]* + a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][1-1]*a[3-1][4-1]* + a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][3-1]*a[3-1][6-1]*a[4-1][1-1]* + a[5-1][4-1]*a[6-1][5-1] + + a[1-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]* + a[6-1][5-1] + - a[1-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + + + a[1-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][4-1]* + a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][3-1]*a[3-1][1-1]* + a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][5-1]*a[3-1][4-1]*a[4-1][3-1]* + a[5-1][1-1]*a[6-1][6-1] + - a[1-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]* + a[6-1][6-1] + + a[1-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][4-1]* + a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][1-1]*a[3-1][5-1]* + a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][1-1]*a[3-1][4-1]*a[4-1][5-1]* + a[5-1][3-1]*a[6-1][6-1] + + a[1-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]* + a[6-1][6-1] + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + + + a[1-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][4-1]* + a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][4-1]*a[3-1][1-1]* + a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][3-1]*a[3-1][1-1]*a[4-1][4-1]* + a[5-1][5-1]*a[6-1][6-1] + + a[1-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[8] = -a[1-1][6-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][5-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[9] = a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][5-1]* + a[2-1][4-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]* + a[3-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]* + a[5-1][4-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][4-1]* + a[6-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][3-1]* + a[2-1][6-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]* + a[3-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]* + a[5-1][6-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][6-1]* + a[6-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][6-1]* + a[2-1][4-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][4-1]* + a[3-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]* + a[5-1][4-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][4-1]* + a[6-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][4-1]* + a[2-1][6-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]* + a[3-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]* + a[5-1][5-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][6-1]* + a[6-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][6-1]* + a[2-1][5-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][3-1]* + a[3-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]* + a[5-1][1-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][3-1]* + a[6-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][1-1]* + a[2-1][5-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]* + a[3-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]* + a[5-1][5-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][5-1]* + a[6-1][4-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][3-1]* + a[2-1][1-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][4-1]* + a[3-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]* + a[5-1][1-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][1-1]* + a[6-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][1-1]* + a[2-1][6-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]* + a[3-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]* + a[5-1][4-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][4-1]* + a[6-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][4-1]* + a[2-1][1-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]* + a[3-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]* + a[5-1][1-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][1-1]* + a[6-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][4-1]* + a[2-1][5-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]* + a[3-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]* + a[5-1][3-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][4-1]* + a[6-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][4-1]* + a[2-1][3-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]* + a[3-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]* + a[5-1][5-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[10] = -a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][5-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][6-1]; + cofactor[11] = a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]; + cofactor[12] = a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + - a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + - a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + + a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + - a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + - a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + + a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + - a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + + a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + + a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + - a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + - a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + - a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + - a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + + a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + - a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + - a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + + a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + - a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + + a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + + a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + - a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + + a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + + a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + - a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + + a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + + a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + - a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + - a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + + a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + + a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + - a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + - a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + + a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + + a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + - a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + + a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + + a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + - a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + + a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + - a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + - a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + + a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + + a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + - a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + - a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + + a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + + a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + - a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + - a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + + a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + + a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + - a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + - a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + + a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + + a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + - a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + + a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + + a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + - a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + - a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + + a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + - a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + + a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + + a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + - a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + - a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + + a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + + a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + - a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + - a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + + a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + + a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + - a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + - a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + + a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + + a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + - a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + - a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + + a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + + a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + - a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + - a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + + a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + + a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + - a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + + a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + - a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + + a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + + a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + - a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + - a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + + a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + + a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + - a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + - a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + + a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + + a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + - a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + - a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + + a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + + a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + - a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + - a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + + a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + + a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + - a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + - a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1] + + a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[13] = -a[1-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[14] = a[1-1][6-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][5-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[15] = -a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[16] = a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][5-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][6-1]; + cofactor[17] = -a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]; + cofactor[18] = -a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + + a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + - a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + - a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + + a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + + a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + - a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + - a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + + a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + - a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + - a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + - a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + - a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + - a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + + a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + + a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + - a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + + a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + - a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + + a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + + a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + - a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + - a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + + a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + + a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + - a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + + a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + + a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + - a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + - a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + + a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + + a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + - a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + + a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + + a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + - a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + - a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + + a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + - a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + + a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + - a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + + a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + + a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + - a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + - a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + + a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + - a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + - a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + + a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + + a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + - a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + - a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + + a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + - a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + - a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + + a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + + a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + - a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + + a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + - a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + - a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + + a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + + a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + - a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + - a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + + a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + + a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + - a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + - a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + + a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + + a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + - a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + - a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + + a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + + a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + - a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + - a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + + a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + + a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + - a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + - a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + + a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + - a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + + a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + + a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + - a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + - a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + + a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + + a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + - a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + - a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + + a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + + a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + - a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + + a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + + a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + - a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + - a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + + a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + + a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + - a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + - a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + + a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + + a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + - a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[19] = a[1-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[20] = -a[1-1][6-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][5-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[21] = a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][5-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][6-1]; + cofactor[22] = -a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][5-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][6-1]; + cofactor[23] = a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]; + cofactor[24] = a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + - a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + - a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + + a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + + a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + - a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + - a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + + a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + + a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + - a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + - a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + + a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + + a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + - a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + - a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + + a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + + a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + - a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + - a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + + a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + + a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + - a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + - a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + + a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + - a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + + a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + + a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + - a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + - a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + + a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + + a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + - a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + - a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + + a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + + a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + - a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + - a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + + a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + + a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + - a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + - a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + + a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + + a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + - a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + - a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + + a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + + a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + - a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + + a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + - a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + - a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + + a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + + a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + - a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + - a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + + a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + + a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + - a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + - a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + + a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + + a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + - a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + - a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + + a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + + a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + - a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + - a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + + a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + + a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + - a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + - a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + + a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + - a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + + a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + + a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + - a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + - a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + + a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + + a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + - a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + - a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + + a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + + a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + - a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + - a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + + a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + + a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + - a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + - a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + + a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + + a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + - a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + - a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + + a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + + a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + - a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + + a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + - a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + - a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + + a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + + a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + - a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + - a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + + a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + + a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + - a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + - a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + + a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + + a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + - a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + - a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + + a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + + a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + - a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + - a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + + a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + + a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + - a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + - a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + + a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1]; + cofactor[25] = -a[1-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1]; + cofactor[26] = a[1-1][6-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][4-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1]; + cofactor[27] = -a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][4-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][6-1]; + cofactor[28] = a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][1-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][2-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][3-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][4-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][6-1]; + cofactor[29] = -a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] + - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] + + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]; + cofactor[30] = -a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + + a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + - a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + - a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + + a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + - a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + + a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + + a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + - a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + - a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + + a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + - a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + - a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + + a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + + a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + - a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + - a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + - a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + + a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + - a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + + a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + + a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + - a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + + a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + + a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + - a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + - a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + + a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + + a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + - a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + + a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + + a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + - a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + - a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + + a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + + a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + - a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + - a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + + a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + - a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + + a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + - a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + - a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + + a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + - a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + - a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + + a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + + a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + - a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + + a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + - a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + - a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + + a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + + a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + - a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + - a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + + a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + + a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + - a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + + a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + - a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + + a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + + a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + - a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + - a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + + a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + + a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + - a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + - a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + + a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + + a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + - a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + - a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + + a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + + a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + - a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + - a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + + a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + + a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + - a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + - a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + + a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + - a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + + a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + + a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + - a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + - a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + + a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + + a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + - a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + - a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + + a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + + a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + - a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + - a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + + a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + + a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + - a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + - a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + + a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + + a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + - a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + - a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + + a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + + a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + - a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1]; + cofactor[31] = a[1-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1]; + + cofactor[32] = -a[1-1][5-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + + - a[1-1][4-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1]; + cofactor[33] = a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][4-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][5-1]; + cofactor[34] = -a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][1-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][2-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][3-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][3-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][4-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][4-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][4-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][5-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][5-1]; + cofactor[35] = a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] + + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] + - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] + + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] + + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] + + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]; + + const double jinv = 1/det; + + for (int i = 1; i <= 6; ++i) { + for (int j = 1; j <= 6; ++j) { + ainv[j + i*6] = cofactor[i + j*6 - 7] *jinv; + } + } + *ok_flag__ = 0; + return 0; +} +#endif + +#define a11 a[ 0] +#define a12 a[6] +#define a13 a[12] +#define a14 a[18] +#define a15 a[24] +#define a16 a[30] +#define a21 a[ 1] +#define a22 a[7] +#define a23 a[13] +#define a24 a[19] +#define a25 a[25] +#define a26 a[31] +#define a31 a[ 2] +#define a32 a[8] +#define a33 a[14] +#define a34 a[20] +#define a35 a[26] +#define a36 a[32] +#define a41 a[3] +#define a42 a[9] +#define a43 a[15] +#define a44 a[21] +#define a45 a[27] +#define a46 a[33] +#define a51 a[4] +#define a52 a[10] +#define a53 a[16] +#define a54 a[22] +#define a55 a[28] +#define a56 a[34] +#define a61 a[5] +#define a62 a[11] +#define a63 a[17] +#define a64 a[23] +#define a65 a[29] +#define a66 a[35] + +int cmx_inv6(const double a[36], double *ainv, int*ok_flag__) +{ + double cofactor[36]; + + /* Parameter adjustments */ +// ainv -= 7; +// a -= 7; + + /* Function Body */ + const double eps = 1e-10; + const double + det = - ( a16*a25*a34*a43*a52 + - a15*a26*a34*a43*a52 + - a16*a24*a35*a43*a52 + + a14*a26*a35*a43*a52 + + a15*a24*a36*a43*a52 + - a14*a25*a36*a43*a52 + - a16*a25*a33*a44*a52 + + a15*a26*a33*a44*a52 + + a16*a23*a35*a44*a52 + - a13*a26*a35*a44*a52 + - a15*a23*a36*a44*a52 + + a13*a25*a36*a44*a52 + + a16*a24*a33*a45*a52 + - a14*a26*a33*a45*a52 + - a16*a23*a34*a45*a52 + + a13*a26*a34*a45*a52 + + a14*a23*a36*a45*a52 + - a13*a24*a36*a45*a52 + - a15*a24*a33*a46*a52 + + a14*a25*a33*a46*a52 + + a15*a23*a34*a46*a52 + - a13*a25*a34*a46*a52 + - a14*a23*a35*a46*a52 + + a13*a24*a35*a46*a52 + - a16*a25*a34*a42*a53 + + a15*a26*a34*a42*a53 + + a16*a24*a35*a42*a53 + - a14*a26*a35*a42*a53 + - a15*a24*a36*a42*a53 + + a14*a25*a36*a42*a53 + + a16*a25*a32*a44*a53 + - a15*a26*a32*a44*a53 + - a16*a22*a35*a44*a53 + + + a12*a26*a35*a44*a53 + + a15*a22*a36*a44*a53 + - a12*a25*a36*a44*a53 + - a16*a24*a32*a45*a53 + + a14*a26*a32*a45*a53 + + a16*a22*a34*a45*a53 + - a12*a26*a34*a45*a53 + - a14*a22*a36*a45*a53 + + a12*a24*a36*a45*a53 + + a15*a24*a32*a46*a53 + - a14*a25*a32*a46*a53 + - + a15*a22*a34*a46*a53 + + a12*a25*a34*a46*a53 + + a14*a22*a35*a46*a53 + - a12*a24*a35*a46*a53 + + a16*a25*a33*a42*a54 + - a15*a26*a33*a42*a54 + - a16*a23*a35*a42*a54 + + a13*a26*a35*a42*a54 + + a15*a23*a36*a42*a54 + - a13*a25*a36*a42*a54 + - a16*a25*a32*a43*a54 + + + a15*a26*a32*a43*a54 + + a16*a22*a35*a43*a54 + - a12*a26*a35*a43*a54 + - a15*a22*a36*a43*a54 + + a12*a25*a36*a43*a54 + + a16*a23*a32*a45*a54 + - a13*a26*a32*a45*a54 + - a16*a22*a33*a45*a54 + + a12*a26*a33*a45*a54 + + a13*a22*a36*a45*a54 + - a12*a23*a36*a45*a54 + - + a15*a23*a32*a46*a54 + + a13*a25*a32*a46*a54 + + a15*a22*a33*a46*a54 + - a12*a25*a33*a46*a54 + - a13*a22*a35*a46*a54 + + a12*a23*a35*a46*a54 + - a16*a24*a33*a42*a55 + + a14*a26*a33*a42*a55 + + a16*a23*a34*a42*a55 + - a13*a26*a34*a42*a55 + - a14*a23*a36*a42*a55 + + a13*a24*a36*a42*a55 + + a16*a24*a32*a43*a55 + - a14*a26*a32*a43*a55 + - a16*a22*a34*a43*a55 + + a12*a26*a34*a43*a55 + + a14*a22*a36*a43*a55 + - a12*a24*a36*a43*a55 + - a16*a23*a32*a44*a55 + + a13*a26*a32*a44*a55 + + a16*a22*a33*a44*a55 + - a12*a26*a33*a44*a55 + - a13*a22*a36*a44*a55 + + a12*a23*a36*a44*a55 + + a14*a23*a32*a46*a55 + - a13*a24*a32*a46*a55 + - a14*a22*a33*a46*a55 + + a12*a24*a33*a46*a55 + + a13*a22*a34*a46*a55 + - a12*a23*a34*a46*a55 + + a15*a24*a33*a42*a56 + - a14*a25*a33*a42*a56 + - a15*a23*a34*a42*a56 + + a13*a25*a34*a42*a56 + + a14*a23*a35*a42*a56 + - a13*a24*a35*a42*a56 + - a15*a24*a32*a43*a56 + + a14*a25*a32*a43*a56 + + a15*a22*a34*a43*a56 + - a12*a25*a34*a43*a56 + - a14*a22*a35*a43*a56 + + a12*a24*a35*a43*a56 + + a15*a23*a32*a44*a56 + - a13*a25*a32*a44*a56 + - a15*a22*a33*a44*a56 + + a12*a25*a33*a44*a56 + + a13*a22*a35*a44*a56 + - a12*a23*a35*a44*a56 + - a14*a23*a32*a45*a56 + + a13*a24*a32*a45*a56 + + a14*a22*a33*a45*a56 + - a12*a24*a33*a45*a56 + - a13*a22*a34*a45*a56 + + a12*a23*a34*a45*a56)*a61 + + + (a16*a25*a34*a43*a51 + - a15*a26*a34*a43*a51 + - a16*a24*a35*a43*a51 + + a14*a26*a35*a43*a51 + + a15*a24*a36*a43*a51 + - a14*a25*a36*a43*a51 + - a16*a25*a33*a44*a51 + + a15*a26*a33*a44*a51 + + a16*a23*a35*a44*a51 + - a13*a26*a35*a44*a51 + - a15*a23*a36*a44*a51 + + a13*a25*a36*a44*a51 + + a16*a24*a33*a45*a51 + - a14*a26*a33*a45*a51 + - a16*a23*a34*a45*a51 + + a13*a26*a34*a45*a51 + + a14*a23*a36*a45*a51 + - a13*a24*a36*a45*a51 + - a15*a24*a33*a46*a51 + + a14*a25*a33*a46*a51 + + a15*a23*a34*a46*a51 + - a13*a25*a34*a46*a51 + - a14*a23*a35*a46*a51 + + a13*a24*a35*a46*a51 + - a16*a25*a34*a41*a53 + + a15*a26*a34*a41*a53 + + a16*a24*a35*a41*a53 + - a14*a26*a35*a41*a53 + - a15*a24*a36*a41*a53 + + a14*a25*a36*a41*a53 + + a16*a25*a31*a44*a53 + - a15*a26*a31*a44*a53 + - a16*a21*a35*a44*a53 + + a11*a26*a35*a44*a53 + + a15*a21*a36*a44*a53 + - a11*a25*a36*a44*a53 + - a16*a24*a31*a45*a53 + + a14*a26*a31*a45*a53 + + a16*a21*a34*a45*a53 + - a11*a26*a34*a45*a53 + - a14*a21*a36*a45*a53 + + a11*a24*a36*a45*a53 + + a15*a24*a31*a46*a53 + - a14*a25*a31*a46*a53 + - a15*a21*a34*a46*a53 + + a11*a25*a34*a46*a53 + + a14*a21*a35*a46*a53 + - a11*a24*a35*a46*a53 + + a16*a25*a33*a41*a54 + - a15*a26*a33*a41*a54 + - a16*a23*a35*a41*a54 + + a13*a26*a35*a41*a54 + + a15*a23*a36*a41*a54 + - a13*a25*a36*a41*a54 + - a16*a25*a31*a43*a54 + + a15*a26*a31*a43*a54 + + a16*a21*a35*a43*a54 + - a11*a26*a35*a43*a54 + - a15*a21*a36*a43*a54 + + a11*a25*a36*a43*a54 + + a16*a23*a31*a45*a54 + - a13*a26*a31*a45*a54 + - a16*a21*a33*a45*a54 + + a11*a26*a33*a45*a54 + + a13*a21*a36*a45*a54 + - a11*a23*a36*a45*a54 + - a15*a23*a31*a46*a54 + + a13*a25*a31*a46*a54 + + a15*a21*a33*a46*a54 + - a11*a25*a33*a46*a54 + - a13*a21*a35*a46*a54 + + a11*a23*a35*a46*a54 + - a16*a24*a33*a41*a55 + + a14*a26*a33*a41*a55 + + a16*a23*a34*a41*a55 + - a13*a26*a34*a41*a55 + - a14*a23*a36*a41*a55 + + a13*a24*a36*a41*a55 + + a16*a24*a31*a43*a55 + - a14*a26*a31*a43*a55 + - a16*a21*a34*a43*a55 + + a11*a26*a34*a43*a55 + + a14*a21*a36*a43*a55 + - a11*a24*a36*a43*a55 + - a16*a23*a31*a44*a55 + + a13*a26*a31*a44*a55 + + a16*a21*a33*a44*a55 + - a11*a26*a33*a44*a55 + - a13*a21*a36*a44*a55 + + a11*a23*a36*a44*a55 + + a14*a23*a31*a46*a55 + - a13*a24*a31*a46*a55 + - a14*a21*a33*a46*a55 + + a11*a24*a33*a46*a55 + + a13*a21*a34*a46*a55 + - a11*a23*a34*a46*a55 + + a15*a24*a33*a41*a56 + - a14*a25*a33*a41*a56 + - a15*a23*a34*a41*a56 + + a13*a25*a34*a41*a56 + + a14*a23*a35*a41*a56 + - a13*a24*a35*a41*a56 + - a15*a24*a31*a43*a56 + + a14*a25*a31*a43*a56 + + a15*a21*a34*a43*a56 + - a11*a25*a34*a43*a56 + - a14*a21*a35*a43*a56 + + a11*a24*a35*a43*a56 + + a15*a23*a31*a44*a56 + - a13*a25*a31*a44*a56 + - a15*a21*a33*a44*a56 + + a11*a25*a33*a44*a56 + + a13*a21*a35*a44*a56 + - a11*a23*a35*a44*a56 + - a14*a23*a31*a45*a56 + + a13*a24*a31*a45*a56 + + a14*a21*a33*a45*a56 + - a11*a24*a33*a45*a56 + - a13*a21*a34*a45*a56 + + a11*a23*a34*a45*a56)*a62 + - (a16*a25*a34*a42*a51 + - a15*a26*a34*a42*a51 + - a16*a24*a35*a42*a51 + + a14*a26*a35*a42*a51 + + a15*a24*a36*a42*a51 + - a14*a25*a36*a42*a51 + - a16*a25*a32*a44*a51 + + a15*a26*a32*a44*a51 + + + a16*a22*a35*a44*a51 + - a12*a26*a35*a44*a51 + - a15*a22*a36*a44*a51 + + a12*a25*a36*a44*a51 + + a16*a24*a32*a45*a51 + - a14*a26*a32*a45*a51 + - a16*a22*a34*a45*a51 + + a12*a26*a34*a45*a51 + + a14*a22*a36*a45*a51 + - a12*a24*a36*a45*a51 + - a15*a24*a32*a46*a51 + + + a14*a25*a32*a46*a51 + + a15*a22*a34*a46*a51 + - a12*a25*a34*a46*a51 + - a14*a22*a35*a46*a51 + + a12*a24*a35*a46*a51 + - a16*a25*a34*a41*a52 + + a15*a26*a34*a41*a52 + + a16*a24*a35*a41*a52 + - a14*a26*a35*a41*a52 + - a15*a24*a36*a41*a52 + + a14*a25*a36*a41*a52 + + + a16*a25*a31*a44*a52 + - a15*a26*a31*a44*a52 + - a16*a21*a35*a44*a52 + + a11*a26*a35*a44*a52 + + a15*a21*a36*a44*a52 + - a11*a25*a36*a44*a52 + - a16*a24*a31*a45*a52 + + a14*a26*a31*a45*a52 + + a16*a21*a34*a45*a52 + - a11*a26*a34*a45*a52 + - a14*a21*a36*a45*a52 + + + a11*a24*a36*a45*a52 + + a15*a24*a31*a46*a52 + - a14*a25*a31*a46*a52 + - a15*a21*a34*a46*a52 + + a11*a25*a34*a46*a52 + + a14*a21*a35*a46*a52 + - a11*a24*a35*a46*a52 + + a16*a25*a32*a41*a54 + - a15*a26*a32*a41*a54 + - a16*a22*a35*a41*a54 + + a12*a26*a35*a41*a54 + + + a15*a22*a36*a41*a54 + - a12*a25*a36*a41*a54 + - a16*a25*a31*a42*a54 + + a15*a26*a31*a42*a54 + + a16*a21*a35*a42*a54 + - a11*a26*a35*a42*a54 + - a15*a21*a36*a42*a54 + + a11*a25*a36*a42*a54 + + a16*a22*a31*a45*a54 + - a12*a26*a31*a45*a54 + - a16*a21*a32*a45*a54 + + + a11*a26*a32*a45*a54 + + a12*a21*a36*a45*a54 + - a11*a22*a36*a45*a54 + - a15*a22*a31*a46*a54 + + a12*a25*a31*a46*a54 + + a15*a21*a32*a46*a54 + - a11*a25*a32*a46*a54 + - a12*a21*a35*a46*a54 + + a11*a22*a35*a46*a54 + - a16*a24*a32*a41*a55 + + a14*a26*a32*a41*a55 + + + a16*a22*a34*a41*a55 + - a12*a26*a34*a41*a55 + - a14*a22*a36*a41*a55 + + a12*a24*a36*a41*a55 + + a16*a24*a31*a42*a55 + - a14*a26*a31*a42*a55 + - a16*a21*a34*a42*a55 + + a11*a26*a34*a42*a55 + + a14*a21*a36*a42*a55 + - a11*a24*a36*a42*a55 + - a16*a22*a31*a44*a55 + + + a12*a26*a31*a44*a55 + + a16*a21*a32*a44*a55 + - a11*a26*a32*a44*a55 + - a12*a21*a36*a44*a55 + + a11*a22*a36*a44*a55 + + a14*a22*a31*a46*a55 + - a12*a24*a31*a46*a55 + - a14*a21*a32*a46*a55 + + a11*a24*a32*a46*a55 + + a12*a21*a34*a46*a55 + - a11*a22*a34*a46*a55 + + + a15*a24*a32*a41*a56 + - a14*a25*a32*a41*a56 + - a15*a22*a34*a41*a56 + + a12*a25*a34*a41*a56 + + a14*a22*a35*a41*a56 + - a12*a24*a35*a41*a56 + - a15*a24*a31*a42*a56 + + a14*a25*a31*a42*a56 + + a15*a21*a34*a42*a56 + - a11*a25*a34*a42*a56 + - a14*a21*a35*a42*a56 + + + a11*a24*a35*a42*a56 + + a15*a22*a31*a44*a56 + - a12*a25*a31*a44*a56 + - a15*a21*a32*a44*a56 + + a11*a25*a32*a44*a56 + + a12*a21*a35*a44*a56 + - a11*a22*a35*a44*a56 + - a14*a22*a31*a45*a56 + + a12*a24*a31*a45*a56 + + a14*a21*a32*a45*a56 + - a11*a24*a32*a45*a56 + - + a12*a21*a34*a45*a56 + + a11*a22*a34*a45*a56)*a63 + + (a16*a25*a33*a42*a51 + - a15*a26*a33*a42*a51 + - + a16*a23*a35*a42*a51 + + a13*a26*a35*a42*a51 + + a15*a23*a36*a42*a51 + - a13*a25*a36*a42*a51 + - a16*a25*a32*a43*a51 + + a15*a26*a32*a43*a51 + + a16*a22*a35*a43*a51 + - a12*a26*a35*a43*a51 + - a15*a22*a36*a43*a51 + + a12*a25*a36*a43*a51 + + a16*a23*a32*a45*a51 + - + a13*a26*a32*a45*a51 + - a16*a22*a33*a45*a51 + + a12*a26*a33*a45*a51 + + a13*a22*a36*a45*a51 + - a12*a23*a36*a45*a51 + - a15*a23*a32*a46*a51 + + a13*a25*a32*a46*a51 + + a15*a22*a33*a46*a51 + - a12*a25*a33*a46*a51 + - a13*a22*a35*a46*a51 + + a12*a23*a35*a46*a51 + - + a16*a25*a33*a41*a52 + + a15*a26*a33*a41*a52 + + a16*a23*a35*a41*a52 + - a13*a26*a35*a41*a52 + - a15*a23*a36*a41*a52 + + a13*a25*a36*a41*a52 + + a16*a25*a31*a43*a52 + - a15*a26*a31*a43*a52 + - a16*a21*a35*a43*a52 + + a11*a26*a35*a43*a52 + + a15*a21*a36*a43*a52 + - a11*a25*a36*a43*a52 + - a16*a23*a31*a45*a52 + + a13*a26*a31*a45*a52 + + a16*a21*a33*a45*a52 + - a11*a26*a33*a45*a52 + - a13*a21*a36*a45*a52 + + a11*a23*a36*a45*a52 + + a15*a23*a31*a46*a52 + - a13*a25*a31*a46*a52 + - a15*a21*a33*a46*a52 + + a11*a25*a33*a46*a52 + + a13*a21*a35*a46*a52 + - a11*a23*a35*a46*a52 + + a16*a25*a32*a41*a53 + - a15*a26*a32*a41*a53 + - a16*a22*a35*a41*a53 + + a12*a26*a35*a41*a53 + + a15*a22*a36*a41*a53 + - a12*a25*a36*a41*a53 + - a16*a25*a31*a42*a53 + + a15*a26*a31*a42*a53 + + a16*a21*a35*a42*a53 + - a11*a26*a35*a42*a53 + - a15*a21*a36*a42*a53 + + a11*a25*a36*a42*a53 + + a16*a22*a31*a45*a53 + - a12*a26*a31*a45*a53 + - a16*a21*a32*a45*a53 + + a11*a26*a32*a45*a53 + + a12*a21*a36*a45*a53 + - a11*a22*a36*a45*a53 + - a15*a22*a31*a46*a53 + + a12*a25*a31*a46*a53 + + a15*a21*a32*a46*a53 + - a11*a25*a32*a46*a53 + - a12*a21*a35*a46*a53 + + a11*a22*a35*a46*a53 + - a16*a23*a32*a41*a55 + + a13*a26*a32*a41*a55 + + a16*a22*a33*a41*a55 + - a12*a26*a33*a41*a55 + - a13*a22*a36*a41*a55 + + a12*a23*a36*a41*a55 + + a16*a23*a31*a42*a55 + - a13*a26*a31*a42*a55 + - a16*a21*a33*a42*a55 + + a11*a26*a33*a42*a55 + + a13*a21*a36*a42*a55 + - a11*a23*a36*a42*a55 + - a16*a22*a31*a43*a55 + + a12*a26*a31*a43*a55 + + a16*a21*a32*a43*a55 + - a11*a26*a32*a43*a55 + - a12*a21*a36*a43*a55 + + a11*a22*a36*a43*a55 + + a13*a22*a31*a46*a55 + - a12*a23*a31*a46*a55 + - a13*a21*a32*a46*a55 + + a11*a23*a32*a46*a55 + + a12*a21*a33*a46*a55 + - a11*a22*a33*a46*a55 + + a15*a23*a32*a41*a56 + - a13*a25*a32*a41*a56 + - a15*a22*a33*a41*a56 + + a12*a25*a33*a41*a56 + + a13*a22*a35*a41*a56 + - a12*a23*a35*a41*a56 + - a15*a23*a31*a42*a56 + + a13*a25*a31*a42*a56 + + a15*a21*a33*a42*a56 + - a11*a25*a33*a42*a56 + - a13*a21*a35*a42*a56 + + a11*a23*a35*a42*a56 + + a15*a22*a31*a43*a56 + - a12*a25*a31*a43*a56 + - a15*a21*a32*a43*a56 + + a11*a25*a32*a43*a56 + + a12*a21*a35*a43*a56 + - a11*a22*a35*a43*a56 + - a13*a22*a31*a45*a56 + + a12*a23*a31*a45*a56 + + a13*a21*a32*a45*a56 + - a11*a23*a32*a45*a56 + - a12*a21*a33*a45*a56 + + a11*a22*a33*a45*a56)*a64 + + - (a16*a24*a33*a42*a51 + - a14*a26*a33*a42*a51 + - a16*a23*a34*a42*a51 + + a13*a26*a34*a42*a51 + + a14*a23*a36*a42*a51 + - a13*a24*a36*a42*a51 + - a16*a24*a32*a43*a51 + + a14*a26*a32*a43*a51 + + a16*a22*a34*a43*a51 + - a12*a26*a34*a43*a51 + - a14*a22*a36*a43*a51 + + a12*a24*a36*a43*a51 + + a16*a23*a32*a44*a51 + - a13*a26*a32*a44*a51 + - a16*a22*a33*a44*a51 + + a12*a26*a33*a44*a51 + + a13*a22*a36*a44*a51 + - a12*a23*a36*a44*a51 + - a14*a23*a32*a46*a51 + + a13*a24*a32*a46*a51 + + a14*a22*a33*a46*a51 + - a12*a24*a33*a46*a51 + - a13*a22*a34*a46*a51 + + a12*a23*a34*a46*a51 + - a16*a24*a33*a41*a52 + + a14*a26*a33*a41*a52 + + a16*a23*a34*a41*a52 + - a13*a26*a34*a41*a52 + - a14*a23*a36*a41*a52 + + a13*a24*a36*a41*a52 + + a16*a24*a31*a43*a52 + - a14*a26*a31*a43*a52 + - a16*a21*a34*a43*a52 + + a11*a26*a34*a43*a52 + + a14*a21*a36*a43*a52 + - a11*a24*a36*a43*a52 + - a16*a23*a31*a44*a52 + + a13*a26*a31*a44*a52 + + a16*a21*a33*a44*a52 + - a11*a26*a33*a44*a52 + - a13*a21*a36*a44*a52 + + a11*a23*a36*a44*a52 + + a14*a23*a31*a46*a52 + - a13*a24*a31*a46*a52 + - a14*a21*a33*a46*a52 + + a11*a24*a33*a46*a52 + + a13*a21*a34*a46*a52 + - a11*a23*a34*a46*a52 + + a16*a24*a32*a41*a53 + - a14*a26*a32*a41*a53 + - a16*a22*a34*a41*a53 + + a12*a26*a34*a41*a53 + + a14*a22*a36*a41*a53 + - a12*a24*a36*a41*a53 + - a16*a24*a31*a42*a53 + + a14*a26*a31*a42*a53 + + a16*a21*a34*a42*a53 + - a11*a26*a34*a42*a53 + - a14*a21*a36*a42*a53 + + a11*a24*a36*a42*a53 + + a16*a22*a31*a44*a53 + - a12*a26*a31*a44*a53 + - a16*a21*a32*a44*a53 + + a11*a26*a32*a44*a53 + + a12*a21*a36*a44*a53 + - a11*a22*a36*a44*a53 + - a14*a22*a31*a46*a53 + + a12*a24*a31*a46*a53 + + a14*a21*a32*a46*a53 + - a11*a24*a32*a46*a53 + - a12*a21*a34*a46*a53 + + a11*a22*a34*a46*a53 + - a16*a23*a32*a41*a54 + + a13*a26*a32*a41*a54 + + a16*a22*a33*a41*a54 + - a12*a26*a33*a41*a54 + - a13*a22*a36*a41*a54 + + a12*a23*a36*a41*a54 + + a16*a23*a31*a42*a54 + - a13*a26*a31*a42*a54 + - a16*a21*a33*a42*a54 + + a11*a26*a33*a42*a54 + + a13*a21*a36*a42*a54 + - a11*a23*a36*a42*a54 + - a16*a22*a31*a43*a54 + + a12*a26*a31*a43*a54 + + a16*a21*a32*a43*a54 + - a11*a26*a32*a43*a54 + - a12*a21*a36*a43*a54 + + a11*a22*a36*a43*a54 + + a13*a22*a31*a46*a54 + - a12*a23*a31*a46*a54 + - a13*a21*a32*a46*a54 + + a11*a23*a32*a46*a54 + + a12*a21*a33*a46*a54 + - a11*a22*a33*a46*a54 + + a14*a23*a32*a41*a56 + - a13*a24*a32*a41*a56 + - a14*a22*a33*a41*a56 + + a12*a24*a33*a41*a56 + + a13*a22*a34*a41*a56 + - a12*a23*a34*a41*a56 + - a14*a23*a31*a42*a56 + + a13*a24*a31*a42*a56 + + a14*a21*a33*a42*a56 + - a11*a24*a33*a42*a56 + - a13*a21*a34*a42*a56 + + a11*a23*a34*a42*a56 + + a14*a22*a31*a43*a56 + - a12*a24*a31*a43*a56 + - a14*a21*a32*a43*a56 + + a11*a24*a32*a43*a56 + + a12*a21*a34*a43*a56 + - a11*a22*a34*a43*a56 + - a13*a22*a31*a44*a56 + + a12*a23*a31*a44*a56 + + a13*a21*a32*a44*a56 + - a11*a23*a32*a44*a56 + - a12*a21*a33*a44*a56 + + a11*a22*a33*a44*a56)*a65 + + (a15*a24*a33*a42*a51 + - a14*a25*a33*a42*a51 + - a15*a23*a34*a42*a51 + + a13*a25*a34*a42*a51 + + a14*a23*a35*a42*a51 + - a13*a24*a35*a42*a51 + - a15*a24*a32*a43*a51 + + a14*a25*a32*a43*a51 + + a15*a22*a34*a43*a51 + - a12*a25*a34*a43*a51 + - a14*a22*a35*a43*a51 + + a12*a24*a35*a43*a51 + + a15*a23*a32*a44*a51 + - a13*a25*a32*a44*a51 + - a15*a22*a33*a44*a51 + + a12*a25*a33*a44*a51 + + a13*a22*a35*a44*a51 + - a12*a23*a35*a44*a51 + - a14*a23*a32*a45*a51 + + a13*a24*a32*a45*a51 + + a14*a22*a33*a45*a51 + - + a12*a24*a33*a45*a51 + - a13*a22*a34*a45*a51 + + a12*a23*a34*a45*a51 + - a15*a24*a33*a41*a52 + + a14*a25*a33*a41*a52 + + a15*a23*a34*a41*a52 + - a13*a25*a34*a41*a52 + - a14*a23*a35*a41*a52 + + a13*a24*a35*a41*a52 + + a15*a24*a31*a43*a52 + - a14*a25*a31*a43*a52 + - + a15*a21*a34*a43*a52 + + a11*a25*a34*a43*a52 + + a14*a21*a35*a43*a52 + - a11*a24*a35*a43*a52 + - a15*a23*a31*a44*a52 + + a13*a25*a31*a44*a52 + + a15*a21*a33*a44*a52 + - a11*a25*a33*a44*a52 + - a13*a21*a35*a44*a52 + + a11*a23*a35*a44*a52 + + a14*a23*a31*a45*a52 + - + a13*a24*a31*a45*a52 + - a14*a21*a33*a45*a52 + + a11*a24*a33*a45*a52 + + a13*a21*a34*a45*a52 + - a11*a23*a34*a45*a52 + + a15*a24*a32*a41*a53 + - a14*a25*a32*a41*a53 + - a15*a22*a34*a41*a53 + + a12*a25*a34*a41*a53 + + a14*a22*a35*a41*a53 + - a12*a24*a35*a41*a53 + - + a15*a24*a31*a42*a53 + + a14*a25*a31*a42*a53 + + a15*a21*a34*a42*a53 + - a11*a25*a34*a42*a53 + - a14*a21*a35*a42*a53 + + a11*a24*a35*a42*a53 + + a15*a22*a31*a44*a53 + - a12*a25*a31*a44*a53 + - a15*a21*a32*a44*a53 + + a11*a25*a32*a44*a53 + + a12*a21*a35*a44*a53 + - + a11*a22*a35*a44*a53 + - a14*a22*a31*a45*a53 + + a12*a24*a31*a45*a53 + + a14*a21*a32*a45*a53 + - a11*a24*a32*a45*a53 + - a12*a21*a34*a45*a53 + + a11*a22*a34*a45*a53 + - a15*a23*a32*a41*a54 + + a13*a25*a32*a41*a54 + + a15*a22*a33*a41*a54 + - a12*a25*a33*a41*a54 + - + a13*a22*a35*a41*a54 + + a12*a23*a35*a41*a54 + + a15*a23*a31*a42*a54 + - a13*a25*a31*a42*a54 + - a15*a21*a33*a42*a54 + + a11*a25*a33*a42*a54 + + a13*a21*a35*a42*a54 + - a11*a23*a35*a42*a54 + - a15*a22*a31*a43*a54 + + a12*a25*a31*a43*a54 + + a15*a21*a32*a43*a54 + - + a11*a25*a32*a43*a54 + - a12*a21*a35*a43*a54 + + a11*a22*a35*a43*a54 + + a13*a22*a31*a45*a54 + - a12*a23*a31*a45*a54 + - a13*a21*a32*a45*a54 + + a11*a23*a32*a45*a54 + + a12*a21*a33*a45*a54 + - a11*a22*a33*a45*a54 + + a14*a23*a32*a41*a55 + - a13*a24*a32*a41*a55 + - + a14*a22*a33*a41*a55 + + a12*a24*a33*a41*a55 + + a13*a22*a34*a41*a55 + - a12*a23*a34*a41*a55 + - a14*a23*a31*a42*a55 + + a13*a24*a31*a42*a55 + + a14*a21*a33*a42*a55 + - a11*a24*a33*a42*a55 + - a13*a21*a34*a42*a55 + + a11*a23*a34*a42*a55 + + a14*a22*a31*a43*a55 + - a12*a24*a31*a43*a55 + - a14*a21*a32*a43*a55 + + a11*a24*a32*a43*a55 + + a12*a21*a34*a43*a55 + - a11*a22*a34*a43*a55 + - a13*a22*a31*a44*a55 + + a12*a23*a31*a44*a55 + + a13*a21*a32*a44*a55 + - a11*a23*a32*a44*a55 + - a12*a21*a33*a44*a55 + + a11*a22*a33*a44*a55)*a66; + + if (fabs(det) <= eps) { + // printf("inv6: det = %lf\n", det); + *ok_flag__ = -1; + // return -1; + } + cofactor[0] = a26*a35*a44*a53*a62 + - a25*a36*a44*a53*a62 + - + a26*a34*a45*a53*a62 + + a24*a36*a45*a53*a62 + + a25* + a34*a46*a53*a62 + - a24*a35*a46*a53*a62 + - a26*a35* + a43*a54*a62 + + a25*a36*a43*a54*a62 + + a26*a33*a45* + a54*a62 + - a23*a36*a45*a54*a62 + - a25*a33*a46*a54* + a62 + + a23*a35*a46*a54*a62 + + a26*a34*a43*a55*a62 + - + a24*a36*a43*a55*a62 + - a26*a33*a44*a55*a62 + + a23* + a36*a44*a55*a62 + + a24*a33*a46*a55*a62 + - a23*a34* + a46*a55*a62 + - a25*a34*a43*a56*a62 + + a24*a35*a43* + a56*a62 + + a25*a33*a44*a56*a62 + - a23*a35*a44*a56* + a62 + - a24*a33*a45*a56*a62 + + a23*a34*a45*a56*a62 + - + a26*a35*a44*a52*a63 + + a25*a36*a44*a52*a63 + + a26* + a34*a45*a52*a63 + - a24*a36*a45*a52*a63 + - a25*a34* + a46*a52*a63 + + a24*a35*a46*a52*a63 + + a26*a35*a42* + a54*a63 + - a25*a36*a42*a54*a63 + - a26*a32*a45*a54* + a63 + + a22*a36*a45*a54*a63 + + a25*a32*a46*a54*a63 + - + a22*a35*a46*a54*a63 + - a26*a34*a42*a55*a63 + + a24* + a36*a42*a55*a63 + + a26*a32*a44*a55*a63 + - a22*a36* + a44*a55*a63 + - a24*a32*a46*a55*a63 + + a22*a34*a46* + a55*a63 + + a25*a34*a42*a56*a63 + - a24*a35*a42*a56* + a63 + - a25*a32*a44*a56*a63 + + a22*a35*a44*a56*a63 + + + a24*a32*a45*a56*a63 + - a22*a34*a45*a56*a63 + + a26* + a35*a43*a52*a64 + - a25*a36*a43*a52*a64 + - a26*a33* + a45*a52*a64 + + a23*a36*a45*a52*a64 + + a25*a33*a46* + a52*a64 + - a23*a35*a46*a52*a64 + - a26*a35*a42*a53* + a64 + + a25*a36*a42*a53*a64 + + a26*a32*a45*a53*a64 + - + a22*a36*a45*a53*a64 + - a25*a32*a46*a53*a64 + + a22* + a35*a46*a53*a64 + + a26*a33*a42*a55*a64 + - a23*a36* + a42*a55*a64 + - a26*a32*a43*a55*a64 + + a22*a36*a43* + a55*a64 + + a23*a32*a46*a55*a64 + - a22*a33*a46*a55* + a64 + - a25*a33*a42*a56*a64 + + a23*a35*a42*a56*a64 + + + a25*a32*a43*a56*a64 + - a22*a35*a43*a56*a64 + - a23* + a32*a45*a56*a64 + + a22*a33*a45*a56*a64 + - a26*a34* + a43*a52*a65 + + a24*a36*a43*a52*a65 + + a26*a33*a44* + a52*a65 + - a23*a36*a44*a52*a65 + - a24*a33*a46*a52* + a65 + + a23*a34*a46*a52*a65 + + a26*a34*a42*a53*a65 + - + a24*a36*a42*a53*a65 + - a26*a32*a44*a53*a65 + + a22* + a36*a44*a53*a65 + + a24*a32*a46*a53*a65 + - a22*a34* + a46*a53*a65 + - a26*a33*a42*a54*a65 + + a23*a36*a42* + a54*a65 + + a26*a32*a43*a54*a65 + - a22*a36*a43*a54* + a65 + - a23*a32*a46*a54*a65 + + a22*a33*a46*a54*a65 + + + a24*a33*a42*a56*a65 + - a23*a34*a42*a56*a65 + - a24* + a32*a43*a56*a65 + + a22*a34*a43*a56*a65 + + a23*a32* + a44*a56*a65 + - a22*a33*a44*a56*a65 + + a25*a34*a43* + a52*a66 + - a24*a35*a43*a52*a66 + - a25*a33*a44*a52* + a66 + + a23*a35*a44*a52*a66 + + a24*a33*a45*a52*a66 + - + a23*a34*a45*a52*a66 + - a25*a34*a42*a53*a66 + + a24* + a35*a42*a53*a66 + + a25*a32*a44*a53*a66 + - a22*a35* + a44*a53*a66 + - a24*a32*a45*a53*a66 + + a22*a34*a45* + a53*a66 + + a25*a33*a42*a54*a66 + - a23*a35*a42*a54* + a66 + - a25*a32*a43*a54*a66 + + a22*a35*a43*a54*a66 + + + a23*a32*a45*a54*a66 + - a22*a33*a45*a54*a66 + - a24* + a33*a42*a55*a66 + + a23*a34*a42*a55*a66 + + a24*a32* + a43*a55*a66 + - a22*a34*a43*a55*a66 + - a23*a32*a44* + a55*a66 + + a22*a33*a44*a55*a66; + cofactor[1] = -a16*a35*a44*a53*a62 + + a15*a36*a44*a53*a62 + + a16*a34*a45*a53*a62 + - a14*a36*a45*a53*a62 + - a15*a34*a46*a53*a62 + + a14*a35*a46*a53*a62 + + a16*a35*a43*a54*a62 + - a15*a36*a43*a54*a62 + - a16*a33*a45*a54*a62 + + a13*a36*a45*a54*a62 + + a15*a33*a46*a54*a62 + - a13*a35*a46*a54*a62 + - a16*a34*a43*a55*a62 + + a14*a36*a43*a55*a62 + + a16*a33*a44*a55*a62 + - a13*a36*a44*a55*a62 + - a14*a33*a46*a55*a62 + + a13*a34*a46*a55*a62 + + a15*a34*a43*a56*a62 + - a14*a35*a43*a56*a62 + - a15*a33*a44*a56*a62 + + a13*a35*a44*a56*a62 + + a14*a33*a45*a56*a62 + - a13*a34*a45*a56*a62 + + a16*a35*a44*a52*a63 + - a15*a36*a44*a52*a63 + - a16*a34*a45*a52*a63 + + a14*a36*a45*a52*a63 + + a15*a34*a46*a52*a63 + - a14*a35*a46*a52*a63 + - a16*a35*a42*a54*a63 + + a15*a36*a42*a54*a63 + + a16*a32*a45*a54*a63 + - a12*a36*a45*a54*a63 + - a15*a32*a46*a54*a63 + + a12*a35*a46*a54*a63 + + a16*a34*a42*a55*a63 + - a14*a36*a42*a55*a63 + - a16*a32*a44*a55*a63 + + a12*a36*a44*a55*a63 + + a14*a32*a46*a55*a63 + - a12*a34*a46*a55*a63 + - a15*a34*a42*a56*a63 + + a14*a35*a42*a56*a63 + + a15*a32*a44*a56*a63 + - a12*a35*a44*a56*a63 + - a14*a32*a45*a56*a63 + + a12*a34*a45*a56*a63 + - a16*a35*a43*a52*a64 + + a15*a36*a43*a52*a64 + + a16*a33*a45*a52*a64 + - a13*a36*a45*a52*a64 + - a15*a33*a46*a52*a64 + + a13*a35*a46*a52*a64 + + a16*a35*a42*a53*a64 + - a15*a36*a42*a53*a64 + - a16*a32*a45*a53*a64 + + a12*a36*a45*a53*a64 + + a15*a32*a46*a53*a64 + - a12*a35*a46*a53*a64 + - a16*a33*a42*a55*a64 + + a13*a36*a42*a55*a64 + + a16*a32*a43*a55*a64 + - a12*a36*a43*a55*a64 + - a13*a32*a46*a55*a64 + + a12*a33*a46*a55*a64 + + a15*a33*a42*a56*a64 + - a13*a35*a42*a56*a64 + - a15*a32*a43*a56*a64 + + a12*a35*a43*a56*a64 + + a13*a32*a45*a56*a64 + - a12*a33*a45*a56*a64 + + a16*a34*a43*a52*a65 + - a14*a36*a43*a52*a65 + - a16*a33*a44*a52*a65 + + a13*a36*a44*a52*a65 + + a14*a33*a46*a52*a65 + - a13*a34*a46*a52*a65 + - a16*a34*a42*a53*a65 + + a14*a36*a42*a53*a65 + + a16*a32*a44*a53*a65 + - a12*a36*a44*a53*a65 + - a14*a32*a46*a53*a65 + + a12*a34*a46*a53*a65 + + a16*a33*a42*a54*a65 + - a13*a36*a42*a54*a65 + - a16*a32*a43*a54*a65 + + a12*a36*a43*a54*a65 + + a13*a32*a46*a54*a65 + - a12*a33*a46*a54*a65 + - a14*a33*a42*a56*a65 + + a13*a34*a42*a56*a65 + + a14*a32*a43*a56*a65 + - a12*a34*a43*a56*a65 + - a13*a32*a44*a56*a65 + + a12*a33*a44*a56*a65 + - a15*a34*a43*a52*a66 + + a14*a35*a43*a52*a66 + + a15*a33*a44*a52*a66 + - a13*a35*a44*a52*a66 + - a14*a33*a45*a52*a66 + + a13*a34*a45*a52*a66 + + a15*a34*a42*a53*a66 + - a14*a35*a42*a53*a66 + - a15*a32*a44*a53*a66 + + a12*a35*a44*a53*a66 + + a14*a32*a45*a53*a66 + - a12*a34*a45*a53*a66 + - a15*a33*a42*a54*a66 + + a13*a35*a42*a54*a66 + + a15*a32*a43*a54*a66 + - a12*a35*a43*a54*a66 + - a13*a32*a45*a54*a66 + + a12*a33*a45*a54*a66 + + a14*a33*a42*a55*a66 + - a13*a34*a42*a55*a66 + - a14*a32*a43*a55*a66 + + a12*a34*a43*a55*a66 + + a13*a32*a44*a55*a66 + - a12*a33*a44*a55*a66; + cofactor[2] = a16*a25*a44*a53*a62 + - a15*a26*a44*a53*a62 + - + a16*a24*a45*a53*a62 + + a14*a26*a45*a53*a62 + + a15* + a24*a46*a53*a62 + - a14*a25*a46*a53*a62 + - a16*a25* + a43*a54*a62 + + a15*a26*a43*a54*a62 + + a16*a23*a45* + a54*a62 + - a13*a26*a45*a54*a62 + - a15*a23*a46*a54* + a62 + + a13*a25*a46*a54*a62 + + a16*a24*a43*a55*a62 + - + a14*a26*a43*a55*a62 + - a16*a23*a44*a55*a62 + + a13* + a26*a44*a55*a62 + + a14*a23*a46*a55*a62 + - a13*a24* + a46*a55*a62 + - a15*a24*a43*a56*a62 + + a14*a25*a43* + a56*a62 + + a15*a23*a44*a56*a62 + - a13*a25*a44*a56* + a62 + - a14*a23*a45*a56*a62 + + a13*a24*a45*a56*a62 + - + a16*a25*a44*a52*a63 + + a15*a26*a44*a52*a63 + + a16* + a24*a45*a52*a63 + - a14*a26*a45*a52*a63 + - a15*a24* + a46*a52*a63 + + a14*a25*a46*a52*a63 + + a16*a25*a42* + a54*a63 + - a15*a26*a42*a54*a63 + - a16*a22*a45*a54* + a63 + + a12*a26*a45*a54*a63 + + a15*a22*a46*a54*a63 + - + a12*a25*a46*a54*a63 + - a16*a24*a42*a55*a63 + + a14* + a26*a42*a55*a63 + + a16*a22*a44*a55*a63 + - a12*a26* + a44*a55*a63 + - a14*a22*a46*a55*a63 + + a12*a24*a46* + a55*a63 + + a15*a24*a42*a56*a63 + - a14*a25*a42*a56* + a63 + - a15*a22*a44*a56*a63 + + a12*a25*a44*a56*a63 + + + a14*a22*a45*a56*a63 + - a12*a24*a45*a56*a63 + + a16* + a25*a43*a52*a64 + - a15*a26*a43*a52*a64 + - a16*a23* + a45*a52*a64 + + a13*a26*a45*a52*a64 + + a15*a23*a46* + a52*a64 + - a13*a25*a46*a52*a64 + - a16*a25*a42*a53* + a64 + + a15*a26*a42*a53*a64 + + a16*a22*a45*a53*a64 + - + a12*a26*a45*a53*a64 + - a15*a22*a46*a53*a64 + + a12* + a25*a46*a53*a64 + + a16*a23*a42*a55*a64 + - a13*a26* + a42*a55*a64 + - a16*a22*a43*a55*a64 + + a12*a26*a43* + a55*a64 + + a13*a22*a46*a55*a64 + - a12*a23*a46*a55* + a64 + - a15*a23*a42*a56*a64 + + a13*a25*a42*a56*a64 + + + a15*a22*a43*a56*a64 + - a12*a25*a43*a56*a64 + - a13* + a22*a45*a56*a64 + + a12*a23*a45*a56*a64 + - a16*a24* + a43*a52*a65 + + a14*a26*a43*a52*a65 + + a16*a23*a44* + a52*a65 + - a13*a26*a44*a52*a65 + - a14*a23*a46*a52* + a65 + + a13*a24*a46*a52*a65 + + a16*a24*a42*a53*a65 + - + a14*a26*a42*a53*a65 + - a16*a22*a44*a53*a65 + + a12* + a26*a44*a53*a65 + + a14*a22*a46*a53*a65 + - a12*a24* + a46*a53*a65 + - a16*a23*a42*a54*a65 + + a13*a26*a42* + a54*a65 + + a16*a22*a43*a54*a65 + - a12*a26*a43*a54* + a65 + - a13*a22*a46*a54*a65 + + a12*a23*a46*a54*a65 + + + a14*a23*a42*a56*a65 + - a13*a24*a42*a56*a65 + - a14* + a22*a43*a56*a65 + + a12*a24*a43*a56*a65 + + a13*a22* + a44*a56*a65 + - a12*a23*a44*a56*a65 + + a15*a24*a43* + a52*a66 + - a14*a25*a43*a52*a66 + - a15*a23*a44*a52* + a66 + + a13*a25*a44*a52*a66 + + a14*a23*a45*a52*a66 + - + a13*a24*a45*a52*a66 + - a15*a24*a42*a53*a66 + + a14* + a25*a42*a53*a66 + + a15*a22*a44*a53*a66 + - a12*a25* + a44*a53*a66 + - a14*a22*a45*a53*a66 + + a12*a24*a45* + a53*a66 + + a15*a23*a42*a54*a66 + - a13*a25*a42*a54* + a66 + - a15*a22*a43*a54*a66 + + a12*a25*a43*a54*a66 + + + a13*a22*a45*a54*a66 + - a12*a23*a45*a54*a66 + - a14* + a23*a42*a55*a66 + + a13*a24*a42*a55*a66 + + a14*a22* + a43*a55*a66 + - a12*a24*a43*a55*a66 + - a13*a22*a44* + a55*a66 + + a12*a23*a44*a55*a66; + cofactor[3] = -a16*a25*a34*a53*a62 + + a15*a26*a34*a53*a62 + + a16*a24*a35*a53*a62 + - a14*a26*a35*a53*a62 + - a15*a24*a36*a53*a62 + + a14*a25*a36*a53*a62 + + a16*a25*a33*a54*a62 + - a15*a26*a33*a54*a62 + - a16*a23*a35*a54*a62 + + a13*a26*a35*a54*a62 + + a15*a23*a36*a54*a62 + - a13*a25*a36*a54*a62 + - a16*a24*a33*a55*a62 + + a14*a26*a33*a55*a62 + + a16*a23*a34*a55*a62 + - a13*a26*a34*a55*a62 + - a14*a23*a36*a55*a62 + + a13*a24*a36*a55*a62 + + a15*a24*a33*a56*a62 + - a14*a25*a33*a56*a62 + - a15*a23*a34*a56*a62 + + a13*a25*a34*a56*a62 + + a14*a23*a35*a56*a62 + - a13*a24*a35*a56*a62 + + a16*a25*a34*a52*a63 + - a15*a26*a34*a52*a63 + - a16*a24*a35*a52*a63 + + a14*a26*a35*a52*a63 + + a15*a24*a36*a52*a63 + - a14*a25*a36*a52*a63 + - a16*a25*a32*a54*a63 + + a15*a26*a32*a54*a63 + + a16*a22*a35*a54*a63 + - a12*a26*a35*a54*a63 + - a15*a22*a36*a54*a63 + + a12*a25*a36*a54*a63 + + a16*a24*a32*a55*a63 + - a14*a26*a32*a55*a63 + - a16*a22*a34*a55*a63 + + a12*a26*a34*a55*a63 + + a14*a22*a36*a55*a63 + - a12*a24*a36*a55*a63 + - a15*a24*a32*a56*a63 + + a14*a25*a32*a56*a63 + + a15*a22*a34*a56*a63 + - a12*a25*a34*a56*a63 + - a14*a22*a35*a56*a63 + + a12*a24*a35*a56*a63 + - a16*a25*a33*a52*a64 + + a15*a26*a33*a52*a64 + + a16*a23*a35*a52*a64 + - a13*a26*a35*a52*a64 + - a15*a23*a36*a52*a64 + + a13*a25*a36*a52*a64 + + a16*a25*a32*a53*a64 + - a15*a26*a32*a53*a64 + - a16*a22*a35*a53*a64 + + a12*a26*a35*a53*a64 + + a15*a22*a36*a53*a64 + - a12*a25*a36*a53*a64 + - a16*a23*a32*a55*a64 + + a13*a26*a32*a55*a64 + + a16*a22*a33*a55*a64 + - a12*a26*a33*a55*a64 + - a13*a22*a36*a55*a64 + + a12*a23*a36*a55*a64 + + a15*a23*a32*a56*a64 + - a13*a25*a32*a56*a64 + - a15*a22*a33*a56*a64 + + a12*a25*a33*a56*a64 + + a13*a22*a35*a56*a64 + - a12*a23*a35*a56*a64 + + a16*a24*a33*a52*a65 + - a14*a26*a33*a52*a65 + - a16*a23*a34*a52*a65 + + a13*a26*a34*a52*a65 + + a14*a23*a36*a52*a65 + - a13*a24*a36*a52*a65 + - a16*a24*a32*a53*a65 + + a14*a26*a32*a53*a65 + + a16*a22*a34*a53*a65 + - a12*a26*a34*a53*a65 + - a14*a22*a36*a53*a65 + + a12*a24*a36*a53*a65 + + a16*a23*a32*a54*a65 + - a13*a26*a32*a54*a65 + - a16*a22*a33*a54*a65 + + a12*a26*a33*a54*a65 + + a13*a22*a36*a54*a65 + - a12*a23*a36*a54*a65 + - a14*a23*a32*a56*a65 + + a13*a24*a32*a56*a65 + + a14*a22*a33*a56*a65 + - a12*a24*a33*a56*a65 + - a13*a22*a34*a56*a65 + + a12*a23*a34*a56*a65 + - a15*a24*a33*a52*a66 + + a14*a25*a33*a52*a66 + + a15*a23*a34*a52*a66 + - a13*a25*a34*a52*a66 + - a14*a23*a35*a52*a66 + + a13*a24*a35*a52*a66 + + a15*a24*a32*a53*a66 + - a14*a25*a32*a53*a66 + - a15*a22*a34*a53*a66 + + a12*a25*a34*a53*a66 + + a14*a22*a35*a53*a66 + - a12*a24*a35*a53*a66 + - a15*a23*a32*a54*a66 + + a13*a25*a32*a54*a66 + + a15*a22*a33*a54*a66 + - a12*a25*a33*a54*a66 + - a13*a22*a35*a54*a66 + + a12*a23*a35*a54*a66 + + a14*a23*a32*a55*a66 + - a13*a24*a32*a55*a66 + - a14*a22*a33*a55*a66 + + a12*a24*a33*a55*a66 + + a13*a22*a34*a55*a66 + - a12*a23*a34*a55*a66; + cofactor[4] = a16*a25*a34*a43*a62 + - a15*a26*a34*a43*a62 + - + a16*a24*a35*a43*a62 + + a14*a26*a35*a43*a62 + + a15* + a24*a36*a43*a62 + - a14*a25*a36*a43*a62 + - a16*a25* + a33*a44*a62 + + a15*a26*a33*a44*a62 + + a16*a23*a35* + a44*a62 + - a13*a26*a35*a44*a62 + - a15*a23*a36*a44* + a62 + + a13*a25*a36*a44*a62 + + a16*a24*a33*a45*a62 + - + a14*a26*a33*a45*a62 + - a16*a23*a34*a45*a62 + + a13* + a26*a34*a45*a62 + + a14*a23*a36*a45*a62 + - a13*a24* + a36*a45*a62 + - a15*a24*a33*a46*a62 + + a14*a25*a33* + a46*a62 + + a15*a23*a34*a46*a62 + - a13*a25*a34*a46* + a62 + - a14*a23*a35*a46*a62 + + a13*a24*a35*a46*a62 + - + a16*a25*a34*a42*a63 + + a15*a26*a34*a42*a63 + + a16* + a24*a35*a42*a63 + - a14*a26*a35*a42*a63 + - a15*a24* + a36*a42*a63 + + a14*a25*a36*a42*a63 + + a16*a25*a32* + a44*a63 + - a15*a26*a32*a44*a63 + - a16*a22*a35*a44* + a63 + + a12*a26*a35*a44*a63 + + a15*a22*a36*a44*a63 + - + a12*a25*a36*a44*a63 + - a16*a24*a32*a45*a63 + + a14* + a26*a32*a45*a63 + + a16*a22*a34*a45*a63 + - a12*a26* + a34*a45*a63 + - a14*a22*a36*a45*a63 + + a12*a24*a36* + a45*a63 + + a15*a24*a32*a46*a63 + - a14*a25*a32*a46* + a63 + - a15*a22*a34*a46*a63 + + a12*a25*a34*a46*a63 + + + a14*a22*a35*a46*a63 + - a12*a24*a35*a46*a63 + + a16* + a25*a33*a42*a64 + - a15*a26*a33*a42*a64 + - a16*a23* + a35*a42*a64 + + a13*a26*a35*a42*a64 + + a15*a23*a36* + a42*a64 + - a13*a25*a36*a42*a64 + - a16*a25*a32*a43* + a64 + + a15*a26*a32*a43*a64 + + a16*a22*a35*a43*a64 + - + a12*a26*a35*a43*a64 + - a15*a22*a36*a43*a64 + + a12* + a25*a36*a43*a64 + + a16*a23*a32*a45*a64 + - a13*a26* + a32*a45*a64 + - a16*a22*a33*a45*a64 + + a12*a26*a33* + a45*a64 + + a13*a22*a36*a45*a64 + - a12*a23*a36*a45* + a64 + - a15*a23*a32*a46*a64 + + a13*a25*a32*a46*a64 + + + a15*a22*a33*a46*a64 + - a12*a25*a33*a46*a64 + - a13* + a22*a35*a46*a64 + + a12*a23*a35*a46*a64 + - a16*a24* + a33*a42*a65 + + a14*a26*a33*a42*a65 + + a16*a23*a34* + a42*a65 + - a13*a26*a34*a42*a65 + - a14*a23*a36*a42* + a65 + + a13*a24*a36*a42*a65 + + a16*a24*a32*a43*a65 + - + a14*a26*a32*a43*a65 + - a16*a22*a34*a43*a65 + + a12* + a26*a34*a43*a65 + + a14*a22*a36*a43*a65 + - a12*a24* + a36*a43*a65 + - a16*a23*a32*a44*a65 + + a13*a26*a32* + a44*a65 + + a16*a22*a33*a44*a65 + - a12*a26*a33*a44* + a65 + - a13*a22*a36*a44*a65 + + a12*a23*a36*a44*a65 + + + a14*a23*a32*a46*a65 + - a13*a24*a32*a46*a65 + - a14* + a22*a33*a46*a65 + + a12*a24*a33*a46*a65 + + a13*a22* + a34*a46*a65 + - a12*a23*a34*a46*a65 + + a15*a24*a33* + a42*a66 + - a14*a25*a33*a42*a66 + - a15*a23*a34*a42* + a66 + + a13*a25*a34*a42*a66 + + a14*a23*a35*a42*a66 + - + a13*a24*a35*a42*a66 + - a15*a24*a32*a43*a66 + + a14* + a25*a32*a43*a66 + + a15*a22*a34*a43*a66 + - a12*a25* + a34*a43*a66 + - a14*a22*a35*a43*a66 + + a12*a24*a35* + a43*a66 + + a15*a23*a32*a44*a66 + - a13*a25*a32*a44* + a66 + - a15*a22*a33*a44*a66 + + a12*a25*a33*a44*a66 + + + a13*a22*a35*a44*a66 + - a12*a23*a35*a44*a66 + - a14* + a23*a32*a45*a66 + + a13*a24*a32*a45*a66 + + a14*a22* + a33*a45*a66 + - a12*a24*a33*a45*a66 + - a13*a22*a34* + a45*a66 + + a12*a23*a34*a45*a66; + cofactor[5] = -a16*a25*a34*a43*a52 + + a15*a26*a34*a43*a52 + + a16*a24*a35*a43*a52 + - a14*a26*a35*a43*a52 + - a15*a24*a36*a43*a52 + + a14*a25*a36*a43*a52 + + a16*a25*a33*a44*a52 + - a15*a26*a33*a44*a52 + - a16*a23*a35*a44*a52 + + a13*a26*a35*a44*a52 + + a15*a23*a36*a44*a52 + - a13*a25*a36*a44*a52 + - a16*a24*a33*a45*a52 + + a14*a26*a33*a45*a52 + + a16*a23*a34*a45*a52 + - a13*a26*a34*a45*a52 + - a14*a23*a36*a45*a52 + + a13*a24*a36*a45*a52 + + a15*a24*a33*a46*a52 + - a14*a25*a33*a46*a52 + - a15*a23*a34*a46*a52 + + a13*a25*a34*a46*a52 + + a14*a23*a35*a46*a52 + - a13*a24*a35*a46*a52 + + a16*a25*a34*a42*a53 + - a15*a26*a34*a42*a53 + - a16*a24*a35*a42*a53 + + a14*a26*a35*a42*a53 + + a15*a24*a36*a42*a53 + - a14*a25*a36*a42*a53 + - a16*a25*a32*a44*a53 + + a15*a26*a32*a44*a53 + + a16*a22*a35*a44*a53 + - a12*a26*a35*a44*a53 + - a15*a22*a36*a44*a53 + + a12*a25*a36*a44*a53 + + a16*a24*a32*a45*a53 + - a14*a26*a32*a45*a53 + - a16*a22*a34*a45*a53 + + a12*a26*a34*a45*a53 + + a14*a22*a36*a45*a53 + - a12*a24*a36*a45*a53 + - a15*a24*a32*a46*a53 + + a14*a25*a32*a46*a53 + + a15*a22*a34*a46*a53 + - a12*a25*a34*a46*a53 + - a14*a22*a35*a46*a53 + + a12*a24*a35*a46*a53 + - a16*a25*a33*a42*a54 + + a15*a26*a33*a42*a54 + + a16*a23*a35*a42*a54 + - a13*a26*a35*a42*a54 + - a15*a23*a36*a42*a54 + + a13*a25*a36*a42*a54 + + a16*a25*a32*a43*a54 + - a15*a26*a32*a43*a54 + - a16*a22*a35*a43*a54 + + a12*a26*a35*a43*a54 + + a15*a22*a36*a43*a54 + - a12*a25*a36*a43*a54 + - a16*a23*a32*a45*a54 + + a13*a26*a32*a45*a54 + + a16*a22*a33*a45*a54 + - a12*a26*a33*a45*a54 + - a13*a22*a36*a45*a54 + + a12*a23*a36*a45*a54 + + a15*a23*a32*a46*a54 + - a13*a25*a32*a46*a54 + - a15*a22*a33*a46*a54 + + a12*a25*a33*a46*a54 + + a13*a22*a35*a46*a54 + - a12*a23*a35*a46*a54 + + a16*a24*a33*a42*a55 + - a14*a26*a33*a42*a55 + - a16*a23*a34*a42*a55 + + a13*a26*a34*a42*a55 + + a14*a23*a36*a42*a55 + - a13*a24*a36*a42*a55 + - a16*a24*a32*a43*a55 + + a14*a26*a32*a43*a55 + + a16*a22*a34*a43*a55 + - a12*a26*a34*a43*a55 + - a14*a22*a36*a43*a55 + + a12*a24*a36*a43*a55 + + a16*a23*a32*a44*a55 + - a13*a26*a32*a44*a55 + - a16*a22*a33*a44*a55 + + a12*a26*a33*a44*a55 + + a13*a22*a36*a44*a55 + - a12*a23*a36*a44*a55 + - a14*a23*a32*a46*a55 + + a13*a24*a32*a46*a55 + + a14*a22*a33*a46*a55 + - a12*a24*a33*a46*a55 + - a13*a22*a34*a46*a55 + + a12*a23*a34*a46*a55 + - a15*a24*a33*a42*a56 + + a14*a25*a33*a42*a56 + + a15*a23*a34*a42*a56 + - a13*a25*a34*a42*a56 + - a14*a23*a35*a42*a56 + + a13*a24*a35*a42*a56 + + a15*a24*a32*a43*a56 + - a14*a25*a32*a43*a56 + - a15*a22*a34*a43*a56 + + a12*a25*a34*a43*a56 + + a14*a22*a35*a43*a56 + - a12*a24*a35*a43*a56 + - a15*a23*a32*a44*a56 + + a13*a25*a32*a44*a56 + + a15*a22*a33*a44*a56 + - a12*a25*a33*a44*a56 + - a13*a22*a35*a44*a56 + + a12*a23*a35*a44*a56 + + a14*a23*a32*a45*a56 + - a13*a24*a32*a45*a56 + - a14*a22*a33*a45*a56 + + a12*a24*a33*a45*a56 + + a13*a22*a34*a45*a56 + - a12*a23*a34*a45*a56; + cofactor[6] = -a26*a35*a44*a53*a61 + + a25*a36*a44*a53*a61 + + a26*a34*a45*a53*a61 + - a24*a36*a45*a53*a61 + - a25*a34*a46*a53*a61 + + a24*a35*a46*a53*a61 + + a26*a35*a43*a54*a61 + - a25*a36*a43*a54*a61 + - a26*a33*a45*a54*a61 + + a23*a36*a45*a54*a61 + + a25*a33*a46*a54*a61 + - a23*a35*a46*a54*a61 + - a26*a34*a43*a55*a61 + + a24*a36*a43*a55*a61 + + a26*a33*a44*a55*a61 + - a23*a36*a44*a55*a61 + - a24*a33*a46*a55*a61 + + a23*a34*a46*a55*a61 + + a25*a34*a43*a56*a61 + - a24*a35*a43*a56*a61 + - a25*a33*a44*a56*a61 + + a23*a35*a44*a56*a61 + + a24*a33*a45*a56*a61 + - a23*a34*a45*a56*a61 + + a26*a35*a44*a51*a63 + - a25*a36*a44*a51*a63 + - a26*a34*a45*a51*a63 + + a24*a36*a45*a51*a63 + + a25*a34*a46*a51*a63 + - a24*a35*a46*a51*a63 + - a26*a35*a41*a54*a63 + + a25*a36*a41*a54*a63 + + a26*a31*a45*a54*a63 + - a21*a36*a45*a54*a63 + - a25*a31*a46*a54*a63 + + a21*a35*a46*a54*a63 + + a26*a34*a41*a55*a63 + - a24*a36*a41*a55*a63 + - a26*a31*a44*a55*a63 + + a21*a36*a44*a55*a63 + + a24*a31*a46*a55*a63 + - a21*a34*a46*a55*a63 + - a25*a34*a41*a56*a63 + + a24*a35*a41*a56*a63 + + a25*a31*a44*a56*a63 + - a21*a35*a44*a56*a63 + - a24*a31*a45*a56*a63 + + a21*a34*a45*a56*a63 + - a26*a35*a43*a51*a64 + + a25*a36*a43*a51*a64 + + a26*a33*a45*a51*a64 + - a23*a36*a45*a51*a64 + - a25*a33*a46*a51*a64 + + a23*a35*a46*a51*a64 + + a26*a35*a41*a53*a64 + - a25*a36*a41*a53*a64 + - a26*a31*a45*a53*a64 + + a21*a36*a45*a53*a64 + + a25*a31*a46*a53*a64 + - a21*a35*a46*a53*a64 + - a26*a33*a41*a55*a64 + + a23*a36*a41*a55*a64 + + a26*a31*a43*a55*a64 + - a21*a36*a43*a55*a64 + - a23*a31*a46*a55*a64 + + a21*a33*a46*a55*a64 + + a25*a33*a41*a56*a64 + - a23*a35*a41*a56*a64 + - a25*a31*a43*a56*a64 + + a21*a35*a43*a56*a64 + + a23*a31*a45*a56*a64 + - a21*a33*a45*a56*a64 + + a26*a34*a43*a51*a65 + - a24*a36*a43*a51*a65 + - a26*a33*a44*a51*a65 + + a23*a36*a44*a51*a65 + + a24*a33*a46*a51*a65 + - a23*a34*a46*a51*a65 + - a26*a34*a41*a53*a65 + + a24*a36*a41*a53*a65 + + a26*a31*a44*a53*a65 + - a21*a36*a44*a53*a65 + - a24*a31*a46*a53*a65 + + a21*a34*a46*a53*a65 + + a26*a33*a41*a54*a65 + - a23*a36*a41*a54*a65 + - a26*a31*a43*a54*a65 + + a21*a36*a43*a54*a65 + + a23*a31*a46*a54*a65 + - a21*a33*a46*a54*a65 + - a24*a33*a41*a56*a65 + + a23*a34*a41*a56*a65 + + a24*a31*a43*a56*a65 + - a21*a34*a43*a56*a65 + - a23*a31*a44*a56*a65 + + a21*a33*a44*a56*a65 + - a25*a34*a43*a51*a66 + + a24*a35*a43*a51*a66 + + a25*a33*a44*a51*a66 + - a23*a35*a44*a51*a66 + - a24*a33*a45*a51*a66 + + a23*a34*a45*a51*a66 + + a25*a34*a41*a53*a66 + - a24*a35*a41*a53*a66 + - a25*a31*a44*a53*a66 + + a21*a35*a44*a53*a66 + + a24*a31*a45*a53*a66 + - a21*a34*a45*a53*a66 + - a25*a33*a41*a54*a66 + + a23*a35*a41*a54*a66 + + a25*a31*a43*a54*a66 + - a21*a35*a43*a54*a66 + - a23*a31*a45*a54*a66 + + a21*a33*a45*a54*a66 + + a24*a33*a41*a55*a66 + - a23*a34*a41*a55*a66 + - a24*a31*a43*a55*a66 + + a21*a34*a43*a55*a66 + + a23*a31*a44*a55*a66 + - a21*a33*a44*a55*a66; + cofactor[7] = a16*a35*a44*a53*a61 + - a15*a36*a44*a53*a61 + - + a16*a34*a45*a53*a61 + + a14*a36*a45*a53*a61 + + a15* + a34*a46*a53*a61 + - a14*a35*a46*a53*a61 + - a16*a35* + a43*a54*a61 + + a15*a36*a43*a54*a61 + + a16*a33*a45* + a54*a61 + - a13*a36*a45*a54*a61 + - a15*a33*a46*a54* + a61 + + a13*a35*a46*a54*a61 + + a16*a34*a43*a55*a61 + - + a14*a36*a43*a55*a61 + - a16*a33*a44*a55*a61 + + a13* + a36*a44*a55*a61 + + a14*a33*a46*a55*a61 + - a13*a34* + a46*a55*a61 + - a15*a34*a43*a56*a61 + + a14*a35*a43* + a56*a61 + + a15*a33*a44*a56*a61 + - a13*a35*a44*a56* + a61 + - a14*a33*a45*a56*a61 + + a13*a34*a45*a56*a61 + - + a16*a35*a44*a51*a63 + + a15*a36*a44*a51*a63 + + a16* + a34*a45*a51*a63 + - a14*a36*a45*a51*a63 + - a15*a34* + a46*a51*a63 + + a14*a35*a46*a51*a63 + + a16*a35*a41* + a54*a63 + - a15*a36*a41*a54*a63 + - a16*a31*a45*a54* + a63 + + a11*a36*a45*a54*a63 + + a15*a31*a46*a54*a63 + - + a11*a35*a46*a54*a63 + - a16*a34*a41*a55*a63 + + a14* + a36*a41*a55*a63 + + a16*a31*a44*a55*a63 + - a11*a36* + a44*a55*a63 + - a14*a31*a46*a55*a63 + + a11*a34*a46* + a55*a63 + + a15*a34*a41*a56*a63 + - a14*a35*a41*a56* + a63 + - a15*a31*a44*a56*a63 + + a11*a35*a44*a56*a63 + + + a14*a31*a45*a56*a63 + - a11*a34*a45*a56*a63 + + a16* + a35*a43*a51*a64 + - a15*a36*a43*a51*a64 + - a16*a33* + a45*a51*a64 + + a13*a36*a45*a51*a64 + + a15*a33*a46* + a51*a64 + - a13*a35*a46*a51*a64 + - a16*a35*a41*a53* + a64 + + a15*a36*a41*a53*a64 + + a16*a31*a45*a53*a64 + - + a11*a36*a45*a53*a64 + - a15*a31*a46*a53*a64 + + a11* + a35*a46*a53*a64 + + a16*a33*a41*a55*a64 + - a13*a36* + a41*a55*a64 + - a16*a31*a43*a55*a64 + + a11*a36*a43* + a55*a64 + + a13*a31*a46*a55*a64 + - a11*a33*a46*a55* + a64 + - a15*a33*a41*a56*a64 + + a13*a35*a41*a56*a64 + + + a15*a31*a43*a56*a64 + - a11*a35*a43*a56*a64 + - a13* + a31*a45*a56*a64 + + a11*a33*a45*a56*a64 + - a16*a34* + a43*a51*a65 + + a14*a36*a43*a51*a65 + + a16*a33*a44* + a51*a65 + - a13*a36*a44*a51*a65 + - a14*a33*a46*a51* + a65 + + a13*a34*a46*a51*a65 + + a16*a34*a41*a53*a65 + - + a14*a36*a41*a53*a65 + - a16*a31*a44*a53*a65 + + a11* + a36*a44*a53*a65 + + a14*a31*a46*a53*a65 + - a11*a34* + a46*a53*a65 + - a16*a33*a41*a54*a65 + + a13*a36*a41* + a54*a65 + + a16*a31*a43*a54*a65 + - a11*a36*a43*a54* + a65 + - a13*a31*a46*a54*a65 + + a11*a33*a46*a54*a65 + + + a14*a33*a41*a56*a65 + - a13*a34*a41*a56*a65 + - a14* + a31*a43*a56*a65 + + a11*a34*a43*a56*a65 + + a13*a31* + a44*a56*a65 + - a11*a33*a44*a56*a65 + + a15*a34*a43* + a51*a66 + - a14*a35*a43*a51*a66 + - a15*a33*a44*a51* + a66 + + a13*a35*a44*a51*a66 + + a14*a33*a45*a51*a66 + - + a13*a34*a45*a51*a66 + - a15*a34*a41*a53*a66 + + a14* + a35*a41*a53*a66 + + a15*a31*a44*a53*a66 + - a11*a35* + a44*a53*a66 + - a14*a31*a45*a53*a66 + + a11*a34*a45* + a53*a66 + + a15*a33*a41*a54*a66 + - a13*a35*a41*a54* + a66 + - a15*a31*a43*a54*a66 + + a11*a35*a43*a54*a66 + + + a13*a31*a45*a54*a66 + - a11*a33*a45*a54*a66 + - a14* + a33*a41*a55*a66 + + a13*a34*a41*a55*a66 + + a14*a31* + a43*a55*a66 + - a11*a34*a43*a55*a66 + - a13*a31*a44* + a55*a66 + + a11*a33*a44*a55*a66; + cofactor[8] = -a16*a25*a44*a53*a61 + + a15*a26*a44*a53*a61 + + a16*a24*a45*a53*a61 + - a14*a26*a45*a53*a61 + - a15*a24*a46*a53*a61 + + a14*a25*a46*a53*a61 + + a16*a25*a43*a54*a61 + - a15*a26*a43*a54*a61 + - a16*a23*a45*a54*a61 + + a13*a26*a45*a54*a61 + + a15*a23*a46*a54*a61 + - a13*a25*a46*a54*a61 + - a16*a24*a43*a55*a61 + + a14*a26*a43*a55*a61 + + a16*a23*a44*a55*a61 + - a13*a26*a44*a55*a61 + - a14*a23*a46*a55*a61 + + a13*a24*a46*a55*a61 + + a15*a24*a43*a56*a61 + - a14*a25*a43*a56*a61 + - a15*a23*a44*a56*a61 + + a13*a25*a44*a56*a61 + + a14*a23*a45*a56*a61 + - a13*a24*a45*a56*a61 + + a16*a25*a44*a51*a63 + - a15*a26*a44*a51*a63 + - a16*a24*a45*a51*a63 + + a14*a26*a45*a51*a63 + + a15*a24*a46*a51*a63 + - a14*a25*a46*a51*a63 + - a16*a25*a41*a54*a63 + + a15*a26*a41*a54*a63 + + a16*a21*a45*a54*a63 + - a11*a26*a45*a54*a63 + - a15*a21*a46*a54*a63 + + a11*a25*a46*a54*a63 + + a16*a24*a41*a55*a63 + - a14*a26*a41*a55*a63 + - a16*a21*a44*a55*a63 + + a11*a26*a44*a55*a63 + + a14*a21*a46*a55*a63 + - a11*a24*a46*a55*a63 + - a15*a24*a41*a56*a63 + + a14*a25*a41*a56*a63 + + a15*a21*a44*a56*a63 + - a11*a25*a44*a56*a63 + - a14*a21*a45*a56*a63 + + a11*a24*a45*a56*a63 + - a16*a25*a43*a51*a64 + + a15*a26*a43*a51*a64 + + a16*a23*a45*a51*a64 + - a13*a26*a45*a51*a64 + - a15*a23*a46*a51*a64 + + a13*a25*a46*a51*a64 + + a16*a25*a41*a53*a64 + - a15*a26*a41*a53*a64 + - a16*a21*a45*a53*a64 + + a11*a26*a45*a53*a64 + + a15*a21*a46*a53*a64 + - a11*a25*a46*a53*a64 + - a16*a23*a41*a55*a64 + + a13*a26*a41*a55*a64 + + a16*a21*a43*a55*a64 + - a11*a26*a43*a55*a64 + - a13*a21*a46*a55*a64 + + a11*a23*a46*a55*a64 + + a15*a23*a41*a56*a64 + - a13*a25*a41*a56*a64 + - a15*a21*a43*a56*a64 + + a11*a25*a43*a56*a64 + + a13*a21*a45*a56*a64 + - a11*a23*a45*a56*a64 + + a16*a24*a43*a51*a65 + - a14*a26*a43*a51*a65 + - a16*a23*a44*a51*a65 + + a13*a26*a44*a51*a65 + + a14*a23*a46*a51*a65 + - a13*a24*a46*a51*a65 + - a16*a24*a41*a53*a65 + + a14*a26*a41*a53*a65 + + a16*a21*a44*a53*a65 + - a11*a26*a44*a53*a65 + - a14*a21*a46*a53*a65 + + a11*a24*a46*a53*a65 + + a16*a23*a41*a54*a65 + - a13*a26*a41*a54*a65 + - a16*a21*a43*a54*a65 + + a11*a26*a43*a54*a65 + + a13*a21*a46*a54*a65 + - a11*a23*a46*a54*a65 + - a14*a23*a41*a56*a65 + + a13*a24*a41*a56*a65 + + a14*a21*a43*a56*a65 + - a11*a24*a43*a56*a65 + - a13*a21*a44*a56*a65 + + a11*a23*a44*a56*a65 + - a15*a24*a43*a51*a66 + + a14*a25*a43*a51*a66 + + a15*a23*a44*a51*a66 + - a13*a25*a44*a51*a66 + - a14*a23*a45*a51*a66 + + a13*a24*a45*a51*a66 + + a15*a24*a41*a53*a66 + - a14*a25*a41*a53*a66 + - a15*a21*a44*a53*a66 + + a11*a25*a44*a53*a66 + + a14*a21*a45*a53*a66 + - a11*a24*a45*a53*a66 + - a15*a23*a41*a54*a66 + + a13*a25*a41*a54*a66 + + a15*a21*a43*a54*a66 + - a11*a25*a43*a54*a66 + - a13*a21*a45*a54*a66 + + a11*a23*a45*a54*a66 + + a14*a23*a41*a55*a66 + - a13*a24*a41*a55*a66 + - a14*a21*a43*a55*a66 + + a11*a24*a43*a55*a66 + + a13*a21*a44*a55*a66 + - a11*a23*a44*a55*a66; + cofactor[9] = a16*a25*a34*a53*a61 + - a15*a26*a34*a53*a61 + - + a16*a24*a35*a53*a61 + + a14*a26*a35*a53*a61 + + a15* + a24*a36*a53*a61 + - a14*a25*a36*a53*a61 + - a16*a25* + a33*a54*a61 + + a15*a26*a33*a54*a61 + + a16*a23*a35* + a54*a61 + - a13*a26*a35*a54*a61 + - a15*a23*a36*a54* + a61 + + a13*a25*a36*a54*a61 + + a16*a24*a33*a55*a61 + - + a14*a26*a33*a55*a61 + - a16*a23*a34*a55*a61 + + a13* + a26*a34*a55*a61 + + a14*a23*a36*a55*a61 + - a13*a24* + a36*a55*a61 + - a15*a24*a33*a56*a61 + + a14*a25*a33* + a56*a61 + + a15*a23*a34*a56*a61 + - a13*a25*a34*a56* + a61 + - a14*a23*a35*a56*a61 + + a13*a24*a35*a56*a61 + - + a16*a25*a34*a51*a63 + + a15*a26*a34*a51*a63 + + a16* + a24*a35*a51*a63 + - a14*a26*a35*a51*a63 + - a15*a24* + a36*a51*a63 + + a14*a25*a36*a51*a63 + + a16*a25*a31* + a54*a63 + - a15*a26*a31*a54*a63 + - a16*a21*a35*a54* + a63 + + a11*a26*a35*a54*a63 + + a15*a21*a36*a54*a63 + - + a11*a25*a36*a54*a63 + - a16*a24*a31*a55*a63 + + a14* + a26*a31*a55*a63 + + a16*a21*a34*a55*a63 + - a11*a26* + a34*a55*a63 + - a14*a21*a36*a55*a63 + + a11*a24*a36* + a55*a63 + + a15*a24*a31*a56*a63 + - a14*a25*a31*a56* + a63 + - a15*a21*a34*a56*a63 + + a11*a25*a34*a56*a63 + + + a14*a21*a35*a56*a63 + - a11*a24*a35*a56*a63 + + a16* + a25*a33*a51*a64 + - a15*a26*a33*a51*a64 + - a16*a23* + a35*a51*a64 + + a13*a26*a35*a51*a64 + + a15*a23*a36* + a51*a64 + - a13*a25*a36*a51*a64 + - a16*a25*a31*a53* + a64 + + a15*a26*a31*a53*a64 + + a16*a21*a35*a53*a64 + - + a11*a26*a35*a53*a64 + - a15*a21*a36*a53*a64 + + a11* + a25*a36*a53*a64 + + a16*a23*a31*a55*a64 + - a13*a26* + a31*a55*a64 + - a16*a21*a33*a55*a64 + + a11*a26*a33* + a55*a64 + + a13*a21*a36*a55*a64 + - a11*a23*a36*a55* + a64 + - a15*a23*a31*a56*a64 + + a13*a25*a31*a56*a64 + + + a15*a21*a33*a56*a64 + - a11*a25*a33*a56*a64 + - a13* + a21*a35*a56*a64 + + a11*a23*a35*a56*a64 + - a16*a24* + a33*a51*a65 + + a14*a26*a33*a51*a65 + + a16*a23*a34* + a51*a65 + - a13*a26*a34*a51*a65 + - a14*a23*a36*a51* + a65 + + a13*a24*a36*a51*a65 + + a16*a24*a31*a53*a65 + - + a14*a26*a31*a53*a65 + - a16*a21*a34*a53*a65 + + a11* + a26*a34*a53*a65 + + a14*a21*a36*a53*a65 + - a11*a24* + a36*a53*a65 + - a16*a23*a31*a54*a65 + + a13*a26*a31* + a54*a65 + + a16*a21*a33*a54*a65 + - a11*a26*a33*a54* + a65 + - a13*a21*a36*a54*a65 + + a11*a23*a36*a54*a65 + + + a14*a23*a31*a56*a65 + - a13*a24*a31*a56*a65 + - a14* + a21*a33*a56*a65 + + a11*a24*a33*a56*a65 + + a13*a21* + a34*a56*a65 + - a11*a23*a34*a56*a65 + + a15*a24*a33* + a51*a66 + - a14*a25*a33*a51*a66 + - a15*a23*a34*a51* + a66 + + a13*a25*a34*a51*a66 + + a14*a23*a35*a51*a66 + - + a13*a24*a35*a51*a66 + - a15*a24*a31*a53*a66 + + a14* + a25*a31*a53*a66 + + a15*a21*a34*a53*a66 + - a11*a25* + a34*a53*a66 + - a14*a21*a35*a53*a66 + + a11*a24*a35* + a53*a66 + + a15*a23*a31*a54*a66 + - a13*a25*a31*a54* + a66 + - a15*a21*a33*a54*a66 + + a11*a25*a33*a54*a66 + + + a13*a21*a35*a54*a66 + - a11*a23*a35*a54*a66 + - a14* + a23*a31*a55*a66 + + a13*a24*a31*a55*a66 + + a14*a21* + a33*a55*a66 + - a11*a24*a33*a55*a66 + - a13*a21*a34* + a55*a66 + + a11*a23*a34*a55*a66; + cofactor[10] = -a16*a25*a34*a43*a61 + + a15*a26*a34*a43*a61 + + a16*a24*a35*a43*a61 + - a14*a26*a35*a43*a61 + - a15*a24*a36*a43*a61 + + a14*a25*a36*a43*a61 + + a16*a25*a33*a44*a61 + - a15*a26*a33*a44*a61 + - a16*a23*a35*a44*a61 + + a13*a26*a35*a44*a61 + + a15*a23*a36*a44*a61 + - a13*a25*a36*a44*a61 + - a16*a24*a33*a45*a61 + + a14*a26*a33*a45*a61 + + a16*a23*a34*a45*a61 + - a13*a26*a34*a45*a61 + - a14*a23*a36*a45*a61 + + a13*a24*a36*a45*a61 + + a15*a24*a33*a46*a61 + - a14*a25*a33*a46*a61 + - a15*a23*a34*a46*a61 + + a13*a25*a34*a46*a61 + + a14*a23*a35*a46*a61 + - a13*a24*a35*a46*a61 + + a16*a25*a34*a41*a63 + - a15*a26*a34*a41*a63 + - a16*a24*a35*a41*a63 + + a14*a26*a35*a41*a63 + + a15*a24*a36*a41*a63 + - a14*a25*a36*a41*a63 + - a16*a25*a31*a44*a63 + + a15*a26*a31*a44*a63 + + a16*a21*a35*a44*a63 + - a11*a26*a35*a44*a63 + - a15*a21*a36*a44*a63 + + a11*a25*a36*a44*a63 + + a16*a24*a31*a45*a63 + - a14*a26*a31*a45*a63 + - a16*a21*a34*a45*a63 + + a11*a26*a34*a45*a63 + + a14*a21*a36*a45*a63 + - a11*a24*a36*a45*a63 + - a15*a24*a31*a46*a63 + + a14*a25*a31*a46*a63 + + a15*a21*a34*a46*a63 + - a11*a25*a34*a46*a63 + - a14*a21*a35*a46*a63 + + a11*a24*a35*a46*a63 + - a16*a25*a33*a41*a64 + + a15*a26*a33*a41*a64 + + a16*a23*a35*a41*a64 + - a13*a26*a35*a41*a64 + - a15*a23*a36*a41*a64 + + a13*a25*a36*a41*a64 + + a16*a25*a31*a43*a64 + - a15*a26*a31*a43*a64 + - a16*a21*a35*a43*a64 + + a11*a26*a35*a43*a64 + + a15*a21*a36*a43*a64 + - a11*a25*a36*a43*a64 + - a16*a23*a31*a45*a64 + + a13*a26*a31*a45*a64 + + a16*a21*a33*a45*a64 + - a11*a26*a33*a45*a64 + - a13*a21*a36*a45*a64 + + a11*a23*a36*a45*a64 + + a15*a23*a31*a46*a64 + - a13*a25*a31*a46*a64 + - a15*a21*a33*a46*a64 + + a11*a25*a33*a46*a64 + + a13*a21*a35*a46*a64 + - a11*a23*a35*a46*a64 + + a16*a24*a33*a41*a65 + - a14*a26*a33*a41*a65 + - a16*a23*a34*a41*a65 + + a13*a26*a34*a41*a65 + + a14*a23*a36*a41*a65 + - a13*a24*a36*a41*a65 + - a16*a24*a31*a43*a65 + + a14*a26*a31*a43*a65 + + a16*a21*a34*a43*a65 + - a11*a26*a34*a43*a65 + - a14*a21*a36*a43*a65 + + a11*a24*a36*a43*a65 + + a16*a23*a31*a44*a65 + - a13*a26*a31*a44*a65 + - a16*a21*a33*a44*a65 + + a11*a26*a33*a44*a65 + + a13*a21*a36*a44*a65 + - a11*a23*a36*a44*a65 + - a14*a23*a31*a46*a65 + + a13*a24*a31*a46*a65 + + a14*a21*a33*a46*a65 + - a11*a24*a33*a46*a65 + - a13*a21*a34*a46*a65 + + a11*a23*a34*a46*a65 + - a15*a24*a33*a41*a66 + + a14*a25*a33*a41*a66 + + a15*a23*a34*a41*a66 + - a13*a25*a34*a41*a66 + - a14*a23*a35*a41*a66 + + a13*a24*a35*a41*a66 + + a15*a24*a31*a43*a66 + - a14*a25*a31*a43*a66 + - a15*a21*a34*a43*a66 + + a11*a25*a34*a43*a66 + + a14*a21*a35*a43*a66 + - a11*a24*a35*a43*a66 + - a15*a23*a31*a44*a66 + + a13*a25*a31*a44*a66 + + a15*a21*a33*a44*a66 + - a11*a25*a33*a44*a66 + - a13*a21*a35*a44*a66 + + a11*a23*a35*a44*a66 + + a14*a23*a31*a45*a66 + - a13*a24*a31*a45*a66 + - a14*a21*a33*a45*a66 + + a11*a24*a33*a45*a66 + + a13*a21*a34*a45*a66 + - a11*a23*a34*a45*a66; + cofactor[11] = a16*a25*a34*a43*a51 + - a15*a26*a34*a43*a51 + - a16*a24*a35*a43*a51 + + a14*a26*a35*a43*a51 + + a15*a24*a36*a43*a51 + - a14*a25*a36*a43*a51 + - a16*a25*a33*a44*a51 + + a15*a26*a33*a44*a51 + + a16*a23*a35*a44*a51 + - a13*a26*a35*a44*a51 + - a15*a23*a36*a44*a51 + + a13*a25*a36*a44*a51 + + a16*a24*a33*a45*a51 + - a14*a26*a33*a45*a51 + - a16*a23*a34*a45*a51 + + a13*a26*a34*a45*a51 + + a14*a23*a36*a45*a51 + - a13*a24*a36*a45*a51 + - a15*a24*a33*a46*a51 + + a14*a25*a33*a46*a51 + + a15*a23*a34*a46*a51 + - a13*a25*a34*a46*a51 + - a14*a23*a35*a46*a51 + + a13*a24*a35*a46*a51 + - a16*a25*a34*a41*a53 + + a15*a26*a34*a41*a53 + + a16*a24*a35*a41*a53 + - a14*a26*a35*a41*a53 + - a15*a24*a36*a41*a53 + + a14*a25*a36*a41*a53 + + a16*a25*a31*a44*a53 + - a15*a26*a31*a44*a53 + - a16*a21*a35*a44*a53 + + a11*a26*a35*a44*a53 + + a15*a21*a36*a44*a53 + - a11*a25*a36*a44*a53 + - a16*a24*a31*a45*a53 + + a14*a26*a31*a45*a53 + + a16*a21*a34*a45*a53 + - a11*a26*a34*a45*a53 + - a14*a21*a36*a45*a53 + + a11*a24*a36*a45*a53 + + a15*a24*a31*a46*a53 + - a14*a25*a31*a46*a53 + - a15*a21*a34*a46*a53 + + a11*a25*a34*a46*a53 + + a14*a21*a35*a46*a53 + - a11*a24*a35*a46*a53 + + a16*a25*a33*a41*a54 + - a15*a26*a33*a41*a54 + - a16*a23*a35*a41*a54 + + a13*a26*a35*a41*a54 + + a15*a23*a36*a41*a54 + - a13*a25*a36*a41*a54 + - a16*a25*a31*a43*a54 + + a15*a26*a31*a43*a54 + + a16*a21*a35*a43*a54 + - a11*a26*a35*a43*a54 + - a15*a21*a36*a43*a54 + + a11*a25*a36*a43*a54 + + a16*a23*a31*a45*a54 + - a13*a26*a31*a45*a54 + - a16*a21*a33*a45*a54 + + a11*a26*a33*a45*a54 + + a13*a21*a36*a45*a54 + - a11*a23*a36*a45*a54 + - a15*a23*a31*a46*a54 + + a13*a25*a31*a46*a54 + + a15*a21*a33*a46*a54 + - a11*a25*a33*a46*a54 + - a13*a21*a35*a46*a54 + + a11*a23*a35*a46*a54 + - a16*a24*a33*a41*a55 + + a14*a26*a33*a41*a55 + + a16*a23*a34*a41*a55 + - a13*a26*a34*a41*a55 + - a14*a23*a36*a41*a55 + + a13*a24*a36*a41*a55 + + a16*a24*a31*a43*a55 + - a14*a26*a31*a43*a55 + - a16*a21*a34*a43*a55 + + a11*a26*a34*a43*a55 + + a14*a21*a36*a43*a55 + - a11*a24*a36*a43*a55 + - a16*a23*a31*a44*a55 + + a13*a26*a31*a44*a55 + + a16*a21*a33*a44*a55 + - a11*a26*a33*a44*a55 + - a13*a21*a36*a44*a55 + + a11*a23*a36*a44*a55 + + a14*a23*a31*a46*a55 + - a13*a24*a31*a46*a55 + - a14*a21*a33*a46*a55 + + a11*a24*a33*a46*a55 + + a13*a21*a34*a46*a55 + - a11*a23*a34*a46*a55 + + a15*a24*a33*a41*a56 + - a14*a25*a33*a41*a56 + - a15*a23*a34*a41*a56 + + a13*a25*a34*a41*a56 + + a14*a23*a35*a41*a56 + - a13*a24*a35*a41*a56 + - a15*a24*a31*a43*a56 + + a14*a25*a31*a43*a56 + + a15*a21*a34*a43*a56 + - a11*a25*a34*a43*a56 + - a14*a21*a35*a43*a56 + + a11*a24*a35*a43*a56 + + a15*a23*a31*a44*a56 + - a13*a25*a31*a44*a56 + - a15*a21*a33*a44*a56 + + a11*a25*a33*a44*a56 + + a13*a21*a35*a44*a56 + - a11*a23*a35*a44*a56 + - a14*a23*a31*a45*a56 + + a13*a24*a31*a45*a56 + + a14*a21*a33*a45*a56 + - a11*a24*a33*a45*a56 + - a13*a21*a34*a45*a56 + + a11*a23*a34*a45*a56; + cofactor[12] = a26*a35*a44*a52*a61 + - a25*a36*a44*a52*a61 + - a26*a34*a45*a52*a61 + + a24*a36*a45*a52*a61 + + a25*a34*a46*a52*a61 + - a24*a35*a46*a52*a61 + - a26*a35*a42*a54*a61 + + a25*a36*a42*a54*a61 + + a26*a32*a45*a54*a61 + - a22*a36*a45*a54*a61 + - a25*a32*a46*a54*a61 + + a22*a35*a46*a54*a61 + + a26*a34*a42*a55*a61 + - a24*a36*a42*a55*a61 + - a26*a32*a44*a55*a61 + + a22*a36*a44*a55*a61 + + a24*a32*a46*a55*a61 + - a22*a34*a46*a55*a61 + - a25*a34*a42*a56*a61 + + a24*a35*a42*a56*a61 + + a25*a32*a44*a56*a61 + - a22*a35*a44*a56*a61 + - a24*a32*a45*a56*a61 + + a22*a34*a45*a56*a61 + - a26*a35*a44*a51*a62 + + a25*a36*a44*a51*a62 + + a26*a34*a45*a51*a62 + - a24*a36*a45*a51*a62 + - a25*a34*a46*a51*a62 + + a24*a35*a46*a51*a62 + + a26*a35*a41*a54*a62 + - a25*a36*a41*a54*a62 + - a26*a31*a45*a54*a62 + + a21*a36*a45*a54*a62 + + a25*a31*a46*a54*a62 + - a21*a35*a46*a54*a62 + - a26*a34*a41*a55*a62 + + a24*a36*a41*a55*a62 + + a26*a31*a44*a55*a62 + - a21*a36*a44*a55*a62 + - a24*a31*a46*a55*a62 + + a21*a34*a46*a55*a62 + + a25*a34*a41*a56*a62 + - a24*a35*a41*a56*a62 + - a25*a31*a44*a56*a62 + + a21*a35*a44*a56*a62 + + a24*a31*a45*a56*a62 + - a21*a34*a45*a56*a62 + + a26*a35*a42*a51*a64 + - a25*a36*a42*a51*a64 + - a26*a32*a45*a51*a64 + + a22*a36*a45*a51*a64 + + a25*a32*a46*a51*a64 + - a22*a35*a46*a51*a64 + - a26*a35*a41*a52*a64 + + a25*a36*a41*a52*a64 + + a26*a31*a45*a52*a64 + - a21*a36*a45*a52*a64 + - a25*a31*a46*a52*a64 + + a21*a35*a46*a52*a64 + + a26*a32*a41*a55*a64 + - a22*a36*a41*a55*a64 + - a26*a31*a42*a55*a64 + + a21*a36*a42*a55*a64 + + a22*a31*a46*a55*a64 + - a21*a32*a46*a55*a64 + - a25*a32*a41*a56*a64 + + a22*a35*a41*a56*a64 + + a25*a31*a42*a56*a64 + - a21*a35*a42*a56*a64 + - a22*a31*a45*a56*a64 + + a21*a32*a45*a56*a64 + - a26*a34*a42*a51*a65 + + a24*a36*a42*a51*a65 + + a26*a32*a44*a51*a65 + - a22*a36*a44*a51*a65 + - a24*a32*a46*a51*a65 + + a22*a34*a46*a51*a65 + + a26*a34*a41*a52*a65 + - a24*a36*a41*a52*a65 + - a26*a31*a44*a52*a65 + + a21*a36*a44*a52*a65 + + a24*a31*a46*a52*a65 + - a21*a34*a46*a52*a65 + - a26*a32*a41*a54*a65 + + a22*a36*a41*a54*a65 + + a26*a31*a42*a54*a65 + - a21*a36*a42*a54*a65 + - a22*a31*a46*a54*a65 + + a21*a32*a46*a54*a65 + + a24*a32*a41*a56*a65 + - a22*a34*a41*a56*a65 + - a24*a31*a42*a56*a65 + + a21*a34*a42*a56*a65 + + a22*a31*a44*a56*a65 + - a21*a32*a44*a56*a65 + + a25*a34*a42*a51*a66 + - a24*a35*a42*a51*a66 + - a25*a32*a44*a51*a66 + + a22*a35*a44*a51*a66 + + a24*a32*a45*a51*a66 + - a22*a34*a45*a51*a66 + - a25*a34*a41*a52*a66 + + a24*a35*a41*a52*a66 + + a25*a31*a44*a52*a66 + - a21*a35*a44*a52*a66 + - a24*a31*a45*a52*a66 + + a21*a34*a45*a52*a66 + + a25*a32*a41*a54*a66 + - a22*a35*a41*a54*a66 + - a25*a31*a42*a54*a66 + + a21*a35*a42*a54*a66 + + a22*a31*a45*a54*a66 + - a21*a32*a45*a54*a66 + - a24*a32*a41*a55*a66 + + a22*a34*a41*a55*a66 + + a24*a31*a42*a55*a66 + - a21*a34*a42*a55*a66 + - a22*a31*a44*a55*a66 + + a21*a32*a44*a55*a66; + cofactor[13] = -a16*a35*a44*a52*a61 + + a15*a36*a44*a52*a61 + + a16*a34*a45*a52*a61 + - a14*a36*a45*a52*a61 + - a15*a34*a46*a52*a61 + + a14*a35*a46*a52*a61 + + a16*a35*a42*a54*a61 + - a15*a36*a42*a54*a61 + - a16*a32*a45*a54*a61 + + a12*a36*a45*a54*a61 + + a15*a32*a46*a54*a61 + - a12*a35*a46*a54*a61 + - a16*a34*a42*a55*a61 + + a14*a36*a42*a55*a61 + + a16*a32*a44*a55*a61 + - a12*a36*a44*a55*a61 + - a14*a32*a46*a55*a61 + + a12*a34*a46*a55*a61 + + a15*a34*a42*a56*a61 + - a14*a35*a42*a56*a61 + - a15*a32*a44*a56*a61 + + a12*a35*a44*a56*a61 + + a14*a32*a45*a56*a61 + - a12*a34*a45*a56*a61 + + a16*a35*a44*a51*a62 + - a15*a36*a44*a51*a62 + - a16*a34*a45*a51*a62 + + a14*a36*a45*a51*a62 + + a15*a34*a46*a51*a62 + - a14*a35*a46*a51*a62 + - a16*a35*a41*a54*a62 + + a15*a36*a41*a54*a62 + + a16*a31*a45*a54*a62 + - a11*a36*a45*a54*a62 + - a15*a31*a46*a54*a62 + + a11*a35*a46*a54*a62 + + a16*a34*a41*a55*a62 + - a14*a36*a41*a55*a62 + - a16*a31*a44*a55*a62 + + a11*a36*a44*a55*a62 + + a14*a31*a46*a55*a62 + - a11*a34*a46*a55*a62 + - a15*a34*a41*a56*a62 + + a14*a35*a41*a56*a62 + + a15*a31*a44*a56*a62 + - a11*a35*a44*a56*a62 + - a14*a31*a45*a56*a62 + + a11*a34*a45*a56*a62 + - a16*a35*a42*a51*a64 + + a15*a36*a42*a51*a64 + + a16*a32*a45*a51*a64 + - a12*a36*a45*a51*a64 + - a15*a32*a46*a51*a64 + + a12*a35*a46*a51*a64 + + a16*a35*a41*a52*a64 + - a15*a36*a41*a52*a64 + - a16*a31*a45*a52*a64 + + a11*a36*a45*a52*a64 + + a15*a31*a46*a52*a64 + - a11*a35*a46*a52*a64 + - a16*a32*a41*a55*a64 + + a12*a36*a41*a55*a64 + + a16*a31*a42*a55*a64 + - a11*a36*a42*a55*a64 + - a12*a31*a46*a55*a64 + + a11*a32*a46*a55*a64 + + a15*a32*a41*a56*a64 + - a12*a35*a41*a56*a64 + - a15*a31*a42*a56*a64 + + a11*a35*a42*a56*a64 + + a12*a31*a45*a56*a64 + - a11*a32*a45*a56*a64 + + a16*a34*a42*a51*a65 + - a14*a36*a42*a51*a65 + - a16*a32*a44*a51*a65 + + a12*a36*a44*a51*a65 + + a14*a32*a46*a51*a65 + - a12*a34*a46*a51*a65 + - a16*a34*a41*a52*a65 + + a14*a36*a41*a52*a65 + + a16*a31*a44*a52*a65 + - a11*a36*a44*a52*a65 + - a14*a31*a46*a52*a65 + + a11*a34*a46*a52*a65 + + a16*a32*a41*a54*a65 + - a12*a36*a41*a54*a65 + - a16*a31*a42*a54*a65 + + a11*a36*a42*a54*a65 + + a12*a31*a46*a54*a65 + - a11*a32*a46*a54*a65 + - a14*a32*a41*a56*a65 + + a12*a34*a41*a56*a65 + + a14*a31*a42*a56*a65 + - a11*a34*a42*a56*a65 + - a12*a31*a44*a56*a65 + + a11*a32*a44*a56*a65 + - a15*a34*a42*a51*a66 + + a14*a35*a42*a51*a66 + + a15*a32*a44*a51*a66 + - a12*a35*a44*a51*a66 + - a14*a32*a45*a51*a66 + + a12*a34*a45*a51*a66 + + a15*a34*a41*a52*a66 + - a14*a35*a41*a52*a66 + - a15*a31*a44*a52*a66 + + a11*a35*a44*a52*a66 + + a14*a31*a45*a52*a66 + - a11*a34*a45*a52*a66 + - a15*a32*a41*a54*a66 + + a12*a35*a41*a54*a66 + + a15*a31*a42*a54*a66 + - a11*a35*a42*a54*a66 + - a12*a31*a45*a54*a66 + + a11*a32*a45*a54*a66 + + a14*a32*a41*a55*a66 + - a12*a34*a41*a55*a66 + - a14*a31*a42*a55*a66 + + a11*a34*a42*a55*a66 + + a12*a31*a44*a55*a66 + - a11*a32*a44*a55*a66; + cofactor[14] = a16*a25*a44*a52*a61 + - a15*a26*a44*a52*a61 + - a16*a24*a45*a52*a61 + + a14*a26*a45*a52*a61 + + a15*a24*a46*a52*a61 + - a14*a25*a46*a52*a61 + - a16*a25*a42*a54*a61 + + a15*a26*a42*a54*a61 + + a16*a22*a45*a54*a61 + - a12*a26*a45*a54*a61 + - a15*a22*a46*a54*a61 + + a12*a25*a46*a54*a61 + + a16*a24*a42*a55*a61 + - a14*a26*a42*a55*a61 + - a16*a22*a44*a55*a61 + + a12*a26*a44*a55*a61 + + a14*a22*a46*a55*a61 + - a12*a24*a46*a55*a61 + - a15*a24*a42*a56*a61 + + a14*a25*a42*a56*a61 + + a15*a22*a44*a56*a61 + - a12*a25*a44*a56*a61 + - a14*a22*a45*a56*a61 + + a12*a24*a45*a56*a61 + - a16*a25*a44*a51*a62 + + a15*a26*a44*a51*a62 + + a16*a24*a45*a51*a62 + - a14*a26*a45*a51*a62 + - a15*a24*a46*a51*a62 + + a14*a25*a46*a51*a62 + + a16*a25*a41*a54*a62 + - a15*a26*a41*a54*a62 + - a16*a21*a45*a54*a62 + + a11*a26*a45*a54*a62 + + a15*a21*a46*a54*a62 + - a11*a25*a46*a54*a62 + - a16*a24*a41*a55*a62 + + a14*a26*a41*a55*a62 + + a16*a21*a44*a55*a62 + - a11*a26*a44*a55*a62 + - a14*a21*a46*a55*a62 + + a11*a24*a46*a55*a62 + + a15*a24*a41*a56*a62 + - a14*a25*a41*a56*a62 + - a15*a21*a44*a56*a62 + + a11*a25*a44*a56*a62 + + a14*a21*a45*a56*a62 + - a11*a24*a45*a56*a62 + + a16*a25*a42*a51*a64 + - a15*a26*a42*a51*a64 + - a16*a22*a45*a51*a64 + + a12*a26*a45*a51*a64 + + a15*a22*a46*a51*a64 + - a12*a25*a46*a51*a64 + - a16*a25*a41*a52*a64 + + a15*a26*a41*a52*a64 + + a16*a21*a45*a52*a64 + - a11*a26*a45*a52*a64 + - a15*a21*a46*a52*a64 + + a11*a25*a46*a52*a64 + + a16*a22*a41*a55*a64 + - a12*a26*a41*a55*a64 + - a16*a21*a42*a55*a64 + + a11*a26*a42*a55*a64 + + a12*a21*a46*a55*a64 + - a11*a22*a46*a55*a64 + - a15*a22*a41*a56*a64 + + a12*a25*a41*a56*a64 + + a15*a21*a42*a56*a64 + - a11*a25*a42*a56*a64 + - a12*a21*a45*a56*a64 + + a11*a22*a45*a56*a64 + - a16*a24*a42*a51*a65 + + a14*a26*a42*a51*a65 + + a16*a22*a44*a51*a65 + - a12*a26*a44*a51*a65 + - a14*a22*a46*a51*a65 + + a12*a24*a46*a51*a65 + + a16*a24*a41*a52*a65 + - a14*a26*a41*a52*a65 + - a16*a21*a44*a52*a65 + + a11*a26*a44*a52*a65 + + a14*a21*a46*a52*a65 + - a11*a24*a46*a52*a65 + - a16*a22*a41*a54*a65 + + a12*a26*a41*a54*a65 + + a16*a21*a42*a54*a65 + - a11*a26*a42*a54*a65 + - a12*a21*a46*a54*a65 + + a11*a22*a46*a54*a65 + + a14*a22*a41*a56*a65 + - a12*a24*a41*a56*a65 + - a14*a21*a42*a56*a65 + + a11*a24*a42*a56*a65 + + a12*a21*a44*a56*a65 + - a11*a22*a44*a56*a65 + + a15*a24*a42*a51*a66 + - a14*a25*a42*a51*a66 + - a15*a22*a44*a51*a66 + + a12*a25*a44*a51*a66 + + a14*a22*a45*a51*a66 + - a12*a24*a45*a51*a66 + - a15*a24*a41*a52*a66 + + a14*a25*a41*a52*a66 + + a15*a21*a44*a52*a66 + - a11*a25*a44*a52*a66 + - a14*a21*a45*a52*a66 + + a11*a24*a45*a52*a66 + + a15*a22*a41*a54*a66 + - a12*a25*a41*a54*a66 + - a15*a21*a42*a54*a66 + + a11*a25*a42*a54*a66 + + a12*a21*a45*a54*a66 + - a11*a22*a45*a54*a66 + - a14*a22*a41*a55*a66 + + a12*a24*a41*a55*a66 + + a14*a21*a42*a55*a66 + - a11*a24*a42*a55*a66 + - a12*a21*a44*a55*a66 + + a11*a22*a44*a55*a66; + cofactor[15] = -a16*a25*a34*a52*a61 + + a15*a26*a34*a52*a61 + + a16*a24*a35*a52*a61 + - a14*a26*a35*a52*a61 + - a15*a24*a36*a52*a61 + + a14*a25*a36*a52*a61 + + a16*a25*a32*a54*a61 + - a15*a26*a32*a54*a61 + - a16*a22*a35*a54*a61 + + a12*a26*a35*a54*a61 + + a15*a22*a36*a54*a61 + - a12*a25*a36*a54*a61 + - a16*a24*a32*a55*a61 + + a14*a26*a32*a55*a61 + + a16*a22*a34*a55*a61 + - a12*a26*a34*a55*a61 + - a14*a22*a36*a55*a61 + + a12*a24*a36*a55*a61 + + a15*a24*a32*a56*a61 + - a14*a25*a32*a56*a61 + - a15*a22*a34*a56*a61 + + a12*a25*a34*a56*a61 + + a14*a22*a35*a56*a61 + - a12*a24*a35*a56*a61 + + a16*a25*a34*a51*a62 + - a15*a26*a34*a51*a62 + - a16*a24*a35*a51*a62 + + a14*a26*a35*a51*a62 + + a15*a24*a36*a51*a62 + - a14*a25*a36*a51*a62 + - a16*a25*a31*a54*a62 + + a15*a26*a31*a54*a62 + + a16*a21*a35*a54*a62 + - a11*a26*a35*a54*a62 + - a15*a21*a36*a54*a62 + + a11*a25*a36*a54*a62 + + a16*a24*a31*a55*a62 + - a14*a26*a31*a55*a62 + - a16*a21*a34*a55*a62 + + a11*a26*a34*a55*a62 + + a14*a21*a36*a55*a62 + - a11*a24*a36*a55*a62 + - a15*a24*a31*a56*a62 + + a14*a25*a31*a56*a62 + + a15*a21*a34*a56*a62 + - a11*a25*a34*a56*a62 + - a14*a21*a35*a56*a62 + + a11*a24*a35*a56*a62 + - a16*a25*a32*a51*a64 + + a15*a26*a32*a51*a64 + + a16*a22*a35*a51*a64 + - a12*a26*a35*a51*a64 + - a15*a22*a36*a51*a64 + + a12*a25*a36*a51*a64 + + a16*a25*a31*a52*a64 + - a15*a26*a31*a52*a64 + - a16*a21*a35*a52*a64 + + a11*a26*a35*a52*a64 + + a15*a21*a36*a52*a64 + - a11*a25*a36*a52*a64 + - a16*a22*a31*a55*a64 + + a12*a26*a31*a55*a64 + + a16*a21*a32*a55*a64 + - a11*a26*a32*a55*a64 + - a12*a21*a36*a55*a64 + + a11*a22*a36*a55*a64 + + a15*a22*a31*a56*a64 + - a12*a25*a31*a56*a64 + - a15*a21*a32*a56*a64 + + a11*a25*a32*a56*a64 + + a12*a21*a35*a56*a64 + - a11*a22*a35*a56*a64 + + a16*a24*a32*a51*a65 + - a14*a26*a32*a51*a65 + - a16*a22*a34*a51*a65 + + a12*a26*a34*a51*a65 + + a14*a22*a36*a51*a65 + - a12*a24*a36*a51*a65 + - a16*a24*a31*a52*a65 + + a14*a26*a31*a52*a65 + + a16*a21*a34*a52*a65 + - a11*a26*a34*a52*a65 + - a14*a21*a36*a52*a65 + + a11*a24*a36*a52*a65 + + a16*a22*a31*a54*a65 + - a12*a26*a31*a54*a65 + - a16*a21*a32*a54*a65 + + a11*a26*a32*a54*a65 + + a12*a21*a36*a54*a65 + - a11*a22*a36*a54*a65 + - a14*a22*a31*a56*a65 + + a12*a24*a31*a56*a65 + + a14*a21*a32*a56*a65 + - a11*a24*a32*a56*a65 + - a12*a21*a34*a56*a65 + + a11*a22*a34*a56*a65 + - a15*a24*a32*a51*a66 + + a14*a25*a32*a51*a66 + + a15*a22*a34*a51*a66 + - a12*a25*a34*a51*a66 + - a14*a22*a35*a51*a66 + + a12*a24*a35*a51*a66 + + a15*a24*a31*a52*a66 + - a14*a25*a31*a52*a66 + - a15*a21*a34*a52*a66 + + a11*a25*a34*a52*a66 + + a14*a21*a35*a52*a66 + - a11*a24*a35*a52*a66 + - a15*a22*a31*a54*a66 + + a12*a25*a31*a54*a66 + + a15*a21*a32*a54*a66 + - a11*a25*a32*a54*a66 + - a12*a21*a35*a54*a66 + + a11*a22*a35*a54*a66 + + a14*a22*a31*a55*a66 + - a12*a24*a31*a55*a66 + - a14*a21*a32*a55*a66 + + a11*a24*a32*a55*a66 + + a12*a21*a34*a55*a66 + - a11*a22*a34*a55*a66; + cofactor[16] = a16*a25*a34*a42*a61 + - a15*a26*a34*a42*a61 + - a16*a24*a35*a42*a61 + + a14*a26*a35*a42*a61 + + a15*a24*a36*a42*a61 + - a14*a25*a36*a42*a61 + - a16*a25*a32*a44*a61 + + a15*a26*a32*a44*a61 + + a16*a22*a35*a44*a61 + - a12*a26*a35*a44*a61 + - a15*a22*a36*a44*a61 + + a12*a25*a36*a44*a61 + + a16*a24*a32*a45*a61 + - a14*a26*a32*a45*a61 + - a16*a22*a34*a45*a61 + + a12*a26*a34*a45*a61 + + a14*a22*a36*a45*a61 + - a12*a24*a36*a45*a61 + - a15*a24*a32*a46*a61 + + a14*a25*a32*a46*a61 + + a15*a22*a34*a46*a61 + - a12*a25*a34*a46*a61 + - a14*a22*a35*a46*a61 + + a12*a24*a35*a46*a61 + - a16*a25*a34*a41*a62 + + a15*a26*a34*a41*a62 + + a16*a24*a35*a41*a62 + - a14*a26*a35*a41*a62 + - a15*a24*a36*a41*a62 + + a14*a25*a36*a41*a62 + + a16*a25*a31*a44*a62 + - a15*a26*a31*a44*a62 + - a16*a21*a35*a44*a62 + + a11*a26*a35*a44*a62 + + a15*a21*a36*a44*a62 + - a11*a25*a36*a44*a62 + - a16*a24*a31*a45*a62 + + a14*a26*a31*a45*a62 + + a16*a21*a34*a45*a62 + - a11*a26*a34*a45*a62 + - a14*a21*a36*a45*a62 + + a11*a24*a36*a45*a62 + + a15*a24*a31*a46*a62 + - a14*a25*a31*a46*a62 + - a15*a21*a34*a46*a62 + + a11*a25*a34*a46*a62 + + a14*a21*a35*a46*a62 + - a11*a24*a35*a46*a62 + + a16*a25*a32*a41*a64 + - a15*a26*a32*a41*a64 + - a16*a22*a35*a41*a64 + + a12*a26*a35*a41*a64 + + a15*a22*a36*a41*a64 + - a12*a25*a36*a41*a64 + - a16*a25*a31*a42*a64 + + a15*a26*a31*a42*a64 + + a16*a21*a35*a42*a64 + - a11*a26*a35*a42*a64 + - a15*a21*a36*a42*a64 + + a11*a25*a36*a42*a64 + + a16*a22*a31*a45*a64 + - a12*a26*a31*a45*a64 + - a16*a21*a32*a45*a64 + + a11*a26*a32*a45*a64 + + a12*a21*a36*a45*a64 + - a11*a22*a36*a45*a64 + - a15*a22*a31*a46*a64 + + a12*a25*a31*a46*a64 + + a15*a21*a32*a46*a64 + - a11*a25*a32*a46*a64 + - a12*a21*a35*a46*a64 + + a11*a22*a35*a46*a64 + - a16*a24*a32*a41*a65 + + a14*a26*a32*a41*a65 + + a16*a22*a34*a41*a65 + - a12*a26*a34*a41*a65 + - a14*a22*a36*a41*a65 + + a12*a24*a36*a41*a65 + + a16*a24*a31*a42*a65 + - a14*a26*a31*a42*a65 + - a16*a21*a34*a42*a65 + + a11*a26*a34*a42*a65 + + a14*a21*a36*a42*a65 + - a11*a24*a36*a42*a65 + - a16*a22*a31*a44*a65 + + a12*a26*a31*a44*a65 + + a16*a21*a32*a44*a65 + - a11*a26*a32*a44*a65 + - a12*a21*a36*a44*a65 + + a11*a22*a36*a44*a65 + + a14*a22*a31*a46*a65 + - a12*a24*a31*a46*a65 + - a14*a21*a32*a46*a65 + + a11*a24*a32*a46*a65 + + a12*a21*a34*a46*a65 + - a11*a22*a34*a46*a65 + + a15*a24*a32*a41*a66 + - a14*a25*a32*a41*a66 + - a15*a22*a34*a41*a66 + + a12*a25*a34*a41*a66 + + a14*a22*a35*a41*a66 + - a12*a24*a35*a41*a66 + - a15*a24*a31*a42*a66 + + a14*a25*a31*a42*a66 + + a15*a21*a34*a42*a66 + - a11*a25*a34*a42*a66 + - a14*a21*a35*a42*a66 + + a11*a24*a35*a42*a66 + + a15*a22*a31*a44*a66 + - a12*a25*a31*a44*a66 + - a15*a21*a32*a44*a66 + + a11*a25*a32*a44*a66 + + a12*a21*a35*a44*a66 + - a11*a22*a35*a44*a66 + - a14*a22*a31*a45*a66 + + a12*a24*a31*a45*a66 + + a14*a21*a32*a45*a66 + - a11*a24*a32*a45*a66 + - a12*a21*a34*a45*a66 + + a11*a22*a34*a45*a66; + cofactor[17] = -a16*a25*a34*a42*a51 + + a15*a26*a34*a42*a51 + + a16*a24*a35*a42*a51 + - a14*a26*a35*a42*a51 + - a15*a24*a36*a42*a51 + + a14*a25*a36*a42*a51 + + a16*a25*a32*a44*a51 + - a15*a26*a32*a44*a51 + - a16*a22*a35*a44*a51 + + a12*a26*a35*a44*a51 + + a15*a22*a36*a44*a51 + - a12*a25*a36*a44*a51 + - a16*a24*a32*a45*a51 + + a14*a26*a32*a45*a51 + + a16*a22*a34*a45*a51 + - a12*a26*a34*a45*a51 + - a14*a22*a36*a45*a51 + + a12*a24*a36*a45*a51 + + a15*a24*a32*a46*a51 + - a14*a25*a32*a46*a51 + - a15*a22*a34*a46*a51 + + a12*a25*a34*a46*a51 + + a14*a22*a35*a46*a51 + - a12*a24*a35*a46*a51 + + a16*a25*a34*a41*a52 + - a15*a26*a34*a41*a52 + - a16*a24*a35*a41*a52 + + a14*a26*a35*a41*a52 + + a15*a24*a36*a41*a52 + - a14*a25*a36*a41*a52 + - a16*a25*a31*a44*a52 + + a15*a26*a31*a44*a52 + + a16*a21*a35*a44*a52 + - a11*a26*a35*a44*a52 + - a15*a21*a36*a44*a52 + + a11*a25*a36*a44*a52 + + a16*a24*a31*a45*a52 + - a14*a26*a31*a45*a52 + - a16*a21*a34*a45*a52 + + a11*a26*a34*a45*a52 + + a14*a21*a36*a45*a52 + - a11*a24*a36*a45*a52 + - a15*a24*a31*a46*a52 + + a14*a25*a31*a46*a52 + + a15*a21*a34*a46*a52 + - a11*a25*a34*a46*a52 + - a14*a21*a35*a46*a52 + + a11*a24*a35*a46*a52 + - a16*a25*a32*a41*a54 + + a15*a26*a32*a41*a54 + + a16*a22*a35*a41*a54 + - a12*a26*a35*a41*a54 + - a15*a22*a36*a41*a54 + + a12*a25*a36*a41*a54 + + a16*a25*a31*a42*a54 + - a15*a26*a31*a42*a54 + - a16*a21*a35*a42*a54 + + a11*a26*a35*a42*a54 + + a15*a21*a36*a42*a54 + - a11*a25*a36*a42*a54 + - a16*a22*a31*a45*a54 + + a12*a26*a31*a45*a54 + + a16*a21*a32*a45*a54 + - a11*a26*a32*a45*a54 + - a12*a21*a36*a45*a54 + + a11*a22*a36*a45*a54 + + a15*a22*a31*a46*a54 + - a12*a25*a31*a46*a54 + - a15*a21*a32*a46*a54 + + a11*a25*a32*a46*a54 + + a12*a21*a35*a46*a54 + - a11*a22*a35*a46*a54 + + a16*a24*a32*a41*a55 + - a14*a26*a32*a41*a55 + - a16*a22*a34*a41*a55 + + a12*a26*a34*a41*a55 + + a14*a22*a36*a41*a55 + - a12*a24*a36*a41*a55 + - a16*a24*a31*a42*a55 + + a14*a26*a31*a42*a55 + + a16*a21*a34*a42*a55 + - a11*a26*a34*a42*a55 + - a14*a21*a36*a42*a55 + + a11*a24*a36*a42*a55 + + a16*a22*a31*a44*a55 + - a12*a26*a31*a44*a55 + - a16*a21*a32*a44*a55 + + a11*a26*a32*a44*a55 + + a12*a21*a36*a44*a55 + - a11*a22*a36*a44*a55 + - a14*a22*a31*a46*a55 + + a12*a24*a31*a46*a55 + + a14*a21*a32*a46*a55 + - a11*a24*a32*a46*a55 + - a12*a21*a34*a46*a55 + + a11*a22*a34*a46*a55 + - a15*a24*a32*a41*a56 + + a14*a25*a32*a41*a56 + + a15*a22*a34*a41*a56 + - a12*a25*a34*a41*a56 + - a14*a22*a35*a41*a56 + + a12*a24*a35*a41*a56 + + a15*a24*a31*a42*a56 + - a14*a25*a31*a42*a56 + - a15*a21*a34*a42*a56 + + a11*a25*a34*a42*a56 + + a14*a21*a35*a42*a56 + - a11*a24*a35*a42*a56 + - a15*a22*a31*a44*a56 + + a12*a25*a31*a44*a56 + + a15*a21*a32*a44*a56 + - a11*a25*a32*a44*a56 + - a12*a21*a35*a44*a56 + + a11*a22*a35*a44*a56 + + a14*a22*a31*a45*a56 + - a12*a24*a31*a45*a56 + - a14*a21*a32*a45*a56 + + a11*a24*a32*a45*a56 + + a12*a21*a34*a45*a56 + - a11*a22*a34*a45*a56; + cofactor[18] = -a26*a35*a43*a52*a61 + + a25*a36*a43*a52*a61 + + a26*a33*a45*a52*a61 + - a23*a36*a45*a52*a61 + - a25*a33*a46*a52*a61 + + a23*a35*a46*a52*a61 + + a26*a35*a42*a53*a61 + - a25*a36*a42*a53*a61 + - a26*a32*a45*a53*a61 + + a22*a36*a45*a53*a61 + + a25*a32*a46*a53*a61 + - a22*a35*a46*a53*a61 + - a26*a33*a42*a55*a61 + + a23*a36*a42*a55*a61 + + a26*a32*a43*a55*a61 + - a22*a36*a43*a55*a61 + - a23*a32*a46*a55*a61 + + a22*a33*a46*a55*a61 + + a25*a33*a42*a56*a61 + - a23*a35*a42*a56*a61 + - a25*a32*a43*a56*a61 + + a22*a35*a43*a56*a61 + + a23*a32*a45*a56*a61 + - a22*a33*a45*a56*a61 + + a26*a35*a43*a51*a62 + - a25*a36*a43*a51*a62 + - a26*a33*a45*a51*a62 + + a23*a36*a45*a51*a62 + + a25*a33*a46*a51*a62 + - a23*a35*a46*a51*a62 + - a26*a35*a41*a53*a62 + + a25*a36*a41*a53*a62 + + a26*a31*a45*a53*a62 + - a21*a36*a45*a53*a62 + - a25*a31*a46*a53*a62 + + a21*a35*a46*a53*a62 + + a26*a33*a41*a55*a62 + - a23*a36*a41*a55*a62 + - a26*a31*a43*a55*a62 + + a21*a36*a43*a55*a62 + + a23*a31*a46*a55*a62 + - a21*a33*a46*a55*a62 + - a25*a33*a41*a56*a62 + + a23*a35*a41*a56*a62 + + a25*a31*a43*a56*a62 + - a21*a35*a43*a56*a62 + - a23*a31*a45*a56*a62 + + a21*a33*a45*a56*a62 + - a26*a35*a42*a51*a63 + + a25*a36*a42*a51*a63 + + a26*a32*a45*a51*a63 + - a22*a36*a45*a51*a63 + - a25*a32*a46*a51*a63 + + a22*a35*a46*a51*a63 + + a26*a35*a41*a52*a63 + - a25*a36*a41*a52*a63 + - a26*a31*a45*a52*a63 + + a21*a36*a45*a52*a63 + + a25*a31*a46*a52*a63 + - a21*a35*a46*a52*a63 + - a26*a32*a41*a55*a63 + + a22*a36*a41*a55*a63 + + a26*a31*a42*a55*a63 + - a21*a36*a42*a55*a63 + - a22*a31*a46*a55*a63 + + a21*a32*a46*a55*a63 + + a25*a32*a41*a56*a63 + - a22*a35*a41*a56*a63 + - a25*a31*a42*a56*a63 + + a21*a35*a42*a56*a63 + + a22*a31*a45*a56*a63 + - a21*a32*a45*a56*a63 + + a26*a33*a42*a51*a65 + - a23*a36*a42*a51*a65 + - a26*a32*a43*a51*a65 + + a22*a36*a43*a51*a65 + + a23*a32*a46*a51*a65 + - a22*a33*a46*a51*a65 + - a26*a33*a41*a52*a65 + + a23*a36*a41*a52*a65 + + a26*a31*a43*a52*a65 + - a21*a36*a43*a52*a65 + - a23*a31*a46*a52*a65 + + a21*a33*a46*a52*a65 + + a26*a32*a41*a53*a65 + - a22*a36*a41*a53*a65 + - a26*a31*a42*a53*a65 + + a21*a36*a42*a53*a65 + + a22*a31*a46*a53*a65 + - a21*a32*a46*a53*a65 + - a23*a32*a41*a56*a65 + + a22*a33*a41*a56*a65 + + a23*a31*a42*a56*a65 + - a21*a33*a42*a56*a65 + - a22*a31*a43*a56*a65 + + a21*a32*a43*a56*a65 + - a25*a33*a42*a51*a66 + + a23*a35*a42*a51*a66 + + a25*a32*a43*a51*a66 + - a22*a35*a43*a51*a66 + - a23*a32*a45*a51*a66 + + a22*a33*a45*a51*a66 + + a25*a33*a41*a52*a66 + - a23*a35*a41*a52*a66 + - a25*a31*a43*a52*a66 + + a21*a35*a43*a52*a66 + + a23*a31*a45*a52*a66 + - a21*a33*a45*a52*a66 + - a25*a32*a41*a53*a66 + + a22*a35*a41*a53*a66 + + a25*a31*a42*a53*a66 + - a21*a35*a42*a53*a66 + - a22*a31*a45*a53*a66 + + a21*a32*a45*a53*a66 + + a23*a32*a41*a55*a66 + - a22*a33*a41*a55*a66 + - a23*a31*a42*a55*a66 + + a21*a33*a42*a55*a66 + + a22*a31*a43*a55*a66 + - a21*a32*a43*a55*a66; + cofactor[19] = a16*a35*a43*a52*a61 + - a15*a36*a43*a52*a61 + - a16*a33*a45*a52*a61 + + a13*a36*a45*a52*a61 + + a15*a33*a46*a52*a61 + - a13*a35*a46*a52*a61 + - a16*a35*a42*a53*a61 + + a15*a36*a42*a53*a61 + + a16*a32*a45*a53*a61 + - a12*a36*a45*a53*a61 + - a15*a32*a46*a53*a61 + + a12*a35*a46*a53*a61 + + a16*a33*a42*a55*a61 + - a13*a36*a42*a55*a61 + - a16*a32*a43*a55*a61 + + a12*a36*a43*a55*a61 + + a13*a32*a46*a55*a61 + - a12*a33*a46*a55*a61 + - a15*a33*a42*a56*a61 + + a13*a35*a42*a56*a61 + + a15*a32*a43*a56*a61 + - a12*a35*a43*a56*a61 + - a13*a32*a45*a56*a61 + + a12*a33*a45*a56*a61 + - a16*a35*a43*a51*a62 + + a15*a36*a43*a51*a62 + + a16*a33*a45*a51*a62 + - a13*a36*a45*a51*a62 + - a15*a33*a46*a51*a62 + + a13*a35*a46*a51*a62 + + a16*a35*a41*a53*a62 + - a15*a36*a41*a53*a62 + - a16*a31*a45*a53*a62 + + a11*a36*a45*a53*a62 + + a15*a31*a46*a53*a62 + - a11*a35*a46*a53*a62 + - a16*a33*a41*a55*a62 + + a13*a36*a41*a55*a62 + + a16*a31*a43*a55*a62 + - a11*a36*a43*a55*a62 + - a13*a31*a46*a55*a62 + + a11*a33*a46*a55*a62 + + a15*a33*a41*a56*a62 + - a13*a35*a41*a56*a62 + - a15*a31*a43*a56*a62 + + a11*a35*a43*a56*a62 + + a13*a31*a45*a56*a62 + - a11*a33*a45*a56*a62 + + a16*a35*a42*a51*a63 + - a15*a36*a42*a51*a63 + - a16*a32*a45*a51*a63 + + a12*a36*a45*a51*a63 + + a15*a32*a46*a51*a63 + - a12*a35*a46*a51*a63 + - a16*a35*a41*a52*a63 + + a15*a36*a41*a52*a63 + + a16*a31*a45*a52*a63 + - a11*a36*a45*a52*a63 + - a15*a31*a46*a52*a63 + + a11*a35*a46*a52*a63 + + a16*a32*a41*a55*a63 + - a12*a36*a41*a55*a63 + - a16*a31*a42*a55*a63 + + a11*a36*a42*a55*a63 + + a12*a31*a46*a55*a63 + - a11*a32*a46*a55*a63 + - a15*a32*a41*a56*a63 + + a12*a35*a41*a56*a63 + + a15*a31*a42*a56*a63 + - a11*a35*a42*a56*a63 + - a12*a31*a45*a56*a63 + + a11*a32*a45*a56*a63 + - a16*a33*a42*a51*a65 + + a13*a36*a42*a51*a65 + + a16*a32*a43*a51*a65 + - a12*a36*a43*a51*a65 + - a13*a32*a46*a51*a65 + + a12*a33*a46*a51*a65 + + a16*a33*a41*a52*a65 + - a13*a36*a41*a52*a65 + - a16*a31*a43*a52*a65 + + a11*a36*a43*a52*a65 + + a13*a31*a46*a52*a65 + - a11*a33*a46*a52*a65 + - a16*a32*a41*a53*a65 + + a12*a36*a41*a53*a65 + + a16*a31*a42*a53*a65 + - a11*a36*a42*a53*a65 + - a12*a31*a46*a53*a65 + + a11*a32*a46*a53*a65 + + a13*a32*a41*a56*a65 + - a12*a33*a41*a56*a65 + - a13*a31*a42*a56*a65 + + a11*a33*a42*a56*a65 + + a12*a31*a43*a56*a65 + - a11*a32*a43*a56*a65 + + a15*a33*a42*a51*a66 + - a13*a35*a42*a51*a66 + - a15*a32*a43*a51*a66 + + a12*a35*a43*a51*a66 + + a13*a32*a45*a51*a66 + - a12*a33*a45*a51*a66 + - a15*a33*a41*a52*a66 + + a13*a35*a41*a52*a66 + + a15*a31*a43*a52*a66 + - a11*a35*a43*a52*a66 + - a13*a31*a45*a52*a66 + + a11*a33*a45*a52*a66 + + a15*a32*a41*a53*a66 + - a12*a35*a41*a53*a66 + - a15*a31*a42*a53*a66 + + a11*a35*a42*a53*a66 + + a12*a31*a45*a53*a66 + - a11*a32*a45*a53*a66 + - a13*a32*a41*a55*a66 + + a12*a33*a41*a55*a66 + + a13*a31*a42*a55*a66 + - a11*a33*a42*a55*a66 + - a12*a31*a43*a55*a66 + + a11*a32*a43*a55*a66; + cofactor[20] = -a16*a25*a43*a52*a61 + + a15*a26*a43*a52*a61 + + a16*a23*a45*a52*a61 + - a13*a26*a45*a52*a61 + - a15*a23*a46*a52*a61 + + a13*a25*a46*a52*a61 + + a16*a25*a42*a53*a61 + - a15*a26*a42*a53*a61 + - a16*a22*a45*a53*a61 + + a12*a26*a45*a53*a61 + + a15*a22*a46*a53*a61 + - a12*a25*a46*a53*a61 + - a16*a23*a42*a55*a61 + + a13*a26*a42*a55*a61 + + a16*a22*a43*a55*a61 + - a12*a26*a43*a55*a61 + - a13*a22*a46*a55*a61 + + a12*a23*a46*a55*a61 + + a15*a23*a42*a56*a61 + - a13*a25*a42*a56*a61 + - a15*a22*a43*a56*a61 + + a12*a25*a43*a56*a61 + + a13*a22*a45*a56*a61 + - a12*a23*a45*a56*a61 + + a16*a25*a43*a51*a62 + - a15*a26*a43*a51*a62 + - a16*a23*a45*a51*a62 + + a13*a26*a45*a51*a62 + + a15*a23*a46*a51*a62 + - a13*a25*a46*a51*a62 + - a16*a25*a41*a53*a62 + + a15*a26*a41*a53*a62 + + a16*a21*a45*a53*a62 + - a11*a26*a45*a53*a62 + - a15*a21*a46*a53*a62 + + a11*a25*a46*a53*a62 + + a16*a23*a41*a55*a62 + - a13*a26*a41*a55*a62 + - a16*a21*a43*a55*a62 + + a11*a26*a43*a55*a62 + + a13*a21*a46*a55*a62 + - a11*a23*a46*a55*a62 + - a15*a23*a41*a56*a62 + + a13*a25*a41*a56*a62 + + a15*a21*a43*a56*a62 + - a11*a25*a43*a56*a62 + - a13*a21*a45*a56*a62 + + a11*a23*a45*a56*a62 + - a16*a25*a42*a51*a63 + + a15*a26*a42*a51*a63 + + a16*a22*a45*a51*a63 + - a12*a26*a45*a51*a63 + - a15*a22*a46*a51*a63 + + a12*a25*a46*a51*a63 + + a16*a25*a41*a52*a63 + - a15*a26*a41*a52*a63 + - a16*a21*a45*a52*a63 + + a11*a26*a45*a52*a63 + + a15*a21*a46*a52*a63 + - a11*a25*a46*a52*a63 + - a16*a22*a41*a55*a63 + + a12*a26*a41*a55*a63 + + a16*a21*a42*a55*a63 + - a11*a26*a42*a55*a63 + - a12*a21*a46*a55*a63 + + a11*a22*a46*a55*a63 + + a15*a22*a41*a56*a63 + - a12*a25*a41*a56*a63 + - a15*a21*a42*a56*a63 + + a11*a25*a42*a56*a63 + + a12*a21*a45*a56*a63 + - a11*a22*a45*a56*a63 + + a16*a23*a42*a51*a65 + - a13*a26*a42*a51*a65 + - a16*a22*a43*a51*a65 + + a12*a26*a43*a51*a65 + + a13*a22*a46*a51*a65 + - a12*a23*a46*a51*a65 + - a16*a23*a41*a52*a65 + + a13*a26*a41*a52*a65 + + a16*a21*a43*a52*a65 + - a11*a26*a43*a52*a65 + - a13*a21*a46*a52*a65 + + a11*a23*a46*a52*a65 + + a16*a22*a41*a53*a65 + - a12*a26*a41*a53*a65 + - a16*a21*a42*a53*a65 + + a11*a26*a42*a53*a65 + + a12*a21*a46*a53*a65 + - a11*a22*a46*a53*a65 + - a13*a22*a41*a56*a65 + + a12*a23*a41*a56*a65 + + a13*a21*a42*a56*a65 + - a11*a23*a42*a56*a65 + - a12*a21*a43*a56*a65 + + a11*a22*a43*a56*a65 + - a15*a23*a42*a51*a66 + + a13*a25*a42*a51*a66 + + a15*a22*a43*a51*a66 + - a12*a25*a43*a51*a66 + - a13*a22*a45*a51*a66 + + a12*a23*a45*a51*a66 + + a15*a23*a41*a52*a66 + - a13*a25*a41*a52*a66 + - a15*a21*a43*a52*a66 + + a11*a25*a43*a52*a66 + + a13*a21*a45*a52*a66 + - a11*a23*a45*a52*a66 + - a15*a22*a41*a53*a66 + + a12*a25*a41*a53*a66 + + a15*a21*a42*a53*a66 + - a11*a25*a42*a53*a66 + - a12*a21*a45*a53*a66 + + a11*a22*a45*a53*a66 + + a13*a22*a41*a55*a66 + - a12*a23*a41*a55*a66 + - a13*a21*a42*a55*a66 + + a11*a23*a42*a55*a66 + + a12*a21*a43*a55*a66 + - a11*a22*a43*a55*a66; + cofactor[21] = a16*a25*a33*a52*a61 + - a15*a26*a33*a52*a61 + - a16*a23*a35*a52*a61 + + a13*a26*a35*a52*a61 + + a15*a23*a36*a52*a61 + - a13*a25*a36*a52*a61 + - a16*a25*a32*a53*a61 + + a15*a26*a32*a53*a61 + + a16*a22*a35*a53*a61 + - a12*a26*a35*a53*a61 + - a15*a22*a36*a53*a61 + + a12*a25*a36*a53*a61 + + a16*a23*a32*a55*a61 + - a13*a26*a32*a55*a61 + - a16*a22*a33*a55*a61 + + a12*a26*a33*a55*a61 + + a13*a22*a36*a55*a61 + - a12*a23*a36*a55*a61 + - a15*a23*a32*a56*a61 + + a13*a25*a32*a56*a61 + + a15*a22*a33*a56*a61 + - a12*a25*a33*a56*a61 + - a13*a22*a35*a56*a61 + + a12*a23*a35*a56*a61 + - a16*a25*a33*a51*a62 + + a15*a26*a33*a51*a62 + + a16*a23*a35*a51*a62 + - a13*a26*a35*a51*a62 + - a15*a23*a36*a51*a62 + + a13*a25*a36*a51*a62 + + a16*a25*a31*a53*a62 + - a15*a26*a31*a53*a62 + - a16*a21*a35*a53*a62 + + a11*a26*a35*a53*a62 + + a15*a21*a36*a53*a62 + - a11*a25*a36*a53*a62 + - a16*a23*a31*a55*a62 + + a13*a26*a31*a55*a62 + + a16*a21*a33*a55*a62 + - a11*a26*a33*a55*a62 + - a13*a21*a36*a55*a62 + + a11*a23*a36*a55*a62 + + a15*a23*a31*a56*a62 + - a13*a25*a31*a56*a62 + - a15*a21*a33*a56*a62 + + a11*a25*a33*a56*a62 + + a13*a21*a35*a56*a62 + - a11*a23*a35*a56*a62 + + a16*a25*a32*a51*a63 + - a15*a26*a32*a51*a63 + - a16*a22*a35*a51*a63 + + a12*a26*a35*a51*a63 + + a15*a22*a36*a51*a63 + - a12*a25*a36*a51*a63 + - a16*a25*a31*a52*a63 + + a15*a26*a31*a52*a63 + + a16*a21*a35*a52*a63 + - a11*a26*a35*a52*a63 + - a15*a21*a36*a52*a63 + + a11*a25*a36*a52*a63 + + a16*a22*a31*a55*a63 + - a12*a26*a31*a55*a63 + - a16*a21*a32*a55*a63 + + a11*a26*a32*a55*a63 + + a12*a21*a36*a55*a63 + - a11*a22*a36*a55*a63 + - a15*a22*a31*a56*a63 + + a12*a25*a31*a56*a63 + + a15*a21*a32*a56*a63 + - a11*a25*a32*a56*a63 + - a12*a21*a35*a56*a63 + + a11*a22*a35*a56*a63 + - a16*a23*a32*a51*a65 + + a13*a26*a32*a51*a65 + + a16*a22*a33*a51*a65 + - a12*a26*a33*a51*a65 + - a13*a22*a36*a51*a65 + + a12*a23*a36*a51*a65 + + a16*a23*a31*a52*a65 + - a13*a26*a31*a52*a65 + - a16*a21*a33*a52*a65 + + a11*a26*a33*a52*a65 + + a13*a21*a36*a52*a65 + - a11*a23*a36*a52*a65 + - a16*a22*a31*a53*a65 + + a12*a26*a31*a53*a65 + + a16*a21*a32*a53*a65 + - a11*a26*a32*a53*a65 + - a12*a21*a36*a53*a65 + + a11*a22*a36*a53*a65 + + a13*a22*a31*a56*a65 + - a12*a23*a31*a56*a65 + - a13*a21*a32*a56*a65 + + a11*a23*a32*a56*a65 + + a12*a21*a33*a56*a65 + - a11*a22*a33*a56*a65 + + a15*a23*a32*a51*a66 + - a13*a25*a32*a51*a66 + - a15*a22*a33*a51*a66 + + a12*a25*a33*a51*a66 + + a13*a22*a35*a51*a66 + - a12*a23*a35*a51*a66 + - a15*a23*a31*a52*a66 + + a13*a25*a31*a52*a66 + + a15*a21*a33*a52*a66 + - a11*a25*a33*a52*a66 + - a13*a21*a35*a52*a66 + + a11*a23*a35*a52*a66 + + a15*a22*a31*a53*a66 + - a12*a25*a31*a53*a66 + - a15*a21*a32*a53*a66 + + a11*a25*a32*a53*a66 + + a12*a21*a35*a53*a66 + - a11*a22*a35*a53*a66 + - a13*a22*a31*a55*a66 + + a12*a23*a31*a55*a66 + + a13*a21*a32*a55*a66 + - a11*a23*a32*a55*a66 + - a12*a21*a33*a55*a66 + + a11*a22*a33*a55*a66; + cofactor[22] = -a16*a25*a33*a42*a61 + + a15*a26*a33*a42*a61 + + a16*a23*a35*a42*a61 + - a13*a26*a35*a42*a61 + - a15*a23*a36*a42*a61 + + a13*a25*a36*a42*a61 + + a16*a25*a32*a43*a61 + - a15*a26*a32*a43*a61 + - a16*a22*a35*a43*a61 + + a12*a26*a35*a43*a61 + + a15*a22*a36*a43*a61 + - a12*a25*a36*a43*a61 + - a16*a23*a32*a45*a61 + + a13*a26*a32*a45*a61 + + a16*a22*a33*a45*a61 + - a12*a26*a33*a45*a61 + - a13*a22*a36*a45*a61 + + a12*a23*a36*a45*a61 + + a15*a23*a32*a46*a61 + - a13*a25*a32*a46*a61 + - a15*a22*a33*a46*a61 + + a12*a25*a33*a46*a61 + + a13*a22*a35*a46*a61 + - a12*a23*a35*a46*a61 + + a16*a25*a33*a41*a62 + - a15*a26*a33*a41*a62 + - a16*a23*a35*a41*a62 + + a13*a26*a35*a41*a62 + + a15*a23*a36*a41*a62 + - a13*a25*a36*a41*a62 + - a16*a25*a31*a43*a62 + + a15*a26*a31*a43*a62 + + a16*a21*a35*a43*a62 + - a11*a26*a35*a43*a62 + - a15*a21*a36*a43*a62 + + a11*a25*a36*a43*a62 + + a16*a23*a31*a45*a62 + - a13*a26*a31*a45*a62 + - a16*a21*a33*a45*a62 + + a11*a26*a33*a45*a62 + + a13*a21*a36*a45*a62 + - a11*a23*a36*a45*a62 + - a15*a23*a31*a46*a62 + + a13*a25*a31*a46*a62 + + a15*a21*a33*a46*a62 + - a11*a25*a33*a46*a62 + - a13*a21*a35*a46*a62 + + a11*a23*a35*a46*a62 + - a16*a25*a32*a41*a63 + + a15*a26*a32*a41*a63 + + a16*a22*a35*a41*a63 + - a12*a26*a35*a41*a63 + - a15*a22*a36*a41*a63 + + a12*a25*a36*a41*a63 + + a16*a25*a31*a42*a63 + - a15*a26*a31*a42*a63 + - a16*a21*a35*a42*a63 + + a11*a26*a35*a42*a63 + + a15*a21*a36*a42*a63 + - a11*a25*a36*a42*a63 + - a16*a22*a31*a45*a63 + + a12*a26*a31*a45*a63 + + a16*a21*a32*a45*a63 + - a11*a26*a32*a45*a63 + - a12*a21*a36*a45*a63 + + a11*a22*a36*a45*a63 + + a15*a22*a31*a46*a63 + - a12*a25*a31*a46*a63 + - a15*a21*a32*a46*a63 + + a11*a25*a32*a46*a63 + + a12*a21*a35*a46*a63 + - a11*a22*a35*a46*a63 + + a16*a23*a32*a41*a65 + - a13*a26*a32*a41*a65 + - a16*a22*a33*a41*a65 + + a12*a26*a33*a41*a65 + + a13*a22*a36*a41*a65 + - a12*a23*a36*a41*a65 + - a16*a23*a31*a42*a65 + + a13*a26*a31*a42*a65 + + a16*a21*a33*a42*a65 + - a11*a26*a33*a42*a65 + - a13*a21*a36*a42*a65 + + a11*a23*a36*a42*a65 + + a16*a22*a31*a43*a65 + - a12*a26*a31*a43*a65 + - a16*a21*a32*a43*a65 + + a11*a26*a32*a43*a65 + + a12*a21*a36*a43*a65 + - a11*a22*a36*a43*a65 + - a13*a22*a31*a46*a65 + + a12*a23*a31*a46*a65 + + a13*a21*a32*a46*a65 + - a11*a23*a32*a46*a65 + - a12*a21*a33*a46*a65 + + a11*a22*a33*a46*a65 + - a15*a23*a32*a41*a66 + + a13*a25*a32*a41*a66 + + a15*a22*a33*a41*a66 + - a12*a25*a33*a41*a66 + - a13*a22*a35*a41*a66 + + a12*a23*a35*a41*a66 + + a15*a23*a31*a42*a66 + - a13*a25*a31*a42*a66 + - a15*a21*a33*a42*a66 + + a11*a25*a33*a42*a66 + + a13*a21*a35*a42*a66 + - a11*a23*a35*a42*a66 + - a15*a22*a31*a43*a66 + + a12*a25*a31*a43*a66 + + a15*a21*a32*a43*a66 + - a11*a25*a32*a43*a66 + - a12*a21*a35*a43*a66 + + a11*a22*a35*a43*a66 + + a13*a22*a31*a45*a66 + - a12*a23*a31*a45*a66 + - a13*a21*a32*a45*a66 + + a11*a23*a32*a45*a66 + + a12*a21*a33*a45*a66 + - a11*a22*a33*a45*a66; + cofactor[23] = a16*a25*a33*a42*a51 + - a15*a26*a33*a42*a51 + - a16*a23*a35*a42*a51 + + a13*a26*a35*a42*a51 + + a15*a23*a36*a42*a51 + - a13*a25*a36*a42*a51 + - a16*a25*a32*a43*a51 + + a15*a26*a32*a43*a51 + + a16*a22*a35*a43*a51 + - a12*a26*a35*a43*a51 + - a15*a22*a36*a43*a51 + + a12*a25*a36*a43*a51 + + a16*a23*a32*a45*a51 + - a13*a26*a32*a45*a51 + - a16*a22*a33*a45*a51 + + a12*a26*a33*a45*a51 + + a13*a22*a36*a45*a51 + - a12*a23*a36*a45*a51 + - a15*a23*a32*a46*a51 + + a13*a25*a32*a46*a51 + + a15*a22*a33*a46*a51 + - a12*a25*a33*a46*a51 + - a13*a22*a35*a46*a51 + + a12*a23*a35*a46*a51 + - a16*a25*a33*a41*a52 + + a15*a26*a33*a41*a52 + + a16*a23*a35*a41*a52 + - a13*a26*a35*a41*a52 + - a15*a23*a36*a41*a52 + + a13*a25*a36*a41*a52 + + a16*a25*a31*a43*a52 + - a15*a26*a31*a43*a52 + - a16*a21*a35*a43*a52 + + a11*a26*a35*a43*a52 + + a15*a21*a36*a43*a52 + - a11*a25*a36*a43*a52 + - a16*a23*a31*a45*a52 + + a13*a26*a31*a45*a52 + + a16*a21*a33*a45*a52 + - a11*a26*a33*a45*a52 + - a13*a21*a36*a45*a52 + + a11*a23*a36*a45*a52 + + a15*a23*a31*a46*a52 + - a13*a25*a31*a46*a52 + - a15*a21*a33*a46*a52 + + a11*a25*a33*a46*a52 + + a13*a21*a35*a46*a52 + - a11*a23*a35*a46*a52 + + a16*a25*a32*a41*a53 + - a15*a26*a32*a41*a53 + - a16*a22*a35*a41*a53 + + a12*a26*a35*a41*a53 + + a15*a22*a36*a41*a53 + - a12*a25*a36*a41*a53 + - a16*a25*a31*a42*a53 + + a15*a26*a31*a42*a53 + + a16*a21*a35*a42*a53 + - a11*a26*a35*a42*a53 + - a15*a21*a36*a42*a53 + + a11*a25*a36*a42*a53 + + a16*a22*a31*a45*a53 + - a12*a26*a31*a45*a53 + - a16*a21*a32*a45*a53 + + a11*a26*a32*a45*a53 + + a12*a21*a36*a45*a53 + - a11*a22*a36*a45*a53 + - a15*a22*a31*a46*a53 + + a12*a25*a31*a46*a53 + + a15*a21*a32*a46*a53 + - a11*a25*a32*a46*a53 + - a12*a21*a35*a46*a53 + + a11*a22*a35*a46*a53 + - a16*a23*a32*a41*a55 + + a13*a26*a32*a41*a55 + + a16*a22*a33*a41*a55 + - a12*a26*a33*a41*a55 + - a13*a22*a36*a41*a55 + + a12*a23*a36*a41*a55 + + a16*a23*a31*a42*a55 + - a13*a26*a31*a42*a55 + - a16*a21*a33*a42*a55 + + a11*a26*a33*a42*a55 + + a13*a21*a36*a42*a55 + - a11*a23*a36*a42*a55 + - a16*a22*a31*a43*a55 + + a12*a26*a31*a43*a55 + + a16*a21*a32*a43*a55 + - a11*a26*a32*a43*a55 + - a12*a21*a36*a43*a55 + + a11*a22*a36*a43*a55 + + a13*a22*a31*a46*a55 + - a12*a23*a31*a46*a55 + - a13*a21*a32*a46*a55 + + a11*a23*a32*a46*a55 + + a12*a21*a33*a46*a55 + - a11*a22*a33*a46*a55 + + a15*a23*a32*a41*a56 + - a13*a25*a32*a41*a56 + - a15*a22*a33*a41*a56 + + a12*a25*a33*a41*a56 + + a13*a22*a35*a41*a56 + - a12*a23*a35*a41*a56 + - a15*a23*a31*a42*a56 + + a13*a25*a31*a42*a56 + + a15*a21*a33*a42*a56 + - a11*a25*a33*a42*a56 + - a13*a21*a35*a42*a56 + + a11*a23*a35*a42*a56 + + a15*a22*a31*a43*a56 + - a12*a25*a31*a43*a56 + - a15*a21*a32*a43*a56 + + a11*a25*a32*a43*a56 + + a12*a21*a35*a43*a56 + - a11*a22*a35*a43*a56 + - a13*a22*a31*a45*a56 + + a12*a23*a31*a45*a56 + + a13*a21*a32*a45*a56 + - a11*a23*a32*a45*a56 + - a12*a21*a33*a45*a56 + + a11*a22*a33*a45*a56; + cofactor[24] = a26*a34*a43*a52*a61 + - a24*a36*a43*a52*a61 + - a26*a33*a44*a52*a61 + + a23*a36*a44*a52*a61 + + a24*a33*a46*a52*a61 + - a23*a34*a46*a52*a61 + - a26*a34*a42*a53*a61 + + a24*a36*a42*a53*a61 + + a26*a32*a44*a53*a61 + - a22*a36*a44*a53*a61 + - a24*a32*a46*a53*a61 + + a22*a34*a46*a53*a61 + + a26*a33*a42*a54*a61 + - a23*a36*a42*a54*a61 + - a26*a32*a43*a54*a61 + + a22*a36*a43*a54*a61 + + a23*a32*a46*a54*a61 + - a22*a33*a46*a54*a61 + - a24*a33*a42*a56*a61 + + a23*a34*a42*a56*a61 + + a24*a32*a43*a56*a61 + - a22*a34*a43*a56*a61 + - a23*a32*a44*a56*a61 + + a22*a33*a44*a56*a61 + - a26*a34*a43*a51*a62 + + a24*a36*a43*a51*a62 + + a26*a33*a44*a51*a62 + - a23*a36*a44*a51*a62 + - a24*a33*a46*a51*a62 + + a23*a34*a46*a51*a62 + + a26*a34*a41*a53*a62 + - a24*a36*a41*a53*a62 + - a26*a31*a44*a53*a62 + + a21*a36*a44*a53*a62 + + a24*a31*a46*a53*a62 + - a21*a34*a46*a53*a62 + - a26*a33*a41*a54*a62 + + a23*a36*a41*a54*a62 + + a26*a31*a43*a54*a62 + - a21*a36*a43*a54*a62 + - a23*a31*a46*a54*a62 + + a21*a33*a46*a54*a62 + + a24*a33*a41*a56*a62 + - a23*a34*a41*a56*a62 + - a24*a31*a43*a56*a62 + + a21*a34*a43*a56*a62 + + a23*a31*a44*a56*a62 + - a21*a33*a44*a56*a62 + + a26*a34*a42*a51*a63 + - a24*a36*a42*a51*a63 + - a26*a32*a44*a51*a63 + + a22*a36*a44*a51*a63 + + a24*a32*a46*a51*a63 + - a22*a34*a46*a51*a63 + - a26*a34*a41*a52*a63 + + a24*a36*a41*a52*a63 + + a26*a31*a44*a52*a63 + - a21*a36*a44*a52*a63 + - a24*a31*a46*a52*a63 + + a21*a34*a46*a52*a63 + + a26*a32*a41*a54*a63 + - a22*a36*a41*a54*a63 + - a26*a31*a42*a54*a63 + + a21*a36*a42*a54*a63 + + a22*a31*a46*a54*a63 + - a21*a32*a46*a54*a63 + - a24*a32*a41*a56*a63 + + a22*a34*a41*a56*a63 + + a24*a31*a42*a56*a63 + - a21*a34*a42*a56*a63 + - a22*a31*a44*a56*a63 + + a21*a32*a44*a56*a63 + - a26*a33*a42*a51*a64 + + a23*a36*a42*a51*a64 + + a26*a32*a43*a51*a64 + - a22*a36*a43*a51*a64 + - a23*a32*a46*a51*a64 + + a22*a33*a46*a51*a64 + + a26*a33*a41*a52*a64 + - a23*a36*a41*a52*a64 + - a26*a31*a43*a52*a64 + + a21*a36*a43*a52*a64 + + a23*a31*a46*a52*a64 + - a21*a33*a46*a52*a64 + - a26*a32*a41*a53*a64 + + a22*a36*a41*a53*a64 + + a26*a31*a42*a53*a64 + - a21*a36*a42*a53*a64 + - a22*a31*a46*a53*a64 + + a21*a32*a46*a53*a64 + + a23*a32*a41*a56*a64 + - a22*a33*a41*a56*a64 + - a23*a31*a42*a56*a64 + + a21*a33*a42*a56*a64 + + a22*a31*a43*a56*a64 + - a21*a32*a43*a56*a64 + + a24*a33*a42*a51*a66 + - a23*a34*a42*a51*a66 + - a24*a32*a43*a51*a66 + + a22*a34*a43*a51*a66 + + a23*a32*a44*a51*a66 + - a22*a33*a44*a51*a66 + - a24*a33*a41*a52*a66 + + a23*a34*a41*a52*a66 + + a24*a31*a43*a52*a66 + - a21*a34*a43*a52*a66 + - a23*a31*a44*a52*a66 + + a21*a33*a44*a52*a66 + + a24*a32*a41*a53*a66 + - a22*a34*a41*a53*a66 + - a24*a31*a42*a53*a66 + + a21*a34*a42*a53*a66 + + a22*a31*a44*a53*a66 + - a21*a32*a44*a53*a66 + - a23*a32*a41*a54*a66 + + a22*a33*a41*a54*a66 + + a23*a31*a42*a54*a66 + - a21*a33*a42*a54*a66 + - a22*a31*a43*a54*a66 + + a21*a32*a43*a54*a66; + cofactor[25] = -a16*a34*a43*a52*a61 + + a14*a36*a43*a52*a61 + + a16*a33*a44*a52*a61 + - a13*a36*a44*a52*a61 + - a14*a33*a46*a52*a61 + + a13*a34*a46*a52*a61 + + a16*a34*a42*a53*a61 + - a14*a36*a42*a53*a61 + - a16*a32*a44*a53*a61 + + a12*a36*a44*a53*a61 + + a14*a32*a46*a53*a61 + - a12*a34*a46*a53*a61 + - a16*a33*a42*a54*a61 + + a13*a36*a42*a54*a61 + + a16*a32*a43*a54*a61 + - a12*a36*a43*a54*a61 + - a13*a32*a46*a54*a61 + + a12*a33*a46*a54*a61 + + a14*a33*a42*a56*a61 + - a13*a34*a42*a56*a61 + - a14*a32*a43*a56*a61 + + a12*a34*a43*a56*a61 + + a13*a32*a44*a56*a61 + - a12*a33*a44*a56*a61 + + a16*a34*a43*a51*a62 + - a14*a36*a43*a51*a62 + - a16*a33*a44*a51*a62 + + a13*a36*a44*a51*a62 + + a14*a33*a46*a51*a62 + - a13*a34*a46*a51*a62 + - a16*a34*a41*a53*a62 + + a14*a36*a41*a53*a62 + + a16*a31*a44*a53*a62 + - a11*a36*a44*a53*a62 + - a14*a31*a46*a53*a62 + + a11*a34*a46*a53*a62 + + a16*a33*a41*a54*a62 + - a13*a36*a41*a54*a62 + - a16*a31*a43*a54*a62 + + a11*a36*a43*a54*a62 + + a13*a31*a46*a54*a62 + - a11*a33*a46*a54*a62 + - a14*a33*a41*a56*a62 + + a13*a34*a41*a56*a62 + + a14*a31*a43*a56*a62 + - a11*a34*a43*a56*a62 + - a13*a31*a44*a56*a62 + + a11*a33*a44*a56*a62 + - a16*a34*a42*a51*a63 + + a14*a36*a42*a51*a63 + + a16*a32*a44*a51*a63 + - a12*a36*a44*a51*a63 + - a14*a32*a46*a51*a63 + + a12*a34*a46*a51*a63 + + a16*a34*a41*a52*a63 + - a14*a36*a41*a52*a63 + - a16*a31*a44*a52*a63 + + a11*a36*a44*a52*a63 + + a14*a31*a46*a52*a63 + - a11*a34*a46*a52*a63 + - a16*a32*a41*a54*a63 + + a12*a36*a41*a54*a63 + + a16*a31*a42*a54*a63 + - a11*a36*a42*a54*a63 + - a12*a31*a46*a54*a63 + + a11*a32*a46*a54*a63 + + a14*a32*a41*a56*a63 + - a12*a34*a41*a56*a63 + - a14*a31*a42*a56*a63 + + a11*a34*a42*a56*a63 + + a12*a31*a44*a56*a63 + - a11*a32*a44*a56*a63 + + a16*a33*a42*a51*a64 + - a13*a36*a42*a51*a64 + - a16*a32*a43*a51*a64 + + a12*a36*a43*a51*a64 + + a13*a32*a46*a51*a64 + - a12*a33*a46*a51*a64 + - a16*a33*a41*a52*a64 + + a13*a36*a41*a52*a64 + + a16*a31*a43*a52*a64 + - a11*a36*a43*a52*a64 + - a13*a31*a46*a52*a64 + + a11*a33*a46*a52*a64 + + a16*a32*a41*a53*a64 + - a12*a36*a41*a53*a64 + - a16*a31*a42*a53*a64 + + a11*a36*a42*a53*a64 + + a12*a31*a46*a53*a64 + - a11*a32*a46*a53*a64 + - a13*a32*a41*a56*a64 + + a12*a33*a41*a56*a64 + + a13*a31*a42*a56*a64 + - a11*a33*a42*a56*a64 + - a12*a31*a43*a56*a64 + + a11*a32*a43*a56*a64 + - a14*a33*a42*a51*a66 + + a13*a34*a42*a51*a66 + + a14*a32*a43*a51*a66 + - a12*a34*a43*a51*a66 + - a13*a32*a44*a51*a66 + + a12*a33*a44*a51*a66 + + a14*a33*a41*a52*a66 + - a13*a34*a41*a52*a66 + - a14*a31*a43*a52*a66 + + a11*a34*a43*a52*a66 + + a13*a31*a44*a52*a66 + - a11*a33*a44*a52*a66 + - a14*a32*a41*a53*a66 + + a12*a34*a41*a53*a66 + + a14*a31*a42*a53*a66 + - a11*a34*a42*a53*a66 + - a12*a31*a44*a53*a66 + + a11*a32*a44*a53*a66 + + a13*a32*a41*a54*a66 + - a12*a33*a41*a54*a66 + - a13*a31*a42*a54*a66 + + a11*a33*a42*a54*a66 + + a12*a31*a43*a54*a66 + - a11*a32*a43*a54*a66; + cofactor[26] = a16*a24*a43*a52*a61 + - a14*a26*a43*a52*a61 + - a16*a23*a44*a52*a61 + + a13*a26*a44*a52*a61 + + a14*a23*a46*a52*a61 + - a13*a24*a46*a52*a61 + - a16*a24*a42*a53*a61 + + a14*a26*a42*a53*a61 + + a16*a22*a44*a53*a61 + - a12*a26*a44*a53*a61 + - a14*a22*a46*a53*a61 + + a12*a24*a46*a53*a61 + + a16*a23*a42*a54*a61 + - a13*a26*a42*a54*a61 + - a16*a22*a43*a54*a61 + + a12*a26*a43*a54*a61 + + a13*a22*a46*a54*a61 + - a12*a23*a46*a54*a61 + - a14*a23*a42*a56*a61 + + a13*a24*a42*a56*a61 + + a14*a22*a43*a56*a61 + - a12*a24*a43*a56*a61 + - a13*a22*a44*a56*a61 + + a12*a23*a44*a56*a61 + - a16*a24*a43*a51*a62 + + a14*a26*a43*a51*a62 + + a16*a23*a44*a51*a62 + - a13*a26*a44*a51*a62 + - a14*a23*a46*a51*a62 + + a13*a24*a46*a51*a62 + + a16*a24*a41*a53*a62 + - a14*a26*a41*a53*a62 + - a16*a21*a44*a53*a62 + + a11*a26*a44*a53*a62 + + a14*a21*a46*a53*a62 + - a11*a24*a46*a53*a62 + - a16*a23*a41*a54*a62 + + a13*a26*a41*a54*a62 + + a16*a21*a43*a54*a62 + - a11*a26*a43*a54*a62 + - a13*a21*a46*a54*a62 + + a11*a23*a46*a54*a62 + + a14*a23*a41*a56*a62 + - a13*a24*a41*a56*a62 + - a14*a21*a43*a56*a62 + + a11*a24*a43*a56*a62 + + a13*a21*a44*a56*a62 + - a11*a23*a44*a56*a62 + + a16*a24*a42*a51*a63 + - a14*a26*a42*a51*a63 + - a16*a22*a44*a51*a63 + + a12*a26*a44*a51*a63 + + a14*a22*a46*a51*a63 + - a12*a24*a46*a51*a63 + - a16*a24*a41*a52*a63 + + a14*a26*a41*a52*a63 + + a16*a21*a44*a52*a63 + - a11*a26*a44*a52*a63 + - a14*a21*a46*a52*a63 + + a11*a24*a46*a52*a63 + + a16*a22*a41*a54*a63 + - a12*a26*a41*a54*a63 + - a16*a21*a42*a54*a63 + + a11*a26*a42*a54*a63 + + a12*a21*a46*a54*a63 + - a11*a22*a46*a54*a63 + - a14*a22*a41*a56*a63 + + a12*a24*a41*a56*a63 + + a14*a21*a42*a56*a63 + - a11*a24*a42*a56*a63 + - a12*a21*a44*a56*a63 + + a11*a22*a44*a56*a63 + - a16*a23*a42*a51*a64 + + a13*a26*a42*a51*a64 + + a16*a22*a43*a51*a64 + - a12*a26*a43*a51*a64 + - a13*a22*a46*a51*a64 + + a12*a23*a46*a51*a64 + + a16*a23*a41*a52*a64 + - a13*a26*a41*a52*a64 + - a16*a21*a43*a52*a64 + + a11*a26*a43*a52*a64 + + a13*a21*a46*a52*a64 + - a11*a23*a46*a52*a64 + - a16*a22*a41*a53*a64 + + a12*a26*a41*a53*a64 + + a16*a21*a42*a53*a64 + - a11*a26*a42*a53*a64 + - a12*a21*a46*a53*a64 + + a11*a22*a46*a53*a64 + + a13*a22*a41*a56*a64 + - a12*a23*a41*a56*a64 + - a13*a21*a42*a56*a64 + + a11*a23*a42*a56*a64 + + a12*a21*a43*a56*a64 + - a11*a22*a43*a56*a64 + + a14*a23*a42*a51*a66 + - a13*a24*a42*a51*a66 + - a14*a22*a43*a51*a66 + + a12*a24*a43*a51*a66 + + a13*a22*a44*a51*a66 + - a12*a23*a44*a51*a66 + - a14*a23*a41*a52*a66 + + a13*a24*a41*a52*a66 + + a14*a21*a43*a52*a66 + - a11*a24*a43*a52*a66 + - a13*a21*a44*a52*a66 + + a11*a23*a44*a52*a66 + + a14*a22*a41*a53*a66 + - a12*a24*a41*a53*a66 + - a14*a21*a42*a53*a66 + + a11*a24*a42*a53*a66 + + a12*a21*a44*a53*a66 + - a11*a22*a44*a53*a66 + - a13*a22*a41*a54*a66 + + a12*a23*a41*a54*a66 + + a13*a21*a42*a54*a66 + - a11*a23*a42*a54*a66 + - a12*a21*a43*a54*a66 + + a11*a22*a43*a54*a66; + cofactor[27] = -a16*a24*a33*a52*a61 + + a14*a26*a33*a52*a61 + + a16*a23*a34*a52*a61 + - a13*a26*a34*a52*a61 + - a14*a23*a36*a52*a61 + + a13*a24*a36*a52*a61 + + a16*a24*a32*a53*a61 + - a14*a26*a32*a53*a61 + - a16*a22*a34*a53*a61 + + a12*a26*a34*a53*a61 + + a14*a22*a36*a53*a61 + - a12*a24*a36*a53*a61 + - a16*a23*a32*a54*a61 + + a13*a26*a32*a54*a61 + + a16*a22*a33*a54*a61 + - a12*a26*a33*a54*a61 + - a13*a22*a36*a54*a61 + + a12*a23*a36*a54*a61 + + a14*a23*a32*a56*a61 + - a13*a24*a32*a56*a61 + - a14*a22*a33*a56*a61 + + a12*a24*a33*a56*a61 + + a13*a22*a34*a56*a61 + - a12*a23*a34*a56*a61 + + a16*a24*a33*a51*a62 + - a14*a26*a33*a51*a62 + - a16*a23*a34*a51*a62 + + a13*a26*a34*a51*a62 + + a14*a23*a36*a51*a62 + - a13*a24*a36*a51*a62 + - a16*a24*a31*a53*a62 + + a14*a26*a31*a53*a62 + + a16*a21*a34*a53*a62 + - a11*a26*a34*a53*a62 + - a14*a21*a36*a53*a62 + + a11*a24*a36*a53*a62 + + a16*a23*a31*a54*a62 + - a13*a26*a31*a54*a62 + - a16*a21*a33*a54*a62 + + a11*a26*a33*a54*a62 + + a13*a21*a36*a54*a62 + - a11*a23*a36*a54*a62 + - a14*a23*a31*a56*a62 + + a13*a24*a31*a56*a62 + + a14*a21*a33*a56*a62 + - a11*a24*a33*a56*a62 + - a13*a21*a34*a56*a62 + + a11*a23*a34*a56*a62 + - a16*a24*a32*a51*a63 + + a14*a26*a32*a51*a63 + + a16*a22*a34*a51*a63 + - a12*a26*a34*a51*a63 + - a14*a22*a36*a51*a63 + + a12*a24*a36*a51*a63 + + a16*a24*a31*a52*a63 + - a14*a26*a31*a52*a63 + - a16*a21*a34*a52*a63 + + a11*a26*a34*a52*a63 + + a14*a21*a36*a52*a63 + - a11*a24*a36*a52*a63 + - a16*a22*a31*a54*a63 + + a12*a26*a31*a54*a63 + + a16*a21*a32*a54*a63 + - a11*a26*a32*a54*a63 + - a12*a21*a36*a54*a63 + + a11*a22*a36*a54*a63 + + a14*a22*a31*a56*a63 + - a12*a24*a31*a56*a63 + - a14*a21*a32*a56*a63 + + a11*a24*a32*a56*a63 + + a12*a21*a34*a56*a63 + - a11*a22*a34*a56*a63 + + a16*a23*a32*a51*a64 + - a13*a26*a32*a51*a64 + - a16*a22*a33*a51*a64 + + a12*a26*a33*a51*a64 + + a13*a22*a36*a51*a64 + - a12*a23*a36*a51*a64 + - a16*a23*a31*a52*a64 + + a13*a26*a31*a52*a64 + + a16*a21*a33*a52*a64 + - a11*a26*a33*a52*a64 + - a13*a21*a36*a52*a64 + + a11*a23*a36*a52*a64 + + a16*a22*a31*a53*a64 + - a12*a26*a31*a53*a64 + - a16*a21*a32*a53*a64 + + a11*a26*a32*a53*a64 + + a12*a21*a36*a53*a64 + - a11*a22*a36*a53*a64 + - a13*a22*a31*a56*a64 + + a12*a23*a31*a56*a64 + + a13*a21*a32*a56*a64 + - a11*a23*a32*a56*a64 + - a12*a21*a33*a56*a64 + + a11*a22*a33*a56*a64 + - a14*a23*a32*a51*a66 + + a13*a24*a32*a51*a66 + + a14*a22*a33*a51*a66 + - a12*a24*a33*a51*a66 + - a13*a22*a34*a51*a66 + + a12*a23*a34*a51*a66 + + a14*a23*a31*a52*a66 + - a13*a24*a31*a52*a66 + - a14*a21*a33*a52*a66 + + a11*a24*a33*a52*a66 + + a13*a21*a34*a52*a66 + - a11*a23*a34*a52*a66 + - a14*a22*a31*a53*a66 + + a12*a24*a31*a53*a66 + + a14*a21*a32*a53*a66 + - a11*a24*a32*a53*a66 + - a12*a21*a34*a53*a66 + + a11*a22*a34*a53*a66 + + a13*a22*a31*a54*a66 + - a12*a23*a31*a54*a66 + - a13*a21*a32*a54*a66 + + a11*a23*a32*a54*a66 + + a12*a21*a33*a54*a66 + - a11*a22*a33*a54*a66; + cofactor[28] = a16*a24*a33*a42*a61 + - a14*a26*a33*a42*a61 + - a16*a23*a34*a42*a61 + + a13*a26*a34*a42*a61 + + a14*a23*a36*a42*a61 + - a13*a24*a36*a42*a61 + - a16*a24*a32*a43*a61 + + a14*a26*a32*a43*a61 + + a16*a22*a34*a43*a61 + - a12*a26*a34*a43*a61 + - a14*a22*a36*a43*a61 + + a12*a24*a36*a43*a61 + + a16*a23*a32*a44*a61 + - a13*a26*a32*a44*a61 + - a16*a22*a33*a44*a61 + + a12*a26*a33*a44*a61 + + a13*a22*a36*a44*a61 + - a12*a23*a36*a44*a61 + - a14*a23*a32*a46*a61 + + a13*a24*a32*a46*a61 + + a14*a22*a33*a46*a61 + - a12*a24*a33*a46*a61 + - a13*a22*a34*a46*a61 + + a12*a23*a34*a46*a61 + - a16*a24*a33*a41*a62 + + a14*a26*a33*a41*a62 + + a16*a23*a34*a41*a62 + - a13*a26*a34*a41*a62 + - a14*a23*a36*a41*a62 + + a13*a24*a36*a41*a62 + + a16*a24*a31*a43*a62 + - a14*a26*a31*a43*a62 + - a16*a21*a34*a43*a62 + + a11*a26*a34*a43*a62 + + a14*a21*a36*a43*a62 + - a11*a24*a36*a43*a62 + - a16*a23*a31*a44*a62 + + a13*a26*a31*a44*a62 + + a16*a21*a33*a44*a62 + - a11*a26*a33*a44*a62 + - a13*a21*a36*a44*a62 + + a11*a23*a36*a44*a62 + + a14*a23*a31*a46*a62 + - a13*a24*a31*a46*a62 + - a14*a21*a33*a46*a62 + + a11*a24*a33*a46*a62 + + a13*a21*a34*a46*a62 + - a11*a23*a34*a46*a62 + + a16*a24*a32*a41*a63 + - a14*a26*a32*a41*a63 + - a16*a22*a34*a41*a63 + + a12*a26*a34*a41*a63 + + a14*a22*a36*a41*a63 + - a12*a24*a36*a41*a63 + - a16*a24*a31*a42*a63 + + a14*a26*a31*a42*a63 + + a16*a21*a34*a42*a63 + - a11*a26*a34*a42*a63 + - a14*a21*a36*a42*a63 + + a11*a24*a36*a42*a63 + + a16*a22*a31*a44*a63 + - a12*a26*a31*a44*a63 + - a16*a21*a32*a44*a63 + + a11*a26*a32*a44*a63 + + a12*a21*a36*a44*a63 + - a11*a22*a36*a44*a63 + - a14*a22*a31*a46*a63 + + a12*a24*a31*a46*a63 + + a14*a21*a32*a46*a63 + - a11*a24*a32*a46*a63 + - a12*a21*a34*a46*a63 + + a11*a22*a34*a46*a63 + - a16*a23*a32*a41*a64 + + a13*a26*a32*a41*a64 + + a16*a22*a33*a41*a64 + - a12*a26*a33*a41*a64 + - a13*a22*a36*a41*a64 + + a12*a23*a36*a41*a64 + + a16*a23*a31*a42*a64 + - a13*a26*a31*a42*a64 + - a16*a21*a33*a42*a64 + + a11*a26*a33*a42*a64 + + a13*a21*a36*a42*a64 + - a11*a23*a36*a42*a64 + - a16*a22*a31*a43*a64 + + a12*a26*a31*a43*a64 + + a16*a21*a32*a43*a64 + - a11*a26*a32*a43*a64 + - a12*a21*a36*a43*a64 + + a11*a22*a36*a43*a64 + + a13*a22*a31*a46*a64 + - a12*a23*a31*a46*a64 + - a13*a21*a32*a46*a64 + + a11*a23*a32*a46*a64 + + a12*a21*a33*a46*a64 + - a11*a22*a33*a46*a64 + + a14*a23*a32*a41*a66 + - a13*a24*a32*a41*a66 + - a14*a22*a33*a41*a66 + + a12*a24*a33*a41*a66 + + a13*a22*a34*a41*a66 + - a12*a23*a34*a41*a66 + - a14*a23*a31*a42*a66 + + a13*a24*a31*a42*a66 + + a14*a21*a33*a42*a66 + - a11*a24*a33*a42*a66 + - a13*a21*a34*a42*a66 + + a11*a23*a34*a42*a66 + + a14*a22*a31*a43*a66 + - a12*a24*a31*a43*a66 + - a14*a21*a32*a43*a66 + + a11*a24*a32*a43*a66 + + a12*a21*a34*a43*a66 + - a11*a22*a34*a43*a66 + - a13*a22*a31*a44*a66 + + a12*a23*a31*a44*a66 + + a13*a21*a32*a44*a66 + - a11*a23*a32*a44*a66 + - a12*a21*a33*a44*a66 + + a11*a22*a33*a44*a66; + cofactor[29] = -a16*a24*a33*a42*a51 + + a14*a26*a33*a42*a51 + + a16*a23*a34*a42*a51 + - a13*a26*a34*a42*a51 + - a14*a23*a36*a42*a51 + + a13*a24*a36*a42*a51 + + a16*a24*a32*a43*a51 + - a14*a26*a32*a43*a51 + - a16*a22*a34*a43*a51 + + a12*a26*a34*a43*a51 + + a14*a22*a36*a43*a51 + - a12*a24*a36*a43*a51 + - a16*a23*a32*a44*a51 + + a13*a26*a32*a44*a51 + + a16*a22*a33*a44*a51 + - a12*a26*a33*a44*a51 + - a13*a22*a36*a44*a51 + + a12*a23*a36*a44*a51 + + a14*a23*a32*a46*a51 + - a13*a24*a32*a46*a51 + - a14*a22*a33*a46*a51 + + a12*a24*a33*a46*a51 + + a13*a22*a34*a46*a51 + - a12*a23*a34*a46*a51 + + a16*a24*a33*a41*a52 + - a14*a26*a33*a41*a52 + - a16*a23*a34*a41*a52 + + a13*a26*a34*a41*a52 + + a14*a23*a36*a41*a52 + - a13*a24*a36*a41*a52 + - a16*a24*a31*a43*a52 + + a14*a26*a31*a43*a52 + + a16*a21*a34*a43*a52 + - a11*a26*a34*a43*a52 + - a14*a21*a36*a43*a52 + + a11*a24*a36*a43*a52 + + a16*a23*a31*a44*a52 + - a13*a26*a31*a44*a52 + - a16*a21*a33*a44*a52 + + a11*a26*a33*a44*a52 + + a13*a21*a36*a44*a52 + - a11*a23*a36*a44*a52 + - a14*a23*a31*a46*a52 + + a13*a24*a31*a46*a52 + + a14*a21*a33*a46*a52 + - a11*a24*a33*a46*a52 + - a13*a21*a34*a46*a52 + + a11*a23*a34*a46*a52 + - a16*a24*a32*a41*a53 + + a14*a26*a32*a41*a53 + + a16*a22*a34*a41*a53 + - a12*a26*a34*a41*a53 + - a14*a22*a36*a41*a53 + + a12*a24*a36*a41*a53 + + a16*a24*a31*a42*a53 + - a14*a26*a31*a42*a53 + - a16*a21*a34*a42*a53 + + a11*a26*a34*a42*a53 + + a14*a21*a36*a42*a53 + - a11*a24*a36*a42*a53 + - a16*a22*a31*a44*a53 + + a12*a26*a31*a44*a53 + + a16*a21*a32*a44*a53 + - a11*a26*a32*a44*a53 + - a12*a21*a36*a44*a53 + + a11*a22*a36*a44*a53 + + a14*a22*a31*a46*a53 + - a12*a24*a31*a46*a53 + - a14*a21*a32*a46*a53 + + a11*a24*a32*a46*a53 + + a12*a21*a34*a46*a53 + - a11*a22*a34*a46*a53 + + a16*a23*a32*a41*a54 + - a13*a26*a32*a41*a54 + - a16*a22*a33*a41*a54 + + a12*a26*a33*a41*a54 + + a13*a22*a36*a41*a54 + - a12*a23*a36*a41*a54 + - a16*a23*a31*a42*a54 + + a13*a26*a31*a42*a54 + + a16*a21*a33*a42*a54 + - a11*a26*a33*a42*a54 + - a13*a21*a36*a42*a54 + + a11*a23*a36*a42*a54 + + a16*a22*a31*a43*a54 + - a12*a26*a31*a43*a54 + - a16*a21*a32*a43*a54 + + a11*a26*a32*a43*a54 + + a12*a21*a36*a43*a54 + - a11*a22*a36*a43*a54 + - a13*a22*a31*a46*a54 + + a12*a23*a31*a46*a54 + + a13*a21*a32*a46*a54 + - a11*a23*a32*a46*a54 + - a12*a21*a33*a46*a54 + + a11*a22*a33*a46*a54 + - a14*a23*a32*a41*a56 + + a13*a24*a32*a41*a56 + + a14*a22*a33*a41*a56 + - a12*a24*a33*a41*a56 + - a13*a22*a34*a41*a56 + + a12*a23*a34*a41*a56 + + a14*a23*a31*a42*a56 + - a13*a24*a31*a42*a56 + - a14*a21*a33*a42*a56 + + a11*a24*a33*a42*a56 + + a13*a21*a34*a42*a56 + - a11*a23*a34*a42*a56 + - a14*a22*a31*a43*a56 + + a12*a24*a31*a43*a56 + + a14*a21*a32*a43*a56 + - a11*a24*a32*a43*a56 + - a12*a21*a34*a43*a56 + + a11*a22*a34*a43*a56 + + a13*a22*a31*a44*a56 + - a12*a23*a31*a44*a56 + - a13*a21*a32*a44*a56 + + a11*a23*a32*a44*a56 + + a12*a21*a33*a44*a56 + - a11*a22*a33*a44*a56; + cofactor[30] = -a25*a34*a43*a52*a61 + + a24*a35*a43*a52*a61 + + a25*a33*a44*a52*a61 + - a23*a35*a44*a52*a61 + - a24*a33*a45*a52*a61 + + a23*a34*a45*a52*a61 + + a25*a34*a42*a53*a61 + - a24*a35*a42*a53*a61 + - a25*a32*a44*a53*a61 + + a22*a35*a44*a53*a61 + + a24*a32*a45*a53*a61 + - a22*a34*a45*a53*a61 + - a25*a33*a42*a54*a61 + + a23*a35*a42*a54*a61 + + a25*a32*a43*a54*a61 + - a22*a35*a43*a54*a61 + - a23*a32*a45*a54*a61 + + a22*a33*a45*a54*a61 + + a24*a33*a42*a55*a61 + - a23*a34*a42*a55*a61 + - a24*a32*a43*a55*a61 + + a22*a34*a43*a55*a61 + + a23*a32*a44*a55*a61 + - a22*a33*a44*a55*a61 + + a25*a34*a43*a51*a62 + - a24*a35*a43*a51*a62 + - a25*a33*a44*a51*a62 + + a23*a35*a44*a51*a62 + + a24*a33*a45*a51*a62 + - a23*a34*a45*a51*a62 + - a25*a34*a41*a53*a62 + + a24*a35*a41*a53*a62 + + a25*a31*a44*a53*a62 + - a21*a35*a44*a53*a62 + - a24*a31*a45*a53*a62 + + a21*a34*a45*a53*a62 + + a25*a33*a41*a54*a62 + - a23*a35*a41*a54*a62 + - a25*a31*a43*a54*a62 + + a21*a35*a43*a54*a62 + + a23*a31*a45*a54*a62 + - a21*a33*a45*a54*a62 + - a24*a33*a41*a55*a62 + + a23*a34*a41*a55*a62 + + a24*a31*a43*a55*a62 + - a21*a34*a43*a55*a62 + - a23*a31*a44*a55*a62 + + a21*a33*a44*a55*a62 + - a25*a34*a42*a51*a63 + + a24*a35*a42*a51*a63 + + a25*a32*a44*a51*a63 + - a22*a35*a44*a51*a63 + - a24*a32*a45*a51*a63 + + a22*a34*a45*a51*a63 + + a25*a34*a41*a52*a63 + - a24*a35*a41*a52*a63 + - a25*a31*a44*a52*a63 + + a21*a35*a44*a52*a63 + + a24*a31*a45*a52*a63 + - a21*a34*a45*a52*a63 + - a25*a32*a41*a54*a63 + + a22*a35*a41*a54*a63 + + a25*a31*a42*a54*a63 + - a21*a35*a42*a54*a63 + - a22*a31*a45*a54*a63 + + a21*a32*a45*a54*a63 + + a24*a32*a41*a55*a63 + - a22*a34*a41*a55*a63 + - a24*a31*a42*a55*a63 + + a21*a34*a42*a55*a63 + + a22*a31*a44*a55*a63 + - a21*a32*a44*a55*a63 + + a25*a33*a42*a51*a64 + - a23*a35*a42*a51*a64 + - a25*a32*a43*a51*a64 + + a22*a35*a43*a51*a64 + + a23*a32*a45*a51*a64 + - a22*a33*a45*a51*a64 + - a25*a33*a41*a52*a64 + + a23*a35*a41*a52*a64 + + a25*a31*a43*a52*a64 + - a21*a35*a43*a52*a64 + - a23*a31*a45*a52*a64 + + a21*a33*a45*a52*a64 + + a25*a32*a41*a53*a64 + - a22*a35*a41*a53*a64 + - a25*a31*a42*a53*a64 + + a21*a35*a42*a53*a64 + + a22*a31*a45*a53*a64 + - a21*a32*a45*a53*a64 + - a23*a32*a41*a55*a64 + + a22*a33*a41*a55*a64 + + a23*a31*a42*a55*a64 + - a21*a33*a42*a55*a64 + - a22*a31*a43*a55*a64 + + a21*a32*a43*a55*a64 + - a24*a33*a42*a51*a65 + + a23*a34*a42*a51*a65 + + a24*a32*a43*a51*a65 + - a22*a34*a43*a51*a65 + - a23*a32*a44*a51*a65 + + a22*a33*a44*a51*a65 + + a24*a33*a41*a52*a65 + - a23*a34*a41*a52*a65 + - a24*a31*a43*a52*a65 + + a21*a34*a43*a52*a65 + + a23*a31*a44*a52*a65 + - a21*a33*a44*a52*a65 + - a24*a32*a41*a53*a65 + + a22*a34*a41*a53*a65 + + a24*a31*a42*a53*a65 + - a21*a34*a42*a53*a65 + - a22*a31*a44*a53*a65 + + a21*a32*a44*a53*a65 + + a23*a32*a41*a54*a65 + - a22*a33*a41*a54*a65 + - a23*a31*a42*a54*a65 + + a21*a33*a42*a54*a65 + + a22*a31*a43*a54*a65 + - a21*a32*a43*a54*a65; + cofactor[31] = a15*a34*a43*a52*a61 + - a14*a35*a43*a52*a61 + - a15*a33*a44*a52*a61 + + a13*a35*a44*a52*a61 + + a14*a33*a45*a52*a61 + - a13*a34*a45*a52*a61 + - a15*a34*a42*a53*a61 + + a14*a35*a42*a53*a61 + + a15*a32*a44*a53*a61 + - a12*a35*a44*a53*a61 + - a14*a32*a45*a53*a61 + + a12*a34*a45*a53*a61 + + a15*a33*a42*a54*a61 + - a13*a35*a42*a54*a61 + - a15*a32*a43*a54*a61 + + a12*a35*a43*a54*a61 + + a13*a32*a45*a54*a61 + - a12*a33*a45*a54*a61 + - a14*a33*a42*a55*a61 + + a13*a34*a42*a55*a61 + + a14*a32*a43*a55*a61 + - a12*a34*a43*a55*a61 + - a13*a32*a44*a55*a61 + + a12*a33*a44*a55*a61 + - a15*a34*a43*a51*a62 + + a14*a35*a43*a51*a62 + + a15*a33*a44*a51*a62 + - a13*a35*a44*a51*a62 + - a14*a33*a45*a51*a62 + + a13*a34*a45*a51*a62 + + a15*a34*a41*a53*a62 + - a14*a35*a41*a53*a62 + - a15*a31*a44*a53*a62 + + a11*a35*a44*a53*a62 + + a14*a31*a45*a53*a62 + - a11*a34*a45*a53*a62 + - a15*a33*a41*a54*a62 + + a13*a35*a41*a54*a62 + + a15*a31*a43*a54*a62 + - a11*a35*a43*a54*a62 + - a13*a31*a45*a54*a62 + + a11*a33*a45*a54*a62 + + a14*a33*a41*a55*a62 + - a13*a34*a41*a55*a62 + - a14*a31*a43*a55*a62 + + a11*a34*a43*a55*a62 + + a13*a31*a44*a55*a62 + - a11*a33*a44*a55*a62 + + a15*a34*a42*a51*a63 + - a14*a35*a42*a51*a63 + - a15*a32*a44*a51*a63 + + a12*a35*a44*a51*a63 + + a14*a32*a45*a51*a63 + - a12*a34*a45*a51*a63 + - a15*a34*a41*a52*a63 + + a14*a35*a41*a52*a63 + + a15*a31*a44*a52*a63 + - a11*a35*a44*a52*a63 + - a14*a31*a45*a52*a63 + + a11*a34*a45*a52*a63 + + a15*a32*a41*a54*a63 + - a12*a35*a41*a54*a63 + - a15*a31*a42*a54*a63 + + a11*a35*a42*a54*a63 + + a12*a31*a45*a54*a63 + - a11*a32*a45*a54*a63 + - a14*a32*a41*a55*a63 + + a12*a34*a41*a55*a63 + + a14*a31*a42*a55*a63 + - a11*a34*a42*a55*a63 + - a12*a31*a44*a55*a63 + + a11*a32*a44*a55*a63 + - a15*a33*a42*a51*a64 + + a13*a35*a42*a51*a64 + + a15*a32*a43*a51*a64 + - a12*a35*a43*a51*a64 + - a13*a32*a45*a51*a64 + + a12*a33*a45*a51*a64 + + a15*a33*a41*a52*a64 + - a13*a35*a41*a52*a64 + - a15*a31*a43*a52*a64 + + a11*a35*a43*a52*a64 + + a13*a31*a45*a52*a64 + - a11*a33*a45*a52*a64 + - a15*a32*a41*a53*a64 + + a12*a35*a41*a53*a64 + + a15*a31*a42*a53*a64 + - a11*a35*a42*a53*a64 + - a12*a31*a45*a53*a64 + + a11*a32*a45*a53*a64 + + a13*a32*a41*a55*a64 + - a12*a33*a41*a55*a64 + - a13*a31*a42*a55*a64 + + a11*a33*a42*a55*a64 + + a12*a31*a43*a55*a64 + - a11*a32*a43*a55*a64 + + a14*a33*a42*a51*a65 + - a13*a34*a42*a51*a65 + - a14*a32*a43*a51*a65 + + a12*a34*a43*a51*a65 + + a13*a32*a44*a51*a65 + - a12*a33*a44*a51*a65 + - a14*a33*a41*a52*a65 + + a13*a34*a41*a52*a65 + + a14*a31*a43*a52*a65 + - a11*a34*a43*a52*a65 + - a13*a31*a44*a52*a65 + + a11*a33*a44*a52*a65 + + a14*a32*a41*a53*a65 + - a12*a34*a41*a53*a65 + - a14*a31*a42*a53*a65 + + a11*a34*a42*a53*a65 + + a12*a31*a44*a53*a65 + - a11*a32*a44*a53*a65 + - a13*a32*a41*a54*a65 + + a12*a33*a41*a54*a65 + + a13*a31*a42*a54*a65 + - a11*a33*a42*a54*a65 + - a12*a31*a43*a54*a65 + + a11*a32*a43*a54*a65; + + cofactor[32] = -a15*a24*a43*a52*a61 + + a14*a25*a43*a52*a61 + + a15*a23*a44*a52*a61 + - a13*a25*a44*a52*a61 + - a14*a23*a45*a52*a61 + + a13*a24*a45*a52*a61 + + a15*a24*a42*a53*a61 + - a14*a25*a42*a53*a61 + - a15*a22*a44*a53*a61 + + a12*a25*a44*a53*a61 + + a14*a22*a45*a53*a61 + - a12*a24*a45*a53*a61 + - a15*a23*a42*a54*a61 + + a13*a25*a42*a54*a61 + + a15*a22*a43*a54*a61 + - a12*a25*a43*a54*a61 + - a13*a22*a45*a54*a61 + + a12*a23*a45*a54*a61 + + a14*a23*a42*a55*a61 + - a13*a24*a42*a55*a61 + - a14*a22*a43*a55*a61 + + a12*a24*a43*a55*a61 + + a13*a22*a44*a55*a61 + - a12*a23*a44*a55*a61 + + a15*a24*a43*a51*a62 + - a14*a25*a43*a51*a62 + - a15*a23*a44*a51*a62 + + a13*a25*a44*a51*a62 + + a14*a23*a45*a51*a62 + - a13*a24*a45*a51*a62 + - a15*a24*a41*a53*a62 + + a14*a25*a41*a53*a62 + + a15*a21*a44*a53*a62 + - a11*a25*a44*a53*a62 + - a14*a21*a45*a53*a62 + + a11*a24*a45*a53*a62 + + a15*a23*a41*a54*a62 + - a13*a25*a41*a54*a62 + - a15*a21*a43*a54*a62 + + a11*a25*a43*a54*a62 + + a13*a21*a45*a54*a62 + - a11*a23*a45*a54*a62 + - a14*a23*a41*a55*a62 + + a13*a24*a41*a55*a62 + + a14*a21*a43*a55*a62 + - a11*a24*a43*a55*a62 + - a13*a21*a44*a55*a62 + + a11*a23*a44*a55*a62 + - a15*a24*a42*a51*a63 + + a14*a25*a42*a51*a63 + + a15*a22*a44*a51*a63 + - a12*a25*a44*a51*a63 + - a14*a22*a45*a51*a63 + + a12*a24*a45*a51*a63 + + a15*a24*a41*a52*a63 + - a14*a25*a41*a52*a63 + - a15*a21*a44*a52*a63 + + a11*a25*a44*a52*a63 + + a14*a21*a45*a52*a63 + - a11*a24*a45*a52*a63 + - a15*a22*a41*a54*a63 + + a12*a25*a41*a54*a63 + + a15*a21*a42*a54*a63 + - a11*a25*a42*a54*a63 + - a12*a21*a45*a54*a63 + + a11*a22*a45*a54*a63 + + a14*a22*a41*a55*a63 + - a12*a24*a41*a55*a63 + - a14*a21*a42*a55*a63 + + a11*a24*a42*a55*a63 + + a12*a21*a44*a55*a63 + - a11*a22*a44*a55*a63 + + a15*a23*a42*a51*a64 + - a13*a25*a42*a51*a64 + - a15*a22*a43*a51*a64 + + a12*a25*a43*a51*a64 + + a13*a22*a45*a51*a64 + - a12*a23*a45*a51*a64 + - a15*a23*a41*a52*a64 + + a13*a25*a41*a52*a64 + + a15*a21*a43*a52*a64 + - a11*a25*a43*a52*a64 + - a13*a21*a45*a52*a64 + + a11*a23*a45*a52*a64 + + a15*a22*a41*a53*a64 + - a12*a25*a41*a53*a64 + - a15*a21*a42*a53*a64 + + a11*a25*a42*a53*a64 + + a12*a21*a45*a53*a64 + - a11*a22*a45*a53*a64 + - a13*a22*a41*a55*a64 + + a12*a23*a41*a55*a64 + + a13*a21*a42*a55*a64 + - a11*a23*a42*a55*a64 + - a12*a21*a43*a55*a64 + + a11*a22*a43*a55*a64 + + - a14*a23*a42*a51*a65 + + a13*a24*a42*a51*a65 + + a14*a22*a43*a51*a65 + - a12*a24*a43*a51*a65 + - a13*a22*a44*a51*a65 + + a12*a23*a44*a51*a65 + + a14*a23*a41*a52*a65 + - a13*a24*a41*a52*a65 + - a14*a21*a43*a52*a65 + + a11*a24*a43*a52*a65 + + a13*a21*a44*a52*a65 + - a11*a23*a44*a52*a65 + - a14*a22*a41*a53*a65 + + a12*a24*a41*a53*a65 + + a14*a21*a42*a53*a65 + - a11*a24*a42*a53*a65 + - a12*a21*a44*a53*a65 + + a11*a22*a44*a53*a65 + + a13*a22*a41*a54*a65 + - a12*a23*a41*a54*a65 + - a13*a21*a42*a54*a65 + + a11*a23*a42*a54*a65 + + a12*a21*a43*a54*a65 + - a11*a22*a43*a54*a65; + cofactor[33] = a15*a24*a33*a52*a61 + - a14*a25*a33*a52*a61 + - a15*a23*a34*a52*a61 + + a13*a25*a34*a52*a61 + + a14*a23*a35*a52*a61 + - a13*a24*a35*a52*a61 + - a15*a24*a32*a53*a61 + + a14*a25*a32*a53*a61 + + a15*a22*a34*a53*a61 + - a12*a25*a34*a53*a61 + - a14*a22*a35*a53*a61 + + a12*a24*a35*a53*a61 + + a15*a23*a32*a54*a61 + - a13*a25*a32*a54*a61 + - a15*a22*a33*a54*a61 + + a12*a25*a33*a54*a61 + + a13*a22*a35*a54*a61 + - a12*a23*a35*a54*a61 + - a14*a23*a32*a55*a61 + + a13*a24*a32*a55*a61 + + a14*a22*a33*a55*a61 + - a12*a24*a33*a55*a61 + - a13*a22*a34*a55*a61 + + a12*a23*a34*a55*a61 + - a15*a24*a33*a51*a62 + + a14*a25*a33*a51*a62 + + a15*a23*a34*a51*a62 + - a13*a25*a34*a51*a62 + - a14*a23*a35*a51*a62 + + a13*a24*a35*a51*a62 + + a15*a24*a31*a53*a62 + - a14*a25*a31*a53*a62 + - a15*a21*a34*a53*a62 + + a11*a25*a34*a53*a62 + + a14*a21*a35*a53*a62 + - a11*a24*a35*a53*a62 + - a15*a23*a31*a54*a62 + + a13*a25*a31*a54*a62 + + a15*a21*a33*a54*a62 + - a11*a25*a33*a54*a62 + - a13*a21*a35*a54*a62 + + a11*a23*a35*a54*a62 + + a14*a23*a31*a55*a62 + - a13*a24*a31*a55*a62 + - a14*a21*a33*a55*a62 + + a11*a24*a33*a55*a62 + + a13*a21*a34*a55*a62 + - a11*a23*a34*a55*a62 + + a15*a24*a32*a51*a63 + - a14*a25*a32*a51*a63 + - a15*a22*a34*a51*a63 + + a12*a25*a34*a51*a63 + + a14*a22*a35*a51*a63 + - a12*a24*a35*a51*a63 + - a15*a24*a31*a52*a63 + + a14*a25*a31*a52*a63 + + a15*a21*a34*a52*a63 + - a11*a25*a34*a52*a63 + - a14*a21*a35*a52*a63 + + a11*a24*a35*a52*a63 + + a15*a22*a31*a54*a63 + - a12*a25*a31*a54*a63 + - a15*a21*a32*a54*a63 + + a11*a25*a32*a54*a63 + + a12*a21*a35*a54*a63 + - a11*a22*a35*a54*a63 + - a14*a22*a31*a55*a63 + + a12*a24*a31*a55*a63 + + a14*a21*a32*a55*a63 + - a11*a24*a32*a55*a63 + - a12*a21*a34*a55*a63 + + a11*a22*a34*a55*a63 + - a15*a23*a32*a51*a64 + + a13*a25*a32*a51*a64 + + a15*a22*a33*a51*a64 + - a12*a25*a33*a51*a64 + - a13*a22*a35*a51*a64 + + a12*a23*a35*a51*a64 + + a15*a23*a31*a52*a64 + - a13*a25*a31*a52*a64 + - a15*a21*a33*a52*a64 + + a11*a25*a33*a52*a64 + + a13*a21*a35*a52*a64 + - a11*a23*a35*a52*a64 + - a15*a22*a31*a53*a64 + + a12*a25*a31*a53*a64 + + a15*a21*a32*a53*a64 + - a11*a25*a32*a53*a64 + - a12*a21*a35*a53*a64 + + a11*a22*a35*a53*a64 + + a13*a22*a31*a55*a64 + - a12*a23*a31*a55*a64 + - a13*a21*a32*a55*a64 + + a11*a23*a32*a55*a64 + + a12*a21*a33*a55*a64 + - a11*a22*a33*a55*a64 + + a14*a23*a32*a51*a65 + - a13*a24*a32*a51*a65 + - a14*a22*a33*a51*a65 + + a12*a24*a33*a51*a65 + + a13*a22*a34*a51*a65 + - a12*a23*a34*a51*a65 + - a14*a23*a31*a52*a65 + + a13*a24*a31*a52*a65 + + a14*a21*a33*a52*a65 + - a11*a24*a33*a52*a65 + - a13*a21*a34*a52*a65 + + a11*a23*a34*a52*a65 + + a14*a22*a31*a53*a65 + - a12*a24*a31*a53*a65 + - a14*a21*a32*a53*a65 + + a11*a24*a32*a53*a65 + + a12*a21*a34*a53*a65 + - a11*a22*a34*a53*a65 + - a13*a22*a31*a54*a65 + + a12*a23*a31*a54*a65 + + a13*a21*a32*a54*a65 + - a11*a23*a32*a54*a65 + - a12*a21*a33*a54*a65 + + a11*a22*a33*a54*a65; + cofactor[34] = -a15*a24*a33*a42*a61 + + a14*a25*a33*a42*a61 + + a15*a23*a34*a42*a61 + - a13*a25*a34*a42*a61 + - a14*a23*a35*a42*a61 + + a13*a24*a35*a42*a61 + + a15*a24*a32*a43*a61 + - a14*a25*a32*a43*a61 + - a15*a22*a34*a43*a61 + + a12*a25*a34*a43*a61 + + a14*a22*a35*a43*a61 + - a12*a24*a35*a43*a61 + - a15*a23*a32*a44*a61 + + a13*a25*a32*a44*a61 + + a15*a22*a33*a44*a61 + - a12*a25*a33*a44*a61 + - a13*a22*a35*a44*a61 + + a12*a23*a35*a44*a61 + + a14*a23*a32*a45*a61 + - a13*a24*a32*a45*a61 + - a14*a22*a33*a45*a61 + + a12*a24*a33*a45*a61 + + a13*a22*a34*a45*a61 + - a12*a23*a34*a45*a61 + + a15*a24*a33*a41*a62 + - a14*a25*a33*a41*a62 + - a15*a23*a34*a41*a62 + + a13*a25*a34*a41*a62 + + a14*a23*a35*a41*a62 + - a13*a24*a35*a41*a62 + - a15*a24*a31*a43*a62 + + a14*a25*a31*a43*a62 + + a15*a21*a34*a43*a62 + - a11*a25*a34*a43*a62 + - a14*a21*a35*a43*a62 + + a11*a24*a35*a43*a62 + + a15*a23*a31*a44*a62 + - a13*a25*a31*a44*a62 + - a15*a21*a33*a44*a62 + + a11*a25*a33*a44*a62 + + a13*a21*a35*a44*a62 + - a11*a23*a35*a44*a62 + - a14*a23*a31*a45*a62 + + a13*a24*a31*a45*a62 + + a14*a21*a33*a45*a62 + - a11*a24*a33*a45*a62 + - a13*a21*a34*a45*a62 + + a11*a23*a34*a45*a62 + - a15*a24*a32*a41*a63 + + a14*a25*a32*a41*a63 + + a15*a22*a34*a41*a63 + - a12*a25*a34*a41*a63 + - a14*a22*a35*a41*a63 + + a12*a24*a35*a41*a63 + + a15*a24*a31*a42*a63 + - a14*a25*a31*a42*a63 + - a15*a21*a34*a42*a63 + + a11*a25*a34*a42*a63 + + a14*a21*a35*a42*a63 + - a11*a24*a35*a42*a63 + - a15*a22*a31*a44*a63 + + a12*a25*a31*a44*a63 + + a15*a21*a32*a44*a63 + - a11*a25*a32*a44*a63 + - a12*a21*a35*a44*a63 + + a11*a22*a35*a44*a63 + + a14*a22*a31*a45*a63 + - a12*a24*a31*a45*a63 + - a14*a21*a32*a45*a63 + + a11*a24*a32*a45*a63 + + a12*a21*a34*a45*a63 + - a11*a22*a34*a45*a63 + + a15*a23*a32*a41*a64 + - a13*a25*a32*a41*a64 + - a15*a22*a33*a41*a64 + + a12*a25*a33*a41*a64 + + a13*a22*a35*a41*a64 + - a12*a23*a35*a41*a64 + - a15*a23*a31*a42*a64 + + a13*a25*a31*a42*a64 + + a15*a21*a33*a42*a64 + - a11*a25*a33*a42*a64 + - a13*a21*a35*a42*a64 + + a11*a23*a35*a42*a64 + + a15*a22*a31*a43*a64 + - a12*a25*a31*a43*a64 + - a15*a21*a32*a43*a64 + + a11*a25*a32*a43*a64 + + a12*a21*a35*a43*a64 + - a11*a22*a35*a43*a64 + - a13*a22*a31*a45*a64 + + a12*a23*a31*a45*a64 + + a13*a21*a32*a45*a64 + - a11*a23*a32*a45*a64 + - a12*a21*a33*a45*a64 + + a11*a22*a33*a45*a64 + - a14*a23*a32*a41*a65 + + a13*a24*a32*a41*a65 + + a14*a22*a33*a41*a65 + - a12*a24*a33*a41*a65 + - a13*a22*a34*a41*a65 + + a12*a23*a34*a41*a65 + + a14*a23*a31*a42*a65 + - a13*a24*a31*a42*a65 + - a14*a21*a33*a42*a65 + + a11*a24*a33*a42*a65 + + a13*a21*a34*a42*a65 + - a11*a23*a34*a42*a65 + - a14*a22*a31*a43*a65 + + a12*a24*a31*a43*a65 + + a14*a21*a32*a43*a65 + - a11*a24*a32*a43*a65 + - a12*a21*a34*a43*a65 + + a11*a22*a34*a43*a65 + + a13*a22*a31*a44*a65 + - a12*a23*a31*a44*a65 + - a13*a21*a32*a44*a65 + + a11*a23*a32*a44*a65 + + a12*a21*a33*a44*a65 + - a11*a22*a33*a44*a65; + cofactor[35] = a15*a24*a33*a42*a51 + - a14*a25*a33*a42*a51 + - a15*a23*a34*a42*a51 + + a13*a25*a34*a42*a51 + + a14*a23*a35*a42*a51 + - a13*a24*a35*a42*a51 + - a15*a24*a32*a43*a51 + + a14*a25*a32*a43*a51 + + a15*a22*a34*a43*a51 + - a12*a25*a34*a43*a51 + - a14*a22*a35*a43*a51 + + a12*a24*a35*a43*a51 + + a15*a23*a32*a44*a51 + - a13*a25*a32*a44*a51 + - a15*a22*a33*a44*a51 + + a12*a25*a33*a44*a51 + + a13*a22*a35*a44*a51 + - a12*a23*a35*a44*a51 + - a14*a23*a32*a45*a51 + + a13*a24*a32*a45*a51 + + a14*a22*a33*a45*a51 + - a12*a24*a33*a45*a51 + - a13*a22*a34*a45*a51 + + a12*a23*a34*a45*a51 + - a15*a24*a33*a41*a52 + + a14*a25*a33*a41*a52 + + a15*a23*a34*a41*a52 + - a13*a25*a34*a41*a52 + - a14*a23*a35*a41*a52 + + a13*a24*a35*a41*a52 + + a15*a24*a31*a43*a52 + - a14*a25*a31*a43*a52 + - a15*a21*a34*a43*a52 + + a11*a25*a34*a43*a52 + + a14*a21*a35*a43*a52 + - a11*a24*a35*a43*a52 + - a15*a23*a31*a44*a52 + + a13*a25*a31*a44*a52 + + a15*a21*a33*a44*a52 + - a11*a25*a33*a44*a52 + - a13*a21*a35*a44*a52 + + a11*a23*a35*a44*a52 + + a14*a23*a31*a45*a52 + - a13*a24*a31*a45*a52 + - a14*a21*a33*a45*a52 + + a11*a24*a33*a45*a52 + + a13*a21*a34*a45*a52 + - a11*a23*a34*a45*a52 + + a15*a24*a32*a41*a53 + - a14*a25*a32*a41*a53 + - a15*a22*a34*a41*a53 + + a12*a25*a34*a41*a53 + + a14*a22*a35*a41*a53 + - a12*a24*a35*a41*a53 + - a15*a24*a31*a42*a53 + + a14*a25*a31*a42*a53 + + a15*a21*a34*a42*a53 + - a11*a25*a34*a42*a53 + - a14*a21*a35*a42*a53 + + a11*a24*a35*a42*a53 + + a15*a22*a31*a44*a53 + - a12*a25*a31*a44*a53 + - a15*a21*a32*a44*a53 + + a11*a25*a32*a44*a53 + + a12*a21*a35*a44*a53 + - a11*a22*a35*a44*a53 + - a14*a22*a31*a45*a53 + + a12*a24*a31*a45*a53 + + a14*a21*a32*a45*a53 + - a11*a24*a32*a45*a53 + - a12*a21*a34*a45*a53 + + a11*a22*a34*a45*a53 + - a15*a23*a32*a41*a54 + + a13*a25*a32*a41*a54 + + a15*a22*a33*a41*a54 + - a12*a25*a33*a41*a54 + - a13*a22*a35*a41*a54 + + a12*a23*a35*a41*a54 + + a15*a23*a31*a42*a54 + - a13*a25*a31*a42*a54 + - a15*a21*a33*a42*a54 + + a11*a25*a33*a42*a54 + + a13*a21*a35*a42*a54 + - a11*a23*a35*a42*a54 + - a15*a22*a31*a43*a54 + + a12*a25*a31*a43*a54 + + a15*a21*a32*a43*a54 + - a11*a25*a32*a43*a54 + - a12*a21*a35*a43*a54 + + a11*a22*a35*a43*a54 + + a13*a22*a31*a45*a54 + - a12*a23*a31*a45*a54 + - a13*a21*a32*a45*a54 + + a11*a23*a32*a45*a54 + + a12*a21*a33*a45*a54 + - a11*a22*a33*a45*a54 + + a14*a23*a32*a41*a55 + - a13*a24*a32*a41*a55 + - a14*a22*a33*a41*a55 + + a12*a24*a33*a41*a55 + + a13*a22*a34*a41*a55 + - a12*a23*a34*a41*a55 + - a14*a23*a31*a42*a55 + + a13*a24*a31*a42*a55 + + a14*a21*a33*a42*a55 + - a11*a24*a33*a42*a55 + - a13*a21*a34*a42*a55 + + a11*a23*a34*a42*a55 + + a14*a22*a31*a43*a55 + - a12*a24*a31*a43*a55 + - a14*a21*a32*a43*a55 + + a11*a24*a32*a43*a55 + + a12*a21*a34*a43*a55 + - a11*a22*a34*a43*a55 + - a13*a22*a31*a44*a55 + + a12*a23*a31*a44*a55 + + a13*a21*a32*a44*a55 + - a11*a23*a32*a44*a55 + - a12*a21*a33*a44*a55 + + a11*a22*a33*a44*a55; + +/* ainv = transpose(cofactor) ! / det */ + const double jinv = 1/det; + ainv[0] = cofactor[0]*jinv; + ainv[1] = cofactor[6]*jinv; + ainv[2] = cofactor[12]*jinv; + ainv[3] = cofactor[18]*jinv; + ainv[4] = cofactor[24]*jinv; + ainv[5] = cofactor[30]*jinv; + ainv[6] = cofactor[1]*jinv; + ainv[7] = cofactor[7]*jinv; + ainv[8] = cofactor[13]*jinv; + ainv[9] = cofactor[19]*jinv; + ainv[10] = cofactor[25]*jinv; + ainv[11] = cofactor[31]*jinv; + ainv[12] = cofactor[2]*jinv; + ainv[13] = cofactor[8]*jinv; + ainv[14] = cofactor[14]*jinv; + ainv[15] = cofactor[20]*jinv; + ainv[16] = cofactor[26]*jinv; + ainv[17] = cofactor[32]*jinv; + ainv[18] = cofactor[3]*jinv; + ainv[19] = cofactor[9]*jinv; + ainv[20] = cofactor[15]*jinv; + ainv[21] = cofactor[21]*jinv; + ainv[22] = cofactor[27]*jinv; + ainv[23] = cofactor[33]*jinv; + ainv[24] = cofactor[4]*jinv; + ainv[25] = cofactor[10]*jinv; + ainv[26] = cofactor[16]*jinv; + ainv[27] = cofactor[22]*jinv; + ainv[28] = cofactor[28]*jinv; + ainv[29] = cofactor[34]*jinv; + ainv[30] = cofactor[5]*jinv; + ainv[31] = cofactor[11]*jinv; + ainv[32] = cofactor[17]*jinv; + ainv[33] = cofactor[23]*jinv; + ainv[34] = cofactor[29]*jinv; + ainv[35] = cofactor[35]*jinv; + + *ok_flag__ = 0; + return 0; +} From 70fba678a187289d7f14ff3549d7afacc44f7e6b Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Tue, 24 Jun 2025 21:02:36 -0700 Subject: [PATCH 097/261] Removing VTK HDF recorder from Makefile --- SRC/recorder/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/recorder/Makefile b/SRC/recorder/Makefile index 675a7516f8..714baae4e6 100644 --- a/SRC/recorder/Makefile +++ b/SRC/recorder/Makefile @@ -23,7 +23,7 @@ OBJS = Recorder.o \ RemoveRecorder.o \ DamageRecorder.o $(GRAPHIC_OBJECTS) \ PVDRecorder.o MPCORecorder.o GmshRecorder.o \ - VTK_Recorder.o VTKHDF_Recorder.o + VTK_Recorder.o # Compilation control From 487f8939dd682e82a4350138328b2c06f7b17055 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Tue, 24 Jun 2025 21:42:37 -0700 Subject: [PATCH 098/261] Turning off print flag --- SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp index 583ab4d38c..47b373313c 100644 --- a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp +++ b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp @@ -323,7 +323,7 @@ ItpackLinSolver::solve(void) iparm[0] = maxIter; // Print flag - iparm[1] = 1; + iparm[1] = 0; // Sparse matrix storage scheme (0 = symmetric, 1 = nonsymmetric) iparm[4] = 1; From fc0c119ef28e1b3481218bff1524be7560a47426 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Tue, 24 Jun 2025 22:36:54 -0700 Subject: [PATCH 099/261] Adding compile notes for test program --- OTHER/ITPACK/README.md | 10 ++++++++++ OTHER/ITPACK/dtst2c.f | 22 +++++++++++----------- 2 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 OTHER/ITPACK/README.md diff --git a/OTHER/ITPACK/README.md b/OTHER/ITPACK/README.md new file mode 100644 index 0000000000..a5ee5fda6e --- /dev/null +++ b/OTHER/ITPACK/README.md @@ -0,0 +1,10 @@ +To compile test problem, `dtst2c.f` + +```console +gfortran -o myprogram dtst2c.f dsrc2c.f jcg.f jsi.f rscg.f rssi.f sor.f ssorcg.f ssorsi.f -lblas +``` + +Additional compilation notes + ++ Rename `IRAND` to `IRANDBLH` (due to name conflict) ++ Changed `PROGRAM` line (on line 1) to `PROGRAM ITPTST` (removed args) diff --git a/OTHER/ITPACK/dtst2c.f b/OTHER/ITPACK/dtst2c.f index cb29465fd9..239b756e58 100644 --- a/OTHER/ITPACK/dtst2c.f +++ b/OTHER/ITPACK/dtst2c.f @@ -1,4 +1,4 @@ - PROGRAM ITPTST (OUTPUT,TAPE6=OUTPUT) + PROGRAM ITPTST C C CHANGES TO BE MADE FOR USE ON DIFFERENT COMPUTERS: C 1. REMOVE OR CHANGE PROGRAM LINE ABOVE OR OPEN LINE BELOW @@ -1608,7 +1608,7 @@ SUBROUTINE SETPER (P,IP) C DO 10 I = 1,N P(I) = I - IP(I) = IRAND(1,N,ISEED) + IP(I) = IRANDBLH(1,N,ISEED) 10 CONTINUE C RETURN @@ -1657,8 +1657,8 @@ SUBROUTINE SETSYS (IA,JA,A,RHS,P,IP,ROW,IROW,IWKSP) C STORE SYMMETRIC SYSTEM OFF-DIAGONAL ELEMENTS C DO 90 K = 1,NZRED - 70 I = IRAND(1,NRED,ISEED) - J = IRAND(NRED+1,N,ISEED) + 70 I = IRANDBLH(1,NRED,ISEED) + J = IRANDBLH(NRED+1,N,ISEED) PI = MIN0(P(I),P(J)) PJ = MAX0(P(I),P(J)) VAL = -DBLE(RANDOM(ISEED)) @@ -1681,8 +1681,8 @@ SUBROUTINE SETSYS (IA,JA,A,RHS,P,IP,ROW,IROW,IWKSP) C STORE NONSYMMETRIC SYSTEM OFF-DIAGONAL ELEMENTS C DO 130 K = 1,NZRED - 120 I = IRAND(1,NRED,ISEED) - J = IRAND(NRED+1,N,ISEED) + 120 I = IRANDBLH(1,NRED,ISEED) + J = IRANDBLH(NRED+1,N,ISEED) PI = P(I) PJ = P(J) VAL = -DBLE(RANDOM(ISEED)) @@ -1693,8 +1693,8 @@ SUBROUTINE SETSYS (IA,JA,A,RHS,P,IP,ROW,IROW,IWKSP) ROW(PI) = ROW(PI)-VAL 130 CONTINUE DO 150 K = 1,NZBLK - 140 I = IRAND(NRED+1,N,ISEED) - J = IRAND(1,NRED,ISEED) + 140 I = IRANDBLH(NRED+1,N,ISEED) + J = IRANDBLH(1,NRED,ISEED) PI = P(I) PJ = P(J) VAL = -DBLE(RANDOM(ISEED)) @@ -1731,7 +1731,7 @@ SUBROUTINE SETSYS (IA,JA,A,RHS,P,IP,ROW,IROW,IWKSP) IF (IER.NE.0) STOP C DO 190 K = 1,N,5 - NBIG = IRAND(1,N,ISEED) + NBIG = IRANDBLH(1,N,ISEED) RHS(NBIG) = EVAL+RHS(NBIG) PI = NBIG PJ = NBIG @@ -2036,7 +2036,7 @@ SUBROUTINE CHKNRM (U,WKSP,DIGIT) C RETURN END - INTEGER FUNCTION IRAND (I,J,ISEED) + INTEGER FUNCTION IRANDBLH (I,J,ISEED) C C***************************************************************** C @@ -2049,7 +2049,7 @@ INTEGER FUNCTION IRAND (I,J,ISEED) C C==================================================================== C - IRAND = IFIX(FLOAT(J-I+1)*RANDOM(ISEED))+I + IRANDBLH = IFIX(FLOAT(J-I+1)*RANDOM(ISEED))+I C RETURN END From 8c1c9841399f8d99b8d9d8f8c443725de6bb375f Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Tue, 24 Jun 2025 22:41:02 -0700 Subject: [PATCH 100/261] Update README.md --- OTHER/ITPACK/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OTHER/ITPACK/README.md b/OTHER/ITPACK/README.md index a5ee5fda6e..d2330530c6 100644 --- a/OTHER/ITPACK/README.md +++ b/OTHER/ITPACK/README.md @@ -7,4 +7,4 @@ gfortran -o myprogram dtst2c.f dsrc2c.f jcg.f jsi.f rscg.f rssi.f sor.f ssorcg.f Additional compilation notes + Rename `IRAND` to `IRANDBLH` (due to name conflict) -+ Changed `PROGRAM` line (on line 1) to `PROGRAM ITPTST` (removed args) ++ Changed line 1 to `PROGRAM ITPTST` (removed args) From 1685efb44361104e85434912d3252ebdf04722c3 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Wed, 25 Jun 2025 13:27:28 -0700 Subject: [PATCH 101/261] Removing output statements and storing symmetric matrix --- SRC/system_of_eqn/linearSOE/itpack/ItpackLinSOE.cpp | 4 +++- .../linearSOE/itpack/ItpackLinSolver.cpp | 11 ++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSOE.cpp b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSOE.cpp index 06430af8b6..f24609fcef 100644 --- a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSOE.cpp +++ b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSOE.cpp @@ -90,7 +90,7 @@ ItpackLinSOE::setSize(Graph &theGraph) } nnz = newNNZ; - opserr << "ItpackLinSOE::setSize - n " << size << " nnz " << nnz << endln; + //opserr << "ItpackLinSOE::setSize - n " << size << " nnz " << nnz << endln; if (nnz > Asize) { // we have to get more space for A and colA @@ -256,6 +256,7 @@ ItpackLinSOE::addA(const Matrix &m, const ID &id, double fact) int endRowLoc = rowStartA[row+1]; for (int j=0; j= 0) { // find place in A using colA for (int k=startRowLoc; k= 0) { // find place in A using colA for (int k=startRowLoc; k Date: Wed, 25 Jun 2025 14:14:35 -0700 Subject: [PATCH 102/261] update, clean and organize --- .../Frame/BasicFrameTransf.h | 174 +++---- .../Frame/BasicFrameTransf.tpp | 13 +- SRC/coordTransformation/Frame/CMakeLists.txt | 2 - .../Frame/EuclidFrameTransf.h | 158 ++++++ .../Frame/EuclidFrameTransf.hpp | 144 ------ .../Frame/EuclidFrameTransf.tpp | 25 +- .../Frame/Isometry/CrisfieldIsometry.tpp | 18 + .../Frame/Isometry/CrisfieldTransform.h | 18 +- .../Frame/Isometry/EuclidIsometry.h | 75 +++ .../Frame/Isometry/RankineIsometry.h | 249 +++++++++ .../Frame/Isometry/RankineIsometry.tpp | 18 + .../Frame/LinearFrameTransf.h | 141 ++++++ .../Frame/LinearFrameTransf.hpp | 126 ----- .../Frame/LinearFrameTransf.tpp | 14 +- .../Frame/PDeltaFrameTransf3d.h | 77 +++ .../Frame/PDeltaFrameTransf3d.hpp | 72 --- .../Frame/PDeltaFrameTransf3d.tpp | 12 +- .../Frame/SouzaFrameTransf.h | 161 ++++++ .../Frame/SouzaFrameTransf.hpp | 148 ------ .../Frame/SouzaFrameTransf.tpp | 474 +++++++++--------- 20 files changed, 1282 insertions(+), 837 deletions(-) create mode 100644 SRC/coordTransformation/Frame/EuclidFrameTransf.h delete mode 100644 SRC/coordTransformation/Frame/EuclidFrameTransf.hpp create mode 100644 SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h create mode 100644 SRC/coordTransformation/Frame/LinearFrameTransf.h delete mode 100644 SRC/coordTransformation/Frame/LinearFrameTransf.hpp create mode 100644 SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h delete mode 100644 SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp create mode 100644 SRC/coordTransformation/Frame/SouzaFrameTransf.h delete mode 100644 SRC/coordTransformation/Frame/SouzaFrameTransf.hpp diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.h b/SRC/coordTransformation/Frame/BasicFrameTransf.h index f76f8dab89..64d1a0f9c0 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.h +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.h @@ -1,17 +1,13 @@ //===----------------------------------------------------------------------===// // // xara -// -//===----------------------------------------------------------------------===// // https://xara.so -//===----------------------------------------------------------------------===// -// -// The purpose of this class is to wrap the more general FrameTransform<> -// templates to reproduce the legacy CrdTransf classes that were derived -// for elements in a "basic" coordinate system. +//----------------------------------------------------------------------------// // -// cmp +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures // +//----------------------------------------------------------------------------// // // Please cite the following resource in any derivative works: // @@ -20,10 +16,19 @@ // https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// + +// +// The purpose of this class is to wrap the more general FrameTransform<> +// templates to reproduce the legacy CrdTransf classes that were derived +// for elements in a "basic" coordinate system. +// +// cmp +// #ifndef BasicFrameTransf3d_h #define BasicFrameTransf3d_h #include +#include #include #include #include @@ -34,88 +39,89 @@ template class BasicFrameTransf3d: public CrdTransf { public: - BasicFrameTransf3d(FrameTransform<2,ndf> *t); - - ~BasicFrameTransf3d(); - - int getLocalAxes(Vector &x, Vector &y, Vector &z) final; - - CrdTransf *getCopy3d() final; - - virtual double getInitialLength(); - virtual double getDeformedLength(); - - int initialize(Node *ni, Node *nj) final; - int update() final; - int commitState() final; - int revertToLastCommit() final; - int revertToStart() final; - - const Vector &getBasicTrialDisp() final; - const Vector &getBasicIncrDisp() final; - const Vector &getBasicIncrDeltaDisp() final; - const Vector &getBasicTrialVel() final; - - const Vector &getGlobalResistingForce(const Vector &basicForce, const Vector &p0) final; - const Matrix &getGlobalStiffMatrix(const Matrix &basicStiff, const Vector &basicForce) final; - const Matrix &getInitialGlobalStiffMatrix(const Matrix &basicStiff) final; - - // rotate consistent mass matrix - const Matrix &getGlobalMatrixFromLocal(const Matrix &local) final; + BasicFrameTransf3d(FrameTransform<2,ndf> *t); + + ~BasicFrameTransf3d(); + + int getLocalAxes(Vector &x, Vector &y, Vector &z) final; + + CrdTransf *getCopy3d() final; + + double getInitialLength() final; + double getDeformedLength() final; + + int initialize(Node *ni, Node *nj) final; + int update() final; + int commitState() final; + int revertToLastCommit() final; + int revertToStart() final; + + const Vector &getBasicTrialDisp() final; + const Vector &getBasicIncrDisp() final; + const Vector &getBasicIncrDeltaDisp() final; + const Vector &getBasicTrialVel() final; + + const Vector &getGlobalResistingForce(const Vector &basicForce, const Vector &p0) final; + const Matrix &getGlobalStiffMatrix(const Matrix &basicStiff, const Vector &basicForce) final; + const Matrix &getInitialGlobalStiffMatrix(const Matrix &basicStiff) final; + + // rotate consistent mass matrix + const Matrix &getGlobalMatrixFromLocal(const Matrix &local) final; + + // methods used in post-processing only + const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); + const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps); + const Vector &getPointLocalDisplFromBasic(double xi, const Vector &basicDisps); + + // + // Sensitivity + // + const Vector & getBasicDisplFixedGrad() final; + const Vector & getBasicDisplTotalGrad(int grad) final; + const Vector &getGlobalResistingForceShapeSensitivity(const Vector &basicForce, const Vector &p0, int grad) final; + bool isShapeSensitivity() final; + double getLengthGrad() final; + double getd1overLdh() final; + + + // MovableObject + int sendSelf(int tag, Channel &) final; + int recvSelf(int tag, Channel &, FEM_ObjectBroker &) final; + const char *getClassType() const final { + return "BasicFrameTransf3d"; + } - // methods used in post-processing only - const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); - const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps); - const Vector &getPointLocalDisplFromBasic( double xi, const Vector &basicDisps); - - // - // Sensitivity - // - const Vector & getBasicDisplFixedGrad(); - const Vector & getBasicDisplTotalGrad(int grad); - const Vector &getGlobalResistingForceShapeSensitivity (const Vector &basicForce, const Vector &p0, int grad); - bool isShapeSensitivity(); - double getLengthGrad(); - double getd1overLdh(); - - - // MovableObject - virtual int sendSelf(int tag, Channel &); - virtual int recvSelf(int tag, Channel &, FEM_ObjectBroker &); - const char *getClassType() const {return "BasicFrameTransf3d";} - - // TaggedObject - void Print(OPS_Stream &s, int flag = 0); + // TaggedObject + void Print(OPS_Stream &s, int flag = 0) final; - FrameTransform<2,ndf> &t; -protected: -private: + FrameTransform<2,ndf> &t; - constexpr static int NBV = 6; - constexpr static int NDF = ndf; - enum : int { - inx = -12, // 0 - iny = -12, // 1 - inz = -12, // 2 - imx = -12, // 3 - imy = 3, // 4 - imz = 1, // 5 - jnx = 0, // 6 - jny = -12, // 7 - jnz = -12, // 8 - jmx = 5, // 9 - jmy = 4, // 10 - jmz = 2, // 11 - }; - - constexpr static int iq[] = { - inx, iny, inz, imx, imy, imz, - jnx, jny, jnz, jmx, jmy, jmz - }; +private: + constexpr static int NBV = 6; + constexpr static int NDF = ndf; + enum : int { + inx = -12, // 0 + iny = -12, // 1 + inz = -12, // 2 + imx = -12, // 3 + imy = 3, // 4 + imz = 1, // 5 + jnx = 0, // 6 + jny = -12, // 7 + jnz = -12, // 8 + jmx = 5, // 9 + jmy = 4, // 10 + jmz = 2, // 11 + }; + + constexpr static int iq[] = { + inx, iny, inz, imx, imy, imz, + jnx, jny, jnz, jmx, jmy, jmz + }; }; } // namespace OpenSees + #include "BasicFrameTransf.tpp" #endif - diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index bc2d479a53..7cb9afa2f4 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -1,11 +1,13 @@ //===----------------------------------------------------------------------===// // // xara -// -//===----------------------------------------------------------------------===// // https://xara.so -//===----------------------------------------------------------------------===// +//----------------------------------------------------------------------------// // +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// // // Please cite the following resource in any derivative works: // @@ -22,8 +24,9 @@ #include #include #include +#include "FrameTransform.h" -using namespace OpenSees; +namespace OpenSees { template BasicFrameTransf3d::BasicFrameTransf3d(FrameTransform<2,ndf> *t) @@ -420,3 +423,5 @@ BasicFrameTransf3d::recvSelf(int cTag, Channel &, { return -1; } + +} diff --git a/SRC/coordTransformation/Frame/CMakeLists.txt b/SRC/coordTransformation/Frame/CMakeLists.txt index e90629c8b8..3ad768efbd 100644 --- a/SRC/coordTransformation/Frame/CMakeLists.txt +++ b/SRC/coordTransformation/Frame/CMakeLists.txt @@ -5,6 +5,4 @@ # #============================================================================== -# target_sources(OPS_Transform PRIVATE BasicFrameTransf.cpp) target_include_directories(OPS_Transform PUBLIC ${CMAKE_CURRENT_LIST_DIR}) - diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h new file mode 100644 index 0000000000..6a10efe3c6 --- /dev/null +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +// +// Description: This file contains the class definition for +// EuclidFrameTransf.h. EuclidFrameTransf provides the +// abstraction of a linear transformation for a spatial frame +// between the global and basic coordinate systems +// +// Written: cmp +// Created: 04/2025 +// +#ifndef EuclidFrameTransf_hpp +#define EuclidFrameTransf_hpp + +#include +#include +#include +#include + +namespace OpenSees { + +template +class EuclidFrameTransf: public FrameTransform +{ +public: + constexpr static int n = nn*ndf; + + EuclidFrameTransf(int tag, + const Vector3D &vecxz, + const std::array *offset=nullptr, + int offset_flags = 0); + + ~EuclidFrameTransf(); + + const char *getClassType() const {return "EuclidFrameTransf";} + + virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; + + virtual FrameTransform *getCopy() const; + + double getInitialLength() final; + double getDeformedLength() final; + const std::array *getRigidOffsets() const final {return offsets;} + + int initialize(std::array& new_nodes) final; + int update() final; + int commit() final; + int revertToLastCommit() final; + int revertToStart() final; + + VectorND getStateVariation() final; + Vector3D getNodePosition(int tag) final; + Versor getNodeRotation(int tag) /* final */; + Vector3D getNodeRotationLogarithm(int tag) final; + + VectorND pushResponse(VectorND&pl) final; + MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + +#if 0 + // method used to rotate consistent mass matrix + const Matrix &getGlobalMatrixFromLocal(const Matrix &local); +#endif + + // Sensitivity + // + bool isShapeSensitivity() final; + double getLengthGrad() final; + double getd1overLdh(); + + // TaggedObject + void Print(OPS_Stream &s, int flag = 0) final; + + +private: + + inline MatrixND + getProjection() { + + MatrixND A{}; + A.addDiagonal(1.0); + + // double L = basis.getLength(); + constexpr Vector3D axis{1, 0, 0}; + constexpr Matrix3D ix = Hat(axis); + MatrixND<3,ndf> Gb{}; + for (int a = 0; a(basis.getRotationGradient(b), 1.0); + // TODO(nn>2): Interpolate coordinate? + A.assemble(ix*Gb, a*ndf , b*ndf, double(a)/double(nn-1)*L); + A.assemble( Gb, a*ndf+3, b*ndf, -1.0); + } + } + + return A; + } + + int computeElemtLengthAndOrient(); + + template + const Vector3D + pullPosition(int node) + { + const Vector &u = (nodes[node]->*Getter)(); + + Vector3D v; + for (int i=0; i<3; i++) + v[i] = u[i]; + + // 1) Offsets + if (offsets) [[unlikely]] { + if (!(offset_flags&OffsetLocal)) { + Vector3D w {u[3], u[4], u[5]}; + v -= offsets->at(node).cross(w); + } + } + + // 2) Constant Rotation + Matrix3D R = basis.getRotation(); + return R^v; + } + + std::array nodes; + std::array ur; // rotation vector + std::array ux; // displacement vector + + std::array *offsets; + int offset_flags; + Matrix3D R0; + Vector3D xi, xj, vz; + double L; // undeformed element length + + BasisT basis; +}; + +} // namespace OpenSees + +#include "EuclidFrameTransf.tpp" + +#endif diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp deleted file mode 100644 index de7cfc9d90..0000000000 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.hpp +++ /dev/null @@ -1,144 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//===----------------------------------------------------------------------===// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures -// -//===----------------------------------------------------------------------===// -// -// Description: This file contains the class definition for -// EuclidFrameTransf.h. EuclidFrameTransf provides the -// abstraction of a linear transformation for a spatial frame -// between the global and basic coordinate systems -// -// Written: cmp -// Created: 04/2025 -// -#ifndef EuclidFrameTransf_hpp -#define EuclidFrameTransf_hpp - -#include -#include -#include -#include - -template -class EuclidFrameTransf: public FrameTransform -{ -public: - constexpr static int n = nn*ndf; - - EuclidFrameTransf(int tag, - const Vector3D &vecxz, - const std::array *offset=nullptr, - int offset_flags = 0); - - ~EuclidFrameTransf(); - - const char *getClassType() const {return "EuclidFrameTransf";} - - virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; - - virtual FrameTransform *getCopy() const; - - double getInitialLength() final; - double getDeformedLength() final; - const std::array *getRigidOffsets() const final {return offsets;} - - int initialize(std::array& new_nodes) final; - int update() final; - int commit() final; - int revertToLastCommit() final; - int revertToStart() final; - - VectorND getStateVariation() final; - Vector3D getNodePosition(int tag) final; - Versor getNodeRotation(int tag) /* final */; - Vector3D getNodeRotationLogarithm(int tag) final; - - VectorND pushResponse(VectorND&pl) final; - MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - -#if 0 - // method used to rotate consistent mass matrix - const Matrix &getGlobalMatrixFromLocal(const Matrix &local); -#endif - - // Sensitivity - // - bool isShapeSensitivity() final; - double getLengthGrad() final; - double getd1overLdh(); - - // TaggedObject - void Print(OPS_Stream &s, int flag = 0) override; - -private: - - inline MatrixND - getProjection() { - - MatrixND A{}; - A.addDiagonal(1.0); - - // double L = basis.getLength(); - constexpr Vector3D axis{1, 0, 0}; - constexpr Matrix3D ix = Hat(axis); - MatrixND<3,ndf> Gb{}; - for (int a = 0; a(basis.getRotationGradient(b), 1.0); - // TODO(nn>2): Interpolate coordinate? - A.assemble(ix*Gb, a*ndf , b*ndf, double(a)/double(nn-1)*L); - A.assemble( Gb, a*ndf+3, b*ndf, -1.0); - } - } - - return A; - } - - int computeElemtLengthAndOrient(); - - template - const Vector3D - pullPosition(int node) - { - const Vector &u = (nodes[node]->*Getter)(); - - Vector3D v; - for (int i=0; i<3; i++) - v[i] = u[i]; - - // 1) Offsets - if (offsets) [[unlikely]] { - if (!(offset_flags&OffsetLocal)) { - Vector3D w {u[3], u[4], u[5]}; - v -= offsets->at(node).cross(w); - } - } - - // 2) Constant Rotation - Matrix3D R = basis.getRotation(); - return R^v; - } - - std::array nodes; - std::array ur; // rotation vector - std::array ux; // displacement vector - - std::array *offsets; - int offset_flags; - Matrix3D R0; - Vector3D xi, xj, vz; - double L; // undeformed element length - - BasisT basis; -}; - -#include "EuclidFrameTransf.tpp" -#endif - diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 135864f2cb..872c3673ec 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -2,36 +2,39 @@ // // xara // https://xara.so -//===----------------------------------------------------------------------===// +//----------------------------------------------------------------------------// // -// FEDEASLab +// FEDEASLab // Finite Elements for Design Evaluation and Analysis of Structures // -//===----------------------------------------------------------------------===// +//----------------------------------------------------------------------------// // -// Description: This file contains the implementation for the -// EuclidFrameTransf class. EuclidFrameTransf is a nonlinear transformation -// for a space frame. +// Please cite the following resource in any derivative works: // // [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // +//===----------------------------------------------------------------------===// + +// +// Description: This file contains the implementation for the +// EuclidFrameTransf class. EuclidFrameTransf is a nonlinear transformation +// for a space frame. +// // Written: cmp // Created: 04/2025 // -//===----------------------------------------------------------------------===// #pragma once #include #include #include #include -#include #include #include -#include +#include "EuclidFrameTransf.h" -using namespace OpenSees; +namespace OpenSees { template @@ -96,7 +99,6 @@ template int EuclidFrameTransf::initialize(std::array& new_nodes) { - for (int i=0; i::Print(OPS_Stream &s, int flag) } } +} \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp index e69de29bb2..1017532ab9 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h index c4e15872f7..40b0477b95 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h @@ -1,11 +1,22 @@ //===----------------------------------------------------------------------===// // // xara -// -//===----------------------------------------------------------------------===// // https://xara.so -//===----------------------------------------------------------------------===// +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// // +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + #pragma once #include #include @@ -93,7 +104,6 @@ class CrisfieldTransform { { return e[0]; } - constexpr const Vector3D& getBasisE2() const noexcept { diff --git a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h new file mode 100644 index 0000000000..bf9aa35545 --- /dev/null +++ b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRIAD C2 +namespace OpenSees { + +class Isometry +{ +public: + virtual int initialize() =0; + virtual int update() =0; + + virtual double getLength() const =0; + // x, \Lambda + virtual Matrix3D getRotation() const =0; + virtual Vector3D getPosition() =0; + // \psi + virtual Vector3D getPositionVariation(int ndf, double* du) =0; + virtual Vector3D getRotationVariation(int ndf, double* du) =0; + virtual Matrix3D getRotationDelta() =0; + // + virtual MatrixND<3,6> getRotationGradient(int node) =0; + +}; + + +template +class AlignedIsometry : public Isometry +{ +public: + + virtual Vector3D + getRotationVariation(int ndf, double* du) { + // psi_r = omega + Vector3D w{}; + for (int i=0; igetIncrDeltaDisp(); + auto Wi = this->getRotationGradient(i); + for (int j=0; j<3; j++) + for (int k=0; k<6; k++) + w[j] += Wi(j,k) * du[ndf*i + k]; + } + return w; + } + +protected: +}; + +} // namespace OpenSees diff --git a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h b/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h index e69de29bb2..8963a7accb 100644 --- a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h @@ -0,0 +1,249 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// +#include +#include +#include +#include +#include "EuclidIsometry.h" + +class Node; + +namespace OpenSees { + +template +class RankineIsometry : public AlignedIsometry +{ +public: + RankineIsometry(std::array& nodes, const Vector3D& vecxz) + : nodes{nodes}, vz(vecxz), Xc{}, c{}, R{} + { + } + + void + setOffsets(std::array* offsets) { + this->offsets = offsets; + } + + virtual int + initialize() { + + for (int i=0; igetTrialRotation(); + + const Vector &XI = nodes[ 0]->getCrds(); + const Vector &XJ = nodes[nn-1]->getCrds(); + + for (int i=0; i<3; i++) + dX[i] = XJ[i] - XI[i]; + + L = dX.norm(); + Ln = L; + Vector3D e1 = dX/L; + + // + Vector3D e2 = vz.cross(e1); + + const double ynorm = e2.norm(); + + if (ynorm == 0.0) + return -1; + + e2 /= ynorm; + + Vector3D e3 = e1.cross(e2); + + e2 = e3.cross(e1); + + for (int i = 0; i < 3; i++) { + R[init](i,0) = e1[i]; + R[init](i,1) = e2[i]; + R[init](i,2) = e3[i]; + } + +#if 1 + Xc = nodes[ic]->getCrds(); + c[init] = R[init]^(Xc); +#endif + + update(); + return 0; + } + + virtual int + update() { + + Vector3D e1 = dX; + { + // + // Update state + // + { + const Vector& uI = nodes[ 0]->getTrialDisp(); + const Vector& uJ = nodes[nn-1]->getTrialDisp(); + for (int k = 0; k < 3; k++) + e1[k] += uJ(k) - uI(k); + + if (offsets != nullptr) [[unlikely]] { + e1.addVector(1.0, (*offsets)[ 0], 1.0); + e1.addVector(1.0, nodes[0]->getTrialRotation().rotate((*offsets)[0]), -1.0); + e1.addVector(1.0, (*offsets)[nn-1], -1.0); + e1.addVector(1.0, nodes[nn-1]->getTrialRotation().rotate((*offsets)[nn-1]), 1.0); + } + + // Calculate the deformed length + Ln = e1.norm(); + + if (Ln == 0.0) [[unlikely]] { + opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; + return -2; + } + + e1 /= Ln; + } + } + + { +#if 1 // TRIAD==R2 + constexpr static Vector3D D2 {0,1,0}; + const Vector3D E2 = R[init]*D2; + Vector3D e2 = MatrixFromVersor(nodes[0]->getTrialRotation())*E2; //*R[init]; + e2.addVector(0.5, MatrixFromVersor(nodes[1]->getTrialRotation())*E2, 0.5); + n = e2[0]/e2[1]; + Vector3D e3 = e1.cross(e2); + e3 /= e3.norm(); + + e2 = e3.cross(e1); + + for (int i = 0; i < 3; i++) { + R[pres](i,0) = e1[i]; + R[pres](i,1) = e2[i]; + R[pres](i,2) = e3[i]; + } + +#elif 1 // TRIAD==C2 + Versor q0 = VersorFromMatrix(R[init]); + Versor qI = nodes[0]->getTrialRotation()*q0; + Versor qJ = nodes[nn-1]->getTrialRotation()*q0; + Vector3D gammaw = CayleyFromVersor(qJ.mult_conj(qI)); + + gammaw *= 0.5; + + // Qbar = VersorProduct(VersorFromMatrix(CaySO3(gammaw)), qI); + Matrix3D Rbar = CaySO3(gammaw)*MatrixFromVersor(qI); // *q0); + Vector3D v { Rbar(0,0), Rbar(1,0), Rbar(2,0) }; + double dot = v.dot(e1); + if (std::fabs(std::fabs(dot)-1.0) < 1.0e-10) { + R[pres] = Rbar; + } else { + v = v.cross(e1); + double scale = std::acos(dot)/v.norm(); + v *= scale; // ::acos(r1.dot(e1)); + + R[pres] = ExpSO3(v)*Rbar; + + Vector3D r1 { R[pres](0,0), R[pres](1,0), R[pres](2,0) }; + Vector3D r2 { R[pres](0,1), R[pres](1,1), R[pres](2,1) }; + Vector3D r3 { R[pres](0,2), R[pres](1,2), R[pres](2,2) }; + // opserr << Vector(r1-e1); + // R[pres] = Rbar^ExpSO3(v); + } +#else + Vector3D e2 = vz.cross(e1); +#endif + } + + Vector3D uc = nodes[ic]->getTrialDisp(); + if (offsets != nullptr) { + uc.addVector(1.0, (*offsets)[ic], -1.0); + uc.addVector(1.0, nodes[ic]->getTrialRotation().rotate((*offsets)[ic]), 1.0); + } + Vector3D X = nodes[ic]->getCrds(); + c[pres] = R[pres]^(X + uc); + return 0; + }; + + virtual MatrixND<3,6> + getRotationGradient(int node) { + MatrixND<3,6> Gb{}; + + constexpr Vector3D axis{1, 0, 0}; + constexpr Matrix3D ix = Hat(axis); + constexpr Matrix3D ioi = axis.bun(axis); + + Gb.template insert<0, 3>(ioi, 0.5); + if (node == 0) + Gb.template insert<0,0>(ix, -1/Ln); + else if (node == nn-1) + Gb.template insert<0,0>(ix, 1/Ln); + + Gb(0,2) = (node == 0? 1.0 : -1.0)*n; + return Gb; + } + + virtual double + getLength() const override { + return Ln; + } + + virtual Matrix3D + getRotation() const override { + return R[pres]; + } + + virtual Matrix3D + getRotationDelta() { + return R[pres] - R[init]; + } + + Vector3D + getLocation() { + return c[pres]; + } + + virtual Vector3D + getPosition() { + // Return Delta c + Vector3D X = nodes[ic]->getCrds(); + Vector3D Dc = c[pres] - (R[init]^X) ; // (R[pres]^c[init]); + return Dc; + } + + virtual Vector3D + getPositionVariation(int ndf, double* du) { + return Vector3D {du[ndf*ic+0], du[ndf*ic+1], du[ndf*ic+2]}; + } + +private: + constexpr static int ic = 0; // std::floor(0.5*(nn+1)); + enum { pres, prev, init}; + double L, Ln; + Vector3D vz, dX, Xc; + Matrix3D R[3]; + Vector3D c[3]; + Matrix3D dR; + std::array& nodes; + std::array* offsets = nullptr; // offsets + + double n = 0, + n11 = 1, + n12 = 0, + n21 = 0, + n22 = 1; +}; +} // namespace OpenSees \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.tpp b/SRC/coordTransformation/Frame/Isometry/RankineIsometry.tpp index e69de29bb2..1017532ab9 100644 --- a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.tpp +++ b/SRC/coordTransformation/Frame/Isometry/RankineIsometry.tpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.h b/SRC/coordTransformation/Frame/LinearFrameTransf.h new file mode 100644 index 0000000000..9d3776d703 --- /dev/null +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.h @@ -0,0 +1,141 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +// +// Description: This file contains the class definition for +// LinearFrameTransf.h. LinearFrameTransf provides the +// abstraction of a linear transformation for a spatial frame +// between the global and basic coordinate systems +// +// Adapted: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) +// +#ifndef LinearFrameTransf_hpp +#define LinearFrameTransf_hpp + +#include +#include +#include +#include + +namespace OpenSees { +template +class LinearFrameTransf: public FrameTransform +{ +public: + constexpr static int n = nn*ndf; + + LinearFrameTransf(int tag, + const Vector3D &vecxz, + const std::array *offset=nullptr, + int offset_flags = 0); + + ~LinearFrameTransf(); + + const char *getClassType() const {return "LinearFrameTransf";} + + virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; + + virtual FrameTransform *getCopy() const; + + double getInitialLength() final; + double getDeformedLength() final; + const std::array *getRigidOffsets() const final {return offsets;} + + int initialize(std::array& new_nodes) final; + int update() final; + int commit() final; + int revertToLastCommit() final; + int revertToStart() final; + + VectorND getStateVariation() final; + Vector3D getNodePosition(int tag) final; + Vector3D getNodeRotationLogarithm(int tag) final; + + VectorND pushResponse(VectorND&pl) final; + MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + + // // method used to rotate consistent mass matrix + // const Matrix &getGlobalMatrixFromLocal(const Matrix &local); + + + // Sensitivity + // + const Vector & getBasicDisplFixedGrad(); + const Vector & getBasicDisplTotalGrad(int gradNumber); + const Vector &getGlobalResistingForceShapeSensitivity (const Vector &basicForce, const Vector &p0, int grad); + bool isShapeSensitivity() final; + double getLengthGrad() final; + double getd1overLdh() final; + + // TaggedObject + void Print(OPS_Stream &s, int flag = 0) final; + + // Personal + Vector3D getDelta() {return Du;} + +private: + + int computeElemtLengthAndOrient(); + + inline VectorND + pullConstant(const VectorND& ug, + const Matrix3D& R, + const std::array *offset = nullptr, + int offset_flags = 0); + + template + const Vector3D + pullPosition(int node) + { + const Vector &u = (nodes[node]->*Getter)(); + + Vector3D v; + for (int i=0; i<3; i++) + v[i] = u[i]; + + // 1) Offsets + if (offsets) { + if (!(offset_flags&OffsetLocal)) { + Vector3D w {u[3], u[4], u[5]}; + v -= offsets->at(node).cross(w); + } + } + + // 2) Constant Rotation + return R^v; + } + + std::array nodes; + Vector3D Du; + + std::array *offsets; + int offset_flags; + + Vector3D xi, xj, vz; + Matrix3D R; // rotation matrix + double L; // undeformed element length + + std::array*, nn> u_init; + bool initialDispChecked; +}; +} + +#include "LinearFrameTransf.tpp" +#endif + diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.hpp b/SRC/coordTransformation/Frame/LinearFrameTransf.hpp deleted file mode 100644 index acb2edef89..0000000000 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.hpp +++ /dev/null @@ -1,126 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// -// -// Description: This file contains the class definition for -// LinearFrameTransf.h. LinearFrameTransf provides the -// abstraction of a linear transformation for a spatial frame -// between the global and basic coordinate systems -// -// Written: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) -// Created: 04/2000 -// -#ifndef LinearFrameTransf_hpp -#define LinearFrameTransf_hpp - -#include -#include -#include -#include - -template -class LinearFrameTransf: public FrameTransform -{ -public: - constexpr static int n = nn*ndf; - - LinearFrameTransf(int tag, - const Vector3D &vecxz, - const std::array *offset=nullptr, - int offset_flags = 0); - - ~LinearFrameTransf(); - - const char *getClassType() const {return "LinearFrameTransf";} - - virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; - - virtual FrameTransform *getCopy() const; - - virtual double getInitialLength(); - virtual double getDeformedLength(); - virtual const std::array *getRigidOffsets() const {return offsets;} - - int initialize(std::array& new_nodes) final; - int update() final; - int commit() final; - int revertToLastCommit() final; - int revertToStart() final; - - VectorND getStateVariation() final; - Vector3D getNodePosition(int tag) final; - Vector3D getNodeRotationLogarithm(int tag) final; - - virtual VectorND pushResponse(VectorND&pl) final; - virtual MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - - // // method used to rotate consistent mass matrix - // const Matrix &getGlobalMatrixFromLocal(const Matrix &local); - - - // Sensitivity - // - const Vector & getBasicDisplFixedGrad(); - const Vector & getBasicDisplTotalGrad(int gradNumber); - const Vector &getGlobalResistingForceShapeSensitivity (const Vector &basicForce, const Vector &p0, int grad); - bool isShapeSensitivity() final; - double getLengthGrad() final; - double getd1overLdh() final; - - // TaggedObject - void Print(OPS_Stream &s, int flag = 0) final; - - // Personal - Vector3D getDelta() {return Du;} - -private: - - int computeElemtLengthAndOrient(); - - inline VectorND - pullConstant(const VectorND& ug, - const Matrix3D& R, - const std::array *offset = nullptr, - int offset_flags = 0); - - template - const Vector3D - pullPosition(int node) - { - const Vector &u = (nodes[node]->*Getter)(); - - Vector3D v; - for (int i=0; i<3; i++) - v[i] = u[i]; - - // 1) Offsets - if (offsets) { - if (!(offset_flags&OffsetLocal)) { - Vector3D w {u[3], u[4], u[5]}; - v -= offsets->at(node).cross(w); - } - } - - // 2) Constant Rotation - return R^v; - } - - std::array nodes; - Vector3D Du; - - std::array *offsets; - int offset_flags; - - Vector3D xi, xj, vz; - Matrix3D R; // rotation matrix - double L; // undeformed element length - - std::array*, nn> u_init; - bool initialDispChecked; -}; - -#include "LinearFrameTransf.tpp" -#endif - diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index cb7c3b9527..d0d6d18908 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -2,8 +2,12 @@ // // xara // https://xara.so +//----------------------------------------------------------------------------// // -//===----------------------------------------------------------------------===// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// // // Please cite the following resource in any derivative works: // @@ -12,6 +16,7 @@ // https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// + // // Description: This file contains the implementation for the // LinearFrameTransf class. LinearFrameTransf is a linear @@ -27,12 +32,11 @@ #include #include #include -#include #include #include -#include +#include "LinearFrameTransf.h" -using namespace OpenSees; +namespace OpenSees { static inline MatrixND<3,3> FrameOrientationGradient(const Vector3D& xi, const Vector3D& xj, @@ -341,7 +345,6 @@ template VectorND LinearFrameTransf::getStateVariation() { - static VectorND ug; for (int i=0; igetIncrDeltaDisp(); @@ -686,3 +689,4 @@ LinearFrameTransf::Print(OPS_Stream &s, int flag) } } +} // namespace OpenSees \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h new file mode 100644 index 0000000000..7082dd7e76 --- /dev/null +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Description: This file contains the class definition for +// PDeltaFrameTransf.h. PDeltaFrameTransf provides the +// abstraction of a linear transformation for a spatial frame +// between the global and basic coordinate systems +// +// Adapted: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) +// Created: 04/2000 +// +#ifndef PDeltaFrameTransf_h +#define PDeltaFrameTransf_h + +#include +#include +#include +#include +#include +#include + +namespace OpenSees { + +template +class PDeltaFrameTransf: public FrameTransform +{ +public: + + PDeltaFrameTransf(int tag, + const Vector3D &vecxz, + const std::array *offset=nullptr, + int offset_flags = 0); + + ~PDeltaFrameTransf(); + + const char *getClassType() const {return "PDeltaFrameTransf";} + + double getInitialLength() final; + double getDeformedLength() final; + + int initialize(std::array& new_nodes) final; + int update() final; + int commit() final; + int revertToLastCommit() final; + int revertToStart() final; + + VectorND getStateVariation() final; + Vector3D getNodePosition(int tag) final; + Vector3D getNodeRotationLogarithm(int tag) final; + const std::array *getRigidOffsets() const final { return linear.getRigidOffsets();} + + VectorND pushResponse(VectorND&pl) final; + MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + + FrameTransform *getCopy() const final; + + int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const final; + + // Sensitivity + double getLengthGrad() final; + + // Tagged Object + void Print(OPS_Stream &s, int flag = 0) final; + +private: + int offset_flags; + LinearFrameTransf linear; + +}; +} +#include "PDeltaFrameTransf3d.tpp" +#endif diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp deleted file mode 100644 index f2fe843c4b..0000000000 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.hpp +++ /dev/null @@ -1,72 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// -//===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// -// -// Description: This file contains the class definition for -// PDeltaFrameTransf.h. PDeltaFrameTransf provides the -// abstraction of a linear transformation for a spatial frame -// between the global and basic coordinate systems -// -// Adapted: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) -// Created: 04/2000 -// -#ifndef PDeltaFrameTransf_h -#define PDeltaFrameTransf_h - -#include -#include -#include -#include - -template -class PDeltaFrameTransf: public FrameTransform -{ -public: - - PDeltaFrameTransf(int tag, - const Vector3D &vecxz, - const std::array *offset=nullptr, - int offset_flags = 0); - - ~PDeltaFrameTransf(); - - const char *getClassType() const {return "PDeltaFrameTransf";} - - double getInitialLength(); - double getDeformedLength(); - - int initialize(std::array& new_nodes) final; - int update() final; - int commit() final; - int revertToLastCommit() final; - int revertToStart() final; - - VectorND getStateVariation() final; - Vector3D getNodePosition(int tag) final; - Vector3D getNodeRotationLogarithm(int tag) final; - const std::array *getRigidOffsets() const final { return linear.getRigidOffsets();} - - virtual VectorND pushResponse(VectorND&pl) final; - virtual MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - - FrameTransform *getCopy() const final; - - int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const final; - - // Sensitivity - double getLengthGrad() final; - - // Tagged Object - void Print(OPS_Stream &s, int flag = 0) final; - - private: - int offset_flags; - LinearFrameTransf linear; - -}; -#include "PDeltaFrameTransf3d.tpp" -#endif diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp index 24b65db4b4..c22c2d963a 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp @@ -14,18 +14,16 @@ // Adapted: Remo Magalhaes de Souza // 04/2000 // +// Written: cmp +// #include #include #include #include -#include -#include -#include - -using OpenSees::Matrix3D; -#define THREAD_LOCAL static +#include "PDeltaFrameTransf3d.h" +namespace OpenSees { template PDeltaFrameTransf::PDeltaFrameTransf(int tag, @@ -194,3 +192,5 @@ PDeltaFrameTransf::Print(OPS_Stream &s, int flag) { linear.Print(s, flag); } + +} \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.h b/SRC/coordTransformation/Frame/SouzaFrameTransf.h new file mode 100644 index 0000000000..70385ae384 --- /dev/null +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.h @@ -0,0 +1,161 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +// +// Description: This file contains the class definition for +// SouzaFrameTransf. SouzaFrameTransf implements the formulation +// of Crisfield (1990) with the objective of maintaining the +// original "Corotational" implementation by Remo Magalhaes de Souza, within +// the new framework proposed by Perez and Filippou (2024). +// +// Written by : cmp, March 2024 +// +// Adapted from work by: Remo Magalhaes de Souza +// +#ifndef SouzaFrameTransf_hpp +#define SouzaFrameTransf_hpp + +#include +#include "FrameTransform.h" +#include +#include +#include +#include +#include +#include "Isometry/CrisfieldTransform.h" + +struct Triad; + +namespace OpenSees { + +template +class SouzaFrameTransf: public FrameTransform +{ +public: + SouzaFrameTransf(int tag, const Vector3D &vecxz, + const std::array *offset=nullptr, + int offset_flags = 0); + + ~SouzaFrameTransf(); + + const char *getClassType() const { + return "SouzaFrameTransf"; + } + + // NOTE: maybe add arg for rotation parameterization + FrameTransform *getCopy() const final; + + int initialize(std::array& new_nodes) final; + int update() final; + int commit() final; + int revertToLastCommit() final; + int revertToStart() final; + int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const final; + const std::array *getRigidOffsets() const final { return offsets; } + + double getInitialLength(); + double getDeformedLength(); + + VectorND getStateVariation() final; + Vector3D getNodePosition(int tag) final; + Vector3D getNodeRotationLogarithm(int tag) final; + + VectorND pushResponse(VectorND&pl) final; + MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + + // Sensitivity + double getLengthGrad() final; + virtual const Vector &getBasicDisplTotalGrad(int grad); + virtual const Vector &getBasicDisplFixedGrad(); + virtual const Vector &getGlobalResistingForceShapeSensitivity(const Vector &pb, const Vector &p0, int gradNumber); + + // Tagged Object + void Print(OPS_Stream &s, int flag = 0) final; + +protected: + int addTangent(MatrixND<12,12>& M, const VectorND<12>& pl); + + VectorND<6> pushResponse(const VectorND<6>& pa, int a, int b); +#if 0 + // MatrixND<6,6> pushResponse(const MatrixND<6,6>& K, const VectorND<12>& pl, int a, int b); + // int addTangent(MatrixND<6,6>& K, const VectorND<6>& p, int a, int b, int c); +#endif + +private: + constexpr static int n = nn*ndf; + + // compute the transformation matrix + void compTransfMatrixBasicGlobal(const Versor&, const Versor*); + + enum { + inx= 0, // axial + iny= 1, // Vy + inz= 2, // Vz + imx= 3, // torsion + imy= 4, // rot y I + imz= 5, // rot z I + + jnx= 6, // axial + jny= 7, + jnz= 8, + jmx= 9, // torsion + jmy=10, // rot y J + jmz=11, // rot z J + }; + + // + // Member data + // + std::array nodes; + + Vector3D xAxis; // local x axis + Vector3D vz; // Vector that lies in local plane xz + Vector3D dX; + + std::array *offsets; + + double *nodeIInitialDisp, *nodeJInitialDisp; + bool initialDispChecked; + + double L; // initial element length + double Ln; // current element length (at trial state) + + Versor Q_past[nn]; // commited rotations + Versor Q_pres[nn]; // trial rotations + + Vector3D alphaI; // last trial rotations end i + Vector3D alphaJ; // last trial rotatations end j + + VectorND ul; // local displacements (size=7) + Vector3D vr[nn]; // + VectorND ulcommit; // commited local displacements + VectorND ulpr; // previous local displacements + + OpenSees::MatrixND T; // transformation from local to global system + + OpenSees::Matrix3D R0; // rotation from local to global coordinates + CrisfieldTransform crs; + + // Static workspace variables + Matrix3D A; + MatrixND<12,3> Lr2, Lr3; // auxiliary matrices +}; +} // namespace OpenSees +#include "SouzaFrameTransf.tpp" +#endif diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp deleted file mode 100644 index 8940a73821..0000000000 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.hpp +++ /dev/null @@ -1,148 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// -//===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// -// -// Description: This file contains the class definition for -// SouzaFrameTransf. SouzaFrameTransf implements the formulation -// of Crisfield (1990) with the objective of maintaining the -// original "Corotational" implementation by Remo Magalhaes de Souza, within -// the new framework proposed by Perez and Filippou (2024). -// -// Written by : cmp, March 2024 -// -// Adapted from work by: Remo Magalhaes de Souza -// -#ifndef SouzaFrameTransf_hpp -#define SouzaFrameTransf_hpp - -#include -#include "FrameTransform.h" -#include -#include -#include -#include -#include -#include "Isometry/CrisfieldTransform.h" - -struct Triad; -using namespace OpenSees; // TODO: Clean namespace use - -template -class SouzaFrameTransf: public FrameTransform -{ -public: - SouzaFrameTransf(int tag, const Vector3D &vecxz, - const std::array *offset=nullptr, - int offset_flags = 0); - - ~SouzaFrameTransf(); - - const char *getClassType() const { - return "SouzaFrameTransf"; - } - - // NOTE: maybe add arg for rotation parameterization - FrameTransform *getCopy() const; - - int initialize(std::array& new_nodes) final; - int update() final; - int commit() final; - int revertToLastCommit() final; - int revertToStart() final; - int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const final; - const std::array *getRigidOffsets() const final { return offsets; } - - double getInitialLength(); - double getDeformedLength(); - - VectorND getStateVariation() final; - Vector3D getNodePosition(int tag) final; - Vector3D getNodeRotationLogarithm(int tag) final; - - VectorND pushResponse(VectorND&pl) final; - MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - - // Sensitivity - double getLengthGrad() final; - virtual const Vector &getBasicDisplTotalGrad(int grad); - virtual const Vector &getBasicDisplFixedGrad(); - virtual const Vector &getGlobalResistingForceShapeSensitivity(const Vector &pb, const Vector &p0, int gradNumber); - - // Tagged Object - void Print(OPS_Stream &s, int flag = 0) final; - -protected: - int addTangent(MatrixND<12,12>& M, const VectorND<12>& pl); - - VectorND<6> pushResponse(const VectorND<6>& pa, int a, int b); - // MatrixND<6,6> pushResponse(const MatrixND<6,6>& K, const VectorND<12>& pl, int a, int b); - // int addTangent(MatrixND<6,6>& K, const VectorND<6>& p, int a, int b, int c); - -protected: - -private: - constexpr static int n = nn*ndf; - - // compute the transformation matrix - void compTransfMatrixBasicGlobal(const Versor&, const Versor*); - - enum { - inx= 0, // axial - iny= 1, // Vy - inz= 2, // Vz - imx= 3, // torsion - imy= 4, // rot y I - imz= 5, // rot z I - - jnx= 6, // axial - jny= 7, - jnz= 8, - jmx= 9, // torsion - jmy=10, // rot y J - jmz=11, // rot z J - }; - - // - // Member data - // - std::array nodes; - - Vector3D xAxis; // local x axis - Vector3D vz; // Vector that lies in local plane xz - Vector3D dX; - - std::array *offsets; - - - double *nodeIInitialDisp, *nodeJInitialDisp; - bool initialDispChecked; - - double L; // initial element length - double Ln; // current element length (at trial state) - - Versor Q_past[nn]; // commited rotations - Versor Q_pres[nn]; // trial rotations - - Vector3D alphaI; // last trial rotations end i - Vector3D alphaJ; // last trial rotatations end j - - VectorND ul; // local displacements (size=7) - Vector3D vr[nn]; // - VectorND ulcommit; // commited local displacements - VectorND ulpr; // previous local displacements - - OpenSees::MatrixND T; // transformation from local to global system - - OpenSees::Matrix3D R0; // rotation from local to global coordinates - CrisfieldTransform crs; - - // Static workspace variables - Matrix3D A; - MatrixND<12,3> Lr2, Lr3; // auxiliary matrices -}; -#include "SouzaFrameTransf.tpp" -#endif diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp index aa2428ef06..5aa96b0906 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp @@ -1,10 +1,22 @@ //===----------------------------------------------------------------------===// // // xara -// -//===----------------------------------------------------------------------===// // https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// //===----------------------------------------------------------------------===// + // // Description: This file contains the implementation for the // SouzaFrameTransf class. SouzaFrameTransf is a Corotational @@ -18,9 +30,8 @@ // #include #include -#include #include -#include +#include "SouzaFrameTransf.h" #include #include @@ -32,7 +43,7 @@ #include #include "Isometry/CrisfieldTransform.h" -using namespace OpenSees; +namespace OpenSees { template SouzaFrameTransf::SouzaFrameTransf(int tag, const Vector3D &vz, @@ -593,252 +604,252 @@ template int SouzaFrameTransf::addTangent(MatrixND<12,12>& kg, const VectorND<12>& pl) { - const Triad r {MatrixFromVersor(crs.getReference())}, - rI{MatrixFromVersor(Q_pres[0])}, - rJ{MatrixFromVersor(Q_pres[1])}; - const Vector3D - &e1 = crs.getBasisE1(), // E[1], - &e2 = crs.getBasisE2(), // E[2], - &e3 = crs.getBasisE3(), // E[3], - &r1 = r[1], // .rotate(E1), - &r2 = r[2], // .rotate(E2), - &r3 = r[3], // .rotate(E3), - &rI1 = rI[1], // .rotate(E1), - &rI2 = rI[2], // .rotate(E2), - &rI3 = rI[3], // .rotate(E3), - &rJ1 = rJ[1], // .rotate(E1), - &rJ2 = rJ[2], // .rotate(E2), - &rJ3 = rJ[3]; // .rotate(E3); - - // NOTE[cmp] - // SouzaFrameTransf::compTransfMatrixBasicGlobal must be - // called first to set Lr1, Lr2 and T - - // Matrix3D A; - // for (int i = 0; i < 3; i++) - // for (int j = 0; j < 3; j++) - // A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; - // getLMatrix(A, e1, r1, r2, Lr2); - // getLMatrix(A, e1, r1, r3, Lr3); - - // - // Ksigma1 - // - { - const double N = -pl[0]; // Axial force - // a=0 - kg.assemble(A, 0, 0, N); - kg.assemble(A, 0, 6, -N); - // a=1 - kg.assemble(A, 6, 0, -N); - kg.assemble(A, 6, 6, N); - } + const Triad r {MatrixFromVersor(crs.getReference())}, + rI{MatrixFromVersor(Q_pres[0])}, + rJ{MatrixFromVersor(Q_pres[1])}; + const Vector3D + &e1 = crs.getBasisE1(), // E[1], + &e2 = crs.getBasisE2(), // E[2], + &e3 = crs.getBasisE3(), // E[3], + &r1 = r[1], // .rotate(E1), + &r2 = r[2], // .rotate(E2), + &r3 = r[3], // .rotate(E3), + &rI1 = rI[1], // .rotate(E1), + &rI2 = rI[2], // .rotate(E2), + &rI3 = rI[3], // .rotate(E3), + &rJ1 = rJ[1], // .rotate(E1), + &rJ2 = rJ[2], // .rotate(E2), + &rJ3 = rJ[3]; // .rotate(E3); + + // NOTE[cmp] + // SouzaFrameTransf::compTransfMatrixBasicGlobal must be + // called first to set Lr1, Lr2 and T - // - // Ksigma3 - // - // ks3 = [o kbar2 | o kbar4]; - // - // where - // - // kbar2 = -Lr2*(m(3)*S(rI3) + m(1)*S(rI1)) + Lr3*(m(3)*S(rI2) - m(2)*S(rI1)) ; - // - // kbar4 = Lr2*(m(3)*S(rJ3) - m(4)*S(rJ1)) - Lr3*(m(3)*S(rJ2) + m(5)*S(rJ1)); - // - // or - // - // ks3 = [o ka+kb | o kc+kd]; - // = [o ka | o kc] + [o kb | o kd]; - // - // where - // - // ka = -Lr2*S(rI3)*m(3) - // +Lr2*S(rI1)*m(1); - // kb = Lr3*S(rI2)*m(3) - // -Lr3*S(rI1)*m(2); - // - // kc = Lr2*S(rJ3)*m(3) - // -Lr2*S(rJ1)*m(4); - // kd = -Lr3*S(rJ2)*m(3) - // +Lr3*S(rJ1)*m(5); + // Matrix3D A; + // for (int i = 0; i < 3; i++) + // for (int j = 0; j < 3; j++) + // A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; + // getLMatrix(A, e1, r1, r2, Lr2); + // getLMatrix(A, e1, r1, r3, Lr3); - VectorND<6> m; - m[0] = 0.5*pl[imx]/std::cos(ul(imx)); - m[2] = -0.5*pl[imy]/std::cos(ul(imy)); - m[1] = 0.5*pl[imz]/std::cos(ul(imz)); + // + // Ksigma1 + // + { + const double N = -pl[0]; // Axial force + // a=0 + kg.assemble(A, 0, 0, N); + kg.assemble(A, 0, 6, -N); + // a=1 + kg.assemble(A, 6, 0, -N); + kg.assemble(A, 6, 6, N); + } - m[3] = 0.5*pl[jmx]/std::cos(ul(jmx)); - m[5] = -0.5*pl[jmy]/std::cos(ul(jmy)); - m[4] = 0.5*pl[jmz]/std::cos(ul(jmz)); + // + // Ksigma3 + // + // ks3 = [o kbar2 | o kbar4]; + // + // where + // + // kbar2 = -Lr2*(m(3)*S(rI3) + m(1)*S(rI1)) + Lr3*(m(3)*S(rI2) - m(2)*S(rI1)) ; + // + // kbar4 = Lr2*(m(3)*S(rJ3) - m(4)*S(rJ1)) - Lr3*(m(3)*S(rJ2) + m(5)*S(rJ1)); + // + // or + // + // ks3 = [o ka+kb | o kc+kd]; + // = [o ka | o kc] + [o kb | o kd]; + // + // where + // + // ka = -Lr2*S(rI3)*m(3) + // +Lr2*S(rI1)*m(1); + // kb = Lr3*S(rI2)*m(3) + // -Lr3*S(rI1)*m(2); + // + // kc = Lr2*S(rJ3)*m(3) + // -Lr2*S(rJ1)*m(4); + // kd = -Lr3*S(rJ2)*m(3) + // +Lr3*S(rJ1)*m(5); + VectorND<6> m; + m[0] = 0.5*pl[imx]/std::cos(ul(imx)); + m[2] = -0.5*pl[imy]/std::cos(ul(imy)); + m[1] = 0.5*pl[imz]/std::cos(ul(imz)); - static Matrix3D Sm; - Sm.zero(); - Sm.addSpin(rI3, m[3]); - Sm.addSpin(rI1, m[1]); - static MatrixND<12,3> kbar; - kbar.zero(); - kbar.addMatrixProduct(Lr2, Sm, -1.0); + m[3] = 0.5*pl[jmx]/std::cos(ul(jmx)); + m[5] = -0.5*pl[jmy]/std::cos(ul(jmy)); + m[4] = 0.5*pl[jmz]/std::cos(ul(jmz)); - Sm.zero(); - Sm.addSpin(rI2, m[3]); - Sm.addSpin(rI1, -m[2]); - kbar.addMatrixProduct(Lr3, Sm, 1.0); - kg.assemble(kbar, 0, 3, 1.0); - kg.assembleTranspose(kbar, 3, 0, 1.0); + static Matrix3D Sm; + Sm.zero(); + Sm.addSpin(rI3, m[3]); + Sm.addSpin(rI1, m[1]); + static MatrixND<12,3> kbar; + kbar.zero(); + kbar.addMatrixProduct(Lr2, Sm, -1.0); - Sm.zero(); - Sm.addSpin(rJ3, m[3]); - Sm.addSpin(rJ1, -m[4]); - kbar.zero(); - kbar.addMatrixProduct(Lr2, Sm, 1.0); + Sm.zero(); + Sm.addSpin(rI2, m[3]); + Sm.addSpin(rI1, -m[2]); + kbar.addMatrixProduct(Lr3, Sm, 1.0); - Sm.zero(); - Sm.addSpin(rJ2, m[3]); - Sm.addSpin(rJ1, m[5]); - kbar.addMatrixProduct(Lr3, Sm, -1.0); + kg.assemble(kbar, 0, 3, 1.0); + kg.assembleTranspose(kbar, 3, 0, 1.0); - kg.assemble(kbar, 0, 9, 1.0); - kg.assembleTranspose(kbar, 9, 0, 1.0); + Sm.zero(); + Sm.addSpin(rJ3, m[3]); + Sm.addSpin(rJ1, -m[4]); + kbar.zero(); + kbar.addMatrixProduct(Lr2, Sm, 1.0); + Sm.zero(); + Sm.addSpin(rJ2, m[3]); + Sm.addSpin(rJ1, m[5]); + kbar.addMatrixProduct(Lr3, Sm, -1.0); - // - // Ksigma4 - // - { - Matrix3D ks33; - ks33.zero(); - ks33.addSpinProduct(e2, rI3, m[3]); - ks33.addSpinProduct(e3, rI2, -m[3]); - ks33.addSpinProduct(e2, rI1, m[1]); - ks33.addSpinProduct(e1, rI2, -m[1]); - ks33.addSpinProduct(e3, rI1, m[2]); - ks33.addSpinProduct(e1, rI3, -m[2]); - kg.assemble(ks33, 3, 3, 1.0); - } + kg.assemble(kbar, 0, 9, 1.0); + kg.assembleTranspose(kbar, 9, 0, 1.0); - // - // Ksigma4 - // - { - Matrix3D ks33; - ks33.zero(); - ks33.addSpinProduct(e2, rJ3, -m[3]); - ks33.addSpinProduct(e3, rJ2, m[3]); - ks33.addSpinProduct(e2, rJ1, m[4]); - ks33.addSpinProduct(e1, rJ2, -m[4]); - ks33.addSpinProduct(e3, rJ1, m[5]); - ks33.addSpinProduct(e1, rJ3, -m[5]); - - kg.assemble(ks33, 9, 9, 1.0); - } + // + // Ksigma4 + // + { + Matrix3D ks33; + ks33.zero(); + ks33.addSpinProduct(e2, rI3, m[3]); + ks33.addSpinProduct(e3, rI2, -m[3]); + ks33.addSpinProduct(e2, rI1, m[1]); + ks33.addSpinProduct(e1, rI2, -m[1]); + ks33.addSpinProduct(e3, rI1, m[2]); + ks33.addSpinProduct(e1, rI3, -m[2]); + kg.assemble(ks33, 3, 3, 1.0); + } - // - // Ksigma5 - // - // Ks5 = [ Ks5_11 Ks5_12 | -Ks5_11 Ks5_14; - // Ks5_12' O | -Ks5_12' O; - // -Ks5_11 -Ks5_12 | Ks5_11 -Ks5_14; - // Ks5_14t O | -Ks5_14' O]; - // - // - // v = (1/Ln)*(m(2)*rI2 + m(3)*rI3 + m(5)*rJ2 + m(6)*rJ3); - // = 1/Ln * (m[1]*rI2 + m[2]*rI3) - // + 1/Ln * (m[4]*rJ2 + m[5]*rJ3); - // = vi + vj - // - { - Vector3D v; - v.addVector(0.0, rI2, m[1]); - v.addVector(1.0, rI3, m[2]); - v.addVector(1.0, rJ2, m[4]); - v.addVector(1.0, rJ3, m[5]); - v /= Ln; - - // Ks5_11 = A*v*e1' + e1*v'*A + (e1'*v)*A; - // = A*vi*e1' + e1*vi'*A + (e1'*vi)*A - // + A*vj*e1' + e1*vj'*A + (e1'*vj)*A; - // - Matrix3D ks33; - ks33.zero(); - ks33.addMatrix(A, e1.dot(v)); - - static Matrix3D m33; - m33.zero(); - m33.addTensorProduct(v, e1, 1.0); - - ks33.addMatrixProduct(A, m33, 1.0); - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - m33(i,j) = e1[i]*v[j]; - - ks33.addMatrixProduct(m33, A, 1.0); - - kg.assemble(ks33, 0, 0, 1.0); - kg.assemble(ks33, 0, 6, -1.0); - kg.assemble(ks33, 6, 0, -1.0); - kg.assemble(ks33, 6, 6, 1.0); - } + // + // Ksigma4 + // + { + Matrix3D ks33; + ks33.zero(); + ks33.addSpinProduct(e2, rJ3, -m[3]); + ks33.addSpinProduct(e3, rJ2, m[3]); + ks33.addSpinProduct(e2, rJ1, m[4]); + ks33.addSpinProduct(e1, rJ2, -m[4]); + ks33.addSpinProduct(e3, rJ1, m[5]); + ks33.addSpinProduct(e1, rJ3, -m[5]); + + kg.assemble(ks33, 9, 9, 1.0); + } - // Ks5_12 = -(m(2)*A*S(rI2) + m(3)*A*S(rI3)); + // + // Ksigma5 + // + // Ks5 = [ Ks5_11 Ks5_12 | -Ks5_11 Ks5_14; + // Ks5_12' O | -Ks5_12' O; + // -Ks5_11 -Ks5_12 | Ks5_11 -Ks5_14; + // Ks5_14t O | -Ks5_14' O]; + // + // + // v = (1/Ln)*(m(2)*rI2 + m(3)*rI3 + m(5)*rJ2 + m(6)*rJ3); + // = 1/Ln * (m[1]*rI2 + m[2]*rI3) + // + 1/Ln * (m[4]*rJ2 + m[5]*rJ3); + // = vi + vj + // + { + Vector3D v; + v.addVector(0.0, rI2, m[1]); + v.addVector(1.0, rI3, m[2]); + v.addVector(1.0, rJ2, m[4]); + v.addVector(1.0, rJ3, m[5]); + v /= Ln; + + // Ks5_11 = A*v*e1' + e1*v'*A + (e1'*v)*A; + // = A*vi*e1' + e1*vi'*A + (e1'*vi)*A + // + A*vj*e1' + e1*vj'*A + (e1'*vj)*A; + // Matrix3D ks33; ks33.zero(); - ks33.addMatrixSpinProduct(A, rI2, -m[1]); - ks33.addMatrixSpinProduct(A, rI3, -m[2]); + ks33.addMatrix(A, e1.dot(v)); - kg.assemble(ks33, 0, 3, 1.0); - kg.assemble(ks33, 6, 3, -1.0); - kg.assembleTranspose(ks33, 3, 0, 1.0); - kg.assembleTranspose(ks33, 3, 6, -1.0); + static Matrix3D m33; + m33.zero(); + m33.addTensorProduct(v, e1, 1.0); - // Ks5_14 = -(m(5)*A*S(rJ2) + m(6)*A*S(rJ3)); + ks33.addMatrixProduct(A, m33, 1.0); - ks33.zero(); - ks33.addMatrixSpinProduct(A, rJ2, -m[4]); - ks33.addMatrixSpinProduct(A, rJ3, -m[5]); + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + m33(i,j) = e1[i]*v[j]; + + ks33.addMatrixProduct(m33, A, 1.0); + + kg.assemble(ks33, 0, 0, 1.0); + kg.assemble(ks33, 0, 6, -1.0); + kg.assemble(ks33, 6, 0, -1.0); + kg.assemble(ks33, 6, 6, 1.0); + } + + // Ks5_12 = -(m(2)*A*S(rI2) + m(3)*A*S(rI3)); + + Matrix3D ks33; + ks33.zero(); + ks33.addMatrixSpinProduct(A, rI2, -m[1]); + ks33.addMatrixSpinProduct(A, rI3, -m[2]); + + kg.assemble(ks33, 0, 3, 1.0); + kg.assemble(ks33, 6, 3, -1.0); + kg.assembleTranspose(ks33, 3, 0, 1.0); + kg.assembleTranspose(ks33, 3, 6, -1.0); + + // Ks5_14 = -(m(5)*A*S(rJ2) + m(6)*A*S(rJ3)); - kg.assemble(ks33, 0, 9, 1.0); - kg.assemble(ks33, 6, 9, -1.0); + ks33.zero(); + ks33.addMatrixSpinProduct(A, rJ2, -m[4]); + ks33.addMatrixSpinProduct(A, rJ3, -m[5]); - kg.assembleTranspose(ks33, 9, 0, 1.0); - kg.assembleTranspose(ks33, 9, 6, -1.0); + kg.assemble(ks33, 0, 9, 1.0); + kg.assemble(ks33, 6, 9, -1.0); - // Ksigma ------------------------------- - Vector3D rm = rI3; + kg.assembleTranspose(ks33, 9, 0, 1.0); + kg.assembleTranspose(ks33, 9, 6, -1.0); - rm.addVector(1.0, rJ3, -1.0); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rm), m[3]); + // Ksigma ------------------------------- + Vector3D rm = rI3; + + rm.addVector(1.0, rJ3, -1.0); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rm), m[3]); // rm = rJ2; - rm.addVector(0.0, rJ2, -1.0); - rm.addVector(1.0, rI2, -1.0); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rm), m[3]); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rI1), m[1]); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rI1), m[2]); - // - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rJ1), m[4]); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rJ1), m[5]); + rm.addVector(0.0, rJ2, -1.0); + rm.addVector(1.0, rI2, -1.0); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rm), m[3]); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rI1), m[1]); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rI1), m[2]); + // + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rJ1), m[4]); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rJ1), m[5]); - // - // T' * diag (M .* tan(thetal))*T - // + // + // T' * diag (M .* tan(thetal))*T + // - for (int node=0; node<2; node++) { - for (int k = 0; k < 3; k++) { - const double factor = pl[6*node+3+k] * std::tan(ul[(node ? jmx : imx) + k]); - for (int i = 0; i < 12; i++) { - const double Tki = T((node ? jmx : imx) + k,i); - for (int j = 0; j < 12; j++) - kg(i,j) += Tki * factor * T((node ? jmx : imx) + k, j); - } + for (int node=0; node<2; node++) { + for (int k = 0; k < 3; k++) { + const double factor = pl[6*node+3+k] * std::tan(ul[(node ? jmx : imx) + k]); + for (int i = 0; i < 12; i++) { + const double Tki = T((node ? jmx : imx) + k,i); + for (int j = 0; j < 12; j++) + kg(i,j) += Tki * factor * T((node ? jmx : imx) + k, j); } } + } - return 0; + return 0; } @@ -877,22 +888,22 @@ template const Vector & SouzaFrameTransf::getBasicDisplTotalGrad(int gradNumber) { - opserr << "WARNING CrdTransf::getBasicDisplTotalGrad() - this method " - << " should not be called.\n"; + opserr << "WARNING CrdTransf::getBasicDisplTotalGrad() - this method " + << " should not be called.\n"; - static Vector dummy(1); - return dummy; + static Vector dummy(1); + return dummy; } template const Vector & SouzaFrameTransf::getBasicDisplFixedGrad() { - opserr << "ERROR CrdTransf::getBasicDisplFixedGrad() - has not been" - << " implemented yet for the chosen transformation\n."; + opserr << "ERROR CrdTransf::getBasicDisplFixedGrad() - has not been" + << " implemented yet for the chosen transformation\n."; - static Vector dummy(1); - return dummy; + static Vector dummy(1); + return dummy; } @@ -902,11 +913,11 @@ SouzaFrameTransf::getGlobalResistingForceShapeSensitivity(const Vector & const Vector &p0, int gradNumber) { - opserr << "ERROR CrdTransf::getGlobalResistingForceSensitivity() - has not been" - << " implemented yet for the chosen transformation." << endln; - - static Vector dummy(1); - return dummy; + opserr << "ERROR CrdTransf::getGlobalResistingForceSensitivity() - has not been" + << " implemented yet for the chosen transformation." << endln; + + static Vector dummy(1); + return dummy; } template @@ -942,3 +953,4 @@ SouzaFrameTransf::Print(OPS_Stream &s, int flag) } } +} // namespace OpenSees \ No newline at end of file From 5154dac3f9541050fa9a775caf64b327bf65db11 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Wed, 25 Jun 2025 14:14:50 -0700 Subject: [PATCH 103/261] clean new matrix classes --- SRC/matrix/MatrixND.h | 653 ++++++++++------------------------------ SRC/matrix/VectorND.h | 13 +- SRC/matrix/VectorND.tpp | 8 + SRC/matrix/Versor.h | 206 ++++++------- 4 files changed, 280 insertions(+), 600 deletions(-) diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index 1e2f7849a6..8e7a4e0835 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -1,9 +1,14 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation -// See https://opensees.berkeley.edu/OpenSees/copyright.php for license. +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so // //===--- MatrixND.h - Matrix with fixed size ------------------------------===// +// +// Desctiption: MatrixND is a fixed-size matrix class that is suitable for +// stack-allocation. // // Objectives: // - little to no overhead above C-style arrays @@ -35,19 +40,16 @@ #include #include #include -#include -#include // overloading << #include "VectorND.h" #include "Matrix.h" #include "Vector.h" -#include "blasdecl.h" #include "routines/cmx.h" #include "routines/SY3.h" #if __cplusplus < 202000L -#define consteval -#define requires(X) +# define consteval +# define requires(X) #endif #define G23_STACK_MAX 10 @@ -65,14 +67,16 @@ struct MatrixND { operator Matrix() { return Matrix(&values[0][0], NR, NC);} operator const Matrix() const { return Matrix(&values[0][0], NR, NC);} - MatrixND& addDiagonal(const double vol) requires(NR == NC); - int symeig(VectorND& vals) requires(NR == NC == 3) { double work[3][3]; cmx_eigSY3(values, work, vals.values); return 0; } + consteval void zero(); + + MatrixND& addDiagonal(const double vol) requires(NR == NC); + template void addMatrix(const MatT& A, const double scale); @@ -82,6 +86,9 @@ struct MatrixND { template void addMatrixProduct(const MatrixND &, const MatT&, double scale); + template void + addMatrixProduct(double, const MatrixND &, const MatT&, double scale); + // += A'B template void addMatrixTransposeProduct(double thisFact, const MatrixND &, const MatT&, double scale); @@ -103,11 +110,6 @@ struct MatrixND { template void map(F func) const; template void map(F func, MatrixND& destination); - int invert(MatrixND &) const; - int invert() { - return Matrix(*this).Invert(); - } - template MatrixND& addSpin(const VecT& V); template MatrixND& addSpin(const VecT& V, double scale); template MatrixND& addSpinSquare(const VecT& V, double scale); @@ -115,6 +117,11 @@ struct MatrixND { template void addMatrixSpinProduct(const MatrixND& A, const VecT& b, double scale); template void addSpinMatrixProduct(const VectorND& a, const MatT& B, double scale); + int invert(MatrixND &) const; + int invert() { + return Matrix(*this).Invert(); + } +#if 0 //template //void addSpinAtRow(const VecT& V, size_t row_index); //template @@ -125,15 +132,21 @@ struct MatrixND { //void addSpinAtRow(const VecT& V, double mult, size_t row_index); //template //void addSpinAtRow(const VecT& V, double mult, size_t vector_index, size_t matrix_row_index); - +#endif // // Indexing // constexpr std::array & - operator[](index_t index) {return values[index];} + operator[](index_t index) + { + return values[index]; + } - constexpr const std::array & // [i] indexing - operator[](index_t index) const {return values[index];} + constexpr const std::array & + operator[](index_t index) const + { + return values[index]; + } // (i,j) indexing constexpr T & @@ -150,28 +163,112 @@ struct MatrixND { return values[index_c][index_r]; } - // - // - // - consteval void zero() { + + constexpr MatrixND & + operator=(const Matrix &other) + { for (index_t j = 0; j < NC; ++j) { for (index_t i = 0; i < NR; ++i) { - values[j][i] = 0.0; + values[j][i] = other(i,j); } } + return *this; } - constexpr MatrixND - transpose() const { - MatrixND result = {}; +/* + constexpr MatrixND & + operator=(const MatrixND &other) + { + for (index_t j = 0; j < NC; ++j) { + for (index_t i = 0; i < NR; ++i) { + values[j][i] = other.values[j][i]; + } + } + return *this; + } +*/ + + constexpr MatrixND & + operator+=(const double value) { + for (index_t j = 0; j < NC; ++j) { + for (index_t i = 0; i < NR; ++i) { + values[j][i] += value; + } + } + return *this; + } + + constexpr MatrixND & + operator+=(const MatrixND &other) { for (index_t j = 0; j < NC; ++j) { for (index_t i = 0; i < NR; ++i) { - result.values[i][j] = values[j][i]; + values[j][i] += other.values[j][i]; } } - return result; + return *this; + } + + constexpr MatrixND & + operator-=(const MatrixND &other) + { + for (index_t j = 0; j < NC; ++j) + for (index_t i = 0; i < NR; ++i) + values[j][i] -= other.values[j][i]; + + return *this; + } + + inline constexpr MatrixND & + operator*=(T const scalar) + { + for (index_t j = 0; j < NC; ++j) + for (index_t i = 0; i < NR; ++i) + values[j][i] *= scalar; + + return *this; + } + + inline constexpr MatrixND & + operator/=(T const scalar) + { + for (index_t j = 0; j < NC; ++j) + for (index_t i = 0; i < NR; ++i) + values[j][i] /= scalar; + + return *this; + } + + inline constexpr VectorND + operator^(const VectorND &V) const + { + VectorND result; + + const double *dataPtr = &values[0][0]; + for (int i=0; i + transpose() const ; + // { + // MatrixND result = {}; + // for (index_t j = 0; j < NC; ++j) { + // for (index_t i = 0; i < NR; ++i) { + // result.values[i][j] = values[j][i]; + // } + // } + // return result; + // } + constexpr T trace() const requires(NR == NC) @@ -183,12 +280,12 @@ struct MatrixND { return sum; } - constexpr T - determinant() const - requires(NR == NC && NR == 2) - { - return values[0][0] * values[1][1] - values[0][1] * values[1][0]; - } + // constexpr T + // determinant() const + // requires(NR == NC && NR == 2) + // { + // return values[0][0] * values[1][1] - values[0][1] * values[1][0]; + // } int solve(const VectorND &V, VectorND &res) const requires(NR == NC) @@ -353,80 +450,9 @@ struct MatrixND { } - - constexpr MatrixND & - operator=(const Matrix &other) - { - for (index_t j = 0; j < NC; ++j) { - for (index_t i = 0; i < NR; ++i) { - values[j][i] = other(i,j); - } - } - return *this; - } - -/* - constexpr MatrixND & - operator=(const MatrixND &other) - { - for (index_t j = 0; j < NC; ++j) { - for (index_t i = 0; i < NR; ++i) { - values[j][i] = other.values[j][i]; - } - } - return *this; - } -*/ - - constexpr MatrixND & - operator+=(const double value) { - for (index_t j = 0; j < NC; ++j) { - for (index_t i = 0; i < NR; ++i) { - values[j][i] += value; - } - } - return *this; - } - - constexpr MatrixND & - operator+=(const MatrixND &other) { - for (index_t j = 0; j < NC; ++j) { - for (index_t i = 0; i < NR; ++i) { - values[j][i] += other.values[j][i]; - } - } - return *this; - } - - constexpr MatrixND & - operator-=(const MatrixND &other) { - for (index_t j = 0; j < NC; ++j) - for (index_t i = 0; i < NR; ++i) - values[j][i] -= other.values[j][i]; - - return *this; - } - - constexpr MatrixND & - operator*=(T const scalar) { - for (index_t j = 0; j < NC; ++j) - for (index_t i = 0; i < NR; ++i) - values[j][i] *= scalar; - - return *this; - } - - constexpr MatrixND & - operator/=(T const scalar) { - for (index_t j = 0; j < NC; ++j) - for (index_t i = 0; i < NR; ++i) - values[j][i] /= scalar; - - return *this; - } - - +// // Notes on operators: +// // - define friend operators inside class for use as header-only library friend constexpr MatrixND operator+(MatrixND left, const MatrixND &right) { @@ -456,14 +482,17 @@ struct MatrixND { inline constexpr friend MatrixND operator*(const MatrixND &left, const MatrixND &right) { MatrixND prod; - for (index_t i = 0; i < NR; ++i) { - for (index_t j = 0; j < J; ++j) { - prod(i, j) = 0.0; - for (index_t k = 0; k < NC; ++k) { - prod(i, j) += left(i,k) * right(k,j); + if constexpr (0 && NR*NC > 16) + prod.addMatrixProduct(0, left, right, 1); + else + for (index_t i = 0; i < NR; ++i) { + for (index_t j = 0; j < J; ++j) { + prod(i, j) = 0.0; + for (index_t k = 0; k < NC; ++k) { + prod(i, j) += left(i,k) * right(k,j); + } } } - } return prod; } @@ -471,32 +500,20 @@ struct MatrixND { inline constexpr friend MatrixND operator^(const MatrixND &left, const MatrixND &right) { MatrixND prod; - for (index_t i = 0; i < NC; ++i) { - for (index_t j = 0; j < K; ++j) { - prod(i, j) = 0.0; - for (index_t k = 0; k < NR; ++k) { - prod(i, j) += left(k,i) * right(k,j); + if constexpr (0 && NR*NC > 16) + prod.addMatrixTransposeProduct(0.0, left, right, 1.0); + else + for (index_t i = 0; i < NC; ++i) { + for (index_t j = 0; j < K; ++j) { + prod(i, j) = 0.0; + for (index_t k = 0; k < NR; ++k) { + prod(i, j) += left(k,i) * right(k,j); + } } } - } return prod; } - VectorND - operator^(const VectorND &V) const - { - VectorND result; - - const double *dataPtr = &values[0][0]; - for (int i=0; i operator*(const MatrixND &left, const VectorND &right) { @@ -545,364 +562,20 @@ struct MatrixND { return mat; } - friend std::ostream & - operator<<(std::ostream &out, MatrixND const &mat) { - out << "{"; - for (int r=0; r -template inline void -MatrixND::map(F func) const -{ - for (int i=0; i -template inline void -MatrixND::map(F func, MatrixND& destination) -{ - for (int i=0; i inline int -template inline int -MatrixND::invert(MatrixND &M) const -{ - static_assert(nr == nc, "Matrix must be square"); - static_assert(nr > 1 && nr < 7, "Matrix must be between 2x2 and 6x6"); - - int status = -1; - if constexpr (nr == 2) { - cmx_inv2(&this->values[0][0], &M.values[0][0], &status); - return status; - } - if constexpr (nr == 3) { - cmx_inv3(&this->values[0][0], &M.values[0][0], &status); - return status; - } - if constexpr (nr == 4) { - cmx_inv4(&this->values[0][0], &M.values[0][0], &status); - return status; - } - if constexpr (nr == 5) { - cmx_inv5(&this->values[0][0], &M.values[0][0], &status); - return status; - } - if constexpr (nr == 6) { - cmx_inv6(&this->values[0][0], &M.values[0][0], &status); - return status; - } - return status; -} - -template inline -MatrixND& -MatrixND::addDiagonal(const double diag) -{ - for (int i=0; i -template inline -void MatrixND::addMatrix(const MatT& A, const double scale) -{ - for (int i=0; i -template -constexpr inline -MatrixND& -MatrixND::addTensorProduct(const VecA& a, const VecB& b, const double scale) -{ - // Chrystal's bun order - for (int j=0; j -template inline -void -MatrixND::addMatrixProduct(const MatrixND& A, const MatT& B, const double scale) -{ - for (int i=0; i -template inline -void -MatrixND::addMatrixTransposeProduct(double thisFact, - const MatrixND& B, - const MatT& C, - const double otherFact) -{ - if (thisFact == 1.0) { - double *aijPtr = &values[0][0]; - for (int j=0; j -template inline -int -MatrixND::addMatrixTripleProduct( - double thisFact, - const MatrixND &T, - const MatrixND &B, - double otherFact) - requires(nr == nc) -{ - if (otherFact == 0.0 && thisFact == 1.0) - return 0; - - MatrixND BT; - BT.zero(); - BT.addMatrixProduct(B, T, otherFact); - this->addMatrixTransposeProduct(thisFact, T, BT, 1.0); - -//{ -// int m = B.numRows, -// n = T.numCols, -// k = B.numCols, -// nrT = T.numRows; -// //k = T.numRows; -// double zero = 0.0, -// one = 1.0; - -// DGEMM ("N", "N", &m , &n , &k,&one , B.data, &m, // m -// T.data, &nrT, // k -// &zero, matrixWork, &m); - -// DGEMM ("T", "N", &numRows, &numCols, &k,&otherFact, T.data, &nrT, -// matrixWork, &m, // k -// &thisFact, data, &numRows); -// return 0; -//} - - return 0; -} - - -template -template inline int -MatrixND::addMatrixTripleProduct(double thisFact, - const MatrixND &A, - const MatrixND &B, - const MatrixND &C, double otherFact) -{ - - if (otherFact == 0.0 && thisFact == 1.0) - return 0; - - MatrixND BC {}; - BC.addMatrixProduct(B, C, otherFact); - this->addMatrixTransposeProduct(thisFact, A, BC, 1.0); - return 0; -} - - -template -MatrixND(const T (&)[nc][nr])->MatrixND; - - -// -// 3D -// - -template -template -inline MatrixND& -MatrixND::addSpin(const VecT& v) requires(NR == 3) -{ - const double v0 = v[0], - v1 = v[1], - v2 = v[2]; - - (*this)(0, 0) += 0.0; (*this)(0, 1) += -v2; (*this)(0, 2) += v1; - (*this)(1, 0) += v2; (*this)(1, 1) += 0.0; (*this)(1, 2) += -v0; - (*this)(2, 0) += -v1; (*this)(2, 1) += v0; (*this)(2, 2) += 0.0; - - return *this; -} - - -template -template -inline MatrixND& -MatrixND::addSpin(const VecT& v, double mult) -{ - const double v0 = mult*v[0], - v1 = mult*v[1], - v2 = mult*v[2]; - - (*this)(0, 0) += 0.0; (*this)(0, 1) += -v2; (*this)(0, 2) += v1; - (*this)(1, 0) += v2; (*this)(1, 1) += 0.00; (*this)(1, 2) += -v0; - (*this)(2, 0) += -v1; (*this)(2, 1) += v0; (*this)(2, 2) += 0.0; - return *this; -} - - -template -template inline -MatrixND& -MatrixND::addSpinSquare(const VecT& v, const double scale) - requires(NR == NC == 3) -{ - const double v1 = v[0], - v2 = v[1], - v3 = v[2]; - - (*this)(0,0) += scale*( -v2*v2 - v3*v3 ); - (*this)(1,1) += scale*( -v1*v1 - v3*v3 ); - (*this)(2,2) += scale*( -v1*v1 - v2*v2 ); - - (*this)(0,1) += scale*( v1*v2 ); - (*this)(1,0) += scale*( v1*v2 ); - (*this)(2,0) += scale*( v1*v3 ); - (*this)(0,2) += scale*( v1*v3 ); - (*this)(1,2) += scale*( v2*v3 ); - (*this)(2,1) += scale*( v2*v3 ); - return *this; -} - - -template -template inline -void MatrixND::addSpinProduct(const VecT& a, const VectorND& b, const double scale) - requires(NR == NC == 3) -{ - // a^b^ = boa - a.b 1 - // where 'o' denotes the tensor product and '.' the dot product - // - this->addTensorProduct(b, a, scale); - this->addDiagonal(-b.dot(a)*scale); -} - -template -template inline -void MatrixND::addMatrixSpinProduct(const MatrixND& A, const VecT& b, const double scale) -{ - // this += s*A*[b^] - // where b^ is the skew-symmetric representation of the three-vector b, s is a scalar, - // and A a 3x3 matrix. - // - (*this)(0, 0) += scale*( A(0,1)*b[2] - A(0,2)*b[1]); - (*this)(0, 1) += scale*(-A(0,0)*b[2] + A(0,2)*b[0]); - (*this)(0, 2) += scale*( A(0,0)*b[1] - A(0,1)*b[0]); - (*this)(1, 0) += scale*( A(1,1)*b[2] - A(1,2)*b[1]); - (*this)(1, 1) += scale*(-A(1,0)*b[2] + A(1,2)*b[0]); - (*this)(1, 2) += scale*( A(1,0)*b[1] - A(1,1)*b[0]); - (*this)(2, 0) += scale*( A(2,1)*b[2] - A(2,2)*b[1]); - (*this)(2, 1) += scale*(-A(2,0)*b[2] + A(2,2)*b[0]); - (*this)(2, 2) += scale*( A(2,0)*b[1] - A(2,1)*b[0]); -} - -template -template inline -void MatrixND::addSpinMatrixProduct(const VectorND& a, const MatT& B, const double scale) - requires(NR == NC == 3) -{ - // this += s*[a^]*B - // where a^ is the skew-symmetric representation of the three-vector a, s is a scalar, - // and B a 3x3 matrix. - // - (*this)(0, 0) += scale*( -B(1,0)*a[2] + B(2,0)*a[1]); - (*this)(0, 1) += scale*( -B(1,1)*a[2] + B(2,1)*a[1]); - (*this)(0, 2) += scale*( -B(1,2)*a[2] + B(2,2)*a[1]); - (*this)(1, 0) += scale*( B(0,0)*a[2] - B(2,0)*a[0]); - (*this)(1, 1) += scale*( B(0,1)*a[2] - B(2,1)*a[0]); - (*this)(1, 2) += scale*( B(0,2)*a[2] - B(2,2)*a[0]); - (*this)(2, 0) += scale*( -B(0,0)*a[1] + B(1,0)*a[0]); - (*this)(2, 1) += scale*( -B(0,1)*a[1] + B(1,1)*a[0]); - (*this)(2, 2) += scale*( -B(0,2)*a[1] + B(1,2)*a[0]); -} - } // namespace OpenSees - +#include "MatrixND.tpp" #endif // MatrixND_H diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index 88366db169..3c10bd451d 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -1,10 +1,11 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // -// // Objectives: // - little to no overhead above C-style arrays // - value semantics; objects do not decay to pointers; @@ -34,8 +35,6 @@ #include #include #include -// #include -// #include #include #include #include "blasdecl.h" @@ -110,16 +109,16 @@ struct VectorND { // Tensor product, also known as the "bun" product template - constexpr inline OpenSees::MatrixND + constexpr inline MatrixND bun(const VectorND &other) const { if constexpr (N == 3 && nc == 3) - return OpenSees::MatrixND {{ + return MatrixND {{ {values[0]*other[0], values[1]*other[0], values[2]*other[0]}, {values[0]*other[1], values[1]*other[1], values[2]*other[1]}, {values[0]*other[2], values[1]*other[2], values[2]*other[2]} }}; else { - OpenSees::MatrixND prod; + MatrixND prod; for (index_t j = 0; j < other.size(); ++j) for (index_t i = 0; i < this->size(); ++i) diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index 82e0559c0e..151e6bb7de 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -1,3 +1,11 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// template inline void assemble(const VectorND &v, double fact=1) diff --git a/SRC/matrix/Versor.h b/SRC/matrix/Versor.h index ea43321b97..e4cd495181 100644 --- a/SRC/matrix/Versor.h +++ b/SRC/matrix/Versor.h @@ -6,120 +6,120 @@ // https://xara.so //===----------------------------------------------------------------------===// // +// Description: Versor implements a unit-normalized quaternion. +// #pragma once #include #include +#if 0 +namespace OpenSees { +#endif + struct Versor { - Vector3D vector; - double scalar; - - template - inline Vec3T - rotate(const Vec3T& u) const { - return u + 2.0 * vector.cross( scalar*u + vector.cross(u) ); - } - - inline Versor conjugate() const { - Versor c; - c.scalar = scalar; - c.vector = -1.0*vector; // element-wise negation - return c; - } - - inline Versor conj_mult(const Versor& other) const - { - // Equivalent to R_IJ = R_I.T @ R_J, - // i.e. q_IJ = conj(q_I)*q_J. - Versor out; - out.scalar = scalar * other.scalar + vector.dot(other.vector); - out.vector = (other.vector * scalar) - (vector * other.scalar) - vector.cross(other.vector); - return out; - } - - inline Versor mult_conj(const Versor& other) const - { - // Equivalent to R_IJ = R_I @ R_J^T, - // i.e. q_IJ = q_I * conj(q_J). - - // Versor out = *this; - // out *= other.conjugate(); - // return out; - - Versor out; - out.scalar = scalar * other.scalar + vector.dot(other.vector); - out.vector = (vector * other.scalar) - - (other.vector * scalar) - - vector.cross(other.vector); - return out; - } - - template - static inline Versor - from_vector(const Vec3T &theta) - { - - double t = 0.0; // theta.norm(); - for (int i=0; i<3; i++) - t += theta[i]*theta[i]; - - t = std::sqrt(t); - - Versor q; - if (t == 0) - q.vector.zero(); - - else { - const double factor = std::sin(t*0.5) / t; - for (int i = 0; i < 3; i++) - q.vector[i] = theta[i] * factor; - } - - q.scalar = std::cos(t*0.5); - - return q; - } + Vector3D vector; + double scalar; + + template + inline Vec3T + rotate(const Vec3T& u) const { + return u + 2.0 * vector.cross( scalar*u + vector.cross(u) ); + } + + inline Versor + conjugate() const { + Versor c; + c.scalar = scalar; + c.vector = -1.0*vector; // element-wise negation + return c; + } + + inline Versor + conj_mult(const Versor& other) const + { + // Equivalent to R_IJ = R_I.T @ R_J, + // i.e. q_IJ = conj(q_I)*q_J. + Versor out; + out.scalar = scalar * other.scalar + vector.dot(other.vector); + out.vector = (other.vector * scalar) - (vector * other.scalar) - vector.cross(other.vector); + return out; + } + + inline Versor + mult_conj(const Versor& other) const + { + // Equivalent to R_IJ = R_I @ R_J^T, + // i.e. q_IJ = q_I * conj(q_J). + + Versor out; + out.scalar = scalar * other.scalar + vector.dot(other.vector); + out.vector = (vector * other.scalar) + - (other.vector * scalar) + - vector.cross(other.vector); + return out; + } + + template + static inline Versor from_vector(const Vec3T &theta); }; -#if 1 + inline Versor operator*(const Versor &qa, const Versor &qb) { - const double qa0 = qa.vector[0], - qa1 = qa.vector[1], - qa2 = qa.vector[2], - qa3 = qa.scalar, - qb0 = qb.vector[0], - qb1 = qb.vector[1], - qb2 = qb.vector[2], - qb3 = qb.scalar; - - // Calculate the dot product qa.qb - const double qaTqb = qa0*qb0 + qa1*qb1 + qa2*qb2; - - // Calculate the cross-product qa x qb - const double - qaxqb0 = qa1*qb2 - qa2*qb1, - qaxqb1 = qa2*qb0 - qa0*qb2, - qaxqb2 = qa0*qb1 - qa1*qb0; - - // Calculate the quaternion product - Versor q12; - q12.vector[0] = qa3*qb0 + qb3*qa0 - qaxqb0; - q12.vector[1] = qa3*qb1 + qb3*qa1 - qaxqb1; - q12.vector[2] = qa3*qb2 + qb3*qa2 - qaxqb2; - q12.scalar = qa3*qb3 - qaTqb; - return q12; + const double qa0 = qa.vector[0], + qa1 = qa.vector[1], + qa2 = qa.vector[2], + qa3 = qa.scalar, + qb0 = qb.vector[0], + qb1 = qb.vector[1], + qb2 = qb.vector[2], + qb3 = qb.scalar; + + // Calculate the dot product qa.qb + const double qaTqb = qa0*qb0 + qa1*qb1 + qa2*qb2; + + // Calculate the cross-product qa x qb + const double + qaxqb0 = qa1*qb2 - qa2*qb1, + qaxqb1 = qa2*qb0 - qa0*qb2, + qaxqb2 = qa0*qb1 - qa1*qb0; + + // Calculate the quaternion product + Versor q12; + q12.vector[0] = qa3*qb0 + qb3*qa0 - qaxqb0; + q12.vector[1] = qa3*qb1 + qb3*qa1 - qaxqb1; + q12.vector[2] = qa3*qb2 + qb3*qa2 - qaxqb2; + q12.scalar = qa3*qb3 - qaTqb; + return q12; } -#else -inline Versor -operator* (const Versor& a, const Versor& b) + + + +template +inline Versor +Versor::from_vector(const Vec3T &theta) { - return Versor{{ - a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3], - a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2], - a[0]*b[2] + a[2]*b[0] + a[3]*b[1] - a[1]*b[3], - a[0]*b[3] + a[3]*b[0] + a[1]*b[2] - a[2]*b[1] - }}; + double t = 0.0; + for (int i=0; i<3; i++) + t += theta[i]*theta[i]; + + t = std::sqrt(t); + + Versor q; + if (t == 0) + q.vector.zero(); + + else { + const double factor = std::sin(t*0.5) / t; + for (int i = 0; i < 3; i++) + q.vector[i] = theta[i] * factor; + } + + q.scalar = std::cos(t*0.5); + return q; } + +#if 0 +} // namespace OpenSees #endif \ No newline at end of file From 0eb740d232a34eeab889299897266e3899b1612e Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Wed, 25 Jun 2025 14:15:56 -0700 Subject: [PATCH 104/261] update namespacing --- SRC/runtime/commands/modeling/geomTransf.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SRC/runtime/commands/modeling/geomTransf.cpp b/SRC/runtime/commands/modeling/geomTransf.cpp index a8b78dcae1..9cf79d8292 100644 --- a/SRC/runtime/commands/modeling/geomTransf.cpp +++ b/SRC/runtime/commands/modeling/geomTransf.cpp @@ -30,6 +30,8 @@ #include #include +using namespace OpenSees; + int TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, int argc, const char ** const argv) From bfe5ce56f6b165b8e719a19bc9120f9f7aa04907 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Wed, 25 Jun 2025 14:16:11 -0700 Subject: [PATCH 105/261] update namespacing --- .../transform/FrameTransformBuilder.hpp | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp index 3a9aa3f3a4..7f1706f893 100644 --- a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp +++ b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp @@ -13,13 +13,13 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +namespace OpenSees { class FrameTransformBuilder : public TaggedObject { public: @@ -61,29 +61,29 @@ class FrameTransformBuilder : public TaggedObject { return new PDeltaFrameTransf (tag, vz, offset_array, offset_flags); else if (strcmp(name, "Isometric") == 0 || strstr(name, "Rigid") != nullptr) - return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); + return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); return nullptr; } virtual void Print(OPS_Stream&s, int flag) { - if (flag == OPS_PRINT_PRINTMODEL_JSON) { - s << OPS_PRINT_JSON_MATE_INDENT << "{"; - s << "\"name\": " << this->getTag() << ", "; - s << "\"type\": \"" << name << "\""; - s << ", "; - s << "\"vz\": [" << vz[0] << ", " << vz[1] << ", " << vz[2] << "]"; - if (offsets.size() > 0) { - s << ", \"offsets\": {"; - for (auto it = offsets.begin(); it != offsets.end(); ++it) { - s << it->first << ": [" << it->second[0] << ", " << it->second[1] << ", " << it->second[2] << "]"; - if (std::next(it) != offsets.end()) - s << ", "; - } - } - s << "}"; + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << OPS_PRINT_JSON_MATE_INDENT << "{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"" << name << "\""; + s << ", "; + s << "\"vz\": [" << vz[0] << ", " << vz[1] << ", " << vz[2] << "]"; + if (offsets.size() > 0) { + s << ", \"offsets\": {"; + for (auto it = offsets.begin(); it != offsets.end(); ++it) { + s << it->first << ": [" << it->second[0] << ", " << it->second[1] << ", " << it->second[2] << "]"; + if (std::next(it) != offsets.end()) + s << ", "; + } } + s << "}"; + } } int ndm; @@ -93,3 +93,4 @@ class FrameTransformBuilder : public TaggedObject { std::map offsets; int offset_flags; }; +} \ No newline at end of file From ac146d4a0e73d2b7de896a51d8cbd781bd51c330 Mon Sep 17 00:00:00 2001 From: Michael Scott Date: Wed, 25 Jun 2025 14:37:22 -0700 Subject: [PATCH 106/261] Adding input option for symmetric matrices (default) --- .../linearSOE/itpack/ItpackLinSOE.cpp | 8 ++++---- SRC/system_of_eqn/linearSOE/itpack/ItpackLinSOE.h | 5 +++-- .../linearSOE/itpack/ItpackLinSolver.cpp | 14 ++++++++++---- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSOE.cpp b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSOE.cpp index f24609fcef..9416895d79 100644 --- a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSOE.cpp +++ b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSOE.cpp @@ -48,10 +48,10 @@ #include -ItpackLinSOE::ItpackLinSOE(ItpackLinSolver &the_Solver) +ItpackLinSOE::ItpackLinSOE(ItpackLinSolver &the_Solver, bool symm) :LinearSOE(the_Solver, LinSOE_TAGS_ItpackLinSOE), size(0), nnz(0), A(0), B(0), X(0), colA(0), rowStartA(0), - vectX(0), vectB(0), Asize(0), Bsize(0), Aformed(false) + vectX(0), vectB(0), Asize(0), Bsize(0), Aformed(false), symmetric(symm) { the_Solver.setLinearSOE(*this); } @@ -256,7 +256,7 @@ ItpackLinSOE::addA(const Matrix &m, const ID &id, double fact) int endRowLoc = rowStartA[row+1]; for (int j=0; j= 0) { // find place in A using colA for (int k=startRowLoc; k= 0) { // find place in A using colA for (int k=startRowLoc; k 0 && OPS_GetIntInput(&numData,&method) < 0) { opserr << "WARNING Itpack -- error reading method\n"; @@ -53,6 +52,7 @@ void* OPS_ItpackLinSolver() int iter = 100; double omega = 1.0; + bool symmetric = true; while (OPS_GetNumRemainingInputArgs() > 1) { const char *arg = OPS_GetString(); if (strcmp(arg,"-iter") == 0) { @@ -62,11 +62,17 @@ void* OPS_ItpackLinSolver() if (strcmp(arg,"-omega") == 0) { if (OPS_GetDoubleInput(&numData,&omega) < 0) return 0; - } + } + if (strcmp(arg,"-symmetric") == 0) { + int symm; + if (OPS_GetIntInput(&numData,&symm) < 0) + return 0; + symmetric = (symm != 0) ? true : false; + } } ItpackLinSolver *theSolver = new ItpackLinSolver(method, iter, omega); - return new ItpackLinSOE(*theSolver); + return new ItpackLinSOE(*theSolver, symmetric); } ItpackLinSolver::ItpackLinSolver(int meth, int iter, double om) From 0f86eb4c2a7659759fb22bbe12facb8adc43db9c Mon Sep 17 00:00:00 2001 From: Michael Scott Date: Wed, 25 Jun 2025 14:40:30 -0700 Subject: [PATCH 107/261] Removing ifdefs --- SRC/interpreter/OpenSeesCommands.cpp | 4 ---- SRC/tcl/commands.cpp | 4 ---- 2 files changed, 8 deletions(-) diff --git a/SRC/interpreter/OpenSeesCommands.cpp b/SRC/interpreter/OpenSeesCommands.cpp index da0373d9cc..7813831652 100644 --- a/SRC/interpreter/OpenSeesCommands.cpp +++ b/SRC/interpreter/OpenSeesCommands.cpp @@ -108,10 +108,8 @@ UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #endif #include -#ifdef _ITPACK #include #include -#endif #ifdef _PARALLEL_INTERPRETERS bool setMPIDSOEFlag = false; @@ -1457,10 +1455,8 @@ int OPS_System() } else if (strcmp(type,"Mumps") == 0) { theSOE = (LinearSOE*)OPS_MumpsSolver(); #endif -#ifdef _ITPACK } else if (strcmp(type,"Itpack") == 0) { theSOE = (LinearSOE*)OPS_ItpackLinSolver(); -#endif } else { opserr<<"WARNING unknown system type "< -#ifdef _ITPACK #include #include -#endif #include #include @@ -3435,7 +3433,6 @@ specifySOE(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) theSOE = new UmfpackGenLinSOE(*theSolver); } -#ifdef _ITPACK else if (strcmp(argv[1],"Itpack") == 0) { // now must determine the type of solver to create from rest of args @@ -3447,7 +3444,6 @@ specifySOE(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) ItpackLinSolver *theSolver = new ItpackLinSolver(method); theSOE = new ItpackLinSOE(*theSolver); } -#endif else if (strcmp(argv[1],"FullGeneral") == 0) { // now must determine the type of solver to create from rest of args From 80d17d14cbdabc932e1b92de2e9f9cb9d4fbf09f Mon Sep 17 00:00:00 2001 From: Michael Scott Date: Wed, 25 Jun 2025 14:41:19 -0700 Subject: [PATCH 108/261] Defining ITPACK libraries in CMake --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index efc3a9255d..397b8f8450 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -286,6 +286,8 @@ set (AMD_LIBRARIES AMD) add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/ARPACK") set (ARPACK_LIBRARIES ARPACK) add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/CSPARSE") +set (ITPACK_LIBRARIES ITPACK) +add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/ITPACK") set (CSPARSE_LIBRARIES CSPARSE) add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/tetgen1.4.3") set (TETGEN_LIBRARIES tet) @@ -406,7 +408,7 @@ target_link_libraries(OPS_Numerics INTERFACE ${TETGEN_LIBRARIES} ${TRIANGLE_LIBRARIES} ${AMD_LIBRARIES} - ${AMD_LIBRARIES} + ${ITPACK_LIBRARIES} ${LAPACK_LIBRARIES} ${EIGENAPI_LIBRARIES} ) From 07c7abad400e74a55ca52450b0a7191b31c4d9f2 Mon Sep 17 00:00:00 2001 From: Michael Scott Date: Wed, 25 Jun 2025 15:04:02 -0700 Subject: [PATCH 109/261] Fixing directory listing --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 397b8f8450..9d7ad9d105 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -286,9 +286,9 @@ set (AMD_LIBRARIES AMD) add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/ARPACK") set (ARPACK_LIBRARIES ARPACK) add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/CSPARSE") -set (ITPACK_LIBRARIES ITPACK) -add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/ITPACK") set (CSPARSE_LIBRARIES CSPARSE) +add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/ITPACK") +set (ITPACK_LIBRARIES ITPACK) add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/tetgen1.4.3") set (TETGEN_LIBRARIES tet) add_subdirectory("${PROJECT_SOURCE_DIR}/OTHER/Triangle") From 88ef5aeedbf1c0f66348c4700b4c60432d67b642 Mon Sep 17 00:00:00 2001 From: Michael Scott Date: Wed, 25 Jun 2025 15:16:29 -0700 Subject: [PATCH 110/261] Adding ITPACK to local CMakeLists --- SRC/system_of_eqn/linearSOE/CMakeLists.txt | 2 +- SRC/system_of_eqn/linearSOE/itpack/CMakeLists.txt | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/SRC/system_of_eqn/linearSOE/CMakeLists.txt b/SRC/system_of_eqn/linearSOE/CMakeLists.txt index 92d4b27beb..d777be4cfa 100644 --- a/SRC/system_of_eqn/linearSOE/CMakeLists.txt +++ b/SRC/system_of_eqn/linearSOE/CMakeLists.txt @@ -30,5 +30,5 @@ add_subdirectory(profileSPD) #add_subdirectory(cg) #add_subdirectory(petsc) #add_subdirectory(mumps) -#add_subdirectory(itpack) +add_subdirectory(itpack) diff --git a/SRC/system_of_eqn/linearSOE/itpack/CMakeLists.txt b/SRC/system_of_eqn/linearSOE/itpack/CMakeLists.txt index 15232f9f8c..7315c18935 100644 --- a/SRC/system_of_eqn/linearSOE/itpack/CMakeLists.txt +++ b/SRC/system_of_eqn/linearSOE/itpack/CMakeLists.txt @@ -7,9 +7,12 @@ target_sources(OPS_SysOfEqn PRIVATE - + ItpackLinSOE.cpp + ItpackLinSolver.cpp + PUBLIC - + ItpackLinSOE.h + ItpackLinSolver.h ) target_include_directories(OPS_SysOfEqn PUBLIC ${CMAKE_CURRENT_LIST_DIR}) From 7e379bae749d726a01a0dfc9467330bd8c1c00fa Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Wed, 25 Jun 2025 20:22:55 -0700 Subject: [PATCH 111/261] organize `MatrixND` --- SRC/matrix/MatrixND.h | 29 +-- SRC/matrix/MatrixND.tpp | 426 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 432 insertions(+), 23 deletions(-) create mode 100644 SRC/matrix/MatrixND.tpp diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index 8e7a4e0835..837507dc10 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -4,15 +4,11 @@ // //===----------------------------------------------------------------------===// // https://xara.so -// -//===--- MatrixND.h - Matrix with fixed size ------------------------------===// +//===----------------------------------------------------------------------===// // // Desctiption: MatrixND is a fixed-size matrix class that is suitable for // stack-allocation. // -// Objectives: -// - little to no overhead above C-style arrays -// - value semantics; objects do not decay to pointers; // // This code is influenced by the following sources // List initialization: @@ -44,7 +40,6 @@ #include "VectorND.h" #include "Matrix.h" #include "Vector.h" -#include "routines/cmx.h" #include "routines/SY3.h" #if __cplusplus < 202000L @@ -61,10 +56,11 @@ requires(NR > 0 && NC > 0) struct MatrixND { double values[NC][NR]; -//MatrixND(const MatrixND&) = default; + //MatrixND(const MatrixND&) = default; // Convert to regular Matrix class operator Matrix() { return Matrix(&values[0][0], NR, NC);} + operator const Matrix() const { return Matrix(&values[0][0], NR, NC);} int symeig(VectorND& vals) requires(NR == NC == 3) { @@ -81,7 +77,7 @@ struct MatrixND { void addMatrix(const MatT& A, const double scale); template constexpr MatrixND& - addTensorProduct(const VecA& V, const VecB& W, const double scale); + addTensorProduct(const VecA& V, const VecB& W, const double scale) noexcept; template void addMatrixProduct(const MatrixND &, const MatT&, double scale); @@ -402,8 +398,7 @@ struct MatrixND { for (int i=0; i +void +MatrixND::zero() +{ + for (index_t j = 0; j < nr; ++j) { + for (index_t i = 0; i < nc; ++i) { + values[j][i] = 0.0; + } + } +} + + +template +constexpr MatrixND +MatrixND::transpose() const +{ + MatrixND result = {}; + for (index_t j = 0; j < nc; ++j) { + for (index_t i = 0; i < nr; ++i) { + result.values[i][j] = values[j][i]; + } + } + return result; +} + + +template +template inline void +MatrixND::map(F func) const +{ + for (int i=0; i +template inline void +MatrixND::map(F func, MatrixND& destination) +{ + for (int i=0; i inline int +MatrixND::invert(MatrixND &M) const +{ + static_assert(nr == nc, "Matrix must be square"); + static_assert(nr > 1 && nr < 7, "Matrix must be between 2x2 and 6x6"); + + int status = -1; + if constexpr (nr == 2) { + cmx_inv2(&this->values[0][0], &M.values[0][0], &status); + return status; + } + if constexpr (nr == 3) { + cmx_inv3(&this->values[0][0], &M.values[0][0], &status); + return status; + } + if constexpr (nr == 4) { + cmx_inv4(&this->values[0][0], &M.values[0][0], &status); + return status; + } + if constexpr (nr == 5) { + cmx_inv5(&this->values[0][0], &M.values[0][0], &status); + return status; + } + if constexpr (nr == 6) { + cmx_inv6(&this->values[0][0], &M.values[0][0], &status); + return status; + } + return status; +} + +template inline +MatrixND& +MatrixND::addDiagonal(const double diag) +{ + for (int i=0; i +template inline +void MatrixND::addMatrix(const MatT& A, const double scale) +{ + for (int i=0; i +template +constexpr inline +MatrixND& +MatrixND::addTensorProduct(const VecA& a, const VecB& b, const double scale) noexcept +{ + // Chrystal's bun order + for (int j=0; j +template inline +void +MatrixND::addMatrixProduct(const MatrixND& A, const MatT& B, double scale) +{ + if constexpr (nr*nc < 16) + for (int i=0; i(&A(0,0)), &m, + const_cast(&B(0,0)), &k, + &one, &(*this)(0,0), &m); + } +} + +template +template inline +void +MatrixND::addMatrixProduct(double scale_this, const MatrixND& A, const MatT& B, double scale) +{ + int m = nr, + n = nc, + k = nk; + DGEMM("N", "N", &m, &n, &k, &scale, + const_cast(&A(0,0)), &m, + const_cast(&B(0,0)), &k, + &scale_this, &(*this)(0,0), &m); + +} + +// B'*C +template +template inline +void +MatrixND::addMatrixTransposeProduct(double thisFact, + const MatrixND& B, + const MatT& C, + const double otherFact) +{ + if constexpr (nr*nc > 16) { + int m = nr, + n = nc, + k = nk; + DGEMM("T", "N", &m, &n, &k, &otherFact, + const_cast(&B(0,0)), &k, + const_cast(&C(0,0)), &k, + &thisFact, &(*this)(0,0), &m); + return; + } + + if (thisFact == 1.0) { + double *aijPtr = &values[0][0]; + for (int j=0; j +template inline +int +MatrixND::addMatrixTripleProduct( + double thisFact, + const MatrixND &T, + const MatrixND &B, + double otherFact) + requires(nr == nc) +{ + if (otherFact == 0.0 && thisFact == 1.0) + return 0; + + MatrixND BT; + BT.zero(); + BT.addMatrixProduct(B, T, otherFact); + this->addMatrixTransposeProduct(thisFact, T, BT, 1.0); + +//{ +// int m = B.numRows, +// n = T.numCols, +// k = B.numCols, +// nrT = T.numRows; +// //k = T.numRows; +// double zero = 0.0, +// one = 1.0; + +// DGEMM ("N", "N", &m , &n , &k,&one , B.data, &m, // m +// T.data, &nrT, // k +// &zero, matrixWork, &m); + +// DGEMM ("T", "N", &numRows, &numCols, &k,&otherFact, T.data, &nrT, +// matrixWork, &m, // k +// &thisFact, data, &numRows); +// return 0; +//} + + return 0; +} + + +template +template inline int +MatrixND::addMatrixTripleProduct(double thisFact, + const MatrixND &A, + const MatrixND &B, + const MatrixND &C, double otherFact) +{ + if (otherFact == 0.0 && thisFact == 1.0) + return 0; + + MatrixND BC {}; + BC.addMatrixProduct(B, C, otherFact); + this->addMatrixTransposeProduct(thisFact, A, BC, 1.0); + return 0; +} + + +template +MatrixND(const T (&)[nc][nr])->MatrixND; + + +// +// 3D +// + +template +template +inline MatrixND& +MatrixND::addSpin(const VecT& v) requires(NR == 3) +{ + const double v0 = v[0], + v1 = v[1], + v2 = v[2]; + + (*this)(0, 0) += 0.0; (*this)(0, 1) += -v2; (*this)(0, 2) += v1; + (*this)(1, 0) += v2; (*this)(1, 1) += 0.0; (*this)(1, 2) += -v0; + (*this)(2, 0) += -v1; (*this)(2, 1) += v0; (*this)(2, 2) += 0.0; + + return *this; +} + + +template +template +inline MatrixND& +MatrixND::addSpin(const VecT& v, double mult) +{ + const double v0 = mult*v[0], + v1 = mult*v[1], + v2 = mult*v[2]; + + (*this)(0, 0) += 0.0; (*this)(0, 1) += -v2; (*this)(0, 2) += v1; + (*this)(1, 0) += v2; (*this)(1, 1) += 0.00; (*this)(1, 2) += -v0; + (*this)(2, 0) += -v1; (*this)(2, 1) += v0; (*this)(2, 2) += 0.0; + return *this; +} + + +template +template inline +MatrixND& +MatrixND::addSpinSquare(const VecT& v, const double scale) + requires(NR == NC == 3) +{ + const double v1 = v[0], + v2 = v[1], + v3 = v[2]; + + (*this)(0,0) += scale*( -v2*v2 - v3*v3 ); + (*this)(1,1) += scale*( -v1*v1 - v3*v3 ); + (*this)(2,2) += scale*( -v1*v1 - v2*v2 ); + + (*this)(0,1) += scale*( v1*v2 ); + (*this)(1,0) += scale*( v1*v2 ); + (*this)(2,0) += scale*( v1*v3 ); + (*this)(0,2) += scale*( v1*v3 ); + (*this)(1,2) += scale*( v2*v3 ); + (*this)(2,1) += scale*( v2*v3 ); + return *this; +} + + +template +template +inline void +MatrixND::addSpinProduct(const VecT& a, const VectorND& b, const double scale) + requires(NR == NC == 3) +{ + // a^b^ = boa - a.b 1 + // where 'o' denotes the tensor product and '.' the dot product + // + this->addTensorProduct(b, a, scale); + this->addDiagonal(-b.dot(a)*scale); +} + +template +template +inline void +MatrixND::addMatrixSpinProduct(const MatrixND& A, const VecT& b, const double scale) +{ + // this += s*A*[b^] + // where b^ is the skew-symmetric representation of the three-vector b, s is a scalar, + // and A a 3x3 matrix. + // + (*this)(0, 0) += scale*( A(0,1)*b[2] - A(0,2)*b[1]); + (*this)(0, 1) += scale*(-A(0,0)*b[2] + A(0,2)*b[0]); + (*this)(0, 2) += scale*( A(0,0)*b[1] - A(0,1)*b[0]); + (*this)(1, 0) += scale*( A(1,1)*b[2] - A(1,2)*b[1]); + (*this)(1, 1) += scale*(-A(1,0)*b[2] + A(1,2)*b[0]); + (*this)(1, 2) += scale*( A(1,0)*b[1] - A(1,1)*b[0]); + (*this)(2, 0) += scale*( A(2,1)*b[2] - A(2,2)*b[1]); + (*this)(2, 1) += scale*(-A(2,0)*b[2] + A(2,2)*b[0]); + (*this)(2, 2) += scale*( A(2,0)*b[1] - A(2,1)*b[0]); +} + +template +template inline +void MatrixND::addSpinMatrixProduct(const VectorND& a, const MatT& B, const double scale) + requires(NR == NC == 3) +{ + // this += s*[a^]*B + // where a^ is the skew-symmetric representation of the three-vector a, s is a scalar, + // and B a 3x3 matrix. + // + (*this)(0, 0) += scale*( -B(1,0)*a[2] + B(2,0)*a[1]); + (*this)(0, 1) += scale*( -B(1,1)*a[2] + B(2,1)*a[1]); + (*this)(0, 2) += scale*( -B(1,2)*a[2] + B(2,2)*a[1]); + (*this)(1, 0) += scale*( B(0,0)*a[2] - B(2,0)*a[0]); + (*this)(1, 1) += scale*( B(0,1)*a[2] - B(2,1)*a[0]); + (*this)(1, 2) += scale*( B(0,2)*a[2] - B(2,2)*a[0]); + (*this)(2, 0) += scale*( -B(0,0)*a[1] + B(1,0)*a[0]); + (*this)(2, 1) += scale*( -B(0,1)*a[1] + B(1,1)*a[0]); + (*this)(2, 2) += scale*( -B(0,2)*a[1] + B(1,2)*a[0]); +} +} \ No newline at end of file From 85b5c4be8e79ac6319550ed4060af83998c3a6fa Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 27 Jun 2025 13:15:29 -0700 Subject: [PATCH 112/261] clean up --- .../Frame/EuclidFrameTransf.h | 4 +-- .../Frame/EuclidFrameTransf.tpp | 1 - .../Frame/LinearFrameTransf.h | 1 + .../Frame/SouzaFrameTransf.tpp | 14 -------- SRC/matrix/MatrixND.h | 2 +- SRC/matrix/MatrixND.tpp | 2 +- SRC/matrix/Rotations.hpp | 33 +++++++++++-------- 7 files changed, 24 insertions(+), 33 deletions(-) diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h index 6a10efe3c6..d9b0f8282c 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.h +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -53,7 +53,7 @@ class EuclidFrameTransf: public FrameTransform virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; - virtual FrameTransform *getCopy() const; + FrameTransform *getCopy() const final; double getInitialLength() final; double getDeformedLength() final; @@ -82,7 +82,7 @@ class EuclidFrameTransf: public FrameTransform // bool isShapeSensitivity() final; double getLengthGrad() final; - double getd1overLdh(); + double getd1overLdh() final; // TaggedObject void Print(OPS_Stream &s, int flag = 0) final; diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 872c3673ec..1c0db3db72 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -36,7 +36,6 @@ namespace OpenSees { - template EuclidFrameTransf::EuclidFrameTransf(int tag, const Vector3D &vecxz, diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.h b/SRC/coordTransformation/Frame/LinearFrameTransf.h index 9d3776d703..36670c40eb 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.h +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.h @@ -34,6 +34,7 @@ #include namespace OpenSees { + template class LinearFrameTransf: public FrameTransform { diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp index 5aa96b0906..e766e82048 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp @@ -202,20 +202,6 @@ SouzaFrameTransf::initialize(std::array& new_nodes) initialDispChecked = true; } -#if 0 - if (nodeIInitialDisp != nullptr) { - dX[0] -= nodeIInitialDisp[0]; - dX[1] -= nodeIInitialDisp[1]; - dX[2] -= nodeIInitialDisp[2]; - } - - if (nodeJInitialDisp != nullptr) { - dX[0] += nodeJInitialDisp[0]; - dX[1] += nodeJInitialDisp[1]; - dX[2] += nodeJInitialDisp[2]; - } -#endif - // // Length and Orientation // diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index 837507dc10..880d1533d6 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -86,7 +86,7 @@ struct MatrixND { addMatrixProduct(double, const MatrixND &, const MatT&, double scale); // += A'B - template void + template void addMatrixTransposeProduct(double thisFact, const MatrixND &, const MatT&, double scale); // += A'BA diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index 8bf07a35e8..3f3c3ccaf3 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -170,7 +170,7 @@ void MatrixND::addMatrixTransposeProduct(double thisFact, const MatrixND& B, const MatT& C, - const double otherFact) + double otherFact) { if constexpr (nr*nc > 16) { int m = nr, diff --git a/SRC/matrix/Rotations.hpp b/SRC/matrix/Rotations.hpp index 0a714924c4..1408324d0b 100755 --- a/SRC/matrix/Rotations.hpp +++ b/SRC/matrix/Rotations.hpp @@ -1,10 +1,22 @@ //===----------------------------------------------------------------------===// // // xara -// -//===----------------------------------------------------------------------===// // https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// //===----------------------------------------------------------------------===// + // // Functions related to exponential coordinates on SO(3). The implementation // follows value semantics with the expectation that RVO will make this @@ -12,11 +24,6 @@ // // Written: cmp // -// [1] Perez, C. M., and Filippou F. C. (2024) "On Nonlinear Geometric -// Transformations of Finite Elements" -// Int. J. Numer. Meth. Engrg. https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// #pragma once #include @@ -39,9 +46,9 @@ static constexpr Matrix3D Eye3 {{ static inline Vector3D Vee(const Matrix3D &X) { -//===----------------------------------------------------------------------===// +// // Return the axial vector x of the given skew-symmetric 3x3 matrix X. -//===----------------------------------------------------------------------===// +// return {X(2,1), X(0,2), X(1,0)}; } @@ -299,8 +306,6 @@ VersorFromMatrix(const Matrix3D &R) static inline Matrix3D ExpSO3(const Vector3D &theta) { - //===--------------------------------------------------------------------===// - // Form the first Gib coefficients double a[4]; GibSO3(theta, a); @@ -315,6 +320,7 @@ ExpSO3(const Vector3D &theta) static inline Matrix3D CaySO3(const Vector3D &cayley) { + // // Cayley map for a rotation matrix given the "tangent-scaled pseudo-vector" // // R = I + (S + S*S/2)/(1 + w' * w / 4); @@ -552,7 +558,7 @@ inline Matrix3D dLogSO3(const Vector3D &v, double* a=nullptr) { // -// d_R LogSO3(v) +// d_R LogSO3(v) = Eye3 - 0.5*Sv + eta*Sv*Sv; // // ========================================================================================= // function by Claudio Perez 2023 @@ -583,7 +589,6 @@ dLogSO3(const Vector3D &v, double* a=nullptr) dH.addSpin(u, -0.5); dH.addSpinSquare(u, eta); return dH; - // return Eye3 - 0.5*Sv + eta*Sv*Sv; } inline Matrix3D @@ -663,4 +668,4 @@ class Align { Vector3D target; }; -#endif \ No newline at end of file +#endif From daf6dcd6727ee3591723da88f0fabd6cdcf40ea0 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 27 Jun 2025 17:18:45 -0700 Subject: [PATCH 113/261] Update DOF_Group.cpp Clarifying error messages --- DEVELOPER/core/DOF_Group.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/DEVELOPER/core/DOF_Group.cpp b/DEVELOPER/core/DOF_Group.cpp index 5c3f723aa8..ca36246085 100644 --- a/DEVELOPER/core/DOF_Group.cpp +++ b/DEVELOPER/core/DOF_Group.cpp @@ -650,14 +650,14 @@ void DOF_Group::incrNodeDisp(const Vector &u) { if (myNode == 0) { - opserr << "DOF_Group::setNodeDisp: 0 Node Pointer\n"; + opserr << "DOF_Group::incrNodeDisp: 0 Node Pointer\n"; exit(-1); } Vector &disp = *unbalance;; if (disp.Size() == 0) { - opserr << "DOF_Group::setNodeIncrDisp - out of space\n"; + opserr << "DOF_Group::incrNodeDisp - out of space\n"; return; } int i; @@ -683,7 +683,7 @@ DOF_Group::incrNodeVel(const Vector &udot) { if (myNode == 0) { - opserr << "DOF_Group::setNodeVel: 0 Node Pointer\n"; + opserr << "DOF_Group::incrNodeVel: 0 Node Pointer\n"; exit(-1); } @@ -711,7 +711,7 @@ DOF_Group::incrNodeAccel(const Vector &udotdot) { if (myNode == 0) { - opserr << "DOF_Group::setNodeAccel: 0 Node Pointer\n"; + opserr << "DOF_Group::incrNodeAccel: 0 Node Pointer\n"; exit(-1); } @@ -735,7 +735,7 @@ DOF_Group::setEigenvector(int mode, const Vector &theVector) { if (myNode == 0) { - opserr << "DOF_Group::setNodeAccel: 0 Node Pointer\n"; + opserr << "DOF_Group::setEigenvector: 0 Node Pointer\n"; exit(-1); } @@ -758,7 +758,7 @@ const Matrix & DOF_Group::getEigenvectors(void) { if (myNode == 0) { - opserr << "DOF_Group::setNodeAccel: 0 Node Pointer\n"; + opserr << "DOF_Group::getEigenvectors: 0 Node Pointer\n"; exit(-1); } From 549dee7d871c09b0ea3337c1f700bf93180acd30 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 27 Jun 2025 17:23:14 -0700 Subject: [PATCH 114/261] Update DOF_Group.cpp Clarifying error messages --- SRC/analysis/dof_grp/DOF_Group.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SRC/analysis/dof_grp/DOF_Group.cpp b/SRC/analysis/dof_grp/DOF_Group.cpp index def7dc9b33..44f9bbdd38 100644 --- a/SRC/analysis/dof_grp/DOF_Group.cpp +++ b/SRC/analysis/dof_grp/DOF_Group.cpp @@ -650,14 +650,14 @@ void DOF_Group::incrNodeDisp(const Vector &u) { if (myNode == 0) { - opserr << "DOF_Group::setNodeDisp: 0 Node Pointer\n"; + opserr << "DOF_Group::incrNodeDisp: 0 Node Pointer\n"; exit(-1); } Vector &disp = *unbalance;; if (disp.Size() == 0) { - opserr << "DOF_Group::setNodeIncrDisp - out of space\n"; + opserr << "DOF_Group::incrNodeDisp - out of space\n"; return; } int i; @@ -683,7 +683,7 @@ DOF_Group::incrNodeVel(const Vector &udot) { if (myNode == 0) { - opserr << "DOF_Group::setNodeVel: 0 Node Pointer\n"; + opserr << "DOF_Group::incrNodeVel: 0 Node Pointer\n"; exit(-1); } @@ -711,7 +711,7 @@ DOF_Group::incrNodeAccel(const Vector &udotdot) { if (myNode == 0) { - opserr << "DOF_Group::setNodeAccel: 0 Node Pointer\n"; + opserr << "DOF_Group::incrNodeAccel: 0 Node Pointer\n"; exit(-1); } @@ -769,7 +769,7 @@ DOF_Group::setEigenvector(int mode, const Vector &theVector) { if (myNode == 0) { - opserr << "DOF_Group::setNodeAccel: 0 Node Pointer\n"; + opserr << "DOF_Group::setEigenvector: 0 Node Pointer\n"; exit(-1); } @@ -792,7 +792,7 @@ const Matrix & DOF_Group::getEigenvectors(void) { if (myNode == 0) { - opserr << "DOF_Group::setNodeAccel: 0 Node Pointer\n"; + opserr << "DOF_Group::getEigenvectors: 0 Node Pointer\n"; exit(-1); } From d967c9bba8524464d0e2a21d29e7501f0ba83d4e Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 27 Jun 2025 17:56:15 -0700 Subject: [PATCH 115/261] Adding setEigenvector method to avoid exit in base class method --- SRC/analysis/dof_grp/LagrangeDOF_Group.cpp | 5 +++++ SRC/analysis/dof_grp/LagrangeDOF_Group.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/SRC/analysis/dof_grp/LagrangeDOF_Group.cpp b/SRC/analysis/dof_grp/LagrangeDOF_Group.cpp index a85d03cbff..2a00e1b9cd 100644 --- a/SRC/analysis/dof_grp/LagrangeDOF_Group.cpp +++ b/SRC/analysis/dof_grp/LagrangeDOF_Group.cpp @@ -186,6 +186,11 @@ LagrangeDOF_Group::incrNodeAccel(const Vector &udotdot) return; } +void +LagrangeDOF_Group::setEigenvector(int mode, const Vector &eigenvector) +{ + return; +} const Vector & LagrangeDOF_Group::getCommittedDisp(void) diff --git a/SRC/analysis/dof_grp/LagrangeDOF_Group.h b/SRC/analysis/dof_grp/LagrangeDOF_Group.h index 57b90115c9..bad60a58c7 100644 --- a/SRC/analysis/dof_grp/LagrangeDOF_Group.h +++ b/SRC/analysis/dof_grp/LagrangeDOF_Group.h @@ -73,6 +73,8 @@ class LagrangeDOF_Group: public DOF_Group virtual void incrNodeVel(const Vector &udot); virtual void incrNodeAccel(const Vector &udotdot); + virtual void setEigenvector(int mode, const Vector &eigenvector); + virtual void zeroTangent(void); virtual void addMtoTang(double fact = 1.0); virtual void zeroUnbalance(void); From 2a411a049b4ef75aabf0b8bac1191603ad10a0ef Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sat, 28 Jun 2025 22:01:56 -0700 Subject: [PATCH 116/261] update isometries --- SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h | 2 +- SRC/coordTransformation/Frame/Isometry/RankineIsometry.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h index bf9aa35545..b90d40062b 100644 --- a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h @@ -27,7 +27,7 @@ #include #include -#define TRIAD C2 + namespace OpenSees { class Isometry diff --git a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h b/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h index 8963a7accb..80ce23c7dc 100644 --- a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h @@ -23,6 +23,7 @@ #include "EuclidIsometry.h" class Node; +#define TRIAD C2 namespace OpenSees { @@ -85,8 +86,8 @@ class RankineIsometry : public AlignedIsometry return 0; } - virtual int - update() { + int + update() final { Vector3D e1 = dX; { From d261228945dadd164724c0e57591d91043c96bd8 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sat, 28 Jun 2025 22:08:17 -0700 Subject: [PATCH 117/261] clean up --- .../Frame/Isometry/CrisfieldIsometry.tpp | 18 - .../Frame/Isometry/CrisfieldTransform.h | 284 ------ .../Frame/SouzaFrameTransf.h | 161 --- .../Frame/SouzaFrameTransf.tpp | 942 ------------------ 4 files changed, 1405 deletions(-) delete mode 100644 SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp delete mode 100644 SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h delete mode 100644 SRC/coordTransformation/Frame/SouzaFrameTransf.h delete mode 100644 SRC/coordTransformation/Frame/SouzaFrameTransf.tpp diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp deleted file mode 100644 index 1017532ab9..0000000000 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp +++ /dev/null @@ -1,18 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures -// -//----------------------------------------------------------------------------// -// -// Please cite the following resource in any derivative works: -// -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; -// https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h deleted file mode 100644 index 40b0477b95..0000000000 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h +++ /dev/null @@ -1,284 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures -// -//----------------------------------------------------------------------------// -// -// Please cite the following resource in any derivative works: -// -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; -// https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// - -#pragma once -#include -#include -#include -#include -#include - -namespace OpenSees { - -class CrisfieldTransform { -public: - CrisfieldTransform() {} - - int - update(const Versor& qI, const Versor& qJ, const Vector3D& dx) - { - - Ln = dx.norm(); - - { - Vector3D gammaw = CayleyFromVersor(qJ.mult_conj(qI)); - - gammaw *= 0.5; - - // Qbar = VersorProduct(VersorFromMatrix(CaySO3(gammaw)), qI); - Qbar = VersorFromMatrix(CaySO3(gammaw)*MatrixFromVersor(qI)); - Triad r{CaySO3(gammaw)*MatrixFromVersor(qI)}; - r1 = r[1]; - r2 = r[2]; - r3 = r[3]; - } - - // - // Compute the base vectors e2, e3 - // - { - // 'rotate' the mean rotation matrix Rbar on to e1 to - // obtain e2 and e3 (using the 'mid-point' procedure) - // - // Vector3D e1, e2, e3; - e[0] = dx; - e[0] /= Ln; - Matrix3D Rbar = MatrixFromVersor(Qbar); - Triad r = Triad{Rbar}; - Vector3D r1 = r[1], - r2 = r[2], - r3 = r[3]; - - // e2 = r2 - (e1 + r1)*((r2^e1)*0.5); - - Vector3D tmp; - tmp = e[0]; - tmp += r1;//Qbar.rotate(E1); - - e[1] = tmp; - { - // const Vector3D r2 = Qbar.rotate(E2); - e[1] *= 0.5*r2.dot(e[0]); - e[1].addVector(-1.0, r2, 1.0); - } - - // e3 = r3 - (e1 + r1)*((r3^e1)*0.5); - e[2] = tmp; - { - // const Vector3D r3 = Qbar.rotate(E3); - e[2] *= r3.dot(e[0])*0.5; - e[2].addVector(-1.0, r3, 1.0); - } - } - return 0; - } - - inline Matrix3D - getRotation() const noexcept - { - Matrix3D E; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - E(i,j) = e[j][i]; - return E; - } - - constexpr const Vector3D& - getBasisE1() const noexcept - { - return e[0]; - } - constexpr const Vector3D& - getBasisE2() const noexcept - { - return e[1]; - } - constexpr const Vector3D& - getBasisE3() const noexcept - { - return e[2]; - } - - - const Versor& - getReference() - { - return Qbar; - } - - static inline void - getLMatrix(const Matrix3D& A, const Vector3D& e1, const Vector3D& r1, const Vector3D &ri, MatrixND<12,3>& L) - { - static Matrix3D L1, L2; - static Matrix3D rie1r1; - static Matrix3D e1e1r1; - - const double rie1 = ri.dot(e1); - - for (int k = 0; k < 3; k++) { - const double e1r1k = (e1[k] + r1[k]); - for (int j = 0; j < 3; j++) { - rie1r1(j,k) = ri[j]*e1r1k; - e1e1r1(j,k) = e1[j]*e1r1k; - } - } - - // L1 = ri'*e1 * A/2 + A*ri*(e1 + r1)'/2; - L1.zero(); - L1.addMatrix(A, rie1*0.5); - L1.addMatrixProduct(A, rie1r1, 0.5); - - // L2 = Sri/2 - ri'*e1*S(r1)/4 - Sri*e1*(e1 + r1)'/4; - L2.zero(); - L2.addSpin(ri, 0.5); - L2.addSpin(r1, -rie1/4.0); - L2.addSpinMatrixProduct(ri, e1e1r1, -0.25); - - // L = [L1 - // L2 - // -L1 - // L2]; - - L.zero(); - L.assemble(L1, 0, 0, 1.0); - L.assemble(L2, 3, 0, 1.0); - L.assemble(L1, 6, 0, -1.0); - L.assemble(L2, 9, 0, 1.0); - - } - - static inline const MatrixND<12,12> & - getKs2Matrix(Matrix3D& A, const Vector3D& e1, const Vector3D& r1, const double Ln, const Vector3D &ri, const Vector3D &z) - { - static MatrixND<12,12> ks2; - - // Ksigma2 = [ K11 K12 -K11 K12 - // K12' K22 -K12' K22 - // -K11 -K12 K11 -K12 - // K12' K22 -K12' K22]; - - // U = (-1/2)*A*z*ri'*A + ri'*e1*A*z*e1'/(2*Ln)+... - // z'*(e1+r1)*A*ri*e1'/(2*Ln); - - const double rite1 = ri.dot(e1); - const double zte1 = z.dot(e1); - const double ztr1 = z.dot(r1); - - static Matrix3D zrit, ze1t; - static Matrix rizt(3,3), rie1t(3,3); - static Matrix3D e1zt; - - // const Matrix3D e1zt = e1.bun(z); - - // Chrystal's looping order - for (int j = 0; j < 3; j++) { - for (int i = 0; i < 3; i++) { - zrit(i,j) = z[i]*ri[j]; - rizt(i,j) = ri[i]*z[j]; - ze1t(i,j) = z[i]*e1[j]; - e1zt(i,j) = e1[i]*z[j]; - rie1t(i,j) = ri[i]*e1[j]; - } - } - - static Matrix3D U; - - U.addMatrixTripleProduct(0.0, A, zrit, -0.5); - U.addMatrixProduct(A, ze1t, rite1/(2*Ln)); - U.addMatrixProduct(A, rie1t, (zte1 + ztr1)/(2*Ln)); - - static Matrix3D ks; - static Matrix3D m1; - - // K11 = U + U' + ri'*e1*(2*(e1'*z)+z'*r1)*A/(2*Ln); - ks.zero(); - ks.addMatrix(U, 1.0); - - // Add matrix U transpose - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - ks(i,j) += U(j,i); - - ks.addMatrix(A, rite1*(2*zte1 + ztr1)/(2*Ln)); - - ks2.zero(); - ks2.assemble(ks, 0, 0, 1.0); - ks2.assemble(ks, 0, 6, -1.0); - ks2.assemble(ks, 6, 0, -1.0); - ks2.assemble(ks, 6, 6, 1.0); - - // K12 = (1/4)*(-A*z*e1'*Sri - A*ri*z'*Sr1 - z'*(e1+r1)*A*Sri); - m1.zero(); - m1.addMatrixProduct(A, ze1t, -1.0); - ks.zero(); - ks.addMatrixSpinProduct(m1, ri, 0.25); - - m1.zero(); - m1.addMatrixProduct(A, rizt, -1.0); - ks.addMatrixSpinProduct(m1, r1, 0.25); - ks.addMatrixSpinProduct(A, ri, -0.25*(zte1+ztr1)); - - ks2.assemble(ks, 0, 3, 1.0); - ks2.assemble(ks, 0, 9, 1.0); - ks2.assemble(ks, 6, 3, -1.0); - ks2.assemble(ks, 6, 9, -1.0); - - ks2.assembleTranspose(ks, 3, 0, 1.0); - ks2.assembleTranspose(ks, 3, 6, -1.0); - ks2.assembleTranspose(ks, 9, 0, 1.0); - ks2.assembleTranspose(ks, 9, 6, -1.0); - - // K22 = (1/8)*((-ri'*e1)*Sz*Sr1 + Sr1*z*e1'*Sri + ... - // Sri*e1*z'*Sr1 - (e1+r1)'*z*S(e1)*Sri + 2*Sz*Sri); - - ks.zero(); - ks.addSpinProduct(z, r1, -0.125*(rite1)); - - m1.zero(); - m1.addSpinMatrixProduct( r1, ze1t, 1.0); - ks.addMatrixSpinProduct( m1, ri, 0.125); - - m1.zero(); - m1.addSpinMatrixProduct(ri, e1zt, 1.0); - ks.addMatrixSpinProduct(m1, r1, 0.125); - - ks.addSpinProduct(e1, ri, -0.125*(zte1 + ztr1)); - ks.addSpinProduct( z, ri, 0.25); - - // Ksigma2 = [ K11 K12 -K11 K12; - // K12t K22 -K12t K22; - // -K11 -K12 K11 -K12; - // K12t K22 -K12t K22]; - - ks2.assemble(ks, 3, 3, 1.0); - ks2.assemble(ks, 3, 9, 1.0); - ks2.assemble(ks, 9, 3, 1.0); - ks2.assemble(ks, 9, 9, 1.0); - - return ks2; - } - -private: - Versor Qbar; - Vector3D r1, r2, r3; - Vector3D e[3]; - double Ln; - -}; -} \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.h b/SRC/coordTransformation/Frame/SouzaFrameTransf.h deleted file mode 100644 index 70385ae384..0000000000 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.h +++ /dev/null @@ -1,161 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures -// -//----------------------------------------------------------------------------// -// -// Please cite the following resource in any derivative works: -// -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; -// https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// - -// -// Description: This file contains the class definition for -// SouzaFrameTransf. SouzaFrameTransf implements the formulation -// of Crisfield (1990) with the objective of maintaining the -// original "Corotational" implementation by Remo Magalhaes de Souza, within -// the new framework proposed by Perez and Filippou (2024). -// -// Written by : cmp, March 2024 -// -// Adapted from work by: Remo Magalhaes de Souza -// -#ifndef SouzaFrameTransf_hpp -#define SouzaFrameTransf_hpp - -#include -#include "FrameTransform.h" -#include -#include -#include -#include -#include -#include "Isometry/CrisfieldTransform.h" - -struct Triad; - -namespace OpenSees { - -template -class SouzaFrameTransf: public FrameTransform -{ -public: - SouzaFrameTransf(int tag, const Vector3D &vecxz, - const std::array *offset=nullptr, - int offset_flags = 0); - - ~SouzaFrameTransf(); - - const char *getClassType() const { - return "SouzaFrameTransf"; - } - - // NOTE: maybe add arg for rotation parameterization - FrameTransform *getCopy() const final; - - int initialize(std::array& new_nodes) final; - int update() final; - int commit() final; - int revertToLastCommit() final; - int revertToStart() final; - int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const final; - const std::array *getRigidOffsets() const final { return offsets; } - - double getInitialLength(); - double getDeformedLength(); - - VectorND getStateVariation() final; - Vector3D getNodePosition(int tag) final; - Vector3D getNodeRotationLogarithm(int tag) final; - - VectorND pushResponse(VectorND&pl) final; - MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - - // Sensitivity - double getLengthGrad() final; - virtual const Vector &getBasicDisplTotalGrad(int grad); - virtual const Vector &getBasicDisplFixedGrad(); - virtual const Vector &getGlobalResistingForceShapeSensitivity(const Vector &pb, const Vector &p0, int gradNumber); - - // Tagged Object - void Print(OPS_Stream &s, int flag = 0) final; - -protected: - int addTangent(MatrixND<12,12>& M, const VectorND<12>& pl); - - VectorND<6> pushResponse(const VectorND<6>& pa, int a, int b); -#if 0 - // MatrixND<6,6> pushResponse(const MatrixND<6,6>& K, const VectorND<12>& pl, int a, int b); - // int addTangent(MatrixND<6,6>& K, const VectorND<6>& p, int a, int b, int c); -#endif - -private: - constexpr static int n = nn*ndf; - - // compute the transformation matrix - void compTransfMatrixBasicGlobal(const Versor&, const Versor*); - - enum { - inx= 0, // axial - iny= 1, // Vy - inz= 2, // Vz - imx= 3, // torsion - imy= 4, // rot y I - imz= 5, // rot z I - - jnx= 6, // axial - jny= 7, - jnz= 8, - jmx= 9, // torsion - jmy=10, // rot y J - jmz=11, // rot z J - }; - - // - // Member data - // - std::array nodes; - - Vector3D xAxis; // local x axis - Vector3D vz; // Vector that lies in local plane xz - Vector3D dX; - - std::array *offsets; - - double *nodeIInitialDisp, *nodeJInitialDisp; - bool initialDispChecked; - - double L; // initial element length - double Ln; // current element length (at trial state) - - Versor Q_past[nn]; // commited rotations - Versor Q_pres[nn]; // trial rotations - - Vector3D alphaI; // last trial rotations end i - Vector3D alphaJ; // last trial rotatations end j - - VectorND ul; // local displacements (size=7) - Vector3D vr[nn]; // - VectorND ulcommit; // commited local displacements - VectorND ulpr; // previous local displacements - - OpenSees::MatrixND T; // transformation from local to global system - - OpenSees::Matrix3D R0; // rotation from local to global coordinates - CrisfieldTransform crs; - - // Static workspace variables - Matrix3D A; - MatrixND<12,3> Lr2, Lr3; // auxiliary matrices -}; -} // namespace OpenSees -#include "SouzaFrameTransf.tpp" -#endif diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp deleted file mode 100644 index e766e82048..0000000000 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp +++ /dev/null @@ -1,942 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures -// -//----------------------------------------------------------------------------// -// -// Please cite the following resource in any derivative works: -// -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; -// https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// - -// -// Description: This file contains the implementation for the -// SouzaFrameTransf class. SouzaFrameTransf is a Corotational -// transformation for a spatial frame element between the global -// and basic coordinate systems. -// -// Written: Claudio Perez -// Created: 05/2024 -// -// Adapted from: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) -// -#include -#include -#include -#include "SouzaFrameTransf.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include "Isometry/CrisfieldTransform.h" - -namespace OpenSees { - -template -SouzaFrameTransf::SouzaFrameTransf(int tag, const Vector3D &vz, - const std::array *offset, - int offset_flags) - : FrameTransform(tag), - vz(vz), - offsets{nullptr}, - L(0), Ln(0), - nodeIInitialDisp(0), nodeJInitialDisp(0), - initialDispChecked(false) -{ - alphaI.zero(); - alphaJ.zero(); - - // Rigid joint offsets - if (offset != nullptr) { - offsets = new std::array{}; - *offsets = *offset; - } -} - - -template -SouzaFrameTransf::~SouzaFrameTransf() -{ - if (offsets != nullptr) - delete offsets; -} - - -template -double -SouzaFrameTransf::getInitialLength() -{ - return L; -} - - -template -double -SouzaFrameTransf::getDeformedLength() -{ - return Ln; -} - - -template -FrameTransform * -SouzaFrameTransf::getCopy() const -{ - - SouzaFrameTransf *theCopy = - new SouzaFrameTransf(this->getTag(), vz, offsets); - - theCopy->nodes[0] = nodes[0]; - theCopy->nodes[1] = nodes[1]; - theCopy->xAxis = xAxis; - theCopy->L = L; - theCopy->Ln = Ln; - theCopy->R0 = R0; - theCopy->Q_pres[0] = Q_pres[0]; - theCopy->Q_pres[1] = Q_pres[1]; - theCopy->Q_past[0] = Q_past[0]; - theCopy->Q_past[1] = Q_past[1]; - theCopy->ul = ul; - theCopy->ulcommit = ulcommit; - return theCopy; -} - - -template -int -SouzaFrameTransf::revertToStart() -{ - ul.zero(); - Q_pres[0] = VersorFromMatrix(R0); - for (int i=1; iupdate(); - return 0; -} - - -template -int -SouzaFrameTransf::commit() -{ - ulcommit = ul; - Q_past[0] = Q_pres[0]; - Q_past[1] = Q_pres[1]; - return 0; -} - - -template -int -SouzaFrameTransf::revertToLastCommit() -{ - // determine global displacement increments from last iteration - const Vector &dispI = nodes[0]->getTrialDisp(); - const Vector &dispJ = nodes[1]->getTrialDisp(); - - for (int k = 0; k < 3; k++) { - alphaI(k) = dispI(k+3); - alphaJ(k) = dispJ(k+3); - } - - ul = ulcommit; - Q_pres[0] = Q_past[0]; - Q_pres[1] = Q_past[1]; - - this->update(); - - return 0; -} - - -template -int -SouzaFrameTransf::initialize(std::array& new_nodes) -{ - for (int i=0; igetCrds() - nodes[0]->getCrds(); - - // Add initial displacements at nodes - if (initialDispChecked == false) { - const Vector &nodeIDisp = nodes[0]->getDisp(); - const Vector &nodeJDisp = nodes[1]->getDisp(); - for (int i = 0; i<6; i++) - if (nodeIDisp[i] != 0.0) { - nodeIInitialDisp = new double [6]; - for (int j = 0; j<6; j++) - nodeIInitialDisp[j] = nodeIDisp[j]; - i = 6; - } - - for (int j = 0; j<6; j++) - if (nodeJDisp[j] != 0.0) { - nodeJInitialDisp = new double [6]; - for (int i = 0; i<6; i++) - nodeJInitialDisp[i] = nodeJDisp[i]; - j = 6; - } - initialDispChecked = true; - } - - // - // Length and Orientation - // - Vector3D dx; - - dx = nodes[nn-1]->getCrds() - nodes[0]->getCrds(); - - L = dx.norm(); - - if (L == 0.0) { - opserr << "\nSouzaFrameTransf::computeElemtLengthAndOrien: 0 length\n"; - return -2; - } - - // - // Set rotation matrix - // - int error = FrameTransform::Orient(dx, vz, R0); - if (error) - return error; - - // Compute initial pseudo-vectors for nodal triads - Q_pres[0] = Q_pres[1] = VersorFromMatrix(R0); - - ul.zero(); - ulpr.zero(); - - for (int i=0; icommit(); - - return 0; -} - -template -VectorND -SouzaFrameTransf::getStateVariation() -{ - return ul - ulpr; -} - -template -Vector3D -SouzaFrameTransf::getNodePosition(int tag) -{ - Vector3D u; - for (int i=0; i<3; i++) - u[i] = ul[tag*ndf+i]; - return u; -} - -template -Vector3D -SouzaFrameTransf::getNodeRotationLogarithm(int tag) -{ - return vr[tag]; -} - -template -void inline -SouzaFrameTransf::compTransfMatrixBasicGlobal( - const Versor& Qbar, - const Versor* Q_pres) -{ - // extract columns of rotation matrices - const Triad r {MatrixFromVersor(Qbar)}, - rI{MatrixFromVersor(Q_pres[0])}, - rJ{MatrixFromVersor(Q_pres[1])}; - const Vector3D - &e1 = crs.getBasisE1(), // E[1], - &e2 = crs.getBasisE2(), // E[2], - &e3 = crs.getBasisE3(), // E[3], - &r1 = r[1], - &r2 = r[2], - &r3 = r[3], - &rI1 = rI[1], - &rI2 = rI[2], - &rI3 = rI[3], - &rJ1 = rJ[1], - &rJ2 = rJ[2], - &rJ3 = rJ[3]; - - // Compute the transformation matrix from the basic to the - // global system - // A = (1/Ln)*(I - e1*e1'); - // Matrix3D A; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; - - // This must be called up here - CrisfieldTransform::getLMatrix(A, e1, r1, r2, Lr2); - CrisfieldTransform::getLMatrix(A, e1, r1, r3, Lr3); - - // 3 | 3 | 3 | 3 | - // T1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', O', O']'; imx - // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; imz - // T3 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', -(A*rI3)', O']'; imy - // - // T4 = [ O', O', O', ( S(rJ2)*e3 - S(rJ3)*e2 )']'; jmx - // T5 = [(A*rJ2)', O', -(A*rJ2)', ( S(rJ1)*e2 - S(rJ2)*e1 )']'; jmz - // T6 = [(A*rJ3)', O', -(A*rJ3)', ( S(rJ1)*e3 - S(rJ3)*e1 )']'; jmy - - T.zero(); - - // T1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', O', O']'; - - // (-S(rI3)*e2 + S(rI2)*e3) - Vector3D Se = rI2.cross(e3); - Se -= rI3.cross(e2); - for (int i = 0; i < 3; i++) - // T(jmx,i+3) = -Se[i]; - T(imx,i+3) = Se[i]; - - // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; - - Vector3D At = A*rI2; - - // (-S(rI2)*e1 + S(rI1)*e2)' - Se = rI1.cross(e2); - Se -= rI2.cross(e1); - for (int i = 0; i < 3; i++) { - T(imz,i ) = At[i]; - T(imz,i+3) = Se[i]; - T(imz,i+6) = -At[i]; - } - - // T3 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', -(A*rI3)', O']'; - - At = A*rI3; - - // -S(rI3)*e1 + S(rI1)*e3 - Se = rI1.cross(e3); - Se -= rI3.cross(e1); - for (int i = 0; i < 3; i++) { - T(imy,i ) = At[i]*-1; - T(imy,i+3) = Se[i]*-1; - T(imy,i+6) = -At[i]*-1; - } - - // T4 = [ O', O', O', (-S(rJ3)*e2 + S(rJ2)*e3)']'; - Se = rJ2.cross(e3); - Se -= rJ3.cross(e2); - for (int i = 0; i < 3; i++) - T(jmx, i+9) = Se[i]; // S(rJ2)*e3 - S(rJ3)*e2 - - // T5 = [(A*rJ2)', O', -(A*rJ2)', (-S(rJ2)*e1 + S(rJ1)*e2)']'; - At = A*rJ2; - Se = rJ1.cross(e2); - Se -= rJ2.cross(e1); - for (int i = 0; i < 3; i++) { - T(jmz, i ) = At[i]; - T(jmz, i+6) = -At[i]; - T(jmz, i+9) = Se[i]; // (-S(rJ2)*e1 + S(rJ1)*e2) - } - - // T6 = [(A*rJ3)', O', -(A*rJ3)', (-S(rJ3)*e1 + S(rJ1)*e3)']' - At = A*rJ3; - Se = rJ1.cross(e3); // (-S(rJ3)*e1 + S(rJ1)*e3) - Se -= rJ3.cross(e1); - for (int i = 0; i < 3; i++) { - T(jmy,i ) = At[i]*-1; - T(jmy,i+6) = -At[i]*-1; - T(jmy,i+9) = Se[i]*-1; - } - - // - // Second part - // - - // T(:,1) += Lr3*rI2 - Lr2*rI3; - // T(:,2) += Lr2*rI1; z - // T(:,3) += Lr3*rI1 ; y - - // T(:,4) += Lr3*rJ2 - Lr2*rJ3; - // T(:,5) += Lr2*rJ1 ; z // ?????? check sign - // T(:,6) += Lr3*rJ1 ; y // ?????? check sign - - // Bending Z - for (int i = 0; i < 12; i++) { - double T1i = 0; - for (int k=0; k<3; k++) - T1i += Lr2(i,k)*rI1[k]; - T(imz,i) += T1i; - } - - for (int i = 0; i < 12; i++) { - double T4i = 0; - for (int k=0; k<3; k++) - T4i += Lr2(i,k)*rJ1[k]; // Lr[i]; - T(jmz,i) += T4i; - } - - // Torsion - for (int i = 0; i < 12; i++) { - double T0i = 0; - for (int k=0; k<3; k++) - T0i += Lr3(i,k)*rI2[k] - Lr2(i,k)*rI3[k]; - // T(jmx,i) += -T0i; - T(imx,i) += T0i; - } - for (int i = 0; i < 12; i++) { - double T3i = 0; - for (int k=0; k<3; k++) - T3i += Lr3(i,k)*rJ2[k] - Lr2(i,k)*rJ3[k]; - T(jmx,i) += T3i; - } - // Bending Y - for (int i = 0; i < 12; i++) { - double T2i = 0; - for (int k=0; k<3; k++) - T2i += Lr3(i,k)*rI1[k]; // Lr[i]; - T(imy,i) += T2i*-1; // TODO: Check - } - for (int i = 0; i < 12; i++) { - double T5i = 0; - for (int k=0; k<3; k++) - T5i += Lr3(i,k)*rJ1[k]; // Lr[i]; - T(jmy,i) += T5i*-1; // TODO: Check - } - - // - // - // - for (int node=0; node < 2; node++) - for (int j = 0; j < 3; j++) { - const double c = 0.5 / std::cos(ul[(node? jmx : imx) + j]); - for (int i = 0; i < 12; i++) - T((node? jmx : imx) + j, i) *= c; - } - - // Axial - // T(:,7) = [-e1' O' e1' O']'; - for (int i = 0; i < 3; i++) { - T(jnx,i ) = -e1[i]; - T(jnx,i+6) = e1[i]; - } - - // Combine torsion - for (int i=0; i<12; i++) { - T(jmx,i) -= T(imx,i); - T(imx,i) = 0; - } -} - -// -// Set RI,RJ,Rbar, Ln, e and ul -// -template -int -SouzaFrameTransf::update() -{ - // determine global displacement increments from last iteration - - const Vector& dispI = nodes[ 0]->getTrialDisp(); - const Vector& dispJ = nodes[nn-1]->getTrialDisp(); - - // - // Update state - // - // 1.1 Relative translation - Vector3D dx = dX;// dx = dX + dJI; - { - // Relative translation - for (int k = 0; k < 3; k++) - dx[k] += dispJ(k) - dispI(k); - - - // Calculate the deformed length - Ln = dx.norm(); - - if (Ln == 0.0) { - opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; - return -2; - } - } - - // 1.2 Rotational displacement increments - { - Vector3D dAlphaI, dAlphaJ; - - for (int k = 0; k < 3; k++) { - dAlphaI[k] = dispI(k+3) - alphaI[k]; - alphaI[k] = dispI(k+3); - dAlphaJ[k] = dispJ(k+3) - alphaJ[k]; - alphaJ[k] = dispJ(k+3); - } - - // Update the nodal rotations - Q_pres[0] = VersorProduct(Q_pres[0], Versor::from_vector(dAlphaI)); - Q_pres[1] = VersorProduct(Q_pres[1], Versor::from_vector(dAlphaJ)); - } - - // - // 2) Form transformation - // - - crs.update(Q_pres[0], Q_pres[1], dx); - // Form the transformation tangent - this->compTransfMatrixBasicGlobal(crs.getReference(), Q_pres); - - // - // 3) Local deformations - // - - // Save previous state - ulpr = ul; - - // Rotations - { - Matrix3D e = crs.getRotation(); - vr[0] = LogC90(e^MatrixFromVersor(Q_pres[0])); - for (int i=0; i<3; i++) - ul[imx+i] = vr[0][i]; - - vr[1] = LogC90(e^MatrixFromVersor(Q_pres[1])); - for (int i=0; i<3; i++) - ul[jmx+i] = vr[1][i]; - } - - // Axial - ul(inx) = 0; - ul(jnx) = Ln - L; - - return 0; -} - - -template -inline VectorND -SouzaFrameTransf::pushResponse(VectorND&pl) -{ - // return T^pl; - VectorND pg{}; - for (int a = 0; a pa {pl(a*ndf+0), pl(a*ndf+1), pl(a*ndf+2), - pl(a*ndf+3), pl(a*ndf+4), pl(a*ndf+5)}; - - for (int b = 0; b<2; b++) { - VectorND<6> pab = pushResponse(pa, a, b); - pg.assemble(b*6, pab, 1.0); - } - } - return pg; -} - -template -VectorND<6> -SouzaFrameTransf::pushResponse(const VectorND<6>&pa, int a, int b) -{ - VectorND<6> pg{}; - for (int i = 0; i < 6; i++) - for (int j = 0; j < 6; j++) - pg[j] += T(a*6 + i, b*6+j) * pa[i]; - - return pg; -} - -// do -// K = ag'*Km*ag + Kp -// -template -MatrixND -SouzaFrameTransf::pushResponse(MatrixND& kl, const VectorND& pl) -{ - MatrixND<12,12> K; - K.addMatrixTripleProduct(0.0, T, kl, 1.0); - - // Add geometric part kg - this->addTangent(K, pl); - - return K; -} - - -// -// Add geometric part of the transformation tangent -// -// kg += T'*kl*T + ks1 + T * diag(m.*tan(thetal))*T' + ... -// m(4)*(ks2r2t3_u3 + ks2r3u2_t2) + ... -// m(2)*ks2r2t1 + m(3)*ks2r3t1 + ... -// m(5)*ks2r2u1 + m(6)*ks2r3u1 + ... -// ks3 + ks3' + ks4 + ks5; -template -int -SouzaFrameTransf::addTangent(MatrixND<12,12>& kg, const VectorND<12>& pl) -{ - const Triad r {MatrixFromVersor(crs.getReference())}, - rI{MatrixFromVersor(Q_pres[0])}, - rJ{MatrixFromVersor(Q_pres[1])}; - const Vector3D - &e1 = crs.getBasisE1(), // E[1], - &e2 = crs.getBasisE2(), // E[2], - &e3 = crs.getBasisE3(), // E[3], - &r1 = r[1], // .rotate(E1), - &r2 = r[2], // .rotate(E2), - &r3 = r[3], // .rotate(E3), - &rI1 = rI[1], // .rotate(E1), - &rI2 = rI[2], // .rotate(E2), - &rI3 = rI[3], // .rotate(E3), - &rJ1 = rJ[1], // .rotate(E1), - &rJ2 = rJ[2], // .rotate(E2), - &rJ3 = rJ[3]; // .rotate(E3); - - // NOTE[cmp] - // SouzaFrameTransf::compTransfMatrixBasicGlobal must be - // called first to set Lr1, Lr2 and T - - // Matrix3D A; - // for (int i = 0; i < 3; i++) - // for (int j = 0; j < 3; j++) - // A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; - // getLMatrix(A, e1, r1, r2, Lr2); - // getLMatrix(A, e1, r1, r3, Lr3); - - // - // Ksigma1 - // - { - const double N = -pl[0]; // Axial force - // a=0 - kg.assemble(A, 0, 0, N); - kg.assemble(A, 0, 6, -N); - // a=1 - kg.assemble(A, 6, 0, -N); - kg.assemble(A, 6, 6, N); - } - - // - // Ksigma3 - // - // ks3 = [o kbar2 | o kbar4]; - // - // where - // - // kbar2 = -Lr2*(m(3)*S(rI3) + m(1)*S(rI1)) + Lr3*(m(3)*S(rI2) - m(2)*S(rI1)) ; - // - // kbar4 = Lr2*(m(3)*S(rJ3) - m(4)*S(rJ1)) - Lr3*(m(3)*S(rJ2) + m(5)*S(rJ1)); - // - // or - // - // ks3 = [o ka+kb | o kc+kd]; - // = [o ka | o kc] + [o kb | o kd]; - // - // where - // - // ka = -Lr2*S(rI3)*m(3) - // +Lr2*S(rI1)*m(1); - // kb = Lr3*S(rI2)*m(3) - // -Lr3*S(rI1)*m(2); - // - // kc = Lr2*S(rJ3)*m(3) - // -Lr2*S(rJ1)*m(4); - // kd = -Lr3*S(rJ2)*m(3) - // +Lr3*S(rJ1)*m(5); - - VectorND<6> m; - m[0] = 0.5*pl[imx]/std::cos(ul(imx)); - m[2] = -0.5*pl[imy]/std::cos(ul(imy)); - m[1] = 0.5*pl[imz]/std::cos(ul(imz)); - - m[3] = 0.5*pl[jmx]/std::cos(ul(jmx)); - m[5] = -0.5*pl[jmy]/std::cos(ul(jmy)); - m[4] = 0.5*pl[jmz]/std::cos(ul(jmz)); - - - static Matrix3D Sm; - Sm.zero(); - Sm.addSpin(rI3, m[3]); - Sm.addSpin(rI1, m[1]); - static MatrixND<12,3> kbar; - kbar.zero(); - kbar.addMatrixProduct(Lr2, Sm, -1.0); - - Sm.zero(); - Sm.addSpin(rI2, m[3]); - Sm.addSpin(rI1, -m[2]); - kbar.addMatrixProduct(Lr3, Sm, 1.0); - - kg.assemble(kbar, 0, 3, 1.0); - kg.assembleTranspose(kbar, 3, 0, 1.0); - - Sm.zero(); - Sm.addSpin(rJ3, m[3]); - Sm.addSpin(rJ1, -m[4]); - kbar.zero(); - kbar.addMatrixProduct(Lr2, Sm, 1.0); - - Sm.zero(); - Sm.addSpin(rJ2, m[3]); - Sm.addSpin(rJ1, m[5]); - kbar.addMatrixProduct(Lr3, Sm, -1.0); - - kg.assemble(kbar, 0, 9, 1.0); - kg.assembleTranspose(kbar, 9, 0, 1.0); - - - // - // Ksigma4 - // - { - Matrix3D ks33; - ks33.zero(); - ks33.addSpinProduct(e2, rI3, m[3]); - ks33.addSpinProduct(e3, rI2, -m[3]); - ks33.addSpinProduct(e2, rI1, m[1]); - ks33.addSpinProduct(e1, rI2, -m[1]); - ks33.addSpinProduct(e3, rI1, m[2]); - ks33.addSpinProduct(e1, rI3, -m[2]); - kg.assemble(ks33, 3, 3, 1.0); - } - - // - // Ksigma4 - // - { - Matrix3D ks33; - ks33.zero(); - ks33.addSpinProduct(e2, rJ3, -m[3]); - ks33.addSpinProduct(e3, rJ2, m[3]); - ks33.addSpinProduct(e2, rJ1, m[4]); - ks33.addSpinProduct(e1, rJ2, -m[4]); - ks33.addSpinProduct(e3, rJ1, m[5]); - ks33.addSpinProduct(e1, rJ3, -m[5]); - - kg.assemble(ks33, 9, 9, 1.0); - } - - - // - // Ksigma5 - // - // Ks5 = [ Ks5_11 Ks5_12 | -Ks5_11 Ks5_14; - // Ks5_12' O | -Ks5_12' O; - // -Ks5_11 -Ks5_12 | Ks5_11 -Ks5_14; - // Ks5_14t O | -Ks5_14' O]; - // - // - // v = (1/Ln)*(m(2)*rI2 + m(3)*rI3 + m(5)*rJ2 + m(6)*rJ3); - // = 1/Ln * (m[1]*rI2 + m[2]*rI3) - // + 1/Ln * (m[4]*rJ2 + m[5]*rJ3); - // = vi + vj - // - { - Vector3D v; - v.addVector(0.0, rI2, m[1]); - v.addVector(1.0, rI3, m[2]); - v.addVector(1.0, rJ2, m[4]); - v.addVector(1.0, rJ3, m[5]); - v /= Ln; - - // Ks5_11 = A*v*e1' + e1*v'*A + (e1'*v)*A; - // = A*vi*e1' + e1*vi'*A + (e1'*vi)*A - // + A*vj*e1' + e1*vj'*A + (e1'*vj)*A; - // - Matrix3D ks33; - ks33.zero(); - ks33.addMatrix(A, e1.dot(v)); - - static Matrix3D m33; - m33.zero(); - m33.addTensorProduct(v, e1, 1.0); - - ks33.addMatrixProduct(A, m33, 1.0); - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - m33(i,j) = e1[i]*v[j]; - - ks33.addMatrixProduct(m33, A, 1.0); - - kg.assemble(ks33, 0, 0, 1.0); - kg.assemble(ks33, 0, 6, -1.0); - kg.assemble(ks33, 6, 0, -1.0); - kg.assemble(ks33, 6, 6, 1.0); - } - - // Ks5_12 = -(m(2)*A*S(rI2) + m(3)*A*S(rI3)); - - Matrix3D ks33; - ks33.zero(); - ks33.addMatrixSpinProduct(A, rI2, -m[1]); - ks33.addMatrixSpinProduct(A, rI3, -m[2]); - - kg.assemble(ks33, 0, 3, 1.0); - kg.assemble(ks33, 6, 3, -1.0); - kg.assembleTranspose(ks33, 3, 0, 1.0); - kg.assembleTranspose(ks33, 3, 6, -1.0); - - // Ks5_14 = -(m(5)*A*S(rJ2) + m(6)*A*S(rJ3)); - - ks33.zero(); - ks33.addMatrixSpinProduct(A, rJ2, -m[4]); - ks33.addMatrixSpinProduct(A, rJ3, -m[5]); - - kg.assemble(ks33, 0, 9, 1.0); - kg.assemble(ks33, 6, 9, -1.0); - - kg.assembleTranspose(ks33, 9, 0, 1.0); - kg.assembleTranspose(ks33, 9, 6, -1.0); - - // Ksigma ------------------------------- - Vector3D rm = rI3; - - rm.addVector(1.0, rJ3, -1.0); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rm), m[3]); - -// rm = rJ2; - rm.addVector(0.0, rJ2, -1.0); - rm.addVector(1.0, rI2, -1.0); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rm), m[3]); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rI1), m[1]); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rI1), m[2]); - // - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rJ1), m[4]); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rJ1), m[5]); - - // - // T' * diag (M .* tan(thetal))*T - // - - for (int node=0; node<2; node++) { - for (int k = 0; k < 3; k++) { - const double factor = pl[6*node+3+k] * std::tan(ul[(node ? jmx : imx) + k]); - for (int i = 0; i < 12; i++) { - const double Tki = T((node ? jmx : imx) + k,i); - for (int j = 0; j < 12; j++) - kg(i,j) += Tki * factor * T((node ? jmx : imx) + k, j); - } - } - } - - return 0; -} - - -template -int -SouzaFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector3D &e3) const -{ - for (int i = 0; i < 3; i++) { - e1[i] = R0(i,0); - e2[i] = R0(i,1); - e3[i] = R0(i,2); - } - return 0; -} - - -template -double -SouzaFrameTransf::getLengthGrad() -{ - const int di = nodes[0]->getCrdsSensitivity(); - const int dj = nodes[1]->getCrdsSensitivity(); - - Vector3D dxi{0.0}; - Vector3D dxj{0.0}; - - if (di != 0) - dxi(di-1) = 1.0; - if (dj != 0) - dxj(dj-1) = 1.0; - - return 1/L * dX.dot(dxj - dxi); -} - -template -const Vector & -SouzaFrameTransf::getBasicDisplTotalGrad(int gradNumber) -{ - opserr << "WARNING CrdTransf::getBasicDisplTotalGrad() - this method " - << " should not be called.\n"; - - static Vector dummy(1); - return dummy; -} - -template -const Vector & -SouzaFrameTransf::getBasicDisplFixedGrad() -{ - opserr << "ERROR CrdTransf::getBasicDisplFixedGrad() - has not been" - << " implemented yet for the chosen transformation\n."; - - static Vector dummy(1); - return dummy; -} - - -template -const Vector & -SouzaFrameTransf::getGlobalResistingForceShapeSensitivity(const Vector &pb, - const Vector &p0, - int gradNumber) -{ - opserr << "ERROR CrdTransf::getGlobalResistingForceSensitivity() - has not been" - << " implemented yet for the chosen transformation." << endln; - - static Vector dummy(1); - return dummy; -} - -template -void -SouzaFrameTransf::Print(OPS_Stream &s, int flag) -{ - - if (flag == OPS_PRINT_CURRENTSTATE) { - s << "\nFrameTransform: " << this->getTag() << " Type: SouzaFrameTransf"; - s << "\tvxz: " << Vector(vz); - } - - if (flag == OPS_PRINT_PRINTMODEL_JSON) { - s << OPS_PRINT_JSON_MATE_INDENT << "{"; - s << "\"name\": " << this->getTag() << ", "; - s << "\"type\": \"SouzaFrameTransf\"" << ", "; - s << "\"vecxz\": [" << vz(0) << ", " << vz(1) << ", " << vz(2) << "]"; - - if (offsets != nullptr) { - s << ", \"offsets\": ["; - for (int i=0; i Date: Sat, 28 Jun 2025 22:16:11 -0700 Subject: [PATCH 118/261] clean up --- .../Frame/EuclidFrameTransf.h | 6 +-- .../Frame/EuclidFrameTransf.tpp | 15 +----- .../Frame/LinearFrameTransf.tpp | 46 ------------------- 3 files changed, 2 insertions(+), 65 deletions(-) diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h index d9b0f8282c..b06e722527 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.h +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -73,11 +73,7 @@ class EuclidFrameTransf: public FrameTransform VectorND pushResponse(VectorND&pl) final; MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; -#if 0 - // method used to rotate consistent mass matrix - const Matrix &getGlobalMatrixFromLocal(const Matrix &local); -#endif - + // // Sensitivity // bool isShapeSensitivity() final; diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 1c0db3db72..338db4708f 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -209,23 +209,10 @@ template Vector3D EuclidFrameTransf::getNodePosition(int node) { -#if 0 - const Vector& ug = nodes[node]->getTrialDisp(); - Vector3D u; - for (int i=0; i<3; i++) - u[i] = ug[i]; - - if (offsets != nullptr) [[unlikely]] { - u.addVector(1.0, (*offsets)[node], -1.0); - u.addVector(1.0, nodes[node]->getTrialRotation().rotate((*offsets)[node]), 1.0); - } - - u.addVector(1.0, basis.getPosition(), -1.0); -#else Vector3D u = this->pullPosition<&Node::getTrialDisp>(node) - basis.getPosition(); -#endif + u += basis.getRotationDelta()^(nodes[node]->getCrds()); return u; diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index d0d6d18908..4d2d3f1254 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -579,53 +579,7 @@ LinearFrameTransf::getBasicDisplFixedGrad() // Form ug // // TODO(sensitivity) -#if 0 - VectorND ug; - for (int i = 0; i < nn; i++) { - const Vector& u = nodes[i]->getTrialDisp(); - for (int j = 0; j < ndf; j++) { - ug[i*ndf+j] = u(j); - } - } - - if (u_init[0] != 0) { - for (int j = 0; j < ndf; j++) - ug[j] -= (*u_init[0])[j]; - } - - if (u_init[nn-1] != 0) { - for (int j = 0; j < ndf; j++) - ug[j + 6] -= (*u_init[nn-1])[j]; - } - - // - // dub += (T_{bl}' T_{lg} + T_{bl} T_{lg}') * ug // - int dv = 0; // TODO(sensitivity) - - // TODO: Sensitivity - int di = nodes[0]->getCrdsSensitivity(); - int dj = nodes[1]->getCrdsSensitivity(); - - - // TODO(sensitivity) - // Matrix3D dR = FrameOrientationGradient(xi, xj, vz, di, dj, dv); - // dub = getBasic(ug, 1/L); - - // - // - VectorND ul = LinearFrameTransf::pullConstant(ug, R, offsets); - // - dub[0] += 0; - double dL = this->getLengthGrad(); - double doneOverL = -dL/(L*L); - double tmp = doneOverL * (ul[1] - ul[7]); - dub[1] += tmp; - dub[2] += tmp; - tmp = doneOverL * (ul[8] - ul[2]); - dub[3] += tmp; - dub[4] += tmp; -#endif return wrapper; } From 15db9eaf6d4952b3c39184c781b7a24c78607b5b Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sat, 28 Jun 2025 23:55:11 -0700 Subject: [PATCH 119/261] clean up --- .../Frame/EuclidFrameTransf.h | 23 +- .../Frame/EuclidFrameTransf.tpp | 114 +-- .../Frame/LinearFrameTransf.h | 2 - .../Frame/LinearFrameTransf.tpp | 117 ++-- .../Frame/PDeltaFrameTransf3d.h | 17 +- .../Frame/PDeltaFrameTransf3d.tpp | 12 +- SRC/matrix/MatrixND.h | 126 +--- SRC/matrix/MatrixND.tpp | 104 ++- SRC/matrix/VectorND.h | 143 ++-- SRC/matrix/VectorND.tpp | 648 +++++++++--------- 10 files changed, 707 insertions(+), 599 deletions(-) diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h index b06e722527..3c5270f433 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.h +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -18,10 +18,11 @@ //===----------------------------------------------------------------------===// // -// Description: This file contains the class definition for -// EuclidFrameTransf.h. EuclidFrameTransf provides the -// abstraction of a linear transformation for a spatial frame -// between the global and basic coordinate systems +// Description: This file contains the implementation for the +// EuclidFrameTransf class. EuclidFrameTransf is a euclidean transformation +// of 3D space. +// When used with the RankineIsometry, it furnishes an improved corotational +// transformation for 3D frames. // // Written: cmp // Created: 04/2025 @@ -36,7 +37,7 @@ namespace OpenSees { -template +template class EuclidFrameTransf: public FrameTransform { public: @@ -73,7 +74,11 @@ class EuclidFrameTransf: public FrameTransform VectorND pushResponse(VectorND&pl) final; MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - // +#if 0 + // method used to rotate consistent mass matrix + const Matrix &getGlobalMatrixFromLocal(const Matrix &local); +#endif + // Sensitivity // bool isShapeSensitivity() final; @@ -86,6 +91,8 @@ class EuclidFrameTransf: public FrameTransform private: + int computeElemtLengthAndOrient(); + inline MatrixND getProjection() { @@ -109,8 +116,6 @@ class EuclidFrameTransf: public FrameTransform return A; } - int computeElemtLengthAndOrient(); - template const Vector3D pullPosition(int node) @@ -144,7 +149,7 @@ class EuclidFrameTransf: public FrameTransform Vector3D xi, xj, vz; double L; // undeformed element length - BasisT basis; + IsoT basis; }; } // namespace OpenSees diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 338db4708f..8d384c3532 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -17,14 +17,11 @@ // //===----------------------------------------------------------------------===// -// -// Description: This file contains the implementation for the -// EuclidFrameTransf class. EuclidFrameTransf is a nonlinear transformation -// for a space frame. // // Written: cmp // Created: 04/2025 // + #pragma once #include #include @@ -36,8 +33,8 @@ namespace OpenSees { -template -EuclidFrameTransf::EuclidFrameTransf(int tag, +template +EuclidFrameTransf::EuclidFrameTransf(int tag, const Vector3D &vecxz, const std::array *offset, int offset_flags) @@ -65,38 +62,38 @@ EuclidFrameTransf::EuclidFrameTransf(int tag, -template -EuclidFrameTransf::~EuclidFrameTransf() +template +EuclidFrameTransf::~EuclidFrameTransf() { if (offsets != nullptr) delete offsets; } -template +template int -EuclidFrameTransf::commit() +EuclidFrameTransf::commit() { return 0; } -template +template int -EuclidFrameTransf::revertToLastCommit() +EuclidFrameTransf::revertToLastCommit() { return 0; } -template +template int -EuclidFrameTransf::revertToStart() +EuclidFrameTransf::revertToStart() { return 0; } -template +template int -EuclidFrameTransf::initialize(std::array& new_nodes) +EuclidFrameTransf::initialize(std::array& new_nodes) { for (int i=0; i::initialize(std::array& new_nodes) } -template +template int -EuclidFrameTransf::computeElemtLengthAndOrient() +EuclidFrameTransf::computeElemtLengthAndOrient() { const Vector &XI = nodes[ 0]->getCrds(); @@ -150,9 +147,9 @@ EuclidFrameTransf::computeElemtLengthAndOrient() } -template +template int -EuclidFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector3D &e3) const +EuclidFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector3D &e3) const { Matrix3D R = basis.getRotation(); for (int i = 0; i < 3; i++) { @@ -163,16 +160,16 @@ EuclidFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vecto return 0; } -template +template double -EuclidFrameTransf::getInitialLength() +EuclidFrameTransf::getInitialLength() { return L; } -template +template double -EuclidFrameTransf::getDeformedLength() +EuclidFrameTransf::getDeformedLength() { return L; } @@ -181,9 +178,9 @@ EuclidFrameTransf::getDeformedLength() // // Pull // -template +template int -EuclidFrameTransf::update() +EuclidFrameTransf::update() { if (basis.update() < 0) return -1; @@ -197,39 +194,52 @@ EuclidFrameTransf::update() return 0; } -template +template Versor -EuclidFrameTransf::getNodeRotation(int tag) +EuclidFrameTransf::getNodeRotation(int tag) { return nodes[tag]->getTrialRotation(); } -template +template Vector3D -EuclidFrameTransf::getNodePosition(int node) +EuclidFrameTransf::getNodePosition(int node) { +#if 0 + const Vector& ug = nodes[node]->getTrialDisp(); + + Vector3D u; + for (int i=0; i<3; i++) + u[i] = ug[i]; + if (offsets != nullptr) [[unlikely]] { + u.addVector(1.0, (*offsets)[node], -1.0); + u.addVector(1.0, nodes[node]->getTrialRotation().rotate((*offsets)[node]), 1.0); + } + + u.addVector(1.0, basis.getPosition(), -1.0); +#else Vector3D u = this->pullPosition<&Node::getTrialDisp>(node) - basis.getPosition(); - +#endif u += basis.getRotationDelta()^(nodes[node]->getCrds()); return u; } -template +template Vector3D -EuclidFrameTransf::getNodeRotationLogarithm(int node) +EuclidFrameTransf::getNodeRotationLogarithm(int node) { return ur[node]; } -template +template VectorND -EuclidFrameTransf::getStateVariation() +EuclidFrameTransf::getStateVariation() { static VectorND ul; @@ -241,7 +251,7 @@ EuclidFrameTransf::getStateVariation() } Matrix3D R = basis.getRotation(); - // return EuclidFrameTransf::pullVariation(ug, R, offsets, offset_flags); + // return EuclidFrameTransf::pullVariation(ug, R, offsets, offset_flags); // VectorND ul = ug; @@ -309,9 +319,9 @@ EuclidFrameTransf::getStateVariation() // // Push // -template +template VectorND -EuclidFrameTransf::pushResponse(VectorND&p) +EuclidFrameTransf::pushResponse(VectorND&p) { VectorND pa = p; @@ -334,9 +344,9 @@ EuclidFrameTransf::pushResponse(VectorND&p) } -template +template MatrixND -EuclidFrameTransf::pushResponse(MatrixND&kb, const VectorND&pb) +EuclidFrameTransf::pushResponse(MatrixND&kb, const VectorND&pb) { MatrixND Kb = kb; VectorND p = pb; @@ -405,20 +415,20 @@ EuclidFrameTransf::pushResponse(MatrixND&kb, const } -template +template FrameTransform * -EuclidFrameTransf::getCopy() const +EuclidFrameTransf::getCopy() const { - return new EuclidFrameTransf(this->getTag(), vz, offsets); + return new EuclidFrameTransf(this->getTag(), vz, offsets); } // // Sensitivity // -template +template bool -EuclidFrameTransf::isShapeSensitivity() +EuclidFrameTransf::isShapeSensitivity() { int nodeParameterI = nodes[ 0]->getCrdsSensitivity(); int nodeParameterJ = nodes[nn-1]->getCrdsSensitivity(); @@ -428,9 +438,9 @@ EuclidFrameTransf::isShapeSensitivity() } -template +template double -EuclidFrameTransf::getLengthGrad() +EuclidFrameTransf::getLengthGrad() { const int di = nodes[0]->getCrdsSensitivity(); const int dj = nodes[1]->getCrdsSensitivity(); @@ -446,17 +456,17 @@ EuclidFrameTransf::getLengthGrad() return 1/L*(xj - xi).dot(dxj - dxi); } -template +template double -EuclidFrameTransf::getd1overLdh() +EuclidFrameTransf::getd1overLdh() { return -getLengthGrad()/(L*L); } -template +template void -EuclidFrameTransf::Print(OPS_Stream &s, int flag) +EuclidFrameTransf::Print(OPS_Stream &s, int flag) { if (flag == OPS_PRINT_PRINTMODEL_JSON) { s << OPS_PRINT_JSON_MATE_INDENT << "{"; @@ -484,4 +494,4 @@ EuclidFrameTransf::Print(OPS_Stream &s, int flag) } } -} \ No newline at end of file +} // namespace OpenSees \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.h b/SRC/coordTransformation/Frame/LinearFrameTransf.h index 36670c40eb..6622b92b01 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.h +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.h @@ -92,8 +92,6 @@ class LinearFrameTransf: public FrameTransform private: - int computeElemtLengthAndOrient(); - inline VectorND pullConstant(const VectorND& ug, const Matrix3D& R, diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index 4d2d3f1254..35ffea2c7a 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -26,7 +26,6 @@ // Adapted: Remo Magalhaes de Souza // Created: 04/2000 // -// #pragma once #include #include @@ -132,6 +131,7 @@ LinearFrameTransf::~LinearFrameTransf() delete u_init[i]; } + template int LinearFrameTransf::commit() @@ -139,6 +139,7 @@ LinearFrameTransf::commit() return 0; } + template int LinearFrameTransf::revertToLastCommit() @@ -184,55 +185,42 @@ LinearFrameTransf::initialize(std::array& new_nodes) initialDispChecked = true; } - int error; - // get element length and orientation - if ((error = this->computeElemtLengthAndOrient())) - return error; - - return 0; -} + { + const Vector &XI = nodes[ 0]->getCrds(); + const Vector &XJ = nodes[nn-1]->getCrds(); + for (int i=0; i<3; i++) { + xi[i] = XI[i]; + xj[i] = XJ[i]; + } + + Vector3D dx = xj - xi; -template -int -LinearFrameTransf::computeElemtLengthAndOrient() -{ + if (offsets != nullptr) { + for (int i=0; i<3; i++) + dx(i) -= (*offsets)[ 0][i]; + for (int i=0; i<3; i++) + dx(i) += (*offsets)[nn-1][i]; + } - const Vector &XI = nodes[ 0]->getCrds(); - const Vector &XJ = nodes[nn-1]->getCrds(); - for (int i=0; i<3; i++) { - xi[i] = XI[i]; - xj[i] = XJ[i]; - } - - Vector3D dx = xj - xi; + if (u_init[0] != 0) { + for (int i=0; i<3; i++) + dx(i) -= (*u_init[0])[i]; + } - if (offsets != nullptr) { - for (int i=0; i<3; i++) - dx(i) -= (*offsets)[ 0][i]; - for (int i=0; i<3; i++) - dx(i) += (*offsets)[nn-1][i]; - } + if (u_init[nn-1] != 0) { + for (int i=0; i<3; i++) + dx(i) += (*u_init[nn-1])[i]; + } + L = dx.norm(); - if (u_init[0] != 0) { - for (int i=0; i<3; i++) - dx(i) -= (*u_init[0])[i]; - } + if (L == 0.0) + return -2; - if (u_init[nn-1] != 0) { - for (int i=0; i<3; i++) - dx(i) += (*u_init[nn-1])[i]; + return FrameTransform::Orient(dx, vz, R); } - - // calculate the element length - L = dx.norm(); - - if (L == 0.0) - return -2; - - return FrameTransform::Orient(dx, vz, R); } @@ -512,6 +500,7 @@ LinearFrameTransf::getLengthGrad() return 1/L*(xj - xi).dot(dxj - dxi); } + template double LinearFrameTransf::getd1overLdh() @@ -579,7 +568,53 @@ LinearFrameTransf::getBasicDisplFixedGrad() // Form ug // // TODO(sensitivity) +#if 0 + VectorND ug; + for (int i = 0; i < nn; i++) { + const Vector& u = nodes[i]->getTrialDisp(); + for (int j = 0; j < ndf; j++) { + ug[i*ndf+j] = u(j); + } + } + + if (u_init[0] != 0) { + for (int j = 0; j < ndf; j++) + ug[j] -= (*u_init[0])[j]; + } + + if (u_init[nn-1] != 0) { + for (int j = 0; j < ndf; j++) + ug[j + 6] -= (*u_init[nn-1])[j]; + } + + // + // dub += (T_{bl}' T_{lg} + T_{bl} T_{lg}') * ug + // + int dv = 0; // TODO(sensitivity) + + // TODO: Sensitivity + int di = nodes[0]->getCrdsSensitivity(); + int dj = nodes[1]->getCrdsSensitivity(); + + + // TODO(sensitivity) + // Matrix3D dR = FrameOrientationGradient(xi, xj, vz, di, dj, dv); + // dub = getBasic(ug, 1/L); + + // // + VectorND ul = LinearFrameTransf::pullConstant(ug, R, offsets); + // + dub[0] += 0; + double dL = this->getLengthGrad(); + double doneOverL = -dL/(L*L); + double tmp = doneOverL * (ul[1] - ul[7]); + dub[1] += tmp; + dub[2] += tmp; + tmp = doneOverL * (ul[8] - ul[2]); + dub[3] += tmp; + dub[4] += tmp; +#endif return wrapper; } diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h index 7082dd7e76..9b92fc79f8 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h @@ -1,15 +1,16 @@ //===----------------------------------------------------------------------===// // // xara -// -//===----------------------------------------------------------------------===// // https://xara.so //===----------------------------------------------------------------------===// // -// Description: This file contains the class definition for -// PDeltaFrameTransf.h. PDeltaFrameTransf provides the -// abstraction of a linear transformation for a spatial frame -// between the global and basic coordinate systems +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// + +// +// Description: PDeltaFrameTransf generalizes the original PDeltaCrdTransf3d +// class to a more general FrameTransform interface. // // Adapted: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) // Created: 04/2000 @@ -72,6 +73,8 @@ class PDeltaFrameTransf: public FrameTransform LinearFrameTransf linear; }; -} + +} // namespace OpenSees + #include "PDeltaFrameTransf3d.tpp" #endif diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp index c22c2d963a..0bbfb3b930 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp @@ -1,15 +1,13 @@ //===----------------------------------------------------------------------===// // // xara -// -//===----------------------------------------------------------------------===// // https://xara.so //===----------------------------------------------------------------------===// // -// Description: This file contains the implementation for the -// PDeltaFrameTransf class. PDeltaFrameTransf is a nonlinear -// transformation for a 3D frame between the global -// and basic coordinate systems +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// + // // Adapted: Remo Magalhaes de Souza // 04/2000 @@ -193,4 +191,4 @@ PDeltaFrameTransf::Print(OPS_Stream &s, int flag) linear.Print(s, flag); } -} \ No newline at end of file +} // namespace OpenSees \ No newline at end of file diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index 880d1533d6..b0fd8a6b33 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -30,8 +30,7 @@ // // Claudio Perez // -#ifndef MatrixND_H -#define MatrixND_H +#pragma once #include #include #include @@ -56,7 +55,7 @@ requires(NR > 0 && NC > 0) struct MatrixND { double values[NC][NR]; - //MatrixND(const MatrixND&) = default; + // MatrixND(const MatrixND&) = default; // Convert to regular Matrix class operator Matrix() { return Matrix(&values[0][0], NR, NC);} @@ -71,6 +70,8 @@ struct MatrixND { consteval void zero(); + constexpr MatrixND transpose() const; + MatrixND& addDiagonal(const double vol) requires(NR == NC); template @@ -117,6 +118,7 @@ struct MatrixND { int invert() { return Matrix(*this).Invert(); } + #if 0 //template //void addSpinAtRow(const VecT& V, size_t row_index); @@ -129,6 +131,7 @@ struct MatrixND { //template //void addSpinAtRow(const VecT& V, double mult, size_t vector_index, size_t matrix_row_index); #endif + // // Indexing // @@ -171,19 +174,6 @@ struct MatrixND { return *this; } -/* - constexpr MatrixND & - operator=(const MatrixND &other) - { - for (index_t j = 0; j < NC; ++j) { - for (index_t i = 0; i < NR; ++i) { - values[j][i] = other.values[j][i]; - } - } - return *this; - } -*/ - constexpr MatrixND & operator+=(const double value) { for (index_t j = 0; j < NC; ++j) { @@ -253,18 +243,6 @@ struct MatrixND { // // - constexpr MatrixND - transpose() const ; - // { - // MatrixND result = {}; - // for (index_t j = 0; j < NC; ++j) { - // for (index_t i = 0; i < NR; ++i) { - // result.values[i][j] = values[j][i]; - // } - // } - // return result; - // } - constexpr T trace() const requires(NR == NC) @@ -276,12 +254,6 @@ struct MatrixND { return sum; } - // constexpr T - // determinant() const - // requires(NR == NC && NR == 2) - // { - // return values[0][0] * values[1][1] - values[0][1] * values[1][0]; - // } int solve(const VectorND &V, VectorND &res) const requires(NR == NC) @@ -297,6 +269,7 @@ struct MatrixND { return -abs(info); } + int solve(const Vector &V, Vector &res) const requires(NR == NC) { @@ -312,7 +285,7 @@ struct MatrixND { return -abs(info); } -//template + int solve(const Matrix &M, Matrix &res) { @@ -404,51 +377,18 @@ struct MatrixND { } template inline void - assemble(const VectorND &v, int init_row, int init_col, double fact) - { - - [[maybe_unused]] int final_row = init_row + nr - 1; - assert((init_row >= 0) && (final_row < NR)); - - for (int j=0; j &v, int init_row, int init_col, double fact) noexcept; - template void - assembleTranspose(const MatrixND &M, int init_row, int init_col, double fact) - { - { - [[maybe_unused]] int final_row = init_row + nc - 1; - [[maybe_unused]] int final_col = init_col + nr - 1; - assert((init_row >= 0) && (final_row < NR) && (init_col >= 0) && (final_col < NC)); - } - - for (int i=0; i inline void + assembleTranspose(const MatrixND &M, int init_row, int init_col, double fact) noexcept; template void - assembleTranspose(const VectorND &v, int init_row, int init_col, double scale) - { - { - [[maybe_unused]] int final_col = init_col + nr - 1; - assert((init_row >= 0) && (init_col >= 0) && (final_col < NC)); - } - - for (int i=0; i &v, int init_row, int init_col, double scale) noexcept; // -// Notes on operators: +// Operators // -// - define friend operators inside class for use as header-only library friend constexpr MatrixND operator+(MatrixND left, const MatrixND &right) { left += right; @@ -477,9 +417,11 @@ struct MatrixND { inline constexpr friend MatrixND operator*(const MatrixND &left, const MatrixND &right) { MatrixND prod; - if constexpr (0 && NR*NC > 16) +#if 0 + if constexpr (NR*NC > 16) prod.addMatrixProduct(0, left, right, 1); else +#endif for (index_t i = 0; i < NR; ++i) { for (index_t j = 0; j < J; ++j) { prod(i, j) = 0.0; @@ -491,6 +433,21 @@ struct MatrixND { return prod; } + template + friend MatrixND + operator*(const MatrixND &left, const Matrix &right) { + MatrixND prod; + for (index_t i = 0; i < NR; ++i) { + for (index_t j = 0; j < J; ++j) { + prod(i, j) = 0.0; + for (index_t k = 0; k < NC; ++k) { + prod(i, j) += left(i,k) * right(k,j); + } + } + } + return prod; + } + template inline constexpr friend MatrixND operator^(const MatrixND &left, const MatrixND &right) { @@ -509,7 +466,7 @@ struct MatrixND { return prod; } -#if 1 + constexpr friend VectorND operator*(const MatrixND &left, const VectorND &right) { VectorND prod; @@ -521,7 +478,6 @@ struct MatrixND { } return prod; } -#endif friend VectorND operator*(const MatrixND &left, const Vector &right) { @@ -535,22 +491,6 @@ struct MatrixND { return prod; } - - template - friend MatrixND - operator*(const MatrixND &left, const Matrix &right) { - MatrixND prod; - for (index_t i = 0; i < NR; ++i) { - for (index_t j = 0; j < J; ++j) { - prod(i, j) = 0.0; - for (index_t k = 0; k < NC; ++k) { - prod(i, j) += left(i,k) * right(k,j); - } - } - } - return prod; - } - friend constexpr MatrixND operator/(MatrixND mat, T scalar) { mat /= scalar; @@ -560,5 +500,3 @@ struct MatrixND { } // namespace OpenSees #include "MatrixND.tpp" -#endif // MatrixND_H - diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index 3f3c3ccaf3..78dd7ec459 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -16,12 +16,16 @@ namespace OpenSees { +template +MatrixND(const T (&)[nc][nr])->MatrixND; + + template void MatrixND::zero() { - for (index_t j = 0; j < nr; ++j) { - for (index_t i = 0; i < nc; ++i) { + for (index_t j = 0; j < nc; ++j) { + for (index_t i = 0; i < nr; ++i) { values[j][i] = 0.0; } } @@ -61,7 +65,57 @@ MatrixND::map(F func, MatrixND& destination) destination(i,j) = func((*this)(i,j)); } +// +// +// +template +template inline void +MatrixND::assemble(const VectorND &v, int init_row, int init_col, double fact) noexcept +{ + + [[maybe_unused]] int final_row = init_row + nr - 1; + assert((init_row >= 0) && (final_row < NR)); + + for (int j=0; j +template void +MatrixND::assembleTranspose(const MatrixND &M, int init_row, int init_col, double fact) noexcept +{ + { + [[maybe_unused]] int final_row = init_row + nc - 1; + [[maybe_unused]] int final_col = init_col + nr - 1; + assert((init_row >= 0) && (final_row < NR) && (init_col >= 0) && (final_col < NC)); + } + + for (int i=0; i +template void +MatrixND::assembleTranspose(const VectorND &v, int init_row, int init_col, double scale) noexcept +{ + { + [[maybe_unused]] int final_col = init_col + nr - 1; + assert((init_row >= 0) && (init_col >= 0) && (final_col < NC)); + } + for (int i=0; i inline int MatrixND::invert(MatrixND &M) const { @@ -148,6 +202,7 @@ MatrixND::addMatrixProduct(const MatrixND& A, const MatT& } } +#if 0 template template inline void @@ -160,8 +215,8 @@ MatrixND::addMatrixProduct(double scale_this, const MatrixND(&A(0,0)), &m, const_cast(&B(0,0)), &k, &scale_this, &(*this)(0,0), &m); - } +#endif // B'*C template @@ -266,25 +321,26 @@ MatrixND::addMatrixTripleProduct( BT.addMatrixProduct(B, T, otherFact); this->addMatrixTransposeProduct(thisFact, T, BT, 1.0); -//{ -// int m = B.numRows, -// n = T.numCols, -// k = B.numCols, -// nrT = T.numRows; -// //k = T.numRows; -// double zero = 0.0, -// one = 1.0; - -// DGEMM ("N", "N", &m , &n , &k,&one , B.data, &m, // m -// T.data, &nrT, // k -// &zero, matrixWork, &m); - -// DGEMM ("T", "N", &numRows, &numCols, &k,&otherFact, T.data, &nrT, -// matrixWork, &m, // k -// &thisFact, data, &numRows); -// return 0; -//} - +#if 0 + { + int m = B.numRows, + n = T.numCols, + k = B.numCols, + nrT = T.numRows; + //k = T.numRows; + double zero = 0.0, + one = 1.0; + + DGEMM ("N", "N", &m , &n , &k,&one , B.data, &m, // m + T.data, &nrT, // k + &zero, matrixWork, &m); + + DGEMM ("T", "N", &numRows, &numCols, &k,&otherFact, T.data, &nrT, + matrixWork, &m, // k + &thisFact, data, &numRows); + return 0; + } +#endif return 0; } @@ -306,8 +362,6 @@ MatrixND::addMatrixTripleProduct(double thisFact, } -template -MatrixND(const T (&)[nc][nr])->MatrixND; // @@ -423,4 +477,4 @@ void MatrixND::addSpinMatrixProduct(const VectorND& a, const MatT (*this)(2, 1) += scale*( -B(0,1)*a[1] + B(1,1)*a[0]); (*this)(2, 2) += scale*( -B(0,2)*a[1] + B(1,2)*a[0]); } -} \ No newline at end of file +} // namespace OpenSees \ No newline at end of file diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index 3c10bd451d..5bc38a621d 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -33,11 +33,8 @@ #ifndef VectorND_H #define VectorND_H #include -#include -#include #include #include -#include "blasdecl.h" #if __cplusplus < 202000L # define consteval @@ -59,32 +56,46 @@ struct VectorND { template friend struct MatrixND; - inline constexpr T& - operator[](index_t index) { - return values[index]; - } + // + template inline void + assemble(const VectorND &v, double fact=1); - inline constexpr const T& - operator[](index_t index) const { - return values[index]; - } + template void + assemble(int a, const VectorND& v, double scale) noexcept; - inline constexpr T& - operator()(index_t index) { - return values[index]; - } + template inline void + insert(const VectorND &v, double fact=1); - inline constexpr const T& - operator()(index_t index) const noexcept { - return values[index]; - } + template void + insert(int a, const VectorND& v, double scale) noexcept; + + template + VectorND + extract(int a) noexcept; + + int + addVector(const T thisFact, const Vector &other, const T otherFact) noexcept; + + int + addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept; + + template + inline int + addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact); + + template + inline int + addMatrixTransposeVector(double thisFact, const MatrixND &m, + const Vector &v, double otherFact); + + inline int + addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact); consteval int size() const { return N; } - consteval inline void fill(double value) { for (T& item : values) @@ -101,9 +112,9 @@ struct VectorND { constexpr T dot(const VecT &other) const noexcept { T sum = 0.0; - for (index_t i = 0; i < N; ++i) { + for (index_t i = 0; i < N; ++i) sum += values[i] * other[i]; - } + return sum; } @@ -117,6 +128,7 @@ struct VectorND { {values[0]*other[1], values[1]*other[1], values[2]*other[1]}, {values[0]*other[2], values[1]*other[2], values[2]*other[2]} }}; + else { MatrixND prod; @@ -128,6 +140,28 @@ struct VectorND { } } + // Return the cross product this vector with another vector, b. + template inline constexpr + void + cross(const VecB& b, VecC& c) requires(N==3) const noexcept { + c[0] = values[1] * b[2] - values[2] * b[1]; + c[1] = values[2] * b[0] - values[0] * b[2]; + c[2] = values[0] * b[1] - values[1] * b[0]; + return c; + } + + + template inline constexpr + VectorND + cross(const Vec3T& b) const noexcept requires(N==3) { + VectorND<3> c; + c[0] = values[1] * b[2] - values[2] * b[1]; + c[1] = values[2] * b[0] - values[0] * b[2]; + c[2] = values[0] * b[1] - values[1] * b[0]; + return c; + } + + constexpr double norm() const noexcept { return std::sqrt(std::fabs(this->dot(*this))); @@ -143,6 +177,27 @@ struct VectorND { return n; } + // + inline constexpr T& + operator[](index_t index) { + return values[index]; + } + + inline constexpr const T& + operator[](index_t index) const { + return values[index]; + } + + inline constexpr T& + operator()(index_t index) { + return values[index]; + } + + inline constexpr const T& + operator()(index_t index) const noexcept { + return values[index]; + } + template inline VectorND &operator=(const VecT &right) noexcept { for (index_t i=0; i< N; i++) @@ -151,41 +206,48 @@ struct VectorND { } inline - VectorND &operator/=(const double &right) { + VectorND & + operator/=(const double &right) { for (index_t i=0; i< N; i++) values[i] /= right; return *this; } inline - VectorND operator/(const double &right) const { + VectorND + operator/(const double &right) const { VectorND res(*this); res /= right; return res; } inline constexpr - VectorND &operator*=(const double &right) noexcept{ + VectorND & + operator*=(const double &right) noexcept{ for (int i=0; i< N; i++) values[i] *= right; return *this; } inline constexpr - VectorND operator*(const double &right) const noexcept { + VectorND + operator*(const double &right) const noexcept { VectorND res(*this); res *= right; return res; } inline constexpr - VectorND &operator+=(const VectorND &right) noexcept { + VectorND & + operator+=(const VectorND &right) noexcept { for (int i=0; i< N; i++) values[i] += right[i]; return *this; } - VectorND &operator+=(const Vector &right) { + inline + VectorND & + operator+=(const Vector &right) { assert(right.Size() == N); for (int i=0; i< N; i++) values[i] += right[i]; @@ -215,33 +277,16 @@ struct VectorND { return res; } - // Return the cross product this vector with another vector, b. - template inline constexpr - void cross(const VecB& b, VecC& c) requires(N==3) const noexcept { - c[0] = values[1] * b[2] - values[2] * b[1]; - c[1] = values[2] * b[0] - values[0] * b[2]; - c[2] = values[0] * b[1] - values[1] * b[0]; - return c; - } - - - template inline constexpr - VectorND cross(const Vec3T& b) const noexcept requires(N==3) { - VectorND<3> c; - c[0] = values[1] * b[2] - values[2] * b[1]; - c[1] = values[2] * b[0] - values[0] * b[2]; - c[2] = values[0] * b[1] - values[1] * b[0]; - return c; - } -#include "VectorND.tpp" - }; } // namespace OpenSees +#include "VectorND.tpp" + template inline OpenSees::VectorND operator * (double a, const OpenSees::VectorND& b) { - return b * a; + return b * a; } + #endif diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index 151e6bb7de..99c16161a9 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -6,361 +6,383 @@ // https://xara.so //===----------------------------------------------------------------------===// // - - template inline void - assemble(const VectorND &v, double fact=1) - { - static_assert((ir >= 0) && ((ir + nr - 1) < N)); - - for (int j=0; j void - assemble(int a, const VectorND& v, double scale) noexcept - { - for (int i=0; i inline void - insert(const VectorND &v, double fact=1) - { - static_assert((ir >= 0) && ((ir + nr - 1) < N)); - - for (int j=0; j void - insert(int a, const VectorND& v, double scale) noexcept - { - for (int i=0; i - VectorND - extract(int a) noexcept - { - VectorND v; - for (int i=0; i +#include "VectorND.h" +#include "blasdecl.h" + + +namespace OpenSees { + +template +template inline void +VectorND::assemble(const VectorND &v, double fact) +{ + static_assert((ir >= 0) && ((ir + nr - 1) < N)); + + for (int j=0; j +template void +VectorND::assemble(int a, const VectorND& v, double scale) noexcept +{ + for (int i=0; i +template inline void +VectorND::insert(const VectorND &v, double fact) +{ + static_assert((ir >= 0) && ((ir + nr - 1) < N)); + + for (int j=0; j +template void +VectorND::insert(int a, const VectorND& v, double scale) noexcept +{ + for (int i=0; i +template +VectorND +VectorND::extract(int a) noexcept +{ + VectorND v; + for (int i=0; i +int +VectorND::addVector(const T thisFact, const Vector &other, const T otherFact) noexcept +{ + if (otherFact == 0.0 && thisFact == 1.0) + return 0; + + else if (thisFact == 1.0) { + // want: this += other * otherFact + double *dataPtr = values; + double *otherDataPtr = other.theData; + if (otherFact == 1.0) { + // no point doing a multiplication if otherFact == 1.0 + for (int i=0; i &other, const T otherFact) - { - if (otherFact == 0.0 && thisFact == 1.0) - return 0; - - else if (thisFact == 1.0) { - // want: this += other * otherFact + // successfull + return 0; +} + + +template +int +VectorND::addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept +{ + if (otherFact == 0.0 && thisFact == 1.0) + return 0; + + else if (thisFact == 1.0) { + // want: this += other * otherFact + double *dataPtr = values; + const double * otherDataPtr = other.values; + if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0 + for (int i=0; i - inline int - addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact) - { - // check the sizes are compatable - assert(NC == v.sz); - - // see if quick return - if (thisFact == 1.0 && otherFact == 0.0) - return 0; - - else { - int incr = 1, - i = N, - n = NC; - DGEMV("N", &i, &n, - &otherFact, - &m.values[0][0], &i, - v.theData, &incr, - &thisFact, - values, - &incr); - - return 0; - } - } + return 0; +} - template - inline int - addMatrixTransposeVector(double thisFact, const MatrixND &m, const Vector &v, double otherFact) - { - // check the sizes are compatable - assert(NR == v.sz); +template +template +inline int +VectorND::addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact) +{ + // check the sizes are compatable + assert(NC == v.sz); - if (thisFact == 1.0 && otherFact == 0.0) - return 0; + // see if quick return + if (thisFact == 1.0 && otherFact == 0.0) + return 0; - else { - int incr = 1, - i = NR, - n = N; - DGEMV("T", &i, &n, + else { + int incr = 1, + i = N, + n = NC; + DGEMV("N", &i, &n, &otherFact, &m.values[0][0], &i, v.theData, &incr, &thisFact, - values, &incr); - return 0; - } - } + values, + &incr); + + return 0; + } +} + +template +template +inline int +VectorND::addMatrixTransposeVector(double thisFact, const MatrixND &m, const Vector &v, double otherFact) +{ + // check the sizes are compatable + assert(NR == v.sz); - inline int - addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact) - { - // check the sizes are compatable - assert(N == m.noRows()); - assert(m.noCols() == v.sz); + if (thisFact == 1.0 && otherFact == 0.0) + return 0; + + else { + int incr = 1, + i = NR, + n = N; + DGEMV("T", &i, &n, + &otherFact, + &m.values[0][0], &i, + v.theData, &incr, + &thisFact, + values, &incr); + return 0; + } +} - // see if quick return - if (thisFact == 1.0 && otherFact == 0.0) - return 0; + +template +inline int +VectorND::addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact) +{ + // check the sizes are compatable + assert(N == m.noRows()); + assert(m.noCols() == v.sz); + + // see if quick return + if (thisFact == 1.0 && otherFact == 0.0) + return 0; #ifdef VECTOR_BLAS - else if (v.sz > 10) { - int incr = 1, - i = m.numRows, - n = m.numCols; - return - DGEMV("N", &i, &n, - &otherFact, - m.data, &i, - v.theData, &incr, - &thisFact, - values, &incr); - } + else if (v.sz > 10) { + int incr = 1, + i = m.numRows, + n = m.numCols; + return + DGEMV("N", &i, &n, + &otherFact, + m.data, &i, + v.theData, &incr, + &thisFact, + values, &incr); + } #endif - else if (thisFact == 1.0) { - - // want: this += m * v * otherFact - if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0 - int otherSize = v.sz; - double *matrixDataPtr = m.data; - const double *otherDataPtr = v.theData; - for (int i=0; i Date: Sun, 29 Jun 2025 10:35:57 -0700 Subject: [PATCH 120/261] remove old files --- .../Frame/Isometry/FrameBasis.h | 279 ------------------ 1 file changed, 279 deletions(-) delete mode 100644 SRC/coordTransformation/Frame/Isometry/FrameBasis.h diff --git a/SRC/coordTransformation/Frame/Isometry/FrameBasis.h b/SRC/coordTransformation/Frame/Isometry/FrameBasis.h deleted file mode 100644 index eb9266ec17..0000000000 --- a/SRC/coordTransformation/Frame/Isometry/FrameBasis.h +++ /dev/null @@ -1,279 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// -//===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// -// -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include - -#define TRIAD C2 -namespace OpenSees { - -class Isometry -{ -public: - virtual int initialize() =0; - virtual int update() =0; - - virtual double getLength() const =0; - // x, \Lambda - virtual Matrix3D getRotation() const =0; - virtual Vector3D getPosition() =0; - // \psi - virtual Vector3D getPositionVariation(int ndf, double* du) =0; - virtual Vector3D getRotationVariation(int ndf, double* du) =0; - virtual Matrix3D getRotationDelta() =0; - // - virtual MatrixND<3,6> getRotationGradient(int node) =0; - -}; - - -template -class RankineIsometry : public Isometry -{ -public: - RankineIsometry(std::array& nodes, const Vector3D& vecxz) - : nodes{nodes}, vz(vecxz), Xc{}, c{}, R{} { - } - - void - setOffsets(std::array* offsets) { - this->offsets = offsets; - } - - virtual int - initialize() { - - for (int i=0; igetTrialRotation(); - - const Vector &XI = nodes[ 0]->getCrds(); - const Vector &XJ = nodes[nn-1]->getCrds(); - - - for (int i=0; i<3; i++) - dX[i] = XJ[i] - XI[i]; - - L = dX.norm(); - Ln = L; - Vector3D e1 = dX/L; - - // - Vector3D e2 = vz.cross(e1); - - const double ynorm = e2.norm(); - - if (ynorm == 0.0) - return -1; - - e2 /= ynorm; - - Vector3D e3 = e1.cross(e2); - - e2 = e3.cross(e1); - - for (int i = 0; i < 3; i++) { - R[init](i,0) = e1[i]; - R[init](i,1) = e2[i]; - R[init](i,2) = e3[i]; - } - -#if 1 - Xc = nodes[ic]->getCrds(); - c[init] = R[init]^(Xc); -#endif - - update(); - return 0; - } - - virtual int - update() { - - Vector3D e1 = dX; - { - // - // Update state - // - { - const Vector& uI = nodes[ 0]->getTrialDisp(); - const Vector& uJ = nodes[nn-1]->getTrialDisp(); - for (int k = 0; k < 3; k++) - e1[k] += uJ(k) - uI(k); - - if (offsets != nullptr) [[unlikely]] { - e1.addVector(1.0, (*offsets)[ 0], 1.0); - e1.addVector(1.0, nodes[0]->getTrialRotation().rotate((*offsets)[0]), -1.0); - e1.addVector(1.0, (*offsets)[nn-1], -1.0); - e1.addVector(1.0, nodes[nn-1]->getTrialRotation().rotate((*offsets)[nn-1]), 1.0); - } - // Calculate the deformed length - Ln = e1.norm(); - - if (Ln == 0.0) [[unlikely]] { - opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; - return -2; - } - - e1 /= Ln; - } - } - - { -#if 1 // TRIAD==R2 - constexpr static Vector3D D2 {0,1,0}; - const Vector3D E2 = R[init]*D2; - Vector3D e2 = MatrixFromVersor(nodes[0]->getTrialRotation())*E2; //*R[init]; - e2.addVector(0.5, MatrixFromVersor(nodes[1]->getTrialRotation())*E2, 0.5); - n = e2[0]/e2[1]; - Vector3D e3 = e1.cross(e2); - e3 /= e3.norm(); - - e2 = e3.cross(e1); - - for (int i = 0; i < 3; i++) { - R[pres](i,0) = e1[i]; - R[pres](i,1) = e2[i]; - R[pres](i,2) = e3[i]; - } - -#elif 1 // TRIAD==C2 - Versor q0 = VersorFromMatrix(R[init]); - Versor qI = nodes[0]->getTrialRotation()*q0; - Versor qJ = nodes[nn-1]->getTrialRotation()*q0; - Vector3D gammaw = CayleyFromVersor(qJ.mult_conj(qI)); - - gammaw *= 0.5; - - // Qbar = VersorProduct(VersorFromMatrix(CaySO3(gammaw)), qI); - Matrix3D Rbar = CaySO3(gammaw)*MatrixFromVersor(qI); // *q0); - Vector3D v { Rbar(0,0), Rbar(1,0), Rbar(2,0) }; - double dot = v.dot(e1); - if (std::fabs(std::fabs(dot)-1.0) < 1.0e-10) { - R[pres] = Rbar; - } else { - v = v.cross(e1); - double scale = std::acos(dot)/v.norm(); - v *= scale; // ::acos(r1.dot(e1)); - - R[pres] = ExpSO3(v)*Rbar; - - Vector3D r1 { R[pres](0,0), R[pres](1,0), R[pres](2,0) }; - Vector3D r2 { R[pres](0,1), R[pres](1,1), R[pres](2,1) }; - Vector3D r3 { R[pres](0,2), R[pres](1,2), R[pres](2,2) }; - // opserr << Vector(r1-e1); - // R[pres] = Rbar^ExpSO3(v); - } -#else - Vector3D e2 = vz.cross(e1); -#endif - - } - - Vector3D uc = nodes[ic]->getTrialDisp(); - if (offsets != nullptr) { - uc.addVector(1.0, (*offsets)[ic], -1.0); - uc.addVector(1.0, nodes[ic]->getTrialRotation().rotate((*offsets)[ic]), 1.0); - } - Vector3D X = nodes[ic]->getCrds(); - c[pres] = R[pres]^(X + uc); - return 0; - }; - - virtual double - getLength() const override { - return Ln; - } - - - virtual Vector3D - getRotationVariation(int ndf, double* du) { - // psi_r = omega - Vector3D w{}; - for (int i=0; igetIncrDeltaDisp(); - auto Wi = this->getRotationGradient(i); - for (int j=0; j<3; j++) - for (int k=0; k<6; k++) - w[j] += Wi(j,k) * du[ndf*i + k]; - } - return w; - } - - - virtual MatrixND<3,6> - getRotationGradient(int node) { - MatrixND<3,6> Gb{}; - - constexpr Vector3D axis{1, 0, 0}; - constexpr Matrix3D ix = Hat(axis); - constexpr Matrix3D ioi = axis.bun(axis); - Gb.template insert<0, 3>(ioi, 0.5); - if (node == 0) - Gb.template insert<0,0>(ix, -1/Ln); - else if (node == nn-1) - Gb.template insert<0,0>(ix, 1/Ln); - - Gb(0,2) = (node == 0? 1.0 : -1.0)*n; - return Gb; - } - - - virtual Matrix3D - getRotation() const override { - return R[pres]; - } - - - virtual Matrix3D - getRotationDelta() { - return R[pres] - R[init]; - } - - Vector3D - getLocation() { - return c[pres]; - } - - virtual Vector3D - getPosition() { - // Return Delta c - Vector3D X = nodes[ic]->getCrds(); - Vector3D Dc = c[pres] - (R[init]^X) ; // (R[pres]^c[init]); - return Dc; - } - - virtual Vector3D - getPositionVariation(int ndf, double* du) { - return Vector3D {du[ndf*ic+0], du[ndf*ic+1], du[ndf*ic+2]}; - } - -private: - constexpr static int ic = 0; // std::floor(0.5*(nn+1)); - enum { pres, prev, init}; - double L, Ln; - double n = 0, - n11 = 1, - n12 = 0, - n21 = 0, - n22 = 1; - Vector3D vz, dX, Xc; - Matrix3D R[3]; - Vector3D c[3]; - Matrix3D dR; - std::array& nodes; - std::array* offsets = nullptr; // offsets -}; - -} // namespace OpenSees From d8e11cbb1b6ecfe3975c41f707990188f41a767c Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 10:38:47 -0700 Subject: [PATCH 121/261] clean --- SRC/matrix/Matrix3D.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SRC/matrix/Matrix3D.h b/SRC/matrix/Matrix3D.h index 5bcd613316..4a5d8afb73 100644 --- a/SRC/matrix/Matrix3D.h +++ b/SRC/matrix/Matrix3D.h @@ -1,8 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // // Claudio Perez // From 16b4953a6284cd4b4a0eff14f8705bee3ed6148d Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 10:40:16 -0700 Subject: [PATCH 122/261] clean out files --- SRC/matrix/routines/cmx.h | 28 - SRC/matrix/routines/invGL2.c | 46 - SRC/matrix/routines/invGL3.c | 54 - SRC/matrix/routines/invGL4.c | 95 - SRC/matrix/routines/invGL5.c | 343 - SRC/matrix/routines/invGL6.c | 13385 --------------------------------- 6 files changed, 13951 deletions(-) delete mode 100644 SRC/matrix/routines/cmx.h delete mode 100644 SRC/matrix/routines/invGL2.c delete mode 100644 SRC/matrix/routines/invGL3.c delete mode 100644 SRC/matrix/routines/invGL4.c delete mode 100644 SRC/matrix/routines/invGL5.c delete mode 100644 SRC/matrix/routines/invGL6.c diff --git a/SRC/matrix/routines/cmx.h b/SRC/matrix/routines/cmx.h deleted file mode 100644 index c9cc19faa7..0000000000 --- a/SRC/matrix/routines/cmx.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef cmx_h -#define cmx_h - -#ifdef __cplusplus -extern "C" { -#endif - -int cmx_inv2 (const double *a, double *ainv, int*ok_flag); -int cmx_inv3 (const double *a, double *ainv, int*ok_flag); -int cmx_inv4 (const double *a, double *ainv, int*ok_flag); -int cmx_inv5 (const double *a, double *ainv, int*ok_flag); -int cmx_inv6 (const double *a, double *ainv, int*ok_flag); -int cmx_inv6_v2(const double *a, double *ainv, int*ok_flag); -int cmx_inv6_v3(const double *a, double *ainv, int*ok_flag); - -#define cmx_inv(a, inv, flag) _Generic(&(a), \ - double(*)[ 4]: cmx_inv2, \ - double(*)[ 9]: cmx_inv3, \ - double(*)[16]: cmx_inv4, \ - double(*)[25]: cmx_inv5, \ - double(*)[36]: cmx_inv6 \ - )(a, inv, flag) - -#ifdef __cplusplus -} -#endif - -#endif // cmx_h diff --git a/SRC/matrix/routines/invGL2.c b/SRC/matrix/routines/invGL2.c deleted file mode 100644 index 305c17c52b..0000000000 --- a/SRC/matrix/routines/invGL2.c +++ /dev/null @@ -1,46 +0,0 @@ -// -// adapted from https://caps.gsfc.nasa.gov/simpson/software/m22inv_f90.txt -// -// David Simpson -// Claudio Perez -// -#include - -int cmx_inv2(double *a, double *ainv, int *ok_flag__) -{ - /* **************************************************************************************** - * m22inv - compute the inverse of a 2x2 matrix. - * - * a : (input) 2x2 matrix to be inverted - * ainv : (output) 2x2 inverse of matrix a - * - * ok_flag: (output) 0 if the input matrix could be inverted, - * and -1 if the input matrix is singular. - * - * ****************************************************************************************/ - - /* Parameter adjustments */ - ainv -= 3; - a -= 3; - - /* Function Body */ - const double eps = 1e-10; - const double det = a[3] * a[6] - a[5] * a[4]; - if (fabs(det) <= eps) { - *ok_flag__ = -1; - } - - double cofactor[4]; - - cofactor[0] = a[6]; - cofactor[2] = -a[4]; - cofactor[1] = -a[5]; - cofactor[3] = a[3]; - - for (int i__ = 1; i__ <= 2; ++i__) - for (int j = 1; j <= 2; ++j) - ainv[j + (i__ << 1)] = cofactor[i__ + (j << 1) - 3] / det; - - *ok_flag__ = 0; - return 0; -} diff --git a/SRC/matrix/routines/invGL3.c b/SRC/matrix/routines/invGL3.c deleted file mode 100644 index a3a12f87e9..0000000000 --- a/SRC/matrix/routines/invGL3.c +++ /dev/null @@ -1,54 +0,0 @@ -// -// adapted from https://caps.gsfc.nasa.gov/simpson/software/m33inv_f90.txt -// -#include - - -int cmx_inv3(double *a, double *ainv, int *ok_flag__) -{ -/* **************************************************************************************** */ -/* m33inv - compute the inverse of a 3x3 matrix. */ - -/* a = input 3x3 matrix to be inverted */ -/* ainv = output 3x3 inverse of matrix a */ -/* ok_flag = (output) .true. if the input matrix could be inverted, and */ -/* .false. if the input matrix is singular. */ -/* **************************************************************************************** */ - - - /* Parameter adjustments */ - ainv -= 4; - a -= 4; - - const double det = a[4]*a[8]*a[12] - - a[4]*a[11]*a[9] - - a[7]*a[5]*a[12] - + a[7]*a[11]*a[6] - + a[10]*a[5]*a[9] - - a[10]*a[8]*a[6]; - - const double eps=1e-10; - if (fabs(det) <= eps) { - *ok_flag__ = -1; - // return 0; - } - - double cofactor[9]; - cofactor[0] = a[8]*a[12] - a[11]*a[9]; - cofactor[3] = -(a[5]*a[12] - a[11]*a[6]); - cofactor[6] = a[5]*a[9] - a[8]*a[6]; - cofactor[1] = -(a[7]*a[12] - a[10]*a[9]); - cofactor[4] = a[4]*a[12] - a[10]*a[6]; - cofactor[7] = -(a[4]*a[9] - a[7]*a[6]); - cofactor[2] = a[7]*a[11] - a[10]*a[8]; - cofactor[5] = -(a[4]*a[11] - a[10]*a[5]); - cofactor[8] = a[4]*a[8] - a[7]*a[5]; - - for (int i__ = 1; i__ <= 3; ++i__) - for (int j = 1; j <= 3; ++j) - ainv[j + i__ * 3] = cofactor[i__ + j * 3 - 4] / det; - - *ok_flag__ = 0; - return 0; -} - diff --git a/SRC/matrix/routines/invGL4.c b/SRC/matrix/routines/invGL4.c deleted file mode 100644 index 7060e2d58c..0000000000 --- a/SRC/matrix/routines/invGL4.c +++ /dev/null @@ -1,95 +0,0 @@ -// -// adapted from https://caps.gsfc.nasa.gov/simpson/software/m44inv_f90.txt -// -#include - -int cmx_inv4(double *a, double *ainv, int *ok_flag__) -{ -/* **************************************************************************************** - * m44inv - compute the inverse of a 4x4 matrix. - - * a = input 4x4 matrix to be inverted - * ainv = output 4x4 inverse of matrix a - * ok_flag = (output) .true. if the input matrix could be inverted, and .false. if the input matrix is singular. - * **************************************************************************************** */ - static double cofactor[16]; - static double eps=1e-10; - - /* Parameter adjustments */ - ainv -= 5; - a -= 5; - - const double det = a[ 5]*(a[10]*(a[15]*a[20] - a[19]*a[16]) - + a[14]*(a[19]*a[12] - a[11]*a[20]) - + a[18]*(a[11]*a[16] - a[15]*a[12])) - - a[ 9]*(a[ 6]*(a[15]*a[20] - a[19]*a[16]) - + a[14]*(a[19]*a[ 8] - a[ 7]*a[20]) - + a[18]*(a[ 7]*a[16] - a[15]*a[ 8])) - + a[13]*(a[ 6]*(a[11]*a[20] - a[19]*a[12]) - + a[10]*(a[19]*a[ 8] - a[ 7]*a[20]) - + a[18]*(a[ 7]*a[12] - a[11]*a[ 8])) - - a[17]*(a[ 6]*(a[11]*a[16] - a[15]*a[12]) - + a[10]*(a[15]*a[ 8] - a[ 7]*a[16]) - + a[14]*(a[ 7]*a[12] - a[11]*a[ 8])); - - if (fabs(det) <= eps) { - *ok_flag__ = -1; - } - - cofactor[ 0] = a[10]*(a[15]*a[20] - a[19]*a[16]) - + a[14]*(a[19]*a[12] - a[11]*a[20]) - + a[18]*(a[11]*a[16] - a[15]*a[12]); - cofactor[ 4] = a[ 6]*(a[19]*a[16] - a[15]*a[20]) - + a[14]*(a[ 7]*a[20] - a[19]*a[ 8]) - + a[18]*(a[15]*a[ 8] - a[ 7]*a[16]); - cofactor[ 8] = a[ 6]*(a[11]*a[20] - a[19]*a[12]) - + a[10]*(a[19]*a[ 8] - a[ 7]*a[20]) - + a[18]*(a[ 7]*a[12] - a[11]*a[ 8]); - cofactor[12] = a[ 6]*(a[15]*a[12] - a[11]*a[16]) - + a[10]*(a[ 7]*a[16] - a[15]*a[ 8]) - + a[14]*(a[11]*a[ 8] - a[ 7]*a[12]); - cofactor[ 1] = a[ 9]*(a[19]*a[16] - a[15]*a[20]) - + a[13]*(a[11]*a[20] - a[19]*a[12]) - + a[17]*(a[15]*a[12] - a[11]*a[16]); - cofactor[ 5] = a[ 5]*(a[15]*a[20] - a[19]*a[16]) - + a[13]*(a[19]*a[ 8] - a[ 7]*a[20]) - + a[17]*(a[ 7]*a[16] - a[15]*a[ 8]); - cofactor[ 9] = a[ 5]*(a[19]*a[12] - a[11]*a[20]) - + a[ 9]*(a[ 7]*a[20] - a[19]*a[ 8]) - + a[17]*(a[11]*a[ 8] - a[ 7]*a[12]); - cofactor[13] = a[ 5]*(a[11]*a[16] - a[15]*a[12]) - + a[ 9]*(a[15]*a[ 8] - a[ 7]*a[16]) - + a[13]*(a[ 7]*a[12] - a[11]*a[ 8]); - cofactor[ 2] = a[ 9]*(a[14]*a[20] - a[18]*a[16]) - + a[13]*(a[18]*a[12] - a[10]*a[20]) - + a[17]*(a[10]*a[16] - a[14]*a[12]); - cofactor[ 6] = a[ 5]*(a[18]*a[16] - a[14]*a[20]) - + a[13]*(a[ 6]*a[20] - a[18]*a[ 8]) - + a[17]*(a[14]*a[ 8] - a[ 6]*a[16]); - cofactor[10] = a[ 5]*(a[10]*a[20] - a[18]*a[12]) - + a[ 9]*(a[18]*a[ 8] - a[ 6]*a[20]) - + a[17]*(a[ 6]*a[12] - a[10]*a[ 8]); - cofactor[14] = a[ 5]*(a[14]*a[12] - a[10]*a[16]) - + a[ 9]*(a[ 6]*a[16] - a[14]*a[ 8]) - + a[13]*(a[10]*a[ 8] - a[ 6]*a[12]); - cofactor[ 3] = a[ 9]*(a[18]*a[15] - a[14]*a[19]) - + a[13]*(a[10]*a[19] - a[18]*a[11]) - + a[17]*(a[14]*a[11] - a[10]*a[15]); - cofactor[ 7] = a[ 5]*(a[14]*a[19] - a[18]*a[15]) - + a[13]*(a[18]*a[ 7] - a[ 6]*a[19]) - + a[17]*(a[ 6]*a[15] - a[14]*a[ 7]); - cofactor[11] = a[ 5]*(a[18]*a[11] - a[10]*a[19]) - + a[ 9]*(a[ 6]*a[19] - a[18]*a[ 7]) - + a[17]*(a[10]*a[ 7] - a[ 6]*a[11]); - cofactor[15] = a[ 5]*(a[10]*a[15] - a[14]*a[11]) - + a[ 9]*(a[14]*a[ 7] - a[ 6]*a[15]) - + a[13]*(a[ 6]*a[11] - a[10]*a[ 7]); - - for (int i__ = 1; i__ <= 4; ++i__) - for (int j = 1; j <= 4; ++j) - ainv[j + (i__ << 2)] = cofactor[i__ + (j << 2) - 5] / det; - - *ok_flag__ = 0; - return 0; -} - diff --git a/SRC/matrix/routines/invGL5.c b/SRC/matrix/routines/invGL5.c deleted file mode 100644 index fe121ccc09..0000000000 --- a/SRC/matrix/routines/invGL5.c +++ /dev/null @@ -1,343 +0,0 @@ -// -// adapted from https://caps.gsfc.nasa.gov/simpson/software/m55inv_f90.txt -// -#include - -int cmx_inv5(double *a, double *ainv, int *ok_flag__) -{ -/* **************************************************************************************** - * m55inv - compute the inverse of a 5x5 matrix. - - * a = input 5x5 matrix to be inverted - * ainv = output 5x5 inverse of matrix a - * ok_flag = (output) .true. if the input matrix could be inverted, and .false. if the input matrix is singular. - ***************************************************************************************** */ - static double cofactor[25]; - static double a11, a12, a13, a14, a15, a21, a22, a23, a24, a25, a31, - a32, a33, a34, a35, a41, a42, a43, a44, a45, a51, a52, a53, a54, - a55, det; - - const double eps = 1e-10; - - /* Parameter adjustments */ - ainv -= 6; - a -= 6; - - a11 = a[6]; - a12 = a[11]; - a13 = a[16]; - a14 = a[21]; - a15 = a[26]; - a21 = a[7]; - a22 = a[12]; - a23 = a[17]; - a24 = a[22]; - a25 = a[27]; - a31 = a[8]; - a32 = a[13]; - a33 = a[18]; - a34 = a[23]; - a35 = a[28]; - a41 = a[9]; - a42 = a[14]; - a43 = a[19]; - a44 = a[24]; - a45 = a[29]; - a51 = a[10]; - a52 = a[15]; - a53 = a[20]; - a54 = a[25]; - a55 = a[30]; - det = a15*a24*a33*a42*a51 - a14*a25*a33*a42*a51 - a15* - a23*a34*a42*a51 + a13*a25*a34*a42*a51 + a14*a23* - a35*a42*a51 - a13*a24*a35*a42*a51 - a15*a24*a32* - a43*a51 + a14*a25*a32*a43*a51 + a15*a22*a34*a43* - a51 - a12*a25*a34*a43*a51 - a14*a22*a35*a43*a51 + - a12*a24*a35*a43*a51 + a15*a23*a32*a44*a51 - a13* - a25*a32*a44*a51 - a15*a22*a33*a44*a51 + a12*a25* - a33*a44*a51 + a13*a22*a35*a44*a51 - a12*a23*a35* - a44*a51 - a14*a23*a32*a45*a51 + a13*a24*a32*a45* - a51 + a14*a22*a33*a45*a51 - a12*a24*a33*a45*a51 - - a13*a22*a34*a45*a51 + a12*a23*a34*a45*a51 - a15* - a24*a33*a41*a52 + a14*a25*a33*a41*a52 + a15*a23* - a34*a41*a52 - a13*a25*a34*a41*a52 - a14*a23*a35* - a41*a52 + a13*a24*a35*a41*a52 + a15*a24*a31*a43* - a52 - a14*a25*a31*a43*a52 - a15*a21*a34*a43*a52 + - a11*a25*a34*a43*a52 + a14*a21*a35*a43*a52 - a11* - a24*a35*a43*a52 - a15*a23*a31*a44*a52 + a13*a25* - a31*a44*a52 + a15*a21*a33*a44*a52 - a11*a25*a33* - a44*a52 - a13*a21*a35*a44*a52 + a11*a23*a35*a44* - a52 + a14*a23*a31*a45*a52 - a13*a24*a31*a45*a52 - - a14*a21*a33*a45*a52 + a11*a24*a33*a45*a52 + a13* - a21*a34*a45*a52 - a11*a23*a34*a45*a52 + a15*a24* - a32*a41*a53 - a14*a25*a32*a41*a53 - a15*a22*a34* - a41*a53 + a12*a25*a34*a41*a53 + a14*a22*a35*a41* - a53 - a12*a24*a35*a41*a53 - a15*a24*a31*a42*a53 + - a14*a25*a31*a42*a53 + a15*a21*a34*a42*a53 - a11* - a25*a34*a42*a53 - a14*a21*a35*a42*a53 + a11*a24* - a35*a42*a53 + a15*a22*a31*a44*a53 - a12*a25*a31* - a44*a53 - a15*a21*a32*a44*a53 + a11*a25*a32*a44* - a53 + a12*a21*a35*a44*a53 - a11*a22*a35*a44*a53 - - a14*a22*a31*a45*a53 + a12*a24*a31*a45*a53 + a14* - a21*a32*a45*a53 - a11*a24*a32*a45*a53 - a12*a21* - a34*a45*a53 + a11*a22*a34*a45*a53 - a15*a23*a32* - a41*a54 + a13*a25*a32*a41*a54 + a15*a22*a33*a41* - a54 - a12*a25*a33*a41*a54 - a13*a22*a35*a41*a54 + - a12*a23*a35*a41*a54 + a15*a23*a31*a42*a54 - a13* - a25*a31*a42*a54 - a15*a21*a33*a42*a54 + a11*a25* - a33*a42*a54 + a13*a21*a35*a42*a54 - a11*a23*a35* - a42*a54 - a15*a22*a31*a43*a54 + a12*a25*a31*a43* - a54 + a15*a21*a32*a43*a54 - a11*a25*a32*a43*a54 - - a12*a21*a35*a43*a54 + a11*a22*a35*a43*a54 + a13* - a22*a31*a45*a54 - a12*a23*a31*a45*a54 - a13*a21* - a32*a45*a54 + a11*a23*a32*a45*a54 + a12*a21*a33* - a45*a54 - a11*a22*a33*a45*a54 + a14*a23*a32*a41* - a55 - a13*a24*a32*a41*a55 - a14*a22*a33*a41*a55 + - a12*a24*a33*a41*a55 + a13*a22*a34*a41*a55 - a12* - a23*a34*a41*a55 - a14*a23*a31*a42*a55 + a13*a24* - a31*a42*a55 + a14*a21*a33*a42*a55 - a11*a24*a33* - a42*a55 - a13*a21*a34*a42*a55 + a11*a23*a34*a42* - a55 + a14*a22*a31*a43*a55 - a12*a24*a31*a43*a55 - - a14*a21*a32*a43*a55 + a11*a24*a32*a43*a55 + a12* - a21*a34*a43*a55 - a11*a22*a34*a43*a55 - a13*a22* - a31*a44*a55 + a12*a23*a31*a44*a55 + a13*a21*a32* - a44*a55 - a11*a23*a32*a44*a55 - a12*a21*a33*a44* - a55 + a11*a22*a33*a44*a55; - if (fabs(det) <= eps) { - *ok_flag__ = -1; - return 0; - } - cofactor[0] = a25*a34*a43*a52 - a24*a35*a43*a52 - a25*a33* - a44*a52 + a23*a35*a44*a52 + a24*a33*a45*a52 - a23* - a34*a45*a52 - a25*a34*a42*a53 + a24*a35*a42*a53 + - a25*a32*a44*a53 - a22*a35*a44*a53 - a24*a32*a45* - a53 + a22*a34*a45*a53 + a25*a33*a42*a54 - a23*a35* - a42*a54 - a25*a32*a43*a54 + a22*a35*a43*a54 + a23* - a32*a45*a54 - a22*a33*a45*a54 - a24*a33*a42*a55 + - a23*a34*a42*a55 + a24*a32*a43*a55 - a22*a34*a43* - a55 - a23*a32*a44*a55 + a22*a33*a44*a55; - cofactor[1] = -a15*a34*a43*a52 + a14*a35*a43*a52 + a15*a33 * - a44*a52 - a13*a35*a44*a52 - a14*a33*a45*a52 + a13 * - a34*a45*a52 + a15*a34*a42*a53 - a14*a35*a42*a53 - - a15*a32*a44*a53 + a12*a35*a44*a53 + a14*a32*a45 - *a53 - a12*a34*a45*a53 - a15*a33*a42*a54 + a13*a35 - *a42*a54 + a15*a32*a43*a54 - a12*a35*a43*a54 - a13 - *a32*a45*a54 + a12*a33*a45*a54 + a14*a33*a42*a55 - - a13*a34*a42*a55 - a14*a32*a43*a55 + a12*a34*a43 - *a55 + a13*a32*a44*a55 - a12*a33*a44*a55; - cofactor[2] = a15*a24*a43*a52 - a14*a25*a43*a52 - a15*a23* - a44*a52 + a13*a25*a44*a52 + a14*a23*a45*a52 - a13* - a24*a45*a52 - a15*a24*a42*a53 + a14*a25*a42*a53 + - a15*a22*a44*a53 - a12*a25*a44*a53 - a14*a22*a45* - a53 + a12*a24*a45*a53 + a15*a23*a42*a54 - a13*a25* - a42*a54 - a15*a22*a43*a54 + a12*a25*a43*a54 + a13* - a22*a45*a54 - a12*a23*a45*a54 - a14*a23*a42*a55 + - a13*a24*a42*a55 + a14*a22*a43*a55 - a12*a24*a43* - a55 - a13*a22*a44*a55 + a12*a23*a44*a55; - cofactor[3] = -a15*a24*a33*a52 + a14*a25*a33*a52 + a15*a23 * - a34*a52 - a13*a25*a34*a52 - a14*a23*a35*a52 + a13 * - a24*a35*a52 + a15*a24*a32*a53 - a14*a25*a32*a53 - - a15*a22*a34*a53 + a12*a25*a34*a53 + a14*a22*a35 - *a53 - a12*a24*a35*a53 - a15*a23*a32*a54 + a13*a25 - *a32*a54 + a15*a22*a33*a54 - a12*a25*a33*a54 - a13 - *a22*a35*a54 + a12*a23*a35*a54 + a14*a23*a32*a55 - - a13*a24*a32*a55 - a14*a22*a33*a55 + a12*a24*a33 - *a55 + a13*a22*a34*a55 - a12*a23*a34*a55; - cofactor[4] = a15*a24*a33*a42 - a14*a25*a33*a42 - a15*a23* - a34*a42 + a13*a25*a34*a42 + a14*a23*a35*a42 - a13* - a24*a35*a42 - a15*a24*a32*a43 + a14*a25*a32*a43 + - a15*a22*a34*a43 - a12*a25*a34*a43 - a14*a22*a35* - a43 + a12*a24*a35*a43 + a15*a23*a32*a44 - a13*a25* - a32*a44 - a15*a22*a33*a44 + a12*a25*a33*a44 + a13* - a22*a35*a44 - a12*a23*a35*a44 - a14*a23*a32*a45 + - a13*a24*a32*a45 + a14*a22*a33*a45 - a12*a24*a33* - a45 - a13*a22*a34*a45 + a12*a23*a34*a45; - cofactor[5] = -a25*a34*a43*a51 + a24*a35*a43*a51 + a25*a33 * - a44*a51 - a23*a35*a44*a51 - a24*a33*a45*a51 + a23 * - a34*a45*a51 + a25*a34*a41*a53 - a24*a35*a41*a53 - - a25*a31*a44*a53 + a21*a35*a44*a53 + a24*a31*a45 - *a53 - a21*a34*a45*a53 - a25*a33*a41*a54 + a23*a35 - *a41*a54 + a25*a31*a43*a54 - a21*a35*a43*a54 - a23 - *a31*a45*a54 + a21*a33*a45*a54 + a24*a33*a41*a55 - - a23*a34*a41*a55 - a24*a31*a43*a55 + a21*a34*a43 - *a55 + a23*a31*a44*a55 - a21*a33*a44*a55; - cofactor[6] = a15*a34*a43*a51 - a14*a35*a43*a51 - a15*a33* - a44*a51 + a13*a35*a44*a51 + a14*a33*a45*a51 - a13* - a34*a45*a51 - a15*a34*a41*a53 + a14*a35*a41*a53 + - a15*a31*a44*a53 - a11*a35*a44*a53 - a14*a31*a45* - a53 + a11*a34*a45*a53 + a15*a33*a41*a54 - a13*a35* - a41*a54 - a15*a31*a43*a54 + a11*a35*a43*a54 + a13* - a31*a45*a54 - a11*a33*a45*a54 - a14*a33*a41*a55 + - a13*a34*a41*a55 + a14*a31*a43*a55 - a11*a34*a43* - a55 - a13*a31*a44*a55 + a11*a33*a44*a55; - cofactor[7] = -a15*a24*a43*a51 + a14*a25*a43*a51 + a15*a23 * - a44*a51 - a13*a25*a44*a51 - a14*a23*a45*a51 + a13 * - a24*a45*a51 + a15*a24*a41*a53 - a14*a25*a41*a53 - - a15*a21*a44*a53 + a11*a25*a44*a53 + a14*a21*a45 - *a53 - a11*a24*a45*a53 - a15*a23*a41*a54 + a13*a25 - *a41*a54 + a15*a21*a43*a54 - a11*a25*a43*a54 - a13 - *a21*a45*a54 + a11*a23*a45*a54 + a14*a23*a41*a55 - - a13*a24*a41*a55 - a14*a21*a43*a55 + a11*a24*a43 - *a55 + a13*a21*a44*a55 - a11*a23*a44*a55; - cofactor[8] = a15*a24*a33*a51 - a14*a25*a33*a51 - a15*a23* - a34*a51 + a13*a25*a34*a51 + a14*a23*a35*a51 - a13* - a24*a35*a51 - a15*a24*a31*a53 + a14*a25*a31*a53 + - a15*a21*a34*a53 - a11*a25*a34*a53 - a14*a21*a35* - a53 + a11*a24*a35*a53 + a15*a23*a31*a54 - a13*a25* - a31*a54 - a15*a21*a33*a54 + a11*a25*a33*a54 + a13* - a21*a35*a54 - a11*a23*a35*a54 - a14*a23*a31*a55 + - a13*a24*a31*a55 + a14*a21*a33*a55 - a11*a24*a33* - a55 - a13*a21*a34*a55 + a11*a23*a34*a55; - cofactor[9] = -a15*a24*a33*a41 + a14*a25*a33*a41 + a15*a23 * - a34*a41 - a13*a25*a34*a41 - a14*a23*a35*a41 + a13 * - a24*a35*a41 + a15*a24*a31*a43 - a14*a25*a31*a43 - - a15*a21*a34*a43 + a11*a25*a34*a43 + a14*a21*a35 - *a43 - a11*a24*a35*a43 - a15*a23*a31*a44 + a13*a25 - *a31*a44 + a15*a21*a33*a44 - a11*a25*a33*a44 - a13 - *a21*a35*a44 + a11*a23*a35*a44 + a14*a23*a31*a45 - - a13*a24*a31*a45 - a14*a21*a33*a45 + a11*a24*a33 - *a45 + a13*a21*a34*a45 - a11*a23*a34*a45; - cofactor[10] = a25*a34*a42*a51 - a24*a35*a42*a51 - a25*a32 * - a44*a51 + a22*a35*a44*a51 + a24*a32*a45*a51 - a22 * - a34*a45*a51 - a25*a34*a41*a52 + a24*a35*a41*a52 - + a25*a31*a44*a52 - a21*a35*a44*a52 - a24*a31*a45 - *a52 + a21*a34*a45*a52 + a25*a32*a41*a54 - a22*a35 - *a41*a54 - a25*a31*a42*a54 + a21*a35*a42*a54 + a22 - *a31*a45*a54 - a21*a32*a45*a54 - a24*a32*a41*a55 - + a22*a34*a41*a55 + a24*a31*a42*a55 - a21*a34*a42 - *a55 - a22*a31*a44*a55 + a21*a32*a44*a55; - cofactor[11] = -a15*a34*a42*a51 + a14*a35*a42*a51 + a15*a32 - *a44*a51 - a12*a35*a44*a51 - a14*a32*a45*a51 + a12 - *a34*a45*a51 + a15*a34*a41*a52 - a14*a35*a41*a52 - - a15*a31*a44*a52 + a11*a35*a44*a52 + a14*a31*a45 - *a52 - a11*a34*a45*a52 - a15*a32*a41*a54 + a12*a35 - *a41*a54 + a15*a31*a42*a54 - a11*a35*a42*a54 - a12 - *a31*a45*a54 + a11*a32*a45*a54 + a14*a32*a41*a55 - - a12*a34*a41*a55 - a14*a31*a42*a55 + a11*a34*a42 - *a55 + a12*a31*a44*a55 - a11*a32*a44*a55; - cofactor[12] = a15*a24*a42*a51 - a14*a25*a42*a51 - a15*a22 * - a44*a51 + a12*a25*a44*a51 + a14*a22*a45*a51 - a12 * - a24*a45*a51 - a15*a24*a41*a52 + a14*a25*a41*a52 - + a15*a21*a44*a52 - a11*a25*a44*a52 - a14*a21*a45 - *a52 + a11*a24*a45*a52 + a15*a22*a41*a54 - a12*a25 - *a41*a54 - a15*a21*a42*a54 + a11*a25*a42*a54 + a12 - *a21*a45*a54 - a11*a22*a45*a54 - a14*a22*a41*a55 - + a12*a24*a41*a55 + a14*a21*a42*a55 - a11*a24*a42 - *a55 - a12*a21*a44*a55 + a11*a22*a44*a55; - cofactor[13] = -a15*a24*a32*a51 + a14*a25*a32*a51 + a15*a22 - *a34*a51 - a12*a25*a34*a51 - a14*a22*a35*a51 + a12 - *a24*a35*a51 + a15*a24*a31*a52 - a14*a25*a31*a52 - - a15*a21*a34*a52 + a11*a25*a34*a52 + a14*a21*a35 - *a52 - a11*a24*a35*a52 - a15*a22*a31*a54 + a12*a25 - *a31*a54 + a15*a21*a32*a54 - a11*a25*a32*a54 - a12 - *a21*a35*a54 + a11*a22*a35*a54 + a14*a22*a31*a55 - - a12*a24*a31*a55 - a14*a21*a32*a55 + a11*a24*a32 - *a55 + a12*a21*a34*a55 - a11*a22*a34*a55; - cofactor[14] = a15*a24*a32*a41 - a14*a25*a32*a41 - a15*a22 * - a34*a41 + a12*a25*a34*a41 + a14*a22*a35*a41 - a12 * - a24*a35*a41 - a15*a24*a31*a42 + a14*a25*a31*a42 - + a15*a21*a34*a42 - a11*a25*a34*a42 - a14*a21*a35 - *a42 + a11*a24*a35*a42 + a15*a22*a31*a44 - a12*a25 - *a31*a44 - a15*a21*a32*a44 + a11*a25*a32*a44 + a12 - *a21*a35*a44 - a11*a22*a35*a44 - a14*a22*a31*a45 - + a12*a24*a31*a45 + a14*a21*a32*a45 - a11*a24*a32 - *a45 - a12*a21*a34*a45 + a11*a22*a34*a45; - cofactor[15] = -a25*a33*a42*a51 + a23*a35*a42*a51 + a25*a32 - *a43*a51 - a22*a35*a43*a51 - a23*a32*a45*a51 + a22 - *a33*a45*a51 + a25*a33*a41*a52 - a23*a35*a41*a52 - - a25*a31*a43*a52 + a21*a35*a43*a52 + a23*a31*a45 - *a52 - a21*a33*a45*a52 - a25*a32*a41*a53 + a22*a35 - *a41*a53 + a25*a31*a42*a53 - a21*a35*a42*a53 - a22 - *a31*a45*a53 + a21*a32*a45*a53 + a23*a32*a41*a55 - - a22*a33*a41*a55 - a23*a31*a42*a55 + a21*a33*a42 - *a55 + a22*a31*a43*a55 - a21*a32*a43*a55; - cofactor[16] = a15*a33*a42*a51 - a13*a35*a42*a51 - a15*a32 * - a43*a51 + a12*a35*a43*a51 + a13*a32*a45*a51 - a12 * - a33*a45*a51 - a15*a33*a41*a52 + a13*a35*a41*a52 - + a15*a31*a43*a52 - a11*a35*a43*a52 - a13*a31*a45 - *a52 + a11*a33*a45*a52 + a15*a32*a41*a53 - a12*a35 - *a41*a53 - a15*a31*a42*a53 + a11*a35*a42*a53 + a12 - *a31*a45*a53 - a11*a32*a45*a53 - a13*a32*a41*a55 - + a12*a33*a41*a55 + a13*a31*a42*a55 - a11*a33*a42 - *a55 - a12*a31*a43*a55 + a11*a32*a43*a55; - cofactor[17] = -a15*a23*a42*a51 + a13*a25*a42*a51 + a15*a22 - *a43*a51 - a12*a25*a43*a51 - a13*a22*a45*a51 + a12 - *a23*a45*a51 + a15*a23*a41*a52 - a13*a25*a41*a52 - - a15*a21*a43*a52 + a11*a25*a43*a52 + a13*a21*a45 - *a52 - a11*a23*a45*a52 - a15*a22*a41*a53 + a12*a25 - *a41*a53 + a15*a21*a42*a53 - a11*a25*a42*a53 - a12 - *a21*a45*a53 + a11*a22*a45*a53 + a13*a22*a41*a55 - - a12*a23*a41*a55 - a13*a21*a42*a55 + a11*a23*a42 - *a55 + a12*a21*a43*a55 - a11*a22*a43*a55; - cofactor[18] = a15*a23*a32*a51 - a13*a25*a32*a51 - a15*a22 * - a33*a51 + a12*a25*a33*a51 + a13*a22*a35*a51 - a12 * - a23*a35*a51 - a15*a23*a31*a52 + a13*a25*a31*a52 - + a15*a21*a33*a52 - a11*a25*a33*a52 - a13*a21*a35 - *a52 + a11*a23*a35*a52 + a15*a22*a31*a53 - a12*a25 - *a31*a53 - a15*a21*a32*a53 + a11*a25*a32*a53 + a12 - *a21*a35*a53 - a11*a22*a35*a53 - a13*a22*a31*a55 - + a12*a23*a31*a55 + a13*a21*a32*a55 - a11*a23*a32 - *a55 - a12*a21*a33*a55 + a11*a22*a33*a55; - cofactor[19] = -a15*a23*a32*a41 + a13*a25*a32*a41 + a15*a22 - *a33*a41 - a12*a25*a33*a41 - a13*a22*a35*a41 + a12 - *a23*a35*a41 + a15*a23*a31*a42 - a13*a25*a31*a42 - - a15*a21*a33*a42 + a11*a25*a33*a42 + a13*a21*a35 - *a42 - a11*a23*a35*a42 - a15*a22*a31*a43 + a12*a25 - *a31*a43 + a15*a21*a32*a43 - a11*a25*a32*a43 - a12 - *a21*a35*a43 + a11*a22*a35*a43 + a13*a22*a31*a45 - - a12*a23*a31*a45 - a13*a21*a32*a45 + a11*a23*a32 - *a45 + a12*a21*a33*a45 - a11*a22*a33*a45; - cofactor[20] = a24*a33*a42*a51 - a23*a34*a42*a51 - a24*a32 * - a43*a51 + a22*a34*a43*a51 + a23*a32*a44*a51 - a22 * - a33*a44*a51 - a24*a33*a41*a52 + a23*a34*a41*a52 - + a24*a31*a43*a52 - a21*a34*a43*a52 - a23*a31*a44 - *a52 + a21*a33*a44*a52 + a24*a32*a41*a53 - a22*a34 - *a41*a53 - a24*a31*a42*a53 + a21*a34*a42*a53 + a22 - *a31*a44*a53 - a21*a32*a44*a53 - a23*a32*a41*a54 - + a22*a33*a41*a54 + a23*a31*a42*a54 - a21*a33*a42 - *a54 - a22*a31*a43*a54 + a21*a32*a43*a54; - cofactor[21] = -a14*a33*a42*a51 + a13*a34*a42*a51 + a14*a32 - *a43*a51 - a12*a34*a43*a51 - a13*a32*a44*a51 + a12 - *a33*a44*a51 + a14*a33*a41*a52 - a13*a34*a41*a52 - - a14*a31*a43*a52 + a11*a34*a43*a52 + a13*a31*a44 - *a52 - a11*a33*a44*a52 - a14*a32*a41*a53 + a12*a34 - *a41*a53 + a14*a31*a42*a53 - a11*a34*a42*a53 - a12 - *a31*a44*a53 + a11*a32*a44*a53 + a13*a32*a41*a54 - - a12*a33*a41*a54 - a13*a31*a42*a54 + a11*a33*a42 - *a54 + a12*a31*a43*a54 - a11*a32*a43*a54; - cofactor[22] = a14*a23*a42*a51 - a13*a24*a42*a51 - a14*a22 * - a43*a51 + a12*a24*a43*a51 + a13*a22*a44*a51 - a12 * - a23*a44*a51 - a14*a23*a41*a52 + a13*a24*a41*a52 - + a14*a21*a43*a52 - a11*a24*a43*a52 - a13*a21*a44 - *a52 + a11*a23*a44*a52 + a14*a22*a41*a53 - a12*a24 - *a41*a53 - a14*a21*a42*a53 + a11*a24*a42*a53 + a12 - *a21*a44*a53 - a11*a22*a44*a53 - a13*a22*a41*a54 - + a12*a23*a41*a54 + a13*a21*a42*a54 - a11*a23*a42 - *a54 - a12*a21*a43*a54 + a11*a22*a43*a54; - cofactor[23] = -a14*a23*a32*a51 + a13*a24*a32*a51 + a14*a22 - *a33*a51 - a12*a24*a33*a51 - a13*a22*a34*a51 + a12 - *a23*a34*a51 + a14*a23*a31*a52 - a13*a24*a31*a52 - - a14*a21*a33*a52 + a11*a24*a33*a52 + a13*a21*a34 - *a52 - a11*a23*a34*a52 - a14*a22*a31*a53 + a12*a24 - *a31*a53 + a14*a21*a32*a53 - a11*a24*a32*a53 - a12 - *a21*a34*a53 + a11*a22*a34*a53 + a13*a22*a31*a54 - - a12*a23*a31*a54 - a13*a21*a32*a54 + a11*a23*a32 - *a54 + a12*a21*a33*a54 - a11*a22*a33*a54; - cofactor[24] = a14*a23*a32*a41 - a13*a24*a32*a41 - a14*a22 * - a33*a41 + a12*a24*a33*a41 + a13*a22*a34*a41 - a12 * - a23*a34*a41 - a14*a23*a31*a42 + a13*a24*a31*a42 - + a14*a21*a33*a42 - a11*a24*a33*a42 - a13*a21*a34 - *a42 + a11*a23*a34*a42 + a14*a22*a31*a43 - a12*a24 - *a31*a43 - a14*a21*a32*a43 + a11*a24*a32*a43 + a12 - *a21*a34*a43 - a11*a22*a34*a43 - a13*a22*a31*a44 - + a12*a23*a31*a44 + a13*a21*a32*a44 - a11*a23*a32 - *a44 - a12*a21*a33*a44 + a11*a22*a33*a44; - - for (int i__ = 1; i__ <= 5; ++i__) - for (int j = 1; j <= 5; ++j) - ainv[j + i__*5] = cofactor[i__ + j*5 - 6] / det; - - *ok_flag__ = 0; - return 0; -} - diff --git a/SRC/matrix/routines/invGL6.c b/SRC/matrix/routines/invGL6.c deleted file mode 100644 index ef7477e39d..0000000000 --- a/SRC/matrix/routines/invGL6.c +++ /dev/null @@ -1,13385 +0,0 @@ -// -// adapted from https://caps.gsfc.nasa.gov/simpson/software/m66inv_f90.txt -// -// TODO: Do symmetric version -// -#include - -#if 0 -int cmx_inv6_v0(double *a, double *ainv, int*ok_flag__) -{ -/* **************************************************************************************** * - * m66inv - compute the inverse of a 6x6 matrix. - * - * a = input 6x6 matrix to be inverted - * ainv = output 6x6 inverse of matrix a - * ok_flag = (output) .true. if the input matrix could be inverted, - * and .false. if the input matrix is singular. - * **************************************************************************************** */ - - double cofactor[36] /* was [6][6] */; - double det; - - /* Parameter adjustments */ - ainv -= 7; - a -= 7; - - /* Function Body */ - const double eps = 1e-10; - const double a11 = a[7]; - const double a12 = a[13]; - const double a13 = a[19]; - const double a14 = a[25]; - const double a15 = a[31]; - const double a16 = a[37]; - const double a21 = a[8]; - const double a22 = a[14]; - const double a23 = a[20]; - const double a24 = a[26]; - const double a25 = a[32]; - const double a26 = a[38]; - const double a31 = a[9]; - const double a32 = a[15]; - const double a33 = a[21]; - const double a34 = a[27]; - const double a35 = a[33]; - const double a36 = a[39]; - const double a41 = a[10]; - const double a42 = a[16]; - const double a43 = a[22]; - const double a44 = a[28]; - const double a45 = a[34]; - const double a46 = a[40]; - const double a51 = a[11]; - const double a52 = a[17]; - const double a53 = a[23]; - const double a54 = a[29]; - const double a55 = a[35]; - const double a56 = a[41]; - const double a61 = a[12]; - const double a62 = a[18]; - const double a63 = a[24]; - const double a64 = a[30]; - const double a65 = a[36]; - const double a66 = a[42]; - det = -(a16 * a25 * a34 * a43 * a52 - a15 * a26 * a34 * a43 * a52 - a16 * - a24 * a35 * a43 * a52 + a14 * a26 * a35 * a43 * a52 + a15 * a24 * - a36 * a43 * a52 - a14 * a25 * a36 * a43 * a52 - a16 * a25 * a33 * - a44 * a52 + a15 * a26 * a33 * a44 * a52 + a16 * a23 * a35 * a44 * - a52 - a13 * a26 * a35 * a44 * a52 - a15 * a23 * a36 * a44 * a52 + - a13 * a25 * a36 * a44 * a52 + a16 * a24 * a33 * a45 * a52 - a14 * - a26 * a33 * a45 * a52 - a16 * a23 * a34 * a45 * a52 + a13 * a26 * - a34 * a45 * a52 + a14 * a23 * a36 * a45 * a52 - a13 * a24 * a36 * - a45 * a52 - a15 * a24 * a33 * a46 * a52 + a14 * a25 * a33 * a46 * - a52 + a15 * a23 * a34 * a46 * a52 - a13 * a25 * a34 * a46 * a52 - - a14 * a23 * a35 * a46 * a52 + a13 * a24 * a35 * a46 * a52 - a16 * - a25 * a34 * a42 * a53 + a15 * a26 * a34 * a42 * a53 + a16 * a24 * - a35 * a42 * a53 - a14 * a26 * a35 * a42 * a53 - a15 * a24 * a36 * - a42 * a53 + a14 * a25 * a36 * a42 * a53 + a16 * a25 * a32 * a44 * - a53 - a15 * a26 * a32 * a44 * a53 - a16 * a22 * a35 * a44 * a53 + - a12 * a26 * a35 * a44 * a53 + a15 * a22 * a36 * a44 * a53 - a12 * - a25 * a36 * a44 * a53 - a16 * a24 * a32 * a45 * a53 + a14 * a26 * - a32 * a45 * a53 + a16 * a22 * a34 * a45 * a53 - a12 * a26 * a34 * - a45 * a53 - a14 * a22 * a36 * a45 * a53 + a12 * a24 * a36 * a45 * - a53 + a15 * a24 * a32 * a46 * a53 - a14 * a25 * a32 * a46 * a53 - - a15 * a22 * a34 * a46 * a53 + a12 * a25 * a34 * a46 * a53 + a14 * - a22 * a35 * a46 * a53 - a12 * a24 * a35 * a46 * a53 + a16 * a25 * - a33 * a42 * a54 - a15 * a26 * a33 * a42 * a54 - a16 * a23 * a35 * - a42 * a54 + a13 * a26 * a35 * a42 * a54 + a15 * a23 * a36 * a42 * - a54 - a13 * a25 * a36 * a42 * a54 - a16 * a25 * a32 * a43 * a54 + - a15 * a26 * a32 * a43 * a54 + a16 * a22 * a35 * a43 * a54 - a12 * - a26 * a35 * a43 * a54 - a15 * a22 * a36 * a43 * a54 + a12 * a25 * - a36 * a43 * a54 + a16 * a23 * a32 * a45 * a54 - a13 * a26 * a32 * - a45 * a54 - a16 * a22 * a33 * a45 * a54 + a12 * a26 * a33 * a45 * - a54 + a13 * a22 * a36 * a45 * a54 - a12 * a23 * a36 * a45 * a54 - - a15 * a23 * a32 * a46 * a54 + a13 * a25 * a32 * a46 * a54 + a15 * - a22 * a33 * a46 * a54 - a12 * a25 * a33 * a46 * a54 - a13 * a22 * - a35 * a46 * a54 + a12 * a23 * a35 * a46 * a54 - a16 * a24 * a33 * - a42 * a55 + a14 * a26 * a33 * a42 * a55 + a16 * a23 * a34 * a42 * - a55 - a13 * a26 * a34 * a42 * a55 - a14 * a23 * a36 * a42 * a55 + - a13 * a24 * a36 * a42 * a55 + a16 * a24 * a32 * a43 * a55 - a14 * - a26 * a32 * a43 * a55 - a16 * a22 * a34 * a43 * a55 + a12 * a26 * - a34 * a43 * a55 + a14 * a22 * a36 * a43 * a55 - a12 * a24 * a36 * - a43 * a55 - a16 * a23 * a32 * a44 * a55 + a13 * a26 * a32 * a44 * - a55 + a16 * a22 * a33 * a44 * a55 - a12 * a26 * a33 * a44 * a55 - - a13 * a22 * a36 * a44 * a55 + a12 * a23 * a36 * a44 * a55 + a14 * - a23 * a32 * a46 * a55 - a13 * a24 * a32 * a46 * a55 - a14 * a22 * - a33 * a46 * a55 + a12 * a24 * a33 * a46 * a55 + a13 * a22 * a34 * - a46 * a55 - a12 * a23 * a34 * a46 * a55 + a15 * a24 * a33 * a42 * - a56 - a14 * a25 * a33 * a42 * a56 - a15 * a23 * a34 * a42 * a56 + - a13 * a25 * a34 * a42 * a56 + a14 * a23 * a35 * a42 * a56 - a13 * - a24 * a35 * a42 * a56 - a15 * a24 * a32 * a43 * a56 + a14 * a25 * - a32 * a43 * a56 + a15 * a22 * a34 * a43 * a56 - a12 * a25 * a34 * - a43 * a56 - a14 * a22 * a35 * a43 * a56 + a12 * a24 * a35 * a43 * - a56 + a15 * a23 * a32 * a44 * a56 - a13 * a25 * a32 * a44 * a56 - - a15 * a22 * a33 * a44 * a56 + a12 * a25 * a33 * a44 * a56 + a13 * - a22 * a35 * a44 * a56 - a12 * a23 * a35 * a44 * a56 - a14 * a23 * - a32 * a45 * a56 + a13 * a24 * a32 * a45 * a56 + a14 * a22 * a33 * - a45 * a56 - a12 * a24 * a33 * a45 * a56 - a13 * a22 * a34 * a45 * - a56 + a12 * a23 * a34 * a45 * a56) * a61 + (a16 * a25 * a34 * a43 - * a51 - a15 * a26 * a34 * a43 * a51 - a16 * a24 * a35 * a43 * a51 - + a14 * a26 * a35 * a43 * a51 + a15 * a24 * a36 * a43 * a51 - a14 - * a25 * a36 * a43 * a51 - a16 * a25 * a33 * a44 * a51 + a15 * a26 - * a33 * a44 * a51 + a16 * a23 * a35 * a44 * a51 - a13 * a26 * a35 - * a44 * a51 - a15 * a23 * a36 * a44 * a51 + a13 * a25 * a36 * a44 - * a51 + a16 * a24 * a33 * a45 * a51 - a14 * a26 * a33 * a45 * a51 - - a16 * a23 * a34 * a45 * a51 + a13 * a26 * a34 * a45 * a51 + a14 - * a23 * a36 * a45 * a51 - a13 * a24 * a36 * a45 * a51 - a15 * a24 - * a33 * a46 * a51 + a14 * a25 * a33 * a46 * a51 + a15 * a23 * a34 - * a46 * a51 - a13 * a25 * a34 * a46 * a51 - a14 * a23 * a35 * a46 - * a51 + a13 * a24 * a35 * a46 * a51 - a16 * a25 * a34 * a41 * a53 - + a15 * a26 * a34 * a41 * a53 + a16 * a24 * a35 * a41 * a53 - a14 - * a26 * a35 * a41 * a53 - a15 * a24 * a36 * a41 * a53 + a14 * a25 - * a36 * a41 * a53 + a16 * a25 * a31 * a44 * a53 - a15 * a26 * a31 - * a44 * a53 - a16 * a21 * a35 * a44 * a53 + a11 * a26 * a35 * a44 - * a53 + a15 * a21 * a36 * a44 * a53 - a11 * a25 * a36 * a44 * a53 - - a16 * a24 * a31 * a45 * a53 + a14 * a26 * a31 * a45 * a53 + a16 - * a21 * a34 * a45 * a53 - a11 * a26 * a34 * a45 * a53 - a14 * a21 - * a36 * a45 * a53 + a11 * a24 * a36 * a45 * a53 + a15 * a24 * a31 - * a46 * a53 - a14 * a25 * a31 * a46 * a53 - a15 * a21 * a34 * a46 - * a53 + a11 * a25 * a34 * a46 * a53 + a14 * a21 * a35 * a46 * a53 - - a11 * a24 * a35 * a46 * a53 + a16 * a25 * a33 * a41 * a54 - a15 - * a26 * a33 * a41 * a54 - a16 * a23 * a35 * a41 * a54 + a13 * a26 - * a35 * a41 * a54 + a15 * a23 * a36 * a41 * a54 - a13 * a25 * a36 - * a41 * a54 - a16 * a25 * a31 * a43 * a54 + a15 * a26 * a31 * a43 - * a54 + a16 * a21 * a35 * a43 * a54 - a11 * a26 * a35 * a43 * a54 - - a15 * a21 * a36 * a43 * a54 + a11 * a25 * a36 * a43 * a54 + a16 - * a23 * a31 * a45 * a54 - a13 * a26 * a31 * a45 * a54 - a16 * a21 - * a33 * a45 * a54 + a11 * a26 * a33 * a45 * a54 + a13 * a21 * a36 - * a45 * a54 - a11 * a23 * a36 * a45 * a54 - a15 * a23 * a31 * a46 - * a54 + a13 * a25 * a31 * a46 * a54 + a15 * a21 * a33 * a46 * a54 - - a11 * a25 * a33 * a46 * a54 - a13 * a21 * a35 * a46 * a54 + a11 - * a23 * a35 * a46 * a54 - a16 * a24 * a33 * a41 * a55 + a14 * a26 - * a33 * a41 * a55 + a16 * a23 * a34 * a41 * a55 - a13 * a26 * a34 - * a41 * a55 - a14 * a23 * a36 * a41 * a55 + a13 * a24 * a36 * a41 - * a55 + a16 * a24 * a31 * a43 * a55 - a14 * a26 * a31 * a43 * a55 - - a16 * a21 * a34 * a43 * a55 + a11 * a26 * a34 * a43 * a55 + a14 - * a21 * a36 * a43 * a55 - a11 * a24 * a36 * a43 * a55 - a16 * a23 - * a31 * a44 * a55 + a13 * a26 * a31 * a44 * a55 + a16 * a21 * a33 - * a44 * a55 - a11 * a26 * a33 * a44 * a55 - a13 * a21 * a36 * a44 - * a55 + a11 * a23 * a36 * a44 * a55 + a14 * a23 * a31 * a46 * a55 - - a13 * a24 * a31 * a46 * a55 - a14 * a21 * a33 * a46 * a55 + a11 - * a24 * a33 * a46 * a55 + a13 * a21 * a34 * a46 * a55 - a11 * a23 - * a34 * a46 * a55 + a15 * a24 * a33 * a41 * a56 - a14 * a25 * a33 - * a41 * a56 - a15 * a23 * a34 * a41 * a56 + a13 * a25 * a34 * a41 - * a56 + a14 * a23 * a35 * a41 * a56 - a13 * a24 * a35 * a41 * a56 - - a15 * a24 * a31 * a43 * a56 + a14 * a25 * a31 * a43 * a56 + a15 - * a21 * a34 * a43 * a56 - a11 * a25 * a34 * a43 * a56 - a14 * a21 - * a35 * a43 * a56 + a11 * a24 * a35 * a43 * a56 + a15 * a23 * a31 - * a44 * a56 - a13 * a25 * a31 * a44 * a56 - a15 * a21 * a33 * a44 - * a56 + a11 * a25 * a33 * a44 * a56 + a13 * a21 * a35 * a44 * a56 - - a11 * a23 * a35 * a44 * a56 - a14 * a23 * a31 * a45 * a56 + a13 - * a24 * a31 * a45 * a56 + a14 * a21 * a33 * a45 * a56 - a11 * a24 - * a33 * a45 * a56 - a13 * a21 * a34 * a45 * a56 + a11 * a23 * a34 - * a45 * a56) * a62 - (a16 * a25 * a34 * a42 * a51 - a15 * a26 * - a34 * a42 * a51 - a16 * a24 * a35 * a42 * a51 + a14 * a26 * a35 * - a42 * a51 + a15 * a24 * a36 * a42 * a51 - a14 * a25 * a36 * a42 * - a51 - a16 * a25 * a32 * a44 * a51 + a15 * a26 * a32 * a44 * a51 + - a16 * a22 * a35 * a44 * a51 - a12 * a26 * a35 * a44 * a51 - a15 * - a22 * a36 * a44 * a51 + a12 * a25 * a36 * a44 * a51 + a16 * a24 * - a32 * a45 * a51 - a14 * a26 * a32 * a45 * a51 - a16 * a22 * a34 * - a45 * a51 + a12 * a26 * a34 * a45 * a51 + a14 * a22 * a36 * a45 * - a51 - a12 * a24 * a36 * a45 * a51 - a15 * a24 * a32 * a46 * a51 + - a14 * a25 * a32 * a46 * a51 + a15 * a22 * a34 * a46 * a51 - a12 * - a25 * a34 * a46 * a51 - a14 * a22 * a35 * a46 * a51 + a12 * a24 * - a35 * a46 * a51 - a16 * a25 * a34 * a41 * a52 + a15 * a26 * a34 * - a41 * a52 + a16 * a24 * a35 * a41 * a52 - a14 * a26 * a35 * a41 * - a52 - a15 * a24 * a36 * a41 * a52 + a14 * a25 * a36 * a41 * a52 + - a16 * a25 * a31 * a44 * a52 - a15 * a26 * a31 * a44 * a52 - a16 * - a21 * a35 * a44 * a52 + a11 * a26 * a35 * a44 * a52 + a15 * a21 * - a36 * a44 * a52 - a11 * a25 * a36 * a44 * a52 - a16 * a24 * a31 * - a45 * a52 + a14 * a26 * a31 * a45 * a52 + a16 * a21 * a34 * a45 * - a52 - a11 * a26 * a34 * a45 * a52 - a14 * a21 * a36 * a45 * a52 + - a11 * a24 * a36 * a45 * a52 + a15 * a24 * a31 * a46 * a52 - a14 * - a25 * a31 * a46 * a52 - a15 * a21 * a34 * a46 * a52 + a11 * a25 * - a34 * a46 * a52 + a14 * a21 * a35 * a46 * a52 - a11 * a24 * a35 * - a46 * a52 + a16 * a25 * a32 * a41 * a54 - a15 * a26 * a32 * a41 * - a54 - a16 * a22 * a35 * a41 * a54 + a12 * a26 * a35 * a41 * a54 + - a15 * a22 * a36 * a41 * a54 - a12 * a25 * a36 * a41 * a54 - a16 * - a25 * a31 * a42 * a54 + a15 * a26 * a31 * a42 * a54 + a16 * a21 * - a35 * a42 * a54 - a11 * a26 * a35 * a42 * a54 - a15 * a21 * a36 * - a42 * a54 + a11 * a25 * a36 * a42 * a54 + a16 * a22 * a31 * a45 * - a54 - a12 * a26 * a31 * a45 * a54 - a16 * a21 * a32 * a45 * a54 + - a11 * a26 * a32 * a45 * a54 + a12 * a21 * a36 * a45 * a54 - a11 * - a22 * a36 * a45 * a54 - a15 * a22 * a31 * a46 * a54 + a12 * a25 * - a31 * a46 * a54 + a15 * a21 * a32 * a46 * a54 - a11 * a25 * a32 * - a46 * a54 - a12 * a21 * a35 * a46 * a54 + a11 * a22 * a35 * a46 * - a54 - a16 * a24 * a32 * a41 * a55 + a14 * a26 * a32 * a41 * a55 + - a16 * a22 * a34 * a41 * a55 - a12 * a26 * a34 * a41 * a55 - a14 * - a22 * a36 * a41 * a55 + a12 * a24 * a36 * a41 * a55 + a16 * a24 * - a31 * a42 * a55 - a14 * a26 * a31 * a42 * a55 - a16 * a21 * a34 * - a42 * a55 + a11 * a26 * a34 * a42 * a55 + a14 * a21 * a36 * a42 * - a55 - a11 * a24 * a36 * a42 * a55 - a16 * a22 * a31 * a44 * a55 + - a12 * a26 * a31 * a44 * a55 + a16 * a21 * a32 * a44 * a55 - a11 * - a26 * a32 * a44 * a55 - a12 * a21 * a36 * a44 * a55 + a11 * a22 * - a36 * a44 * a55 + a14 * a22 * a31 * a46 * a55 - a12 * a24 * a31 * - a46 * a55 - a14 * a21 * a32 * a46 * a55 + a11 * a24 * a32 * a46 * - a55 + a12 * a21 * a34 * a46 * a55 - a11 * a22 * a34 * a46 * a55 + - a15 * a24 * a32 * a41 * a56 - a14 * a25 * a32 * a41 * a56 - a15 * - a22 * a34 * a41 * a56 + a12 * a25 * a34 * a41 * a56 + a14 * a22 * - a35 * a41 * a56 - a12 * a24 * a35 * a41 * a56 - a15 * a24 * a31 * - a42 * a56 + a14 * a25 * a31 * a42 * a56 + a15 * a21 * a34 * a42 * - a56 - a11 * a25 * a34 * a42 * a56 - a14 * a21 * a35 * a42 * a56 + - a11 * a24 * a35 * a42 * a56 + a15 * a22 * a31 * a44 * a56 - a12 * - a25 * a31 * a44 * a56 - a15 * a21 * a32 * a44 * a56 + a11 * a25 * - a32 * a44 * a56 + a12 * a21 * a35 * a44 * a56 - a11 * a22 * a35 * - a44 * a56 - a14 * a22 * a31 * a45 * a56 + a12 * a24 * a31 * a45 * - a56 + a14 * a21 * a32 * a45 * a56 - a11 * a24 * a32 * a45 * a56 - - a12 * a21 * a34 * a45 * a56 + a11 * a22 * a34 * a45 * a56) * a63 - + (a16 * a25 * a33 * a42 * a51 - a15 * a26 * a33 * a42 * a51 - - a16 * a23 * a35 * a42 * a51 + a13 * a26 * a35 * a42 * a51 + a15 * - a23 * a36 * a42 * a51 - a13 * a25 * a36 * a42 * a51 - a16 * a25 * - a32 * a43 * a51 + a15 * a26 * a32 * a43 * a51 + a16 * a22 * a35 * - a43 * a51 - a12 * a26 * a35 * a43 * a51 - a15 * a22 * a36 * a43 * - a51 + a12 * a25 * a36 * a43 * a51 + a16 * a23 * a32 * a45 * a51 - - a13 * a26 * a32 * a45 * a51 - a16 * a22 * a33 * a45 * a51 + a12 * - a26 * a33 * a45 * a51 + a13 * a22 * a36 * a45 * a51 - a12 * a23 * - a36 * a45 * a51 - a15 * a23 * a32 * a46 * a51 + a13 * a25 * a32 * - a46 * a51 + a15 * a22 * a33 * a46 * a51 - a12 * a25 * a33 * a46 * - a51 - a13 * a22 * a35 * a46 * a51 + a12 * a23 * a35 * a46 * a51 - - a16 * a25 * a33 * a41 * a52 + a15 * a26 * a33 * a41 * a52 + a16 * - a23 * a35 * a41 * a52 - a13 * a26 * a35 * a41 * a52 - a15 * a23 * - a36 * a41 * a52 + a13 * a25 * a36 * a41 * a52 + a16 * a25 * a31 * - a43 * a52 - a15 * a26 * a31 * a43 * a52 - a16 * a21 * a35 * a43 * - a52 + a11 * a26 * a35 * a43 * a52 + a15 * a21 * a36 * a43 * a52 - - a11 * a25 * a36 * a43 * a52 - a16 * a23 * a31 * a45 * a52 + a13 * - a26 * a31 * a45 * a52 + a16 * a21 * a33 * a45 * a52 - a11 * a26 * - a33 * a45 * a52 - a13 * a21 * a36 * a45 * a52 + a11 * a23 * a36 * - a45 * a52 + a15 * a23 * a31 * a46 * a52 - a13 * a25 * a31 * a46 * - a52 - a15 * a21 * a33 * a46 * a52 + a11 * a25 * a33 * a46 * a52 + - a13 * a21 * a35 * a46 * a52 - a11 * a23 * a35 * a46 * a52 + a16 * - a25 * a32 * a41 * a53 - a15 * a26 * a32 * a41 * a53 - a16 * a22 * - a35 * a41 * a53 + a12 * a26 * a35 * a41 * a53 + a15 * a22 * a36 * - a41 * a53 - a12 * a25 * a36 * a41 * a53 - a16 * a25 * a31 * a42 * - a53 + a15 * a26 * a31 * a42 * a53 + a16 * a21 * a35 * a42 * a53 - - a11 * a26 * a35 * a42 * a53 - a15 * a21 * a36 * a42 * a53 + a11 * - a25 * a36 * a42 * a53 + a16 * a22 * a31 * a45 * a53 - a12 * a26 * - a31 * a45 * a53 - a16 * a21 * a32 * a45 * a53 + a11 * a26 * a32 * - a45 * a53 + a12 * a21 * a36 * a45 * a53 - a11 * a22 * a36 * a45 * - a53 - a15 * a22 * a31 * a46 * a53 + a12 * a25 * a31 * a46 * a53 + - a15 * a21 * a32 * a46 * a53 - a11 * a25 * a32 * a46 * a53 - a12 * - a21 * a35 * a46 * a53 + a11 * a22 * a35 * a46 * a53 - a16 * a23 * - a32 * a41 * a55 + a13 * a26 * a32 * a41 * a55 + a16 * a22 * a33 * - a41 * a55 - a12 * a26 * a33 * a41 * a55 - a13 * a22 * a36 * a41 * - a55 + a12 * a23 * a36 * a41 * a55 + a16 * a23 * a31 * a42 * a55 - - a13 * a26 * a31 * a42 * a55 - a16 * a21 * a33 * a42 * a55 + a11 * - a26 * a33 * a42 * a55 + a13 * a21 * a36 * a42 * a55 - a11 * a23 * - a36 * a42 * a55 - a16 * a22 * a31 * a43 * a55 + a12 * a26 * a31 * - a43 * a55 + a16 * a21 * a32 * a43 * a55 - a11 * a26 * a32 * a43 * - a55 - a12 * a21 * a36 * a43 * a55 + a11 * a22 * a36 * a43 * a55 + - a13 * a22 * a31 * a46 * a55 - a12 * a23 * a31 * a46 * a55 - a13 * - a21 * a32 * a46 * a55 + a11 * a23 * a32 * a46 * a55 + a12 * a21 * - a33 * a46 * a55 - a11 * a22 * a33 * a46 * a55 + a15 * a23 * a32 * - a41 * a56 - a13 * a25 * a32 * a41 * a56 - a15 * a22 * a33 * a41 * - a56 + a12 * a25 * a33 * a41 * a56 + a13 * a22 * a35 * a41 * a56 - - a12 * a23 * a35 * a41 * a56 - a15 * a23 * a31 * a42 * a56 + a13 * - a25 * a31 * a42 * a56 + a15 * a21 * a33 * a42 * a56 - a11 * a25 * - a33 * a42 * a56 - a13 * a21 * a35 * a42 * a56 + a11 * a23 * a35 * - a42 * a56 + a15 * a22 * a31 * a43 * a56 - a12 * a25 * a31 * a43 * - a56 - a15 * a21 * a32 * a43 * a56 + a11 * a25 * a32 * a43 * a56 + - a12 * a21 * a35 * a43 * a56 - a11 * a22 * a35 * a43 * a56 - a13 * - a22 * a31 * a45 * a56 + a12 * a23 * a31 * a45 * a56 + a13 * a21 * - a32 * a45 * a56 - a11 * a23 * a32 * a45 * a56 - a12 * a21 * a33 * - a45 * a56 + a11 * a22 * a33 * a45 * a56) * a64 - (a16 * a24 * a33 - * a42 * a51 - a14 * a26 * a33 * a42 * a51 - a16 * a23 * a34 * a42 - * a51 + a13 * a26 * a34 * a42 * a51 + a14 * a23 * a36 * a42 * a51 - - a13 * a24 * a36 * a42 * a51 - a16 * a24 * a32 * a43 * a51 + a14 - * a26 * a32 * a43 * a51 + a16 * a22 * a34 * a43 * a51 - a12 * a26 - * a34 * a43 * a51 - a14 * a22 * a36 * a43 * a51 + a12 * a24 * a36 - * a43 * a51 + a16 * a23 * a32 * a44 * a51 - a13 * a26 * a32 * a44 - * a51 - a16 * a22 * a33 * a44 * a51 + a12 * a26 * a33 * a44 * a51 - + a13 * a22 * a36 * a44 * a51 - a12 * a23 * a36 * a44 * a51 - a14 - * a23 * a32 * a46 * a51 + a13 * a24 * a32 * a46 * a51 + a14 * a22 - * a33 * a46 * a51 - a12 * a24 * a33 * a46 * a51 - a13 * a22 * a34 - * a46 * a51 + a12 * a23 * a34 * a46 * a51 - a16 * a24 * a33 * a41 - * a52 + a14 * a26 * a33 * a41 * a52 + a16 * a23 * a34 * a41 * a52 - - a13 * a26 * a34 * a41 * a52 - a14 * a23 * a36 * a41 * a52 + a13 - * a24 * a36 * a41 * a52 + a16 * a24 * a31 * a43 * a52 - a14 * a26 - * a31 * a43 * a52 - a16 * a21 * a34 * a43 * a52 + a11 * a26 * a34 - * a43 * a52 + a14 * a21 * a36 * a43 * a52 - a11 * a24 * a36 * a43 - * a52 - a16 * a23 * a31 * a44 * a52 + a13 * a26 * a31 * a44 * a52 - + a16 * a21 * a33 * a44 * a52 - a11 * a26 * a33 * a44 * a52 - a13 - * a21 * a36 * a44 * a52 + a11 * a23 * a36 * a44 * a52 + a14 * a23 - * a31 * a46 * a52 - a13 * a24 * a31 * a46 * a52 - a14 * a21 * a33 - * a46 * a52 + a11 * a24 * a33 * a46 * a52 + a13 * a21 * a34 * a46 - * a52 - a11 * a23 * a34 * a46 * a52 + a16 * a24 * a32 * a41 * a53 - - a14 * a26 * a32 * a41 * a53 - a16 * a22 * a34 * a41 * a53 + a12 - * a26 * a34 * a41 * a53 + a14 * a22 * a36 * a41 * a53 - a12 * a24 - * a36 * a41 * a53 - a16 * a24 * a31 * a42 * a53 + a14 * a26 * a31 - * a42 * a53 + a16 * a21 * a34 * a42 * a53 - a11 * a26 * a34 * a42 - * a53 - a14 * a21 * a36 * a42 * a53 + a11 * a24 * a36 * a42 * a53 - + a16 * a22 * a31 * a44 * a53 - a12 * a26 * a31 * a44 * a53 - a16 - * a21 * a32 * a44 * a53 + a11 * a26 * a32 * a44 * a53 + a12 * a21 - * a36 * a44 * a53 - a11 * a22 * a36 * a44 * a53 - a14 * a22 * a31 - * a46 * a53 + a12 * a24 * a31 * a46 * a53 + a14 * a21 * a32 * a46 - * a53 - a11 * a24 * a32 * a46 * a53 - a12 * a21 * a34 * a46 * a53 - + a11 * a22 * a34 * a46 * a53 - a16 * a23 * a32 * a41 * a54 + a13 - * a26 * a32 * a41 * a54 + a16 * a22 * a33 * a41 * a54 - a12 * a26 - * a33 * a41 * a54 - a13 * a22 * a36 * a41 * a54 + a12 * a23 * a36 - * a41 * a54 + a16 * a23 * a31 * a42 * a54 - a13 * a26 * a31 * a42 - * a54 - a16 * a21 * a33 * a42 * a54 + a11 * a26 * a33 * a42 * a54 - + a13 * a21 * a36 * a42 * a54 - a11 * a23 * a36 * a42 * a54 - a16 - * a22 * a31 * a43 * a54 + a12 * a26 * a31 * a43 * a54 + a16 * a21 - * a32 * a43 * a54 - a11 * a26 * a32 * a43 * a54 - a12 * a21 * a36 - * a43 * a54 + a11 * a22 * a36 * a43 * a54 + a13 * a22 * a31 * a46 - * a54 - a12 * a23 * a31 * a46 * a54 - a13 * a21 * a32 * a46 * a54 - + a11 * a23 * a32 * a46 * a54 + a12 * a21 * a33 * a46 * a54 - a11 - * a22 * a33 * a46 * a54 + a14 * a23 * a32 * a41 * a56 - a13 * a24 - * a32 * a41 * a56 - a14 * a22 * a33 * a41 * a56 + a12 * a24 * a33 - * a41 * a56 + a13 * a22 * a34 * a41 * a56 - a12 * a23 * a34 * a41 - * a56 - a14 * a23 * a31 * a42 * a56 + a13 * a24 * a31 * a42 * a56 - + a14 * a21 * a33 * a42 * a56 - a11 * a24 * a33 * a42 * a56 - a13 - * a21 * a34 * a42 * a56 + a11 * a23 * a34 * a42 * a56 + a14 * a22 - * a31 * a43 * a56 - a12 * a24 * a31 * a43 * a56 - a14 * a21 * a32 - * a43 * a56 + a11 * a24 * a32 * a43 * a56 + a12 * a21 * a34 * a43 - * a56 - a11 * a22 * a34 * a43 * a56 - a13 * a22 * a31 * a44 * a56 - + a12 * a23 * a31 * a44 * a56 + a13 * a21 * a32 * a44 * a56 - a11 - * a23 * a32 * a44 * a56 - a12 * a21 * a33 * a44 * a56 + a11 * a22 - * a33 * a44 * a56) * a65 + (a15 * a24 * a33 * a42 * a51 - a14 * - a25 * a33 * a42 * a51 - a15 * a23 * a34 * a42 * a51 + a13 * a25 * - a34 * a42 * a51 + a14 * a23 * a35 * a42 * a51 - a13 * a24 * a35 * - a42 * a51 - a15 * a24 * a32 * a43 * a51 + a14 * a25 * a32 * a43 * - a51 + a15 * a22 * a34 * a43 * a51 - a12 * a25 * a34 * a43 * a51 - - a14 * a22 * a35 * a43 * a51 + a12 * a24 * a35 * a43 * a51 + a15 * - a23 * a32 * a44 * a51 - a13 * a25 * a32 * a44 * a51 - a15 * a22 * - a33 * a44 * a51 + a12 * a25 * a33 * a44 * a51 + a13 * a22 * a35 * - a44 * a51 - a12 * a23 * a35 * a44 * a51 - a14 * a23 * a32 * a45 * - a51 + a13 * a24 * a32 * a45 * a51 + a14 * a22 * a33 * a45 * a51 - - a12 * a24 * a33 * a45 * a51 - a13 * a22 * a34 * a45 * a51 + a12 * - a23 * a34 * a45 * a51 - a15 * a24 * a33 * a41 * a52 + a14 * a25 * - a33 * a41 * a52 + a15 * a23 * a34 * a41 * a52 - a13 * a25 * a34 * - a41 * a52 - a14 * a23 * a35 * a41 * a52 + a13 * a24 * a35 * a41 * - a52 + a15 * a24 * a31 * a43 * a52 - a14 * a25 * a31 * a43 * a52 - - a15 * a21 * a34 * a43 * a52 + a11 * a25 * a34 * a43 * a52 + a14 * - a21 * a35 * a43 * a52 - a11 * a24 * a35 * a43 * a52 - a15 * a23 * - a31 * a44 * a52 + a13 * a25 * a31 * a44 * a52 + a15 * a21 * a33 * - a44 * a52 - a11 * a25 * a33 * a44 * a52 - a13 * a21 * a35 * a44 * - a52 + a11 * a23 * a35 * a44 * a52 + a14 * a23 * a31 * a45 * a52 - - a13 * a24 * a31 * a45 * a52 - a14 * a21 * a33 * a45 * a52 + a11 * - a24 * a33 * a45 * a52 + a13 * a21 * a34 * a45 * a52 - a11 * a23 * - a34 * a45 * a52 + a15 * a24 * a32 * a41 * a53 - a14 * a25 * a32 * - a41 * a53 - a15 * a22 * a34 * a41 * a53 + a12 * a25 * a34 * a41 * - a53 + a14 * a22 * a35 * a41 * a53 - a12 * a24 * a35 * a41 * a53 - - a15 * a24 * a31 * a42 * a53 + a14 * a25 * a31 * a42 * a53 + a15 * - a21 * a34 * a42 * a53 - a11 * a25 * a34 * a42 * a53 - a14 * a21 * - a35 * a42 * a53 + a11 * a24 * a35 * a42 * a53 + a15 * a22 * a31 * - a44 * a53 - a12 * a25 * a31 * a44 * a53 - a15 * a21 * a32 * a44 * - a53 + a11 * a25 * a32 * a44 * a53 + a12 * a21 * a35 * a44 * a53 - - a11 * a22 * a35 * a44 * a53 - a14 * a22 * a31 * a45 * a53 + a12 * - a24 * a31 * a45 * a53 + a14 * a21 * a32 * a45 * a53 - a11 * a24 * - a32 * a45 * a53 - a12 * a21 * a34 * a45 * a53 + a11 * a22 * a34 * - a45 * a53 - a15 * a23 * a32 * a41 * a54 + a13 * a25 * a32 * a41 * - a54 + a15 * a22 * a33 * a41 * a54 - a12 * a25 * a33 * a41 * a54 - - a13 * a22 * a35 * a41 * a54 + a12 * a23 * a35 * a41 * a54 + a15 * - a23 * a31 * a42 * a54 - a13 * a25 * a31 * a42 * a54 - a15 * a21 * - a33 * a42 * a54 + a11 * a25 * a33 * a42 * a54 + a13 * a21 * a35 * - a42 * a54 - a11 * a23 * a35 * a42 * a54 - a15 * a22 * a31 * a43 * - a54 + a12 * a25 * a31 * a43 * a54 + a15 * a21 * a32 * a43 * a54 - - a11 * a25 * a32 * a43 * a54 - a12 * a21 * a35 * a43 * a54 + a11 * - a22 * a35 * a43 * a54 + a13 * a22 * a31 * a45 * a54 - a12 * a23 * - a31 * a45 * a54 - a13 * a21 * a32 * a45 * a54 + a11 * a23 * a32 * - a45 * a54 + a12 * a21 * a33 * a45 * a54 - a11 * a22 * a33 * a45 * - a54 + a14 * a23 * a32 * a41 * a55 - a13 * a24 * a32 * a41 * a55 - - a14 * a22 * a33 * a41 * a55 + a12 * a24 * a33 * a41 * a55 + a13 * - a22 * a34 * a41 * a55 - a12 * a23 * a34 * a41 * a55 - a14 * a23 * - a31 * a42 * a55 + a13 * a24 * a31 * a42 * a55 + a14 * a21 * a33 * - a42 * a55 - a11 * a24 * a33 * a42 * a55 - a13 * a21 * a34 * a42 * - a55 + a11 * a23 * a34 * a42 * a55 + a14 * a22 * a31 * a43 * a55 - - a12 * a24 * a31 * a43 * a55 - a14 * a21 * a32 * a43 * a55 + a11 * - a24 * a32 * a43 * a55 + a12 * a21 * a34 * a43 * a55 - a11 * a22 * - a34 * a43 * a55 - a13 * a22 * a31 * a44 * a55 + a12 * a23 * a31 * - a44 * a55 + a13 * a21 * a32 * a44 * a55 - a11 * a23 * a32 * a44 * - a55 - a12 * a21 * a33 * a44 * a55 + a11 * a22 * a33 * a44 * a55) * - a66; - - if (fabs(det) <= eps) { -/* ainv = 0.0d0 */ - *ok_flag__ = -1; - return 0; - } - cofactor[0] = a26 * a35 * a44 * a53 * a62 - a25 * a36 * a44 * a53 * a62 - - a26 * a34 * a45 * a53 * a62 + a24 * a36 * a45 * a53 * a62 + a25 * - a34 * a46 * a53 * a62 - a24 * a35 * a46 * a53 * a62 - a26 * a35 * - a43 * a54 * a62 + a25 * a36 * a43 * a54 * a62 + a26 * a33 * a45 * - a54 * a62 - a23 * a36 * a45 * a54 * a62 - a25 * a33 * a46 * a54 * - a62 + a23 * a35 * a46 * a54 * a62 + a26 * a34 * a43 * a55 * a62 - - a24 * a36 * a43 * a55 * a62 - a26 * a33 * a44 * a55 * a62 + a23 * - a36 * a44 * a55 * a62 + a24 * a33 * a46 * a55 * a62 - a23 * a34 * - a46 * a55 * a62 - a25 * a34 * a43 * a56 * a62 + a24 * a35 * a43 * - a56 * a62 + a25 * a33 * a44 * a56 * a62 - a23 * a35 * a44 * a56 * - a62 - a24 * a33 * a45 * a56 * a62 + a23 * a34 * a45 * a56 * a62 - - a26 * a35 * a44 * a52 * a63 + a25 * a36 * a44 * a52 * a63 + a26 * - a34 * a45 * a52 * a63 - a24 * a36 * a45 * a52 * a63 - a25 * a34 * - a46 * a52 * a63 + a24 * a35 * a46 * a52 * a63 + a26 * a35 * a42 * - a54 * a63 - a25 * a36 * a42 * a54 * a63 - a26 * a32 * a45 * a54 * - a63 + a22 * a36 * a45 * a54 * a63 + a25 * a32 * a46 * a54 * a63 - - a22 * a35 * a46 * a54 * a63 - a26 * a34 * a42 * a55 * a63 + a24 * - a36 * a42 * a55 * a63 + a26 * a32 * a44 * a55 * a63 - a22 * a36 * - a44 * a55 * a63 - a24 * a32 * a46 * a55 * a63 + a22 * a34 * a46 * - a55 * a63 + a25 * a34 * a42 * a56 * a63 - a24 * a35 * a42 * a56 * - a63 - a25 * a32 * a44 * a56 * a63 + a22 * a35 * a44 * a56 * a63 + - a24 * a32 * a45 * a56 * a63 - a22 * a34 * a45 * a56 * a63 + a26 * - a35 * a43 * a52 * a64 - a25 * a36 * a43 * a52 * a64 - a26 * a33 * - a45 * a52 * a64 + a23 * a36 * a45 * a52 * a64 + a25 * a33 * a46 * - a52 * a64 - a23 * a35 * a46 * a52 * a64 - a26 * a35 * a42 * a53 * - a64 + a25 * a36 * a42 * a53 * a64 + a26 * a32 * a45 * a53 * a64 - - a22 * a36 * a45 * a53 * a64 - a25 * a32 * a46 * a53 * a64 + a22 * - a35 * a46 * a53 * a64 + a26 * a33 * a42 * a55 * a64 - a23 * a36 * - a42 * a55 * a64 - a26 * a32 * a43 * a55 * a64 + a22 * a36 * a43 * - a55 * a64 + a23 * a32 * a46 * a55 * a64 - a22 * a33 * a46 * a55 * - a64 - a25 * a33 * a42 * a56 * a64 + a23 * a35 * a42 * a56 * a64 + - a25 * a32 * a43 * a56 * a64 - a22 * a35 * a43 * a56 * a64 - a23 * - a32 * a45 * a56 * a64 + a22 * a33 * a45 * a56 * a64 - a26 * a34 * - a43 * a52 * a65 + a24 * a36 * a43 * a52 * a65 + a26 * a33 * a44 * - a52 * a65 - a23 * a36 * a44 * a52 * a65 - a24 * a33 * a46 * a52 * - a65 + a23 * a34 * a46 * a52 * a65 + a26 * a34 * a42 * a53 * a65 - - a24 * a36 * a42 * a53 * a65 - a26 * a32 * a44 * a53 * a65 + a22 * - a36 * a44 * a53 * a65 + a24 * a32 * a46 * a53 * a65 - a22 * a34 * - a46 * a53 * a65 - a26 * a33 * a42 * a54 * a65 + a23 * a36 * a42 * - a54 * a65 + a26 * a32 * a43 * a54 * a65 - a22 * a36 * a43 * a54 * - a65 - a23 * a32 * a46 * a54 * a65 + a22 * a33 * a46 * a54 * a65 + - a24 * a33 * a42 * a56 * a65 - a23 * a34 * a42 * a56 * a65 - a24 * - a32 * a43 * a56 * a65 + a22 * a34 * a43 * a56 * a65 + a23 * a32 * - a44 * a56 * a65 - a22 * a33 * a44 * a56 * a65 + a25 * a34 * a43 * - a52 * a66 - a24 * a35 * a43 * a52 * a66 - a25 * a33 * a44 * a52 * - a66 + a23 * a35 * a44 * a52 * a66 + a24 * a33 * a45 * a52 * a66 - - a23 * a34 * a45 * a52 * a66 - a25 * a34 * a42 * a53 * a66 + a24 * - a35 * a42 * a53 * a66 + a25 * a32 * a44 * a53 * a66 - a22 * a35 * - a44 * a53 * a66 - a24 * a32 * a45 * a53 * a66 + a22 * a34 * a45 * - a53 * a66 + a25 * a33 * a42 * a54 * a66 - a23 * a35 * a42 * a54 * - a66 - a25 * a32 * a43 * a54 * a66 + a22 * a35 * a43 * a54 * a66 + - a23 * a32 * a45 * a54 * a66 - a22 * a33 * a45 * a54 * a66 - a24 * - a33 * a42 * a55 * a66 + a23 * a34 * a42 * a55 * a66 + a24 * a32 * - a43 * a55 * a66 - a22 * a34 * a43 * a55 * a66 - a23 * a32 * a44 * - a55 * a66 + a22 * a33 * a44 * a55 * a66; - cofactor[1] = -a16 * a35 * a44 * a53 * a62 + a15 * a36 * a44 * a53 * a62 - + a16 * a34 * a45 * a53 * a62 - a14 * a36 * a45 * a53 * a62 - a15 - * a34 * a46 * a53 * a62 + a14 * a35 * a46 * a53 * a62 + a16 * a35 - * a43 * a54 * a62 - a15 * a36 * a43 * a54 * a62 - a16 * a33 * a45 - * a54 * a62 + a13 * a36 * a45 * a54 * a62 + a15 * a33 * a46 * a54 - * a62 - a13 * a35 * a46 * a54 * a62 - a16 * a34 * a43 * a55 * a62 - + a14 * a36 * a43 * a55 * a62 + a16 * a33 * a44 * a55 * a62 - a13 - * a36 * a44 * a55 * a62 - a14 * a33 * a46 * a55 * a62 + a13 * a34 - * a46 * a55 * a62 + a15 * a34 * a43 * a56 * a62 - a14 * a35 * a43 - * a56 * a62 - a15 * a33 * a44 * a56 * a62 + a13 * a35 * a44 * a56 - * a62 + a14 * a33 * a45 * a56 * a62 - a13 * a34 * a45 * a56 * a62 - + a16 * a35 * a44 * a52 * a63 - a15 * a36 * a44 * a52 * a63 - a16 - * a34 * a45 * a52 * a63 + a14 * a36 * a45 * a52 * a63 + a15 * a34 - * a46 * a52 * a63 - a14 * a35 * a46 * a52 * a63 - a16 * a35 * a42 - * a54 * a63 + a15 * a36 * a42 * a54 * a63 + a16 * a32 * a45 * a54 - * a63 - a12 * a36 * a45 * a54 * a63 - a15 * a32 * a46 * a54 * a63 - + a12 * a35 * a46 * a54 * a63 + a16 * a34 * a42 * a55 * a63 - a14 - * a36 * a42 * a55 * a63 - a16 * a32 * a44 * a55 * a63 + a12 * a36 - * a44 * a55 * a63 + a14 * a32 * a46 * a55 * a63 - a12 * a34 * a46 - * a55 * a63 - a15 * a34 * a42 * a56 * a63 + a14 * a35 * a42 * a56 - * a63 + a15 * a32 * a44 * a56 * a63 - a12 * a35 * a44 * a56 * a63 - - a14 * a32 * a45 * a56 * a63 + a12 * a34 * a45 * a56 * a63 - a16 - * a35 * a43 * a52 * a64 + a15 * a36 * a43 * a52 * a64 + a16 * a33 - * a45 * a52 * a64 - a13 * a36 * a45 * a52 * a64 - a15 * a33 * a46 - * a52 * a64 + a13 * a35 * a46 * a52 * a64 + a16 * a35 * a42 * a53 - * a64 - a15 * a36 * a42 * a53 * a64 - a16 * a32 * a45 * a53 * a64 - + a12 * a36 * a45 * a53 * a64 + a15 * a32 * a46 * a53 * a64 - a12 - * a35 * a46 * a53 * a64 - a16 * a33 * a42 * a55 * a64 + a13 * a36 - * a42 * a55 * a64 + a16 * a32 * a43 * a55 * a64 - a12 * a36 * a43 - * a55 * a64 - a13 * a32 * a46 * a55 * a64 + a12 * a33 * a46 * a55 - * a64 + a15 * a33 * a42 * a56 * a64 - a13 * a35 * a42 * a56 * a64 - - a15 * a32 * a43 * a56 * a64 + a12 * a35 * a43 * a56 * a64 + a13 - * a32 * a45 * a56 * a64 - a12 * a33 * a45 * a56 * a64 + a16 * a34 - * a43 * a52 * a65 - a14 * a36 * a43 * a52 * a65 - a16 * a33 * a44 - * a52 * a65 + a13 * a36 * a44 * a52 * a65 + a14 * a33 * a46 * a52 - * a65 - a13 * a34 * a46 * a52 * a65 - a16 * a34 * a42 * a53 * a65 - + a14 * a36 * a42 * a53 * a65 + a16 * a32 * a44 * a53 * a65 - a12 - * a36 * a44 * a53 * a65 - a14 * a32 * a46 * a53 * a65 + a12 * a34 - * a46 * a53 * a65 + a16 * a33 * a42 * a54 * a65 - a13 * a36 * a42 - * a54 * a65 - a16 * a32 * a43 * a54 * a65 + a12 * a36 * a43 * a54 - * a65 + a13 * a32 * a46 * a54 * a65 - a12 * a33 * a46 * a54 * a65 - - a14 * a33 * a42 * a56 * a65 + a13 * a34 * a42 * a56 * a65 + a14 - * a32 * a43 * a56 * a65 - a12 * a34 * a43 * a56 * a65 - a13 * a32 - * a44 * a56 * a65 + a12 * a33 * a44 * a56 * a65 - a15 * a34 * a43 - * a52 * a66 + a14 * a35 * a43 * a52 * a66 + a15 * a33 * a44 * a52 - * a66 - a13 * a35 * a44 * a52 * a66 - a14 * a33 * a45 * a52 * a66 - + a13 * a34 * a45 * a52 * a66 + a15 * a34 * a42 * a53 * a66 - a14 - * a35 * a42 * a53 * a66 - a15 * a32 * a44 * a53 * a66 + a12 * a35 - * a44 * a53 * a66 + a14 * a32 * a45 * a53 * a66 - a12 * a34 * a45 - * a53 * a66 - a15 * a33 * a42 * a54 * a66 + a13 * a35 * a42 * a54 - * a66 + a15 * a32 * a43 * a54 * a66 - a12 * a35 * a43 * a54 * a66 - - a13 * a32 * a45 * a54 * a66 + a12 * a33 * a45 * a54 * a66 + a14 - * a33 * a42 * a55 * a66 - a13 * a34 * a42 * a55 * a66 - a14 * a32 - * a43 * a55 * a66 + a12 * a34 * a43 * a55 * a66 + a13 * a32 * a44 - * a55 * a66 - a12 * a33 * a44 * a55 * a66; - cofactor[2] = a16 * a25 * a44 * a53 * a62 - a15 * a26 * a44 * a53 * a62 - - a16 * a24 * a45 * a53 * a62 + a14 * a26 * a45 * a53 * a62 + a15 * - a24 * a46 * a53 * a62 - a14 * a25 * a46 * a53 * a62 - a16 * a25 * - a43 * a54 * a62 + a15 * a26 * a43 * a54 * a62 + a16 * a23 * a45 * - a54 * a62 - a13 * a26 * a45 * a54 * a62 - a15 * a23 * a46 * a54 * - a62 + a13 * a25 * a46 * a54 * a62 + a16 * a24 * a43 * a55 * a62 - - a14 * a26 * a43 * a55 * a62 - a16 * a23 * a44 * a55 * a62 + a13 * - a26 * a44 * a55 * a62 + a14 * a23 * a46 * a55 * a62 - a13 * a24 * - a46 * a55 * a62 - a15 * a24 * a43 * a56 * a62 + a14 * a25 * a43 * - a56 * a62 + a15 * a23 * a44 * a56 * a62 - a13 * a25 * a44 * a56 * - a62 - a14 * a23 * a45 * a56 * a62 + a13 * a24 * a45 * a56 * a62 - - a16 * a25 * a44 * a52 * a63 + a15 * a26 * a44 * a52 * a63 + a16 * - a24 * a45 * a52 * a63 - a14 * a26 * a45 * a52 * a63 - a15 * a24 * - a46 * a52 * a63 + a14 * a25 * a46 * a52 * a63 + a16 * a25 * a42 * - a54 * a63 - a15 * a26 * a42 * a54 * a63 - a16 * a22 * a45 * a54 * - a63 + a12 * a26 * a45 * a54 * a63 + a15 * a22 * a46 * a54 * a63 - - a12 * a25 * a46 * a54 * a63 - a16 * a24 * a42 * a55 * a63 + a14 * - a26 * a42 * a55 * a63 + a16 * a22 * a44 * a55 * a63 - a12 * a26 * - a44 * a55 * a63 - a14 * a22 * a46 * a55 * a63 + a12 * a24 * a46 * - a55 * a63 + a15 * a24 * a42 * a56 * a63 - a14 * a25 * a42 * a56 * - a63 - a15 * a22 * a44 * a56 * a63 + a12 * a25 * a44 * a56 * a63 + - a14 * a22 * a45 * a56 * a63 - a12 * a24 * a45 * a56 * a63 + a16 * - a25 * a43 * a52 * a64 - a15 * a26 * a43 * a52 * a64 - a16 * a23 * - a45 * a52 * a64 + a13 * a26 * a45 * a52 * a64 + a15 * a23 * a46 * - a52 * a64 - a13 * a25 * a46 * a52 * a64 - a16 * a25 * a42 * a53 * - a64 + a15 * a26 * a42 * a53 * a64 + a16 * a22 * a45 * a53 * a64 - - a12 * a26 * a45 * a53 * a64 - a15 * a22 * a46 * a53 * a64 + a12 * - a25 * a46 * a53 * a64 + a16 * a23 * a42 * a55 * a64 - a13 * a26 * - a42 * a55 * a64 - a16 * a22 * a43 * a55 * a64 + a12 * a26 * a43 * - a55 * a64 + a13 * a22 * a46 * a55 * a64 - a12 * a23 * a46 * a55 * - a64 - a15 * a23 * a42 * a56 * a64 + a13 * a25 * a42 * a56 * a64 + - a15 * a22 * a43 * a56 * a64 - a12 * a25 * a43 * a56 * a64 - a13 * - a22 * a45 * a56 * a64 + a12 * a23 * a45 * a56 * a64 - a16 * a24 * - a43 * a52 * a65 + a14 * a26 * a43 * a52 * a65 + a16 * a23 * a44 * - a52 * a65 - a13 * a26 * a44 * a52 * a65 - a14 * a23 * a46 * a52 * - a65 + a13 * a24 * a46 * a52 * a65 + a16 * a24 * a42 * a53 * a65 - - a14 * a26 * a42 * a53 * a65 - a16 * a22 * a44 * a53 * a65 + a12 * - a26 * a44 * a53 * a65 + a14 * a22 * a46 * a53 * a65 - a12 * a24 * - a46 * a53 * a65 - a16 * a23 * a42 * a54 * a65 + a13 * a26 * a42 * - a54 * a65 + a16 * a22 * a43 * a54 * a65 - a12 * a26 * a43 * a54 * - a65 - a13 * a22 * a46 * a54 * a65 + a12 * a23 * a46 * a54 * a65 + - a14 * a23 * a42 * a56 * a65 - a13 * a24 * a42 * a56 * a65 - a14 * - a22 * a43 * a56 * a65 + a12 * a24 * a43 * a56 * a65 + a13 * a22 * - a44 * a56 * a65 - a12 * a23 * a44 * a56 * a65 + a15 * a24 * a43 * - a52 * a66 - a14 * a25 * a43 * a52 * a66 - a15 * a23 * a44 * a52 * - a66 + a13 * a25 * a44 * a52 * a66 + a14 * a23 * a45 * a52 * a66 - - a13 * a24 * a45 * a52 * a66 - a15 * a24 * a42 * a53 * a66 + a14 * - a25 * a42 * a53 * a66 + a15 * a22 * a44 * a53 * a66 - a12 * a25 * - a44 * a53 * a66 - a14 * a22 * a45 * a53 * a66 + a12 * a24 * a45 * - a53 * a66 + a15 * a23 * a42 * a54 * a66 - a13 * a25 * a42 * a54 * - a66 - a15 * a22 * a43 * a54 * a66 + a12 * a25 * a43 * a54 * a66 + - a13 * a22 * a45 * a54 * a66 - a12 * a23 * a45 * a54 * a66 - a14 * - a23 * a42 * a55 * a66 + a13 * a24 * a42 * a55 * a66 + a14 * a22 * - a43 * a55 * a66 - a12 * a24 * a43 * a55 * a66 - a13 * a22 * a44 * - a55 * a66 + a12 * a23 * a44 * a55 * a66; - cofactor[3] = -a16 * a25 * a34 * a53 * a62 + a15 * a26 * a34 * a53 * a62 - + a16 * a24 * a35 * a53 * a62 - a14 * a26 * a35 * a53 * a62 - a15 - * a24 * a36 * a53 * a62 + a14 * a25 * a36 * a53 * a62 + a16 * a25 - * a33 * a54 * a62 - a15 * a26 * a33 * a54 * a62 - a16 * a23 * a35 - * a54 * a62 + a13 * a26 * a35 * a54 * a62 + a15 * a23 * a36 * a54 - * a62 - a13 * a25 * a36 * a54 * a62 - a16 * a24 * a33 * a55 * a62 - + a14 * a26 * a33 * a55 * a62 + a16 * a23 * a34 * a55 * a62 - a13 - * a26 * a34 * a55 * a62 - a14 * a23 * a36 * a55 * a62 + a13 * a24 - * a36 * a55 * a62 + a15 * a24 * a33 * a56 * a62 - a14 * a25 * a33 - * a56 * a62 - a15 * a23 * a34 * a56 * a62 + a13 * a25 * a34 * a56 - * a62 + a14 * a23 * a35 * a56 * a62 - a13 * a24 * a35 * a56 * a62 - + a16 * a25 * a34 * a52 * a63 - a15 * a26 * a34 * a52 * a63 - a16 - * a24 * a35 * a52 * a63 + a14 * a26 * a35 * a52 * a63 + a15 * a24 - * a36 * a52 * a63 - a14 * a25 * a36 * a52 * a63 - a16 * a25 * a32 - * a54 * a63 + a15 * a26 * a32 * a54 * a63 + a16 * a22 * a35 * a54 - * a63 - a12 * a26 * a35 * a54 * a63 - a15 * a22 * a36 * a54 * a63 - + a12 * a25 * a36 * a54 * a63 + a16 * a24 * a32 * a55 * a63 - a14 - * a26 * a32 * a55 * a63 - a16 * a22 * a34 * a55 * a63 + a12 * a26 - * a34 * a55 * a63 + a14 * a22 * a36 * a55 * a63 - a12 * a24 * a36 - * a55 * a63 - a15 * a24 * a32 * a56 * a63 + a14 * a25 * a32 * a56 - * a63 + a15 * a22 * a34 * a56 * a63 - a12 * a25 * a34 * a56 * a63 - - a14 * a22 * a35 * a56 * a63 + a12 * a24 * a35 * a56 * a63 - a16 - * a25 * a33 * a52 * a64 + a15 * a26 * a33 * a52 * a64 + a16 * a23 - * a35 * a52 * a64 - a13 * a26 * a35 * a52 * a64 - a15 * a23 * a36 - * a52 * a64 + a13 * a25 * a36 * a52 * a64 + a16 * a25 * a32 * a53 - * a64 - a15 * a26 * a32 * a53 * a64 - a16 * a22 * a35 * a53 * a64 - + a12 * a26 * a35 * a53 * a64 + a15 * a22 * a36 * a53 * a64 - a12 - * a25 * a36 * a53 * a64 - a16 * a23 * a32 * a55 * a64 + a13 * a26 - * a32 * a55 * a64 + a16 * a22 * a33 * a55 * a64 - a12 * a26 * a33 - * a55 * a64 - a13 * a22 * a36 * a55 * a64 + a12 * a23 * a36 * a55 - * a64 + a15 * a23 * a32 * a56 * a64 - a13 * a25 * a32 * a56 * a64 - - a15 * a22 * a33 * a56 * a64 + a12 * a25 * a33 * a56 * a64 + a13 - * a22 * a35 * a56 * a64 - a12 * a23 * a35 * a56 * a64 + a16 * a24 - * a33 * a52 * a65 - a14 * a26 * a33 * a52 * a65 - a16 * a23 * a34 - * a52 * a65 + a13 * a26 * a34 * a52 * a65 + a14 * a23 * a36 * a52 - * a65 - a13 * a24 * a36 * a52 * a65 - a16 * a24 * a32 * a53 * a65 - + a14 * a26 * a32 * a53 * a65 + a16 * a22 * a34 * a53 * a65 - a12 - * a26 * a34 * a53 * a65 - a14 * a22 * a36 * a53 * a65 + a12 * a24 - * a36 * a53 * a65 + a16 * a23 * a32 * a54 * a65 - a13 * a26 * a32 - * a54 * a65 - a16 * a22 * a33 * a54 * a65 + a12 * a26 * a33 * a54 - * a65 + a13 * a22 * a36 * a54 * a65 - a12 * a23 * a36 * a54 * a65 - - a14 * a23 * a32 * a56 * a65 + a13 * a24 * a32 * a56 * a65 + a14 - * a22 * a33 * a56 * a65 - a12 * a24 * a33 * a56 * a65 - a13 * a22 - * a34 * a56 * a65 + a12 * a23 * a34 * a56 * a65 - a15 * a24 * a33 - * a52 * a66 + a14 * a25 * a33 * a52 * a66 + a15 * a23 * a34 * a52 - * a66 - a13 * a25 * a34 * a52 * a66 - a14 * a23 * a35 * a52 * a66 - + a13 * a24 * a35 * a52 * a66 + a15 * a24 * a32 * a53 * a66 - a14 - * a25 * a32 * a53 * a66 - a15 * a22 * a34 * a53 * a66 + a12 * a25 - * a34 * a53 * a66 + a14 * a22 * a35 * a53 * a66 - a12 * a24 * a35 - * a53 * a66 - a15 * a23 * a32 * a54 * a66 + a13 * a25 * a32 * a54 - * a66 + a15 * a22 * a33 * a54 * a66 - a12 * a25 * a33 * a54 * a66 - - a13 * a22 * a35 * a54 * a66 + a12 * a23 * a35 * a54 * a66 + a14 - * a23 * a32 * a55 * a66 - a13 * a24 * a32 * a55 * a66 - a14 * a22 - * a33 * a55 * a66 + a12 * a24 * a33 * a55 * a66 + a13 * a22 * a34 - * a55 * a66 - a12 * a23 * a34 * a55 * a66; - cofactor[4] = a16 * a25 * a34 * a43 * a62 - a15 * a26 * a34 * a43 * a62 - - a16 * a24 * a35 * a43 * a62 + a14 * a26 * a35 * a43 * a62 + a15 * - a24 * a36 * a43 * a62 - a14 * a25 * a36 * a43 * a62 - a16 * a25 * - a33 * a44 * a62 + a15 * a26 * a33 * a44 * a62 + a16 * a23 * a35 * - a44 * a62 - a13 * a26 * a35 * a44 * a62 - a15 * a23 * a36 * a44 * - a62 + a13 * a25 * a36 * a44 * a62 + a16 * a24 * a33 * a45 * a62 - - a14 * a26 * a33 * a45 * a62 - a16 * a23 * a34 * a45 * a62 + a13 * - a26 * a34 * a45 * a62 + a14 * a23 * a36 * a45 * a62 - a13 * a24 * - a36 * a45 * a62 - a15 * a24 * a33 * a46 * a62 + a14 * a25 * a33 * - a46 * a62 + a15 * a23 * a34 * a46 * a62 - a13 * a25 * a34 * a46 * - a62 - a14 * a23 * a35 * a46 * a62 + a13 * a24 * a35 * a46 * a62 - - a16 * a25 * a34 * a42 * a63 + a15 * a26 * a34 * a42 * a63 + a16 * - a24 * a35 * a42 * a63 - a14 * a26 * a35 * a42 * a63 - a15 * a24 * - a36 * a42 * a63 + a14 * a25 * a36 * a42 * a63 + a16 * a25 * a32 * - a44 * a63 - a15 * a26 * a32 * a44 * a63 - a16 * a22 * a35 * a44 * - a63 + a12 * a26 * a35 * a44 * a63 + a15 * a22 * a36 * a44 * a63 - - a12 * a25 * a36 * a44 * a63 - a16 * a24 * a32 * a45 * a63 + a14 * - a26 * a32 * a45 * a63 + a16 * a22 * a34 * a45 * a63 - a12 * a26 * - a34 * a45 * a63 - a14 * a22 * a36 * a45 * a63 + a12 * a24 * a36 * - a45 * a63 + a15 * a24 * a32 * a46 * a63 - a14 * a25 * a32 * a46 * - a63 - a15 * a22 * a34 * a46 * a63 + a12 * a25 * a34 * a46 * a63 + - a14 * a22 * a35 * a46 * a63 - a12 * a24 * a35 * a46 * a63 + a16 * - a25 * a33 * a42 * a64 - a15 * a26 * a33 * a42 * a64 - a16 * a23 * - a35 * a42 * a64 + a13 * a26 * a35 * a42 * a64 + a15 * a23 * a36 * - a42 * a64 - a13 * a25 * a36 * a42 * a64 - a16 * a25 * a32 * a43 * - a64 + a15 * a26 * a32 * a43 * a64 + a16 * a22 * a35 * a43 * a64 - - a12 * a26 * a35 * a43 * a64 - a15 * a22 * a36 * a43 * a64 + a12 * - a25 * a36 * a43 * a64 + a16 * a23 * a32 * a45 * a64 - a13 * a26 * - a32 * a45 * a64 - a16 * a22 * a33 * a45 * a64 + a12 * a26 * a33 * - a45 * a64 + a13 * a22 * a36 * a45 * a64 - a12 * a23 * a36 * a45 * - a64 - a15 * a23 * a32 * a46 * a64 + a13 * a25 * a32 * a46 * a64 + - a15 * a22 * a33 * a46 * a64 - a12 * a25 * a33 * a46 * a64 - a13 * - a22 * a35 * a46 * a64 + a12 * a23 * a35 * a46 * a64 - a16 * a24 * - a33 * a42 * a65 + a14 * a26 * a33 * a42 * a65 + a16 * a23 * a34 * - a42 * a65 - a13 * a26 * a34 * a42 * a65 - a14 * a23 * a36 * a42 * - a65 + a13 * a24 * a36 * a42 * a65 + a16 * a24 * a32 * a43 * a65 - - a14 * a26 * a32 * a43 * a65 - a16 * a22 * a34 * a43 * a65 + a12 * - a26 * a34 * a43 * a65 + a14 * a22 * a36 * a43 * a65 - a12 * a24 * - a36 * a43 * a65 - a16 * a23 * a32 * a44 * a65 + a13 * a26 * a32 * - a44 * a65 + a16 * a22 * a33 * a44 * a65 - a12 * a26 * a33 * a44 * - a65 - a13 * a22 * a36 * a44 * a65 + a12 * a23 * a36 * a44 * a65 + - a14 * a23 * a32 * a46 * a65 - a13 * a24 * a32 * a46 * a65 - a14 * - a22 * a33 * a46 * a65 + a12 * a24 * a33 * a46 * a65 + a13 * a22 * - a34 * a46 * a65 - a12 * a23 * a34 * a46 * a65 + a15 * a24 * a33 * - a42 * a66 - a14 * a25 * a33 * a42 * a66 - a15 * a23 * a34 * a42 * - a66 + a13 * a25 * a34 * a42 * a66 + a14 * a23 * a35 * a42 * a66 - - a13 * a24 * a35 * a42 * a66 - a15 * a24 * a32 * a43 * a66 + a14 * - a25 * a32 * a43 * a66 + a15 * a22 * a34 * a43 * a66 - a12 * a25 * - a34 * a43 * a66 - a14 * a22 * a35 * a43 * a66 + a12 * a24 * a35 * - a43 * a66 + a15 * a23 * a32 * a44 * a66 - a13 * a25 * a32 * a44 * - a66 - a15 * a22 * a33 * a44 * a66 + a12 * a25 * a33 * a44 * a66 + - a13 * a22 * a35 * a44 * a66 - a12 * a23 * a35 * a44 * a66 - a14 * - a23 * a32 * a45 * a66 + a13 * a24 * a32 * a45 * a66 + a14 * a22 * - a33 * a45 * a66 - a12 * a24 * a33 * a45 * a66 - a13 * a22 * a34 * - a45 * a66 + a12 * a23 * a34 * a45 * a66; - cofactor[5] = -a16 * a25 * a34 * a43 * a52 + a15 * a26 * a34 * a43 * a52 - + a16 * a24 * a35 * a43 * a52 - a14 * a26 * a35 * a43 * a52 - a15 - * a24 * a36 * a43 * a52 + a14 * a25 * a36 * a43 * a52 + a16 * a25 - * a33 * a44 * a52 - a15 * a26 * a33 * a44 * a52 - a16 * a23 * a35 - * a44 * a52 + a13 * a26 * a35 * a44 * a52 + a15 * a23 * a36 * a44 - * a52 - a13 * a25 * a36 * a44 * a52 - a16 * a24 * a33 * a45 * a52 - + a14 * a26 * a33 * a45 * a52 + a16 * a23 * a34 * a45 * a52 - a13 - * a26 * a34 * a45 * a52 - a14 * a23 * a36 * a45 * a52 + a13 * a24 - * a36 * a45 * a52 + a15 * a24 * a33 * a46 * a52 - a14 * a25 * a33 - * a46 * a52 - a15 * a23 * a34 * a46 * a52 + a13 * a25 * a34 * a46 - * a52 + a14 * a23 * a35 * a46 * a52 - a13 * a24 * a35 * a46 * a52 - + a16 * a25 * a34 * a42 * a53 - a15 * a26 * a34 * a42 * a53 - a16 - * a24 * a35 * a42 * a53 + a14 * a26 * a35 * a42 * a53 + a15 * a24 - * a36 * a42 * a53 - a14 * a25 * a36 * a42 * a53 - a16 * a25 * a32 - * a44 * a53 + a15 * a26 * a32 * a44 * a53 + a16 * a22 * a35 * a44 - * a53 - a12 * a26 * a35 * a44 * a53 - a15 * a22 * a36 * a44 * a53 - + a12 * a25 * a36 * a44 * a53 + a16 * a24 * a32 * a45 * a53 - a14 - * a26 * a32 * a45 * a53 - a16 * a22 * a34 * a45 * a53 + a12 * a26 - * a34 * a45 * a53 + a14 * a22 * a36 * a45 * a53 - a12 * a24 * a36 - * a45 * a53 - a15 * a24 * a32 * a46 * a53 + a14 * a25 * a32 * a46 - * a53 + a15 * a22 * a34 * a46 * a53 - a12 * a25 * a34 * a46 * a53 - - a14 * a22 * a35 * a46 * a53 + a12 * a24 * a35 * a46 * a53 - a16 - * a25 * a33 * a42 * a54 + a15 * a26 * a33 * a42 * a54 + a16 * a23 - * a35 * a42 * a54 - a13 * a26 * a35 * a42 * a54 - a15 * a23 * a36 - * a42 * a54 + a13 * a25 * a36 * a42 * a54 + a16 * a25 * a32 * a43 - * a54 - a15 * a26 * a32 * a43 * a54 - a16 * a22 * a35 * a43 * a54 - + a12 * a26 * a35 * a43 * a54 + a15 * a22 * a36 * a43 * a54 - a12 - * a25 * a36 * a43 * a54 - a16 * a23 * a32 * a45 * a54 + a13 * a26 - * a32 * a45 * a54 + a16 * a22 * a33 * a45 * a54 - a12 * a26 * a33 - * a45 * a54 - a13 * a22 * a36 * a45 * a54 + a12 * a23 * a36 * a45 - * a54 + a15 * a23 * a32 * a46 * a54 - a13 * a25 * a32 * a46 * a54 - - a15 * a22 * a33 * a46 * a54 + a12 * a25 * a33 * a46 * a54 + a13 - * a22 * a35 * a46 * a54 - a12 * a23 * a35 * a46 * a54 + a16 * a24 - * a33 * a42 * a55 - a14 * a26 * a33 * a42 * a55 - a16 * a23 * a34 - * a42 * a55 + a13 * a26 * a34 * a42 * a55 + a14 * a23 * a36 * a42 - * a55 - a13 * a24 * a36 * a42 * a55 - a16 * a24 * a32 * a43 * a55 - + a14 * a26 * a32 * a43 * a55 + a16 * a22 * a34 * a43 * a55 - a12 - * a26 * a34 * a43 * a55 - a14 * a22 * a36 * a43 * a55 + a12 * a24 - * a36 * a43 * a55 + a16 * a23 * a32 * a44 * a55 - a13 * a26 * a32 - * a44 * a55 - a16 * a22 * a33 * a44 * a55 + a12 * a26 * a33 * a44 - * a55 + a13 * a22 * a36 * a44 * a55 - a12 * a23 * a36 * a44 * a55 - - a14 * a23 * a32 * a46 * a55 + a13 * a24 * a32 * a46 * a55 + a14 - * a22 * a33 * a46 * a55 - a12 * a24 * a33 * a46 * a55 - a13 * a22 - * a34 * a46 * a55 + a12 * a23 * a34 * a46 * a55 - a15 * a24 * a33 - * a42 * a56 + a14 * a25 * a33 * a42 * a56 + a15 * a23 * a34 * a42 - * a56 - a13 * a25 * a34 * a42 * a56 - a14 * a23 * a35 * a42 * a56 - + a13 * a24 * a35 * a42 * a56 + a15 * a24 * a32 * a43 * a56 - a14 - * a25 * a32 * a43 * a56 - a15 * a22 * a34 * a43 * a56 + a12 * a25 - * a34 * a43 * a56 + a14 * a22 * a35 * a43 * a56 - a12 * a24 * a35 - * a43 * a56 - a15 * a23 * a32 * a44 * a56 + a13 * a25 * a32 * a44 - * a56 + a15 * a22 * a33 * a44 * a56 - a12 * a25 * a33 * a44 * a56 - - a13 * a22 * a35 * a44 * a56 + a12 * a23 * a35 * a44 * a56 + a14 - * a23 * a32 * a45 * a56 - a13 * a24 * a32 * a45 * a56 - a14 * a22 - * a33 * a45 * a56 + a12 * a24 * a33 * a45 * a56 + a13 * a22 * a34 - * a45 * a56 - a12 * a23 * a34 * a45 * a56; - cofactor[6] = -a26 * a35 * a44 * a53 * a61 + a25 * a36 * a44 * a53 * a61 - + a26 * a34 * a45 * a53 * a61 - a24 * a36 * a45 * a53 * a61 - a25 - * a34 * a46 * a53 * a61 + a24 * a35 * a46 * a53 * a61 + a26 * a35 - * a43 * a54 * a61 - a25 * a36 * a43 * a54 * a61 - a26 * a33 * a45 - * a54 * a61 + a23 * a36 * a45 * a54 * a61 + a25 * a33 * a46 * a54 - * a61 - a23 * a35 * a46 * a54 * a61 - a26 * a34 * a43 * a55 * a61 - + a24 * a36 * a43 * a55 * a61 + a26 * a33 * a44 * a55 * a61 - a23 - * a36 * a44 * a55 * a61 - a24 * a33 * a46 * a55 * a61 + a23 * a34 - * a46 * a55 * a61 + a25 * a34 * a43 * a56 * a61 - a24 * a35 * a43 - * a56 * a61 - a25 * a33 * a44 * a56 * a61 + a23 * a35 * a44 * a56 - * a61 + a24 * a33 * a45 * a56 * a61 - a23 * a34 * a45 * a56 * a61 - + a26 * a35 * a44 * a51 * a63 - a25 * a36 * a44 * a51 * a63 - a26 - * a34 * a45 * a51 * a63 + a24 * a36 * a45 * a51 * a63 + a25 * a34 - * a46 * a51 * a63 - a24 * a35 * a46 * a51 * a63 - a26 * a35 * a41 - * a54 * a63 + a25 * a36 * a41 * a54 * a63 + a26 * a31 * a45 * a54 - * a63 - a21 * a36 * a45 * a54 * a63 - a25 * a31 * a46 * a54 * a63 - + a21 * a35 * a46 * a54 * a63 + a26 * a34 * a41 * a55 * a63 - a24 - * a36 * a41 * a55 * a63 - a26 * a31 * a44 * a55 * a63 + a21 * a36 - * a44 * a55 * a63 + a24 * a31 * a46 * a55 * a63 - a21 * a34 * a46 - * a55 * a63 - a25 * a34 * a41 * a56 * a63 + a24 * a35 * a41 * a56 - * a63 + a25 * a31 * a44 * a56 * a63 - a21 * a35 * a44 * a56 * a63 - - a24 * a31 * a45 * a56 * a63 + a21 * a34 * a45 * a56 * a63 - a26 - * a35 * a43 * a51 * a64 + a25 * a36 * a43 * a51 * a64 + a26 * a33 - * a45 * a51 * a64 - a23 * a36 * a45 * a51 * a64 - a25 * a33 * a46 - * a51 * a64 + a23 * a35 * a46 * a51 * a64 + a26 * a35 * a41 * a53 - * a64 - a25 * a36 * a41 * a53 * a64 - a26 * a31 * a45 * a53 * a64 - + a21 * a36 * a45 * a53 * a64 + a25 * a31 * a46 * a53 * a64 - a21 - * a35 * a46 * a53 * a64 - a26 * a33 * a41 * a55 * a64 + a23 * a36 - * a41 * a55 * a64 + a26 * a31 * a43 * a55 * a64 - a21 * a36 * a43 - * a55 * a64 - a23 * a31 * a46 * a55 * a64 + a21 * a33 * a46 * a55 - * a64 + a25 * a33 * a41 * a56 * a64 - a23 * a35 * a41 * a56 * a64 - - a25 * a31 * a43 * a56 * a64 + a21 * a35 * a43 * a56 * a64 + a23 - * a31 * a45 * a56 * a64 - a21 * a33 * a45 * a56 * a64 + a26 * a34 - * a43 * a51 * a65 - a24 * a36 * a43 * a51 * a65 - a26 * a33 * a44 - * a51 * a65 + a23 * a36 * a44 * a51 * a65 + a24 * a33 * a46 * a51 - * a65 - a23 * a34 * a46 * a51 * a65 - a26 * a34 * a41 * a53 * a65 - + a24 * a36 * a41 * a53 * a65 + a26 * a31 * a44 * a53 * a65 - a21 - * a36 * a44 * a53 * a65 - a24 * a31 * a46 * a53 * a65 + a21 * a34 - * a46 * a53 * a65 + a26 * a33 * a41 * a54 * a65 - a23 * a36 * a41 - * a54 * a65 - a26 * a31 * a43 * a54 * a65 + a21 * a36 * a43 * a54 - * a65 + a23 * a31 * a46 * a54 * a65 - a21 * a33 * a46 * a54 * a65 - - a24 * a33 * a41 * a56 * a65 + a23 * a34 * a41 * a56 * a65 + a24 - * a31 * a43 * a56 * a65 - a21 * a34 * a43 * a56 * a65 - a23 * a31 - * a44 * a56 * a65 + a21 * a33 * a44 * a56 * a65 - a25 * a34 * a43 - * a51 * a66 + a24 * a35 * a43 * a51 * a66 + a25 * a33 * a44 * a51 - * a66 - a23 * a35 * a44 * a51 * a66 - a24 * a33 * a45 * a51 * a66 - + a23 * a34 * a45 * a51 * a66 + a25 * a34 * a41 * a53 * a66 - a24 - * a35 * a41 * a53 * a66 - a25 * a31 * a44 * a53 * a66 + a21 * a35 - * a44 * a53 * a66 + a24 * a31 * a45 * a53 * a66 - a21 * a34 * a45 - * a53 * a66 - a25 * a33 * a41 * a54 * a66 + a23 * a35 * a41 * a54 - * a66 + a25 * a31 * a43 * a54 * a66 - a21 * a35 * a43 * a54 * a66 - - a23 * a31 * a45 * a54 * a66 + a21 * a33 * a45 * a54 * a66 + a24 - * a33 * a41 * a55 * a66 - a23 * a34 * a41 * a55 * a66 - a24 * a31 - * a43 * a55 * a66 + a21 * a34 * a43 * a55 * a66 + a23 * a31 * a44 - * a55 * a66 - a21 * a33 * a44 * a55 * a66; - cofactor[7] = a16 * a35 * a44 * a53 * a61 - a15 * a36 * a44 * a53 * a61 - - a16 * a34 * a45 * a53 * a61 + a14 * a36 * a45 * a53 * a61 + a15 * - a34 * a46 * a53 * a61 - a14 * a35 * a46 * a53 * a61 - a16 * a35 * - a43 * a54 * a61 + a15 * a36 * a43 * a54 * a61 + a16 * a33 * a45 * - a54 * a61 - a13 * a36 * a45 * a54 * a61 - a15 * a33 * a46 * a54 * - a61 + a13 * a35 * a46 * a54 * a61 + a16 * a34 * a43 * a55 * a61 - - a14 * a36 * a43 * a55 * a61 - a16 * a33 * a44 * a55 * a61 + a13 * - a36 * a44 * a55 * a61 + a14 * a33 * a46 * a55 * a61 - a13 * a34 * - a46 * a55 * a61 - a15 * a34 * a43 * a56 * a61 + a14 * a35 * a43 * - a56 * a61 + a15 * a33 * a44 * a56 * a61 - a13 * a35 * a44 * a56 * - a61 - a14 * a33 * a45 * a56 * a61 + a13 * a34 * a45 * a56 * a61 - - a16 * a35 * a44 * a51 * a63 + a15 * a36 * a44 * a51 * a63 + a16 * - a34 * a45 * a51 * a63 - a14 * a36 * a45 * a51 * a63 - a15 * a34 * - a46 * a51 * a63 + a14 * a35 * a46 * a51 * a63 + a16 * a35 * a41 * - a54 * a63 - a15 * a36 * a41 * a54 * a63 - a16 * a31 * a45 * a54 * - a63 + a11 * a36 * a45 * a54 * a63 + a15 * a31 * a46 * a54 * a63 - - a11 * a35 * a46 * a54 * a63 - a16 * a34 * a41 * a55 * a63 + a14 * - a36 * a41 * a55 * a63 + a16 * a31 * a44 * a55 * a63 - a11 * a36 * - a44 * a55 * a63 - a14 * a31 * a46 * a55 * a63 + a11 * a34 * a46 * - a55 * a63 + a15 * a34 * a41 * a56 * a63 - a14 * a35 * a41 * a56 * - a63 - a15 * a31 * a44 * a56 * a63 + a11 * a35 * a44 * a56 * a63 + - a14 * a31 * a45 * a56 * a63 - a11 * a34 * a45 * a56 * a63 + a16 * - a35 * a43 * a51 * a64 - a15 * a36 * a43 * a51 * a64 - a16 * a33 * - a45 * a51 * a64 + a13 * a36 * a45 * a51 * a64 + a15 * a33 * a46 * - a51 * a64 - a13 * a35 * a46 * a51 * a64 - a16 * a35 * a41 * a53 * - a64 + a15 * a36 * a41 * a53 * a64 + a16 * a31 * a45 * a53 * a64 - - a11 * a36 * a45 * a53 * a64 - a15 * a31 * a46 * a53 * a64 + a11 * - a35 * a46 * a53 * a64 + a16 * a33 * a41 * a55 * a64 - a13 * a36 * - a41 * a55 * a64 - a16 * a31 * a43 * a55 * a64 + a11 * a36 * a43 * - a55 * a64 + a13 * a31 * a46 * a55 * a64 - a11 * a33 * a46 * a55 * - a64 - a15 * a33 * a41 * a56 * a64 + a13 * a35 * a41 * a56 * a64 + - a15 * a31 * a43 * a56 * a64 - a11 * a35 * a43 * a56 * a64 - a13 * - a31 * a45 * a56 * a64 + a11 * a33 * a45 * a56 * a64 - a16 * a34 * - a43 * a51 * a65 + a14 * a36 * a43 * a51 * a65 + a16 * a33 * a44 * - a51 * a65 - a13 * a36 * a44 * a51 * a65 - a14 * a33 * a46 * a51 * - a65 + a13 * a34 * a46 * a51 * a65 + a16 * a34 * a41 * a53 * a65 - - a14 * a36 * a41 * a53 * a65 - a16 * a31 * a44 * a53 * a65 + a11 * - a36 * a44 * a53 * a65 + a14 * a31 * a46 * a53 * a65 - a11 * a34 * - a46 * a53 * a65 - a16 * a33 * a41 * a54 * a65 + a13 * a36 * a41 * - a54 * a65 + a16 * a31 * a43 * a54 * a65 - a11 * a36 * a43 * a54 * - a65 - a13 * a31 * a46 * a54 * a65 + a11 * a33 * a46 * a54 * a65 + - a14 * a33 * a41 * a56 * a65 - a13 * a34 * a41 * a56 * a65 - a14 * - a31 * a43 * a56 * a65 + a11 * a34 * a43 * a56 * a65 + a13 * a31 * - a44 * a56 * a65 - a11 * a33 * a44 * a56 * a65 + a15 * a34 * a43 * - a51 * a66 - a14 * a35 * a43 * a51 * a66 - a15 * a33 * a44 * a51 * - a66 + a13 * a35 * a44 * a51 * a66 + a14 * a33 * a45 * a51 * a66 - - a13 * a34 * a45 * a51 * a66 - a15 * a34 * a41 * a53 * a66 + a14 * - a35 * a41 * a53 * a66 + a15 * a31 * a44 * a53 * a66 - a11 * a35 * - a44 * a53 * a66 - a14 * a31 * a45 * a53 * a66 + a11 * a34 * a45 * - a53 * a66 + a15 * a33 * a41 * a54 * a66 - a13 * a35 * a41 * a54 * - a66 - a15 * a31 * a43 * a54 * a66 + a11 * a35 * a43 * a54 * a66 + - a13 * a31 * a45 * a54 * a66 - a11 * a33 * a45 * a54 * a66 - a14 * - a33 * a41 * a55 * a66 + a13 * a34 * a41 * a55 * a66 + a14 * a31 * - a43 * a55 * a66 - a11 * a34 * a43 * a55 * a66 - a13 * a31 * a44 * - a55 * a66 + a11 * a33 * a44 * a55 * a66; - cofactor[8] = -a16 * a25 * a44 * a53 * a61 + a15 * a26 * a44 * a53 * a61 - + a16 * a24 * a45 * a53 * a61 - a14 * a26 * a45 * a53 * a61 - a15 - * a24 * a46 * a53 * a61 + a14 * a25 * a46 * a53 * a61 + a16 * a25 - * a43 * a54 * a61 - a15 * a26 * a43 * a54 * a61 - a16 * a23 * a45 - * a54 * a61 + a13 * a26 * a45 * a54 * a61 + a15 * a23 * a46 * a54 - * a61 - a13 * a25 * a46 * a54 * a61 - a16 * a24 * a43 * a55 * a61 - + a14 * a26 * a43 * a55 * a61 + a16 * a23 * a44 * a55 * a61 - a13 - * a26 * a44 * a55 * a61 - a14 * a23 * a46 * a55 * a61 + a13 * a24 - * a46 * a55 * a61 + a15 * a24 * a43 * a56 * a61 - a14 * a25 * a43 - * a56 * a61 - a15 * a23 * a44 * a56 * a61 + a13 * a25 * a44 * a56 - * a61 + a14 * a23 * a45 * a56 * a61 - a13 * a24 * a45 * a56 * a61 - + a16 * a25 * a44 * a51 * a63 - a15 * a26 * a44 * a51 * a63 - a16 - * a24 * a45 * a51 * a63 + a14 * a26 * a45 * a51 * a63 + a15 * a24 - * a46 * a51 * a63 - a14 * a25 * a46 * a51 * a63 - a16 * a25 * a41 - * a54 * a63 + a15 * a26 * a41 * a54 * a63 + a16 * a21 * a45 * a54 - * a63 - a11 * a26 * a45 * a54 * a63 - a15 * a21 * a46 * a54 * a63 - + a11 * a25 * a46 * a54 * a63 + a16 * a24 * a41 * a55 * a63 - a14 - * a26 * a41 * a55 * a63 - a16 * a21 * a44 * a55 * a63 + a11 * a26 - * a44 * a55 * a63 + a14 * a21 * a46 * a55 * a63 - a11 * a24 * a46 - * a55 * a63 - a15 * a24 * a41 * a56 * a63 + a14 * a25 * a41 * a56 - * a63 + a15 * a21 * a44 * a56 * a63 - a11 * a25 * a44 * a56 * a63 - - a14 * a21 * a45 * a56 * a63 + a11 * a24 * a45 * a56 * a63 - a16 - * a25 * a43 * a51 * a64 + a15 * a26 * a43 * a51 * a64 + a16 * a23 - * a45 * a51 * a64 - a13 * a26 * a45 * a51 * a64 - a15 * a23 * a46 - * a51 * a64 + a13 * a25 * a46 * a51 * a64 + a16 * a25 * a41 * a53 - * a64 - a15 * a26 * a41 * a53 * a64 - a16 * a21 * a45 * a53 * a64 - + a11 * a26 * a45 * a53 * a64 + a15 * a21 * a46 * a53 * a64 - a11 - * a25 * a46 * a53 * a64 - a16 * a23 * a41 * a55 * a64 + a13 * a26 - * a41 * a55 * a64 + a16 * a21 * a43 * a55 * a64 - a11 * a26 * a43 - * a55 * a64 - a13 * a21 * a46 * a55 * a64 + a11 * a23 * a46 * a55 - * a64 + a15 * a23 * a41 * a56 * a64 - a13 * a25 * a41 * a56 * a64 - - a15 * a21 * a43 * a56 * a64 + a11 * a25 * a43 * a56 * a64 + a13 - * a21 * a45 * a56 * a64 - a11 * a23 * a45 * a56 * a64 + a16 * a24 - * a43 * a51 * a65 - a14 * a26 * a43 * a51 * a65 - a16 * a23 * a44 - * a51 * a65 + a13 * a26 * a44 * a51 * a65 + a14 * a23 * a46 * a51 - * a65 - a13 * a24 * a46 * a51 * a65 - a16 * a24 * a41 * a53 * a65 - + a14 * a26 * a41 * a53 * a65 + a16 * a21 * a44 * a53 * a65 - a11 - * a26 * a44 * a53 * a65 - a14 * a21 * a46 * a53 * a65 + a11 * a24 - * a46 * a53 * a65 + a16 * a23 * a41 * a54 * a65 - a13 * a26 * a41 - * a54 * a65 - a16 * a21 * a43 * a54 * a65 + a11 * a26 * a43 * a54 - * a65 + a13 * a21 * a46 * a54 * a65 - a11 * a23 * a46 * a54 * a65 - - a14 * a23 * a41 * a56 * a65 + a13 * a24 * a41 * a56 * a65 + a14 - * a21 * a43 * a56 * a65 - a11 * a24 * a43 * a56 * a65 - a13 * a21 - * a44 * a56 * a65 + a11 * a23 * a44 * a56 * a65 - a15 * a24 * a43 - * a51 * a66 + a14 * a25 * a43 * a51 * a66 + a15 * a23 * a44 * a51 - * a66 - a13 * a25 * a44 * a51 * a66 - a14 * a23 * a45 * a51 * a66 - + a13 * a24 * a45 * a51 * a66 + a15 * a24 * a41 * a53 * a66 - a14 - * a25 * a41 * a53 * a66 - a15 * a21 * a44 * a53 * a66 + a11 * a25 - * a44 * a53 * a66 + a14 * a21 * a45 * a53 * a66 - a11 * a24 * a45 - * a53 * a66 - a15 * a23 * a41 * a54 * a66 + a13 * a25 * a41 * a54 - * a66 + a15 * a21 * a43 * a54 * a66 - a11 * a25 * a43 * a54 * a66 - - a13 * a21 * a45 * a54 * a66 + a11 * a23 * a45 * a54 * a66 + a14 - * a23 * a41 * a55 * a66 - a13 * a24 * a41 * a55 * a66 - a14 * a21 - * a43 * a55 * a66 + a11 * a24 * a43 * a55 * a66 + a13 * a21 * a44 - * a55 * a66 - a11 * a23 * a44 * a55 * a66; - cofactor[9] = a16 * a25 * a34 * a53 * a61 - a15 * a26 * a34 * a53 * a61 - - a16 * a24 * a35 * a53 * a61 + a14 * a26 * a35 * a53 * a61 + a15 * - a24 * a36 * a53 * a61 - a14 * a25 * a36 * a53 * a61 - a16 * a25 * - a33 * a54 * a61 + a15 * a26 * a33 * a54 * a61 + a16 * a23 * a35 * - a54 * a61 - a13 * a26 * a35 * a54 * a61 - a15 * a23 * a36 * a54 * - a61 + a13 * a25 * a36 * a54 * a61 + a16 * a24 * a33 * a55 * a61 - - a14 * a26 * a33 * a55 * a61 - a16 * a23 * a34 * a55 * a61 + a13 * - a26 * a34 * a55 * a61 + a14 * a23 * a36 * a55 * a61 - a13 * a24 * - a36 * a55 * a61 - a15 * a24 * a33 * a56 * a61 + a14 * a25 * a33 * - a56 * a61 + a15 * a23 * a34 * a56 * a61 - a13 * a25 * a34 * a56 * - a61 - a14 * a23 * a35 * a56 * a61 + a13 * a24 * a35 * a56 * a61 - - a16 * a25 * a34 * a51 * a63 + a15 * a26 * a34 * a51 * a63 + a16 * - a24 * a35 * a51 * a63 - a14 * a26 * a35 * a51 * a63 - a15 * a24 * - a36 * a51 * a63 + a14 * a25 * a36 * a51 * a63 + a16 * a25 * a31 * - a54 * a63 - a15 * a26 * a31 * a54 * a63 - a16 * a21 * a35 * a54 * - a63 + a11 * a26 * a35 * a54 * a63 + a15 * a21 * a36 * a54 * a63 - - a11 * a25 * a36 * a54 * a63 - a16 * a24 * a31 * a55 * a63 + a14 * - a26 * a31 * a55 * a63 + a16 * a21 * a34 * a55 * a63 - a11 * a26 * - a34 * a55 * a63 - a14 * a21 * a36 * a55 * a63 + a11 * a24 * a36 * - a55 * a63 + a15 * a24 * a31 * a56 * a63 - a14 * a25 * a31 * a56 * - a63 - a15 * a21 * a34 * a56 * a63 + a11 * a25 * a34 * a56 * a63 + - a14 * a21 * a35 * a56 * a63 - a11 * a24 * a35 * a56 * a63 + a16 * - a25 * a33 * a51 * a64 - a15 * a26 * a33 * a51 * a64 - a16 * a23 * - a35 * a51 * a64 + a13 * a26 * a35 * a51 * a64 + a15 * a23 * a36 * - a51 * a64 - a13 * a25 * a36 * a51 * a64 - a16 * a25 * a31 * a53 * - a64 + a15 * a26 * a31 * a53 * a64 + a16 * a21 * a35 * a53 * a64 - - a11 * a26 * a35 * a53 * a64 - a15 * a21 * a36 * a53 * a64 + a11 * - a25 * a36 * a53 * a64 + a16 * a23 * a31 * a55 * a64 - a13 * a26 * - a31 * a55 * a64 - a16 * a21 * a33 * a55 * a64 + a11 * a26 * a33 * - a55 * a64 + a13 * a21 * a36 * a55 * a64 - a11 * a23 * a36 * a55 * - a64 - a15 * a23 * a31 * a56 * a64 + a13 * a25 * a31 * a56 * a64 + - a15 * a21 * a33 * a56 * a64 - a11 * a25 * a33 * a56 * a64 - a13 * - a21 * a35 * a56 * a64 + a11 * a23 * a35 * a56 * a64 - a16 * a24 * - a33 * a51 * a65 + a14 * a26 * a33 * a51 * a65 + a16 * a23 * a34 * - a51 * a65 - a13 * a26 * a34 * a51 * a65 - a14 * a23 * a36 * a51 * - a65 + a13 * a24 * a36 * a51 * a65 + a16 * a24 * a31 * a53 * a65 - - a14 * a26 * a31 * a53 * a65 - a16 * a21 * a34 * a53 * a65 + a11 * - a26 * a34 * a53 * a65 + a14 * a21 * a36 * a53 * a65 - a11 * a24 * - a36 * a53 * a65 - a16 * a23 * a31 * a54 * a65 + a13 * a26 * a31 * - a54 * a65 + a16 * a21 * a33 * a54 * a65 - a11 * a26 * a33 * a54 * - a65 - a13 * a21 * a36 * a54 * a65 + a11 * a23 * a36 * a54 * a65 + - a14 * a23 * a31 * a56 * a65 - a13 * a24 * a31 * a56 * a65 - a14 * - a21 * a33 * a56 * a65 + a11 * a24 * a33 * a56 * a65 + a13 * a21 * - a34 * a56 * a65 - a11 * a23 * a34 * a56 * a65 + a15 * a24 * a33 * - a51 * a66 - a14 * a25 * a33 * a51 * a66 - a15 * a23 * a34 * a51 * - a66 + a13 * a25 * a34 * a51 * a66 + a14 * a23 * a35 * a51 * a66 - - a13 * a24 * a35 * a51 * a66 - a15 * a24 * a31 * a53 * a66 + a14 * - a25 * a31 * a53 * a66 + a15 * a21 * a34 * a53 * a66 - a11 * a25 * - a34 * a53 * a66 - a14 * a21 * a35 * a53 * a66 + a11 * a24 * a35 * - a53 * a66 + a15 * a23 * a31 * a54 * a66 - a13 * a25 * a31 * a54 * - a66 - a15 * a21 * a33 * a54 * a66 + a11 * a25 * a33 * a54 * a66 + - a13 * a21 * a35 * a54 * a66 - a11 * a23 * a35 * a54 * a66 - a14 * - a23 * a31 * a55 * a66 + a13 * a24 * a31 * a55 * a66 + a14 * a21 * - a33 * a55 * a66 - a11 * a24 * a33 * a55 * a66 - a13 * a21 * a34 * - a55 * a66 + a11 * a23 * a34 * a55 * a66; - cofactor[10] = -a16 * a25 * a34 * a43 * a61 + a15 * a26 * a34 * a43 * a61 - + a16 * a24 * a35 * a43 * a61 - a14 * a26 * a35 * a43 * a61 - a15 - * a24 * a36 * a43 * a61 + a14 * a25 * a36 * a43 * a61 + a16 * a25 - * a33 * a44 * a61 - a15 * a26 * a33 * a44 * a61 - a16 * a23 * a35 - * a44 * a61 + a13 * a26 * a35 * a44 * a61 + a15 * a23 * a36 * a44 - * a61 - a13 * a25 * a36 * a44 * a61 - a16 * a24 * a33 * a45 * a61 - + a14 * a26 * a33 * a45 * a61 + a16 * a23 * a34 * a45 * a61 - a13 - * a26 * a34 * a45 * a61 - a14 * a23 * a36 * a45 * a61 + a13 * a24 - * a36 * a45 * a61 + a15 * a24 * a33 * a46 * a61 - a14 * a25 * a33 - * a46 * a61 - a15 * a23 * a34 * a46 * a61 + a13 * a25 * a34 * a46 - * a61 + a14 * a23 * a35 * a46 * a61 - a13 * a24 * a35 * a46 * a61 - + a16 * a25 * a34 * a41 * a63 - a15 * a26 * a34 * a41 * a63 - a16 - * a24 * a35 * a41 * a63 + a14 * a26 * a35 * a41 * a63 + a15 * a24 - * a36 * a41 * a63 - a14 * a25 * a36 * a41 * a63 - a16 * a25 * a31 - * a44 * a63 + a15 * a26 * a31 * a44 * a63 + a16 * a21 * a35 * a44 - * a63 - a11 * a26 * a35 * a44 * a63 - a15 * a21 * a36 * a44 * a63 - + a11 * a25 * a36 * a44 * a63 + a16 * a24 * a31 * a45 * a63 - a14 - * a26 * a31 * a45 * a63 - a16 * a21 * a34 * a45 * a63 + a11 * a26 - * a34 * a45 * a63 + a14 * a21 * a36 * a45 * a63 - a11 * a24 * a36 - * a45 * a63 - a15 * a24 * a31 * a46 * a63 + a14 * a25 * a31 * a46 - * a63 + a15 * a21 * a34 * a46 * a63 - a11 * a25 * a34 * a46 * a63 - - a14 * a21 * a35 * a46 * a63 + a11 * a24 * a35 * a46 * a63 - a16 - * a25 * a33 * a41 * a64 + a15 * a26 * a33 * a41 * a64 + a16 * a23 - * a35 * a41 * a64 - a13 * a26 * a35 * a41 * a64 - a15 * a23 * a36 - * a41 * a64 + a13 * a25 * a36 * a41 * a64 + a16 * a25 * a31 * a43 - * a64 - a15 * a26 * a31 * a43 * a64 - a16 * a21 * a35 * a43 * a64 - + a11 * a26 * a35 * a43 * a64 + a15 * a21 * a36 * a43 * a64 - a11 - * a25 * a36 * a43 * a64 - a16 * a23 * a31 * a45 * a64 + a13 * a26 - * a31 * a45 * a64 + a16 * a21 * a33 * a45 * a64 - a11 * a26 * a33 - * a45 * a64 - a13 * a21 * a36 * a45 * a64 + a11 * a23 * a36 * a45 - * a64 + a15 * a23 * a31 * a46 * a64 - a13 * a25 * a31 * a46 * a64 - - a15 * a21 * a33 * a46 * a64 + a11 * a25 * a33 * a46 * a64 + a13 - * a21 * a35 * a46 * a64 - a11 * a23 * a35 * a46 * a64 + a16 * a24 - * a33 * a41 * a65 - a14 * a26 * a33 * a41 * a65 - a16 * a23 * a34 - * a41 * a65 + a13 * a26 * a34 * a41 * a65 + a14 * a23 * a36 * a41 - * a65 - a13 * a24 * a36 * a41 * a65 - a16 * a24 * a31 * a43 * a65 - + a14 * a26 * a31 * a43 * a65 + a16 * a21 * a34 * a43 * a65 - a11 - * a26 * a34 * a43 * a65 - a14 * a21 * a36 * a43 * a65 + a11 * a24 - * a36 * a43 * a65 + a16 * a23 * a31 * a44 * a65 - a13 * a26 * a31 - * a44 * a65 - a16 * a21 * a33 * a44 * a65 + a11 * a26 * a33 * a44 - * a65 + a13 * a21 * a36 * a44 * a65 - a11 * a23 * a36 * a44 * a65 - - a14 * a23 * a31 * a46 * a65 + a13 * a24 * a31 * a46 * a65 + a14 - * a21 * a33 * a46 * a65 - a11 * a24 * a33 * a46 * a65 - a13 * a21 - * a34 * a46 * a65 + a11 * a23 * a34 * a46 * a65 - a15 * a24 * a33 - * a41 * a66 + a14 * a25 * a33 * a41 * a66 + a15 * a23 * a34 * a41 - * a66 - a13 * a25 * a34 * a41 * a66 - a14 * a23 * a35 * a41 * a66 - + a13 * a24 * a35 * a41 * a66 + a15 * a24 * a31 * a43 * a66 - a14 - * a25 * a31 * a43 * a66 - a15 * a21 * a34 * a43 * a66 + a11 * a25 - * a34 * a43 * a66 + a14 * a21 * a35 * a43 * a66 - a11 * a24 * a35 - * a43 * a66 - a15 * a23 * a31 * a44 * a66 + a13 * a25 * a31 * a44 - * a66 + a15 * a21 * a33 * a44 * a66 - a11 * a25 * a33 * a44 * a66 - - a13 * a21 * a35 * a44 * a66 + a11 * a23 * a35 * a44 * a66 + a14 - * a23 * a31 * a45 * a66 - a13 * a24 * a31 * a45 * a66 - a14 * a21 - * a33 * a45 * a66 + a11 * a24 * a33 * a45 * a66 + a13 * a21 * a34 - * a45 * a66 - a11 * a23 * a34 * a45 * a66; - cofactor[11] = a16 * a25 * a34 * a43 * a51 - a15 * a26 * a34 * a43 * a51 - - a16 * a24 * a35 * a43 * a51 + a14 * a26 * a35 * a43 * a51 + a15 - * a24 * a36 * a43 * a51 - a14 * a25 * a36 * a43 * a51 - a16 * a25 - * a33 * a44 * a51 + a15 * a26 * a33 * a44 * a51 + a16 * a23 * a35 - * a44 * a51 - a13 * a26 * a35 * a44 * a51 - a15 * a23 * a36 * a44 - * a51 + a13 * a25 * a36 * a44 * a51 + a16 * a24 * a33 * a45 * a51 - - a14 * a26 * a33 * a45 * a51 - a16 * a23 * a34 * a45 * a51 + a13 - * a26 * a34 * a45 * a51 + a14 * a23 * a36 * a45 * a51 - a13 * a24 - * a36 * a45 * a51 - a15 * a24 * a33 * a46 * a51 + a14 * a25 * a33 - * a46 * a51 + a15 * a23 * a34 * a46 * a51 - a13 * a25 * a34 * a46 - * a51 - a14 * a23 * a35 * a46 * a51 + a13 * a24 * a35 * a46 * a51 - - a16 * a25 * a34 * a41 * a53 + a15 * a26 * a34 * a41 * a53 + a16 - * a24 * a35 * a41 * a53 - a14 * a26 * a35 * a41 * a53 - a15 * a24 - * a36 * a41 * a53 + a14 * a25 * a36 * a41 * a53 + a16 * a25 * a31 - * a44 * a53 - a15 * a26 * a31 * a44 * a53 - a16 * a21 * a35 * a44 - * a53 + a11 * a26 * a35 * a44 * a53 + a15 * a21 * a36 * a44 * a53 - - a11 * a25 * a36 * a44 * a53 - a16 * a24 * a31 * a45 * a53 + a14 - * a26 * a31 * a45 * a53 + a16 * a21 * a34 * a45 * a53 - a11 * a26 - * a34 * a45 * a53 - a14 * a21 * a36 * a45 * a53 + a11 * a24 * a36 - * a45 * a53 + a15 * a24 * a31 * a46 * a53 - a14 * a25 * a31 * a46 - * a53 - a15 * a21 * a34 * a46 * a53 + a11 * a25 * a34 * a46 * a53 - + a14 * a21 * a35 * a46 * a53 - a11 * a24 * a35 * a46 * a53 + a16 - * a25 * a33 * a41 * a54 - a15 * a26 * a33 * a41 * a54 - a16 * a23 - * a35 * a41 * a54 + a13 * a26 * a35 * a41 * a54 + a15 * a23 * a36 - * a41 * a54 - a13 * a25 * a36 * a41 * a54 - a16 * a25 * a31 * a43 - * a54 + a15 * a26 * a31 * a43 * a54 + a16 * a21 * a35 * a43 * a54 - - a11 * a26 * a35 * a43 * a54 - a15 * a21 * a36 * a43 * a54 + a11 - * a25 * a36 * a43 * a54 + a16 * a23 * a31 * a45 * a54 - a13 * a26 - * a31 * a45 * a54 - a16 * a21 * a33 * a45 * a54 + a11 * a26 * a33 - * a45 * a54 + a13 * a21 * a36 * a45 * a54 - a11 * a23 * a36 * a45 - * a54 - a15 * a23 * a31 * a46 * a54 + a13 * a25 * a31 * a46 * a54 - + a15 * a21 * a33 * a46 * a54 - a11 * a25 * a33 * a46 * a54 - a13 - * a21 * a35 * a46 * a54 + a11 * a23 * a35 * a46 * a54 - a16 * a24 - * a33 * a41 * a55 + a14 * a26 * a33 * a41 * a55 + a16 * a23 * a34 - * a41 * a55 - a13 * a26 * a34 * a41 * a55 - a14 * a23 * a36 * a41 - * a55 + a13 * a24 * a36 * a41 * a55 + a16 * a24 * a31 * a43 * a55 - - a14 * a26 * a31 * a43 * a55 - a16 * a21 * a34 * a43 * a55 + a11 - * a26 * a34 * a43 * a55 + a14 * a21 * a36 * a43 * a55 - a11 * a24 - * a36 * a43 * a55 - a16 * a23 * a31 * a44 * a55 + a13 * a26 * a31 - * a44 * a55 + a16 * a21 * a33 * a44 * a55 - a11 * a26 * a33 * a44 - * a55 - a13 * a21 * a36 * a44 * a55 + a11 * a23 * a36 * a44 * a55 - + a14 * a23 * a31 * a46 * a55 - a13 * a24 * a31 * a46 * a55 - a14 - * a21 * a33 * a46 * a55 + a11 * a24 * a33 * a46 * a55 + a13 * a21 - * a34 * a46 * a55 - a11 * a23 * a34 * a46 * a55 + a15 * a24 * a33 - * a41 * a56 - a14 * a25 * a33 * a41 * a56 - a15 * a23 * a34 * a41 - * a56 + a13 * a25 * a34 * a41 * a56 + a14 * a23 * a35 * a41 * a56 - - a13 * a24 * a35 * a41 * a56 - a15 * a24 * a31 * a43 * a56 + a14 - * a25 * a31 * a43 * a56 + a15 * a21 * a34 * a43 * a56 - a11 * a25 - * a34 * a43 * a56 - a14 * a21 * a35 * a43 * a56 + a11 * a24 * a35 - * a43 * a56 + a15 * a23 * a31 * a44 * a56 - a13 * a25 * a31 * a44 - * a56 - a15 * a21 * a33 * a44 * a56 + a11 * a25 * a33 * a44 * a56 - + a13 * a21 * a35 * a44 * a56 - a11 * a23 * a35 * a44 * a56 - a14 - * a23 * a31 * a45 * a56 + a13 * a24 * a31 * a45 * a56 + a14 * a21 - * a33 * a45 * a56 - a11 * a24 * a33 * a45 * a56 - a13 * a21 * a34 - * a45 * a56 + a11 * a23 * a34 * a45 * a56; - cofactor[12] = a26 * a35 * a44 * a52 * a61 - a25 * a36 * a44 * a52 * a61 - - a26 * a34 * a45 * a52 * a61 + a24 * a36 * a45 * a52 * a61 + a25 - * a34 * a46 * a52 * a61 - a24 * a35 * a46 * a52 * a61 - a26 * a35 - * a42 * a54 * a61 + a25 * a36 * a42 * a54 * a61 + a26 * a32 * a45 - * a54 * a61 - a22 * a36 * a45 * a54 * a61 - a25 * a32 * a46 * a54 - * a61 + a22 * a35 * a46 * a54 * a61 + a26 * a34 * a42 * a55 * a61 - - a24 * a36 * a42 * a55 * a61 - a26 * a32 * a44 * a55 * a61 + a22 - * a36 * a44 * a55 * a61 + a24 * a32 * a46 * a55 * a61 - a22 * a34 - * a46 * a55 * a61 - a25 * a34 * a42 * a56 * a61 + a24 * a35 * a42 - * a56 * a61 + a25 * a32 * a44 * a56 * a61 - a22 * a35 * a44 * a56 - * a61 - a24 * a32 * a45 * a56 * a61 + a22 * a34 * a45 * a56 * a61 - - a26 * a35 * a44 * a51 * a62 + a25 * a36 * a44 * a51 * a62 + a26 - * a34 * a45 * a51 * a62 - a24 * a36 * a45 * a51 * a62 - a25 * a34 - * a46 * a51 * a62 + a24 * a35 * a46 * a51 * a62 + a26 * a35 * a41 - * a54 * a62 - a25 * a36 * a41 * a54 * a62 - a26 * a31 * a45 * a54 - * a62 + a21 * a36 * a45 * a54 * a62 + a25 * a31 * a46 * a54 * a62 - - a21 * a35 * a46 * a54 * a62 - a26 * a34 * a41 * a55 * a62 + a24 - * a36 * a41 * a55 * a62 + a26 * a31 * a44 * a55 * a62 - a21 * a36 - * a44 * a55 * a62 - a24 * a31 * a46 * a55 * a62 + a21 * a34 * a46 - * a55 * a62 + a25 * a34 * a41 * a56 * a62 - a24 * a35 * a41 * a56 - * a62 - a25 * a31 * a44 * a56 * a62 + a21 * a35 * a44 * a56 * a62 - + a24 * a31 * a45 * a56 * a62 - a21 * a34 * a45 * a56 * a62 + a26 - * a35 * a42 * a51 * a64 - a25 * a36 * a42 * a51 * a64 - a26 * a32 - * a45 * a51 * a64 + a22 * a36 * a45 * a51 * a64 + a25 * a32 * a46 - * a51 * a64 - a22 * a35 * a46 * a51 * a64 - a26 * a35 * a41 * a52 - * a64 + a25 * a36 * a41 * a52 * a64 + a26 * a31 * a45 * a52 * a64 - - a21 * a36 * a45 * a52 * a64 - a25 * a31 * a46 * a52 * a64 + a21 - * a35 * a46 * a52 * a64 + a26 * a32 * a41 * a55 * a64 - a22 * a36 - * a41 * a55 * a64 - a26 * a31 * a42 * a55 * a64 + a21 * a36 * a42 - * a55 * a64 + a22 * a31 * a46 * a55 * a64 - a21 * a32 * a46 * a55 - * a64 - a25 * a32 * a41 * a56 * a64 + a22 * a35 * a41 * a56 * a64 - + a25 * a31 * a42 * a56 * a64 - a21 * a35 * a42 * a56 * a64 - a22 - * a31 * a45 * a56 * a64 + a21 * a32 * a45 * a56 * a64 - a26 * a34 - * a42 * a51 * a65 + a24 * a36 * a42 * a51 * a65 + a26 * a32 * a44 - * a51 * a65 - a22 * a36 * a44 * a51 * a65 - a24 * a32 * a46 * a51 - * a65 + a22 * a34 * a46 * a51 * a65 + a26 * a34 * a41 * a52 * a65 - - a24 * a36 * a41 * a52 * a65 - a26 * a31 * a44 * a52 * a65 + a21 - * a36 * a44 * a52 * a65 + a24 * a31 * a46 * a52 * a65 - a21 * a34 - * a46 * a52 * a65 - a26 * a32 * a41 * a54 * a65 + a22 * a36 * a41 - * a54 * a65 + a26 * a31 * a42 * a54 * a65 - a21 * a36 * a42 * a54 - * a65 - a22 * a31 * a46 * a54 * a65 + a21 * a32 * a46 * a54 * a65 - + a24 * a32 * a41 * a56 * a65 - a22 * a34 * a41 * a56 * a65 - a24 - * a31 * a42 * a56 * a65 + a21 * a34 * a42 * a56 * a65 + a22 * a31 - * a44 * a56 * a65 - a21 * a32 * a44 * a56 * a65 + a25 * a34 * a42 - * a51 * a66 - a24 * a35 * a42 * a51 * a66 - a25 * a32 * a44 * a51 - * a66 + a22 * a35 * a44 * a51 * a66 + a24 * a32 * a45 * a51 * a66 - - a22 * a34 * a45 * a51 * a66 - a25 * a34 * a41 * a52 * a66 + a24 - * a35 * a41 * a52 * a66 + a25 * a31 * a44 * a52 * a66 - a21 * a35 - * a44 * a52 * a66 - a24 * a31 * a45 * a52 * a66 + a21 * a34 * a45 - * a52 * a66 + a25 * a32 * a41 * a54 * a66 - a22 * a35 * a41 * a54 - * a66 - a25 * a31 * a42 * a54 * a66 + a21 * a35 * a42 * a54 * a66 - + a22 * a31 * a45 * a54 * a66 - a21 * a32 * a45 * a54 * a66 - a24 - * a32 * a41 * a55 * a66 + a22 * a34 * a41 * a55 * a66 + a24 * a31 - * a42 * a55 * a66 - a21 * a34 * a42 * a55 * a66 - a22 * a31 * a44 - * a55 * a66 + a21 * a32 * a44 * a55 * a66; - cofactor[13] = -a16 * a35 * a44 * a52 * a61 + a15 * a36 * a44 * a52 * a61 - + a16 * a34 * a45 * a52 * a61 - a14 * a36 * a45 * a52 * a61 - a15 - * a34 * a46 * a52 * a61 + a14 * a35 * a46 * a52 * a61 + a16 * a35 - * a42 * a54 * a61 - a15 * a36 * a42 * a54 * a61 - a16 * a32 * a45 - * a54 * a61 + a12 * a36 * a45 * a54 * a61 + a15 * a32 * a46 * a54 - * a61 - a12 * a35 * a46 * a54 * a61 - a16 * a34 * a42 * a55 * a61 - + a14 * a36 * a42 * a55 * a61 + a16 * a32 * a44 * a55 * a61 - a12 - * a36 * a44 * a55 * a61 - a14 * a32 * a46 * a55 * a61 + a12 * a34 - * a46 * a55 * a61 + a15 * a34 * a42 * a56 * a61 - a14 * a35 * a42 - * a56 * a61 - a15 * a32 * a44 * a56 * a61 + a12 * a35 * a44 * a56 - * a61 + a14 * a32 * a45 * a56 * a61 - a12 * a34 * a45 * a56 * a61 - + a16 * a35 * a44 * a51 * a62 - a15 * a36 * a44 * a51 * a62 - a16 - * a34 * a45 * a51 * a62 + a14 * a36 * a45 * a51 * a62 + a15 * a34 - * a46 * a51 * a62 - a14 * a35 * a46 * a51 * a62 - a16 * a35 * a41 - * a54 * a62 + a15 * a36 * a41 * a54 * a62 + a16 * a31 * a45 * a54 - * a62 - a11 * a36 * a45 * a54 * a62 - a15 * a31 * a46 * a54 * a62 - + a11 * a35 * a46 * a54 * a62 + a16 * a34 * a41 * a55 * a62 - a14 - * a36 * a41 * a55 * a62 - a16 * a31 * a44 * a55 * a62 + a11 * a36 - * a44 * a55 * a62 + a14 * a31 * a46 * a55 * a62 - a11 * a34 * a46 - * a55 * a62 - a15 * a34 * a41 * a56 * a62 + a14 * a35 * a41 * a56 - * a62 + a15 * a31 * a44 * a56 * a62 - a11 * a35 * a44 * a56 * a62 - - a14 * a31 * a45 * a56 * a62 + a11 * a34 * a45 * a56 * a62 - a16 - * a35 * a42 * a51 * a64 + a15 * a36 * a42 * a51 * a64 + a16 * a32 - * a45 * a51 * a64 - a12 * a36 * a45 * a51 * a64 - a15 * a32 * a46 - * a51 * a64 + a12 * a35 * a46 * a51 * a64 + a16 * a35 * a41 * a52 - * a64 - a15 * a36 * a41 * a52 * a64 - a16 * a31 * a45 * a52 * a64 - + a11 * a36 * a45 * a52 * a64 + a15 * a31 * a46 * a52 * a64 - a11 - * a35 * a46 * a52 * a64 - a16 * a32 * a41 * a55 * a64 + a12 * a36 - * a41 * a55 * a64 + a16 * a31 * a42 * a55 * a64 - a11 * a36 * a42 - * a55 * a64 - a12 * a31 * a46 * a55 * a64 + a11 * a32 * a46 * a55 - * a64 + a15 * a32 * a41 * a56 * a64 - a12 * a35 * a41 * a56 * a64 - - a15 * a31 * a42 * a56 * a64 + a11 * a35 * a42 * a56 * a64 + a12 - * a31 * a45 * a56 * a64 - a11 * a32 * a45 * a56 * a64 + a16 * a34 - * a42 * a51 * a65 - a14 * a36 * a42 * a51 * a65 - a16 * a32 * a44 - * a51 * a65 + a12 * a36 * a44 * a51 * a65 + a14 * a32 * a46 * a51 - * a65 - a12 * a34 * a46 * a51 * a65 - a16 * a34 * a41 * a52 * a65 - + a14 * a36 * a41 * a52 * a65 + a16 * a31 * a44 * a52 * a65 - a11 - * a36 * a44 * a52 * a65 - a14 * a31 * a46 * a52 * a65 + a11 * a34 - * a46 * a52 * a65 + a16 * a32 * a41 * a54 * a65 - a12 * a36 * a41 - * a54 * a65 - a16 * a31 * a42 * a54 * a65 + a11 * a36 * a42 * a54 - * a65 + a12 * a31 * a46 * a54 * a65 - a11 * a32 * a46 * a54 * a65 - - a14 * a32 * a41 * a56 * a65 + a12 * a34 * a41 * a56 * a65 + a14 - * a31 * a42 * a56 * a65 - a11 * a34 * a42 * a56 * a65 - a12 * a31 - * a44 * a56 * a65 + a11 * a32 * a44 * a56 * a65 - a15 * a34 * a42 - * a51 * a66 + a14 * a35 * a42 * a51 * a66 + a15 * a32 * a44 * a51 - * a66 - a12 * a35 * a44 * a51 * a66 - a14 * a32 * a45 * a51 * a66 - + a12 * a34 * a45 * a51 * a66 + a15 * a34 * a41 * a52 * a66 - a14 - * a35 * a41 * a52 * a66 - a15 * a31 * a44 * a52 * a66 + a11 * a35 - * a44 * a52 * a66 + a14 * a31 * a45 * a52 * a66 - a11 * a34 * a45 - * a52 * a66 - a15 * a32 * a41 * a54 * a66 + a12 * a35 * a41 * a54 - * a66 + a15 * a31 * a42 * a54 * a66 - a11 * a35 * a42 * a54 * a66 - - a12 * a31 * a45 * a54 * a66 + a11 * a32 * a45 * a54 * a66 + a14 - * a32 * a41 * a55 * a66 - a12 * a34 * a41 * a55 * a66 - a14 * a31 - * a42 * a55 * a66 + a11 * a34 * a42 * a55 * a66 + a12 * a31 * a44 - * a55 * a66 - a11 * a32 * a44 * a55 * a66; - cofactor[14] = a16 * a25 * a44 * a52 * a61 - a15 * a26 * a44 * a52 * a61 - - a16 * a24 * a45 * a52 * a61 + a14 * a26 * a45 * a52 * a61 + a15 - * a24 * a46 * a52 * a61 - a14 * a25 * a46 * a52 * a61 - a16 * a25 - * a42 * a54 * a61 + a15 * a26 * a42 * a54 * a61 + a16 * a22 * a45 - * a54 * a61 - a12 * a26 * a45 * a54 * a61 - a15 * a22 * a46 * a54 - * a61 + a12 * a25 * a46 * a54 * a61 + a16 * a24 * a42 * a55 * a61 - - a14 * a26 * a42 * a55 * a61 - a16 * a22 * a44 * a55 * a61 + a12 - * a26 * a44 * a55 * a61 + a14 * a22 * a46 * a55 * a61 - a12 * a24 - * a46 * a55 * a61 - a15 * a24 * a42 * a56 * a61 + a14 * a25 * a42 - * a56 * a61 + a15 * a22 * a44 * a56 * a61 - a12 * a25 * a44 * a56 - * a61 - a14 * a22 * a45 * a56 * a61 + a12 * a24 * a45 * a56 * a61 - - a16 * a25 * a44 * a51 * a62 + a15 * a26 * a44 * a51 * a62 + a16 - * a24 * a45 * a51 * a62 - a14 * a26 * a45 * a51 * a62 - a15 * a24 - * a46 * a51 * a62 + a14 * a25 * a46 * a51 * a62 + a16 * a25 * a41 - * a54 * a62 - a15 * a26 * a41 * a54 * a62 - a16 * a21 * a45 * a54 - * a62 + a11 * a26 * a45 * a54 * a62 + a15 * a21 * a46 * a54 * a62 - - a11 * a25 * a46 * a54 * a62 - a16 * a24 * a41 * a55 * a62 + a14 - * a26 * a41 * a55 * a62 + a16 * a21 * a44 * a55 * a62 - a11 * a26 - * a44 * a55 * a62 - a14 * a21 * a46 * a55 * a62 + a11 * a24 * a46 - * a55 * a62 + a15 * a24 * a41 * a56 * a62 - a14 * a25 * a41 * a56 - * a62 - a15 * a21 * a44 * a56 * a62 + a11 * a25 * a44 * a56 * a62 - + a14 * a21 * a45 * a56 * a62 - a11 * a24 * a45 * a56 * a62 + a16 - * a25 * a42 * a51 * a64 - a15 * a26 * a42 * a51 * a64 - a16 * a22 - * a45 * a51 * a64 + a12 * a26 * a45 * a51 * a64 + a15 * a22 * a46 - * a51 * a64 - a12 * a25 * a46 * a51 * a64 - a16 * a25 * a41 * a52 - * a64 + a15 * a26 * a41 * a52 * a64 + a16 * a21 * a45 * a52 * a64 - - a11 * a26 * a45 * a52 * a64 - a15 * a21 * a46 * a52 * a64 + a11 - * a25 * a46 * a52 * a64 + a16 * a22 * a41 * a55 * a64 - a12 * a26 - * a41 * a55 * a64 - a16 * a21 * a42 * a55 * a64 + a11 * a26 * a42 - * a55 * a64 + a12 * a21 * a46 * a55 * a64 - a11 * a22 * a46 * a55 - * a64 - a15 * a22 * a41 * a56 * a64 + a12 * a25 * a41 * a56 * a64 - + a15 * a21 * a42 * a56 * a64 - a11 * a25 * a42 * a56 * a64 - a12 - * a21 * a45 * a56 * a64 + a11 * a22 * a45 * a56 * a64 - a16 * a24 - * a42 * a51 * a65 + a14 * a26 * a42 * a51 * a65 + a16 * a22 * a44 - * a51 * a65 - a12 * a26 * a44 * a51 * a65 - a14 * a22 * a46 * a51 - * a65 + a12 * a24 * a46 * a51 * a65 + a16 * a24 * a41 * a52 * a65 - - a14 * a26 * a41 * a52 * a65 - a16 * a21 * a44 * a52 * a65 + a11 - * a26 * a44 * a52 * a65 + a14 * a21 * a46 * a52 * a65 - a11 * a24 - * a46 * a52 * a65 - a16 * a22 * a41 * a54 * a65 + a12 * a26 * a41 - * a54 * a65 + a16 * a21 * a42 * a54 * a65 - a11 * a26 * a42 * a54 - * a65 - a12 * a21 * a46 * a54 * a65 + a11 * a22 * a46 * a54 * a65 - + a14 * a22 * a41 * a56 * a65 - a12 * a24 * a41 * a56 * a65 - a14 - * a21 * a42 * a56 * a65 + a11 * a24 * a42 * a56 * a65 + a12 * a21 - * a44 * a56 * a65 - a11 * a22 * a44 * a56 * a65 + a15 * a24 * a42 - * a51 * a66 - a14 * a25 * a42 * a51 * a66 - a15 * a22 * a44 * a51 - * a66 + a12 * a25 * a44 * a51 * a66 + a14 * a22 * a45 * a51 * a66 - - a12 * a24 * a45 * a51 * a66 - a15 * a24 * a41 * a52 * a66 + a14 - * a25 * a41 * a52 * a66 + a15 * a21 * a44 * a52 * a66 - a11 * a25 - * a44 * a52 * a66 - a14 * a21 * a45 * a52 * a66 + a11 * a24 * a45 - * a52 * a66 + a15 * a22 * a41 * a54 * a66 - a12 * a25 * a41 * a54 - * a66 - a15 * a21 * a42 * a54 * a66 + a11 * a25 * a42 * a54 * a66 - + a12 * a21 * a45 * a54 * a66 - a11 * a22 * a45 * a54 * a66 - a14 - * a22 * a41 * a55 * a66 + a12 * a24 * a41 * a55 * a66 + a14 * a21 - * a42 * a55 * a66 - a11 * a24 * a42 * a55 * a66 - a12 * a21 * a44 - * a55 * a66 + a11 * a22 * a44 * a55 * a66; - cofactor[15] = -a16 * a25 * a34 * a52 * a61 + a15 * a26 * a34 * a52 * a61 - + a16 * a24 * a35 * a52 * a61 - a14 * a26 * a35 * a52 * a61 - a15 - * a24 * a36 * a52 * a61 + a14 * a25 * a36 * a52 * a61 + a16 * a25 - * a32 * a54 * a61 - a15 * a26 * a32 * a54 * a61 - a16 * a22 * a35 - * a54 * a61 + a12 * a26 * a35 * a54 * a61 + a15 * a22 * a36 * a54 - * a61 - a12 * a25 * a36 * a54 * a61 - a16 * a24 * a32 * a55 * a61 - + a14 * a26 * a32 * a55 * a61 + a16 * a22 * a34 * a55 * a61 - a12 - * a26 * a34 * a55 * a61 - a14 * a22 * a36 * a55 * a61 + a12 * a24 - * a36 * a55 * a61 + a15 * a24 * a32 * a56 * a61 - a14 * a25 * a32 - * a56 * a61 - a15 * a22 * a34 * a56 * a61 + a12 * a25 * a34 * a56 - * a61 + a14 * a22 * a35 * a56 * a61 - a12 * a24 * a35 * a56 * a61 - + a16 * a25 * a34 * a51 * a62 - a15 * a26 * a34 * a51 * a62 - a16 - * a24 * a35 * a51 * a62 + a14 * a26 * a35 * a51 * a62 + a15 * a24 - * a36 * a51 * a62 - a14 * a25 * a36 * a51 * a62 - a16 * a25 * a31 - * a54 * a62 + a15 * a26 * a31 * a54 * a62 + a16 * a21 * a35 * a54 - * a62 - a11 * a26 * a35 * a54 * a62 - a15 * a21 * a36 * a54 * a62 - + a11 * a25 * a36 * a54 * a62 + a16 * a24 * a31 * a55 * a62 - a14 - * a26 * a31 * a55 * a62 - a16 * a21 * a34 * a55 * a62 + a11 * a26 - * a34 * a55 * a62 + a14 * a21 * a36 * a55 * a62 - a11 * a24 * a36 - * a55 * a62 - a15 * a24 * a31 * a56 * a62 + a14 * a25 * a31 * a56 - * a62 + a15 * a21 * a34 * a56 * a62 - a11 * a25 * a34 * a56 * a62 - - a14 * a21 * a35 * a56 * a62 + a11 * a24 * a35 * a56 * a62 - a16 - * a25 * a32 * a51 * a64 + a15 * a26 * a32 * a51 * a64 + a16 * a22 - * a35 * a51 * a64 - a12 * a26 * a35 * a51 * a64 - a15 * a22 * a36 - * a51 * a64 + a12 * a25 * a36 * a51 * a64 + a16 * a25 * a31 * a52 - * a64 - a15 * a26 * a31 * a52 * a64 - a16 * a21 * a35 * a52 * a64 - + a11 * a26 * a35 * a52 * a64 + a15 * a21 * a36 * a52 * a64 - a11 - * a25 * a36 * a52 * a64 - a16 * a22 * a31 * a55 * a64 + a12 * a26 - * a31 * a55 * a64 + a16 * a21 * a32 * a55 * a64 - a11 * a26 * a32 - * a55 * a64 - a12 * a21 * a36 * a55 * a64 + a11 * a22 * a36 * a55 - * a64 + a15 * a22 * a31 * a56 * a64 - a12 * a25 * a31 * a56 * a64 - - a15 * a21 * a32 * a56 * a64 + a11 * a25 * a32 * a56 * a64 + a12 - * a21 * a35 * a56 * a64 - a11 * a22 * a35 * a56 * a64 + a16 * a24 - * a32 * a51 * a65 - a14 * a26 * a32 * a51 * a65 - a16 * a22 * a34 - * a51 * a65 + a12 * a26 * a34 * a51 * a65 + a14 * a22 * a36 * a51 - * a65 - a12 * a24 * a36 * a51 * a65 - a16 * a24 * a31 * a52 * a65 - + a14 * a26 * a31 * a52 * a65 + a16 * a21 * a34 * a52 * a65 - a11 - * a26 * a34 * a52 * a65 - a14 * a21 * a36 * a52 * a65 + a11 * a24 - * a36 * a52 * a65 + a16 * a22 * a31 * a54 * a65 - a12 * a26 * a31 - * a54 * a65 - a16 * a21 * a32 * a54 * a65 + a11 * a26 * a32 * a54 - * a65 + a12 * a21 * a36 * a54 * a65 - a11 * a22 * a36 * a54 * a65 - - a14 * a22 * a31 * a56 * a65 + a12 * a24 * a31 * a56 * a65 + a14 - * a21 * a32 * a56 * a65 - a11 * a24 * a32 * a56 * a65 - a12 * a21 - * a34 * a56 * a65 + a11 * a22 * a34 * a56 * a65 - a15 * a24 * a32 - * a51 * a66 + a14 * a25 * a32 * a51 * a66 + a15 * a22 * a34 * a51 - * a66 - a12 * a25 * a34 * a51 * a66 - a14 * a22 * a35 * a51 * a66 - + a12 * a24 * a35 * a51 * a66 + a15 * a24 * a31 * a52 * a66 - a14 - * a25 * a31 * a52 * a66 - a15 * a21 * a34 * a52 * a66 + a11 * a25 - * a34 * a52 * a66 + a14 * a21 * a35 * a52 * a66 - a11 * a24 * a35 - * a52 * a66 - a15 * a22 * a31 * a54 * a66 + a12 * a25 * a31 * a54 - * a66 + a15 * a21 * a32 * a54 * a66 - a11 * a25 * a32 * a54 * a66 - - a12 * a21 * a35 * a54 * a66 + a11 * a22 * a35 * a54 * a66 + a14 - * a22 * a31 * a55 * a66 - a12 * a24 * a31 * a55 * a66 - a14 * a21 - * a32 * a55 * a66 + a11 * a24 * a32 * a55 * a66 + a12 * a21 * a34 - * a55 * a66 - a11 * a22 * a34 * a55 * a66; - cofactor[16] = a16 * a25 * a34 * a42 * a61 - a15 * a26 * a34 * a42 * a61 - - a16 * a24 * a35 * a42 * a61 + a14 * a26 * a35 * a42 * a61 + a15 - * a24 * a36 * a42 * a61 - a14 * a25 * a36 * a42 * a61 - a16 * a25 - * a32 * a44 * a61 + a15 * a26 * a32 * a44 * a61 + a16 * a22 * a35 - * a44 * a61 - a12 * a26 * a35 * a44 * a61 - a15 * a22 * a36 * a44 - * a61 + a12 * a25 * a36 * a44 * a61 + a16 * a24 * a32 * a45 * a61 - - a14 * a26 * a32 * a45 * a61 - a16 * a22 * a34 * a45 * a61 + a12 - * a26 * a34 * a45 * a61 + a14 * a22 * a36 * a45 * a61 - a12 * a24 - * a36 * a45 * a61 - a15 * a24 * a32 * a46 * a61 + a14 * a25 * a32 - * a46 * a61 + a15 * a22 * a34 * a46 * a61 - a12 * a25 * a34 * a46 - * a61 - a14 * a22 * a35 * a46 * a61 + a12 * a24 * a35 * a46 * a61 - - a16 * a25 * a34 * a41 * a62 + a15 * a26 * a34 * a41 * a62 + a16 - * a24 * a35 * a41 * a62 - a14 * a26 * a35 * a41 * a62 - a15 * a24 - * a36 * a41 * a62 + a14 * a25 * a36 * a41 * a62 + a16 * a25 * a31 - * a44 * a62 - a15 * a26 * a31 * a44 * a62 - a16 * a21 * a35 * a44 - * a62 + a11 * a26 * a35 * a44 * a62 + a15 * a21 * a36 * a44 * a62 - - a11 * a25 * a36 * a44 * a62 - a16 * a24 * a31 * a45 * a62 + a14 - * a26 * a31 * a45 * a62 + a16 * a21 * a34 * a45 * a62 - a11 * a26 - * a34 * a45 * a62 - a14 * a21 * a36 * a45 * a62 + a11 * a24 * a36 - * a45 * a62 + a15 * a24 * a31 * a46 * a62 - a14 * a25 * a31 * a46 - * a62 - a15 * a21 * a34 * a46 * a62 + a11 * a25 * a34 * a46 * a62 - + a14 * a21 * a35 * a46 * a62 - a11 * a24 * a35 * a46 * a62 + a16 - * a25 * a32 * a41 * a64 - a15 * a26 * a32 * a41 * a64 - a16 * a22 - * a35 * a41 * a64 + a12 * a26 * a35 * a41 * a64 + a15 * a22 * a36 - * a41 * a64 - a12 * a25 * a36 * a41 * a64 - a16 * a25 * a31 * a42 - * a64 + a15 * a26 * a31 * a42 * a64 + a16 * a21 * a35 * a42 * a64 - - a11 * a26 * a35 * a42 * a64 - a15 * a21 * a36 * a42 * a64 + a11 - * a25 * a36 * a42 * a64 + a16 * a22 * a31 * a45 * a64 - a12 * a26 - * a31 * a45 * a64 - a16 * a21 * a32 * a45 * a64 + a11 * a26 * a32 - * a45 * a64 + a12 * a21 * a36 * a45 * a64 - a11 * a22 * a36 * a45 - * a64 - a15 * a22 * a31 * a46 * a64 + a12 * a25 * a31 * a46 * a64 - + a15 * a21 * a32 * a46 * a64 - a11 * a25 * a32 * a46 * a64 - a12 - * a21 * a35 * a46 * a64 + a11 * a22 * a35 * a46 * a64 - a16 * a24 - * a32 * a41 * a65 + a14 * a26 * a32 * a41 * a65 + a16 * a22 * a34 - * a41 * a65 - a12 * a26 * a34 * a41 * a65 - a14 * a22 * a36 * a41 - * a65 + a12 * a24 * a36 * a41 * a65 + a16 * a24 * a31 * a42 * a65 - - a14 * a26 * a31 * a42 * a65 - a16 * a21 * a34 * a42 * a65 + a11 - * a26 * a34 * a42 * a65 + a14 * a21 * a36 * a42 * a65 - a11 * a24 - * a36 * a42 * a65 - a16 * a22 * a31 * a44 * a65 + a12 * a26 * a31 - * a44 * a65 + a16 * a21 * a32 * a44 * a65 - a11 * a26 * a32 * a44 - * a65 - a12 * a21 * a36 * a44 * a65 + a11 * a22 * a36 * a44 * a65 - + a14 * a22 * a31 * a46 * a65 - a12 * a24 * a31 * a46 * a65 - a14 - * a21 * a32 * a46 * a65 + a11 * a24 * a32 * a46 * a65 + a12 * a21 - * a34 * a46 * a65 - a11 * a22 * a34 * a46 * a65 + a15 * a24 * a32 - * a41 * a66 - a14 * a25 * a32 * a41 * a66 - a15 * a22 * a34 * a41 - * a66 + a12 * a25 * a34 * a41 * a66 + a14 * a22 * a35 * a41 * a66 - - a12 * a24 * a35 * a41 * a66 - a15 * a24 * a31 * a42 * a66 + a14 - * a25 * a31 * a42 * a66 + a15 * a21 * a34 * a42 * a66 - a11 * a25 - * a34 * a42 * a66 - a14 * a21 * a35 * a42 * a66 + a11 * a24 * a35 - * a42 * a66 + a15 * a22 * a31 * a44 * a66 - a12 * a25 * a31 * a44 - * a66 - a15 * a21 * a32 * a44 * a66 + a11 * a25 * a32 * a44 * a66 - + a12 * a21 * a35 * a44 * a66 - a11 * a22 * a35 * a44 * a66 - a14 - * a22 * a31 * a45 * a66 + a12 * a24 * a31 * a45 * a66 + a14 * a21 - * a32 * a45 * a66 - a11 * a24 * a32 * a45 * a66 - a12 * a21 * a34 - * a45 * a66 + a11 * a22 * a34 * a45 * a66; - cofactor[17] = -a16 * a25 * a34 * a42 * a51 + a15 * a26 * a34 * a42 * a51 - + a16 * a24 * a35 * a42 * a51 - a14 * a26 * a35 * a42 * a51 - a15 - * a24 * a36 * a42 * a51 + a14 * a25 * a36 * a42 * a51 + a16 * a25 - * a32 * a44 * a51 - a15 * a26 * a32 * a44 * a51 - a16 * a22 * a35 - * a44 * a51 + a12 * a26 * a35 * a44 * a51 + a15 * a22 * a36 * a44 - * a51 - a12 * a25 * a36 * a44 * a51 - a16 * a24 * a32 * a45 * a51 - + a14 * a26 * a32 * a45 * a51 + a16 * a22 * a34 * a45 * a51 - a12 - * a26 * a34 * a45 * a51 - a14 * a22 * a36 * a45 * a51 + a12 * a24 - * a36 * a45 * a51 + a15 * a24 * a32 * a46 * a51 - a14 * a25 * a32 - * a46 * a51 - a15 * a22 * a34 * a46 * a51 + a12 * a25 * a34 * a46 - * a51 + a14 * a22 * a35 * a46 * a51 - a12 * a24 * a35 * a46 * a51 - + a16 * a25 * a34 * a41 * a52 - a15 * a26 * a34 * a41 * a52 - a16 - * a24 * a35 * a41 * a52 + a14 * a26 * a35 * a41 * a52 + a15 * a24 - * a36 * a41 * a52 - a14 * a25 * a36 * a41 * a52 - a16 * a25 * a31 - * a44 * a52 + a15 * a26 * a31 * a44 * a52 + a16 * a21 * a35 * a44 - * a52 - a11 * a26 * a35 * a44 * a52 - a15 * a21 * a36 * a44 * a52 - + a11 * a25 * a36 * a44 * a52 + a16 * a24 * a31 * a45 * a52 - a14 - * a26 * a31 * a45 * a52 - a16 * a21 * a34 * a45 * a52 + a11 * a26 - * a34 * a45 * a52 + a14 * a21 * a36 * a45 * a52 - a11 * a24 * a36 - * a45 * a52 - a15 * a24 * a31 * a46 * a52 + a14 * a25 * a31 * a46 - * a52 + a15 * a21 * a34 * a46 * a52 - a11 * a25 * a34 * a46 * a52 - - a14 * a21 * a35 * a46 * a52 + a11 * a24 * a35 * a46 * a52 - a16 - * a25 * a32 * a41 * a54 + a15 * a26 * a32 * a41 * a54 + a16 * a22 - * a35 * a41 * a54 - a12 * a26 * a35 * a41 * a54 - a15 * a22 * a36 - * a41 * a54 + a12 * a25 * a36 * a41 * a54 + a16 * a25 * a31 * a42 - * a54 - a15 * a26 * a31 * a42 * a54 - a16 * a21 * a35 * a42 * a54 - + a11 * a26 * a35 * a42 * a54 + a15 * a21 * a36 * a42 * a54 - a11 - * a25 * a36 * a42 * a54 - a16 * a22 * a31 * a45 * a54 + a12 * a26 - * a31 * a45 * a54 + a16 * a21 * a32 * a45 * a54 - a11 * a26 * a32 - * a45 * a54 - a12 * a21 * a36 * a45 * a54 + a11 * a22 * a36 * a45 - * a54 + a15 * a22 * a31 * a46 * a54 - a12 * a25 * a31 * a46 * a54 - - a15 * a21 * a32 * a46 * a54 + a11 * a25 * a32 * a46 * a54 + a12 - * a21 * a35 * a46 * a54 - a11 * a22 * a35 * a46 * a54 + a16 * a24 - * a32 * a41 * a55 - a14 * a26 * a32 * a41 * a55 - a16 * a22 * a34 - * a41 * a55 + a12 * a26 * a34 * a41 * a55 + a14 * a22 * a36 * a41 - * a55 - a12 * a24 * a36 * a41 * a55 - a16 * a24 * a31 * a42 * a55 - + a14 * a26 * a31 * a42 * a55 + a16 * a21 * a34 * a42 * a55 - a11 - * a26 * a34 * a42 * a55 - a14 * a21 * a36 * a42 * a55 + a11 * a24 - * a36 * a42 * a55 + a16 * a22 * a31 * a44 * a55 - a12 * a26 * a31 - * a44 * a55 - a16 * a21 * a32 * a44 * a55 + a11 * a26 * a32 * a44 - * a55 + a12 * a21 * a36 * a44 * a55 - a11 * a22 * a36 * a44 * a55 - - a14 * a22 * a31 * a46 * a55 + a12 * a24 * a31 * a46 * a55 + a14 - * a21 * a32 * a46 * a55 - a11 * a24 * a32 * a46 * a55 - a12 * a21 - * a34 * a46 * a55 + a11 * a22 * a34 * a46 * a55 - a15 * a24 * a32 - * a41 * a56 + a14 * a25 * a32 * a41 * a56 + a15 * a22 * a34 * a41 - * a56 - a12 * a25 * a34 * a41 * a56 - a14 * a22 * a35 * a41 * a56 - + a12 * a24 * a35 * a41 * a56 + a15 * a24 * a31 * a42 * a56 - a14 - * a25 * a31 * a42 * a56 - a15 * a21 * a34 * a42 * a56 + a11 * a25 - * a34 * a42 * a56 + a14 * a21 * a35 * a42 * a56 - a11 * a24 * a35 - * a42 * a56 - a15 * a22 * a31 * a44 * a56 + a12 * a25 * a31 * a44 - * a56 + a15 * a21 * a32 * a44 * a56 - a11 * a25 * a32 * a44 * a56 - - a12 * a21 * a35 * a44 * a56 + a11 * a22 * a35 * a44 * a56 + a14 - * a22 * a31 * a45 * a56 - a12 * a24 * a31 * a45 * a56 - a14 * a21 - * a32 * a45 * a56 + a11 * a24 * a32 * a45 * a56 + a12 * a21 * a34 - * a45 * a56 - a11 * a22 * a34 * a45 * a56; - cofactor[18] = -a26 * a35 * a43 * a52 * a61 + a25 * a36 * a43 * a52 * a61 - + a26 * a33 * a45 * a52 * a61 - a23 * a36 * a45 * a52 * a61 - a25 - * a33 * a46 * a52 * a61 + a23 * a35 * a46 * a52 * a61 + a26 * a35 - * a42 * a53 * a61 - a25 * a36 * a42 * a53 * a61 - a26 * a32 * a45 - * a53 * a61 + a22 * a36 * a45 * a53 * a61 + a25 * a32 * a46 * a53 - * a61 - a22 * a35 * a46 * a53 * a61 - a26 * a33 * a42 * a55 * a61 - + a23 * a36 * a42 * a55 * a61 + a26 * a32 * a43 * a55 * a61 - a22 - * a36 * a43 * a55 * a61 - a23 * a32 * a46 * a55 * a61 + a22 * a33 - * a46 * a55 * a61 + a25 * a33 * a42 * a56 * a61 - a23 * a35 * a42 - * a56 * a61 - a25 * a32 * a43 * a56 * a61 + a22 * a35 * a43 * a56 - * a61 + a23 * a32 * a45 * a56 * a61 - a22 * a33 * a45 * a56 * a61 - + a26 * a35 * a43 * a51 * a62 - a25 * a36 * a43 * a51 * a62 - a26 - * a33 * a45 * a51 * a62 + a23 * a36 * a45 * a51 * a62 + a25 * a33 - * a46 * a51 * a62 - a23 * a35 * a46 * a51 * a62 - a26 * a35 * a41 - * a53 * a62 + a25 * a36 * a41 * a53 * a62 + a26 * a31 * a45 * a53 - * a62 - a21 * a36 * a45 * a53 * a62 - a25 * a31 * a46 * a53 * a62 - + a21 * a35 * a46 * a53 * a62 + a26 * a33 * a41 * a55 * a62 - a23 - * a36 * a41 * a55 * a62 - a26 * a31 * a43 * a55 * a62 + a21 * a36 - * a43 * a55 * a62 + a23 * a31 * a46 * a55 * a62 - a21 * a33 * a46 - * a55 * a62 - a25 * a33 * a41 * a56 * a62 + a23 * a35 * a41 * a56 - * a62 + a25 * a31 * a43 * a56 * a62 - a21 * a35 * a43 * a56 * a62 - - a23 * a31 * a45 * a56 * a62 + a21 * a33 * a45 * a56 * a62 - a26 - * a35 * a42 * a51 * a63 + a25 * a36 * a42 * a51 * a63 + a26 * a32 - * a45 * a51 * a63 - a22 * a36 * a45 * a51 * a63 - a25 * a32 * a46 - * a51 * a63 + a22 * a35 * a46 * a51 * a63 + a26 * a35 * a41 * a52 - * a63 - a25 * a36 * a41 * a52 * a63 - a26 * a31 * a45 * a52 * a63 - + a21 * a36 * a45 * a52 * a63 + a25 * a31 * a46 * a52 * a63 - a21 - * a35 * a46 * a52 * a63 - a26 * a32 * a41 * a55 * a63 + a22 * a36 - * a41 * a55 * a63 + a26 * a31 * a42 * a55 * a63 - a21 * a36 * a42 - * a55 * a63 - a22 * a31 * a46 * a55 * a63 + a21 * a32 * a46 * a55 - * a63 + a25 * a32 * a41 * a56 * a63 - a22 * a35 * a41 * a56 * a63 - - a25 * a31 * a42 * a56 * a63 + a21 * a35 * a42 * a56 * a63 + a22 - * a31 * a45 * a56 * a63 - a21 * a32 * a45 * a56 * a63 + a26 * a33 - * a42 * a51 * a65 - a23 * a36 * a42 * a51 * a65 - a26 * a32 * a43 - * a51 * a65 + a22 * a36 * a43 * a51 * a65 + a23 * a32 * a46 * a51 - * a65 - a22 * a33 * a46 * a51 * a65 - a26 * a33 * a41 * a52 * a65 - + a23 * a36 * a41 * a52 * a65 + a26 * a31 * a43 * a52 * a65 - a21 - * a36 * a43 * a52 * a65 - a23 * a31 * a46 * a52 * a65 + a21 * a33 - * a46 * a52 * a65 + a26 * a32 * a41 * a53 * a65 - a22 * a36 * a41 - * a53 * a65 - a26 * a31 * a42 * a53 * a65 + a21 * a36 * a42 * a53 - * a65 + a22 * a31 * a46 * a53 * a65 - a21 * a32 * a46 * a53 * a65 - - a23 * a32 * a41 * a56 * a65 + a22 * a33 * a41 * a56 * a65 + a23 - * a31 * a42 * a56 * a65 - a21 * a33 * a42 * a56 * a65 - a22 * a31 - * a43 * a56 * a65 + a21 * a32 * a43 * a56 * a65 - a25 * a33 * a42 - * a51 * a66 + a23 * a35 * a42 * a51 * a66 + a25 * a32 * a43 * a51 - * a66 - a22 * a35 * a43 * a51 * a66 - a23 * a32 * a45 * a51 * a66 - + a22 * a33 * a45 * a51 * a66 + a25 * a33 * a41 * a52 * a66 - a23 - * a35 * a41 * a52 * a66 - a25 * a31 * a43 * a52 * a66 + a21 * a35 - * a43 * a52 * a66 + a23 * a31 * a45 * a52 * a66 - a21 * a33 * a45 - * a52 * a66 - a25 * a32 * a41 * a53 * a66 + a22 * a35 * a41 * a53 - * a66 + a25 * a31 * a42 * a53 * a66 - a21 * a35 * a42 * a53 * a66 - - a22 * a31 * a45 * a53 * a66 + a21 * a32 * a45 * a53 * a66 + a23 - * a32 * a41 * a55 * a66 - a22 * a33 * a41 * a55 * a66 - a23 * a31 - * a42 * a55 * a66 + a21 * a33 * a42 * a55 * a66 + a22 * a31 * a43 - * a55 * a66 - a21 * a32 * a43 * a55 * a66; - cofactor[19] = a16 * a35 * a43 * a52 * a61 - a15 * a36 * a43 * a52 * a61 - - a16 * a33 * a45 * a52 * a61 + a13 * a36 * a45 * a52 * a61 + a15 - * a33 * a46 * a52 * a61 - a13 * a35 * a46 * a52 * a61 - a16 * a35 - * a42 * a53 * a61 + a15 * a36 * a42 * a53 * a61 + a16 * a32 * a45 - * a53 * a61 - a12 * a36 * a45 * a53 * a61 - a15 * a32 * a46 * a53 - * a61 + a12 * a35 * a46 * a53 * a61 + a16 * a33 * a42 * a55 * a61 - - a13 * a36 * a42 * a55 * a61 - a16 * a32 * a43 * a55 * a61 + a12 - * a36 * a43 * a55 * a61 + a13 * a32 * a46 * a55 * a61 - a12 * a33 - * a46 * a55 * a61 - a15 * a33 * a42 * a56 * a61 + a13 * a35 * a42 - * a56 * a61 + a15 * a32 * a43 * a56 * a61 - a12 * a35 * a43 * a56 - * a61 - a13 * a32 * a45 * a56 * a61 + a12 * a33 * a45 * a56 * a61 - - a16 * a35 * a43 * a51 * a62 + a15 * a36 * a43 * a51 * a62 + a16 - * a33 * a45 * a51 * a62 - a13 * a36 * a45 * a51 * a62 - a15 * a33 - * a46 * a51 * a62 + a13 * a35 * a46 * a51 * a62 + a16 * a35 * a41 - * a53 * a62 - a15 * a36 * a41 * a53 * a62 - a16 * a31 * a45 * a53 - * a62 + a11 * a36 * a45 * a53 * a62 + a15 * a31 * a46 * a53 * a62 - - a11 * a35 * a46 * a53 * a62 - a16 * a33 * a41 * a55 * a62 + a13 - * a36 * a41 * a55 * a62 + a16 * a31 * a43 * a55 * a62 - a11 * a36 - * a43 * a55 * a62 - a13 * a31 * a46 * a55 * a62 + a11 * a33 * a46 - * a55 * a62 + a15 * a33 * a41 * a56 * a62 - a13 * a35 * a41 * a56 - * a62 - a15 * a31 * a43 * a56 * a62 + a11 * a35 * a43 * a56 * a62 - + a13 * a31 * a45 * a56 * a62 - a11 * a33 * a45 * a56 * a62 + a16 - * a35 * a42 * a51 * a63 - a15 * a36 * a42 * a51 * a63 - a16 * a32 - * a45 * a51 * a63 + a12 * a36 * a45 * a51 * a63 + a15 * a32 * a46 - * a51 * a63 - a12 * a35 * a46 * a51 * a63 - a16 * a35 * a41 * a52 - * a63 + a15 * a36 * a41 * a52 * a63 + a16 * a31 * a45 * a52 * a63 - - a11 * a36 * a45 * a52 * a63 - a15 * a31 * a46 * a52 * a63 + a11 - * a35 * a46 * a52 * a63 + a16 * a32 * a41 * a55 * a63 - a12 * a36 - * a41 * a55 * a63 - a16 * a31 * a42 * a55 * a63 + a11 * a36 * a42 - * a55 * a63 + a12 * a31 * a46 * a55 * a63 - a11 * a32 * a46 * a55 - * a63 - a15 * a32 * a41 * a56 * a63 + a12 * a35 * a41 * a56 * a63 - + a15 * a31 * a42 * a56 * a63 - a11 * a35 * a42 * a56 * a63 - a12 - * a31 * a45 * a56 * a63 + a11 * a32 * a45 * a56 * a63 - a16 * a33 - * a42 * a51 * a65 + a13 * a36 * a42 * a51 * a65 + a16 * a32 * a43 - * a51 * a65 - a12 * a36 * a43 * a51 * a65 - a13 * a32 * a46 * a51 - * a65 + a12 * a33 * a46 * a51 * a65 + a16 * a33 * a41 * a52 * a65 - - a13 * a36 * a41 * a52 * a65 - a16 * a31 * a43 * a52 * a65 + a11 - * a36 * a43 * a52 * a65 + a13 * a31 * a46 * a52 * a65 - a11 * a33 - * a46 * a52 * a65 - a16 * a32 * a41 * a53 * a65 + a12 * a36 * a41 - * a53 * a65 + a16 * a31 * a42 * a53 * a65 - a11 * a36 * a42 * a53 - * a65 - a12 * a31 * a46 * a53 * a65 + a11 * a32 * a46 * a53 * a65 - + a13 * a32 * a41 * a56 * a65 - a12 * a33 * a41 * a56 * a65 - a13 - * a31 * a42 * a56 * a65 + a11 * a33 * a42 * a56 * a65 + a12 * a31 - * a43 * a56 * a65 - a11 * a32 * a43 * a56 * a65 + a15 * a33 * a42 - * a51 * a66 - a13 * a35 * a42 * a51 * a66 - a15 * a32 * a43 * a51 - * a66 + a12 * a35 * a43 * a51 * a66 + a13 * a32 * a45 * a51 * a66 - - a12 * a33 * a45 * a51 * a66 - a15 * a33 * a41 * a52 * a66 + a13 - * a35 * a41 * a52 * a66 + a15 * a31 * a43 * a52 * a66 - a11 * a35 - * a43 * a52 * a66 - a13 * a31 * a45 * a52 * a66 + a11 * a33 * a45 - * a52 * a66 + a15 * a32 * a41 * a53 * a66 - a12 * a35 * a41 * a53 - * a66 - a15 * a31 * a42 * a53 * a66 + a11 * a35 * a42 * a53 * a66 - + a12 * a31 * a45 * a53 * a66 - a11 * a32 * a45 * a53 * a66 - a13 - * a32 * a41 * a55 * a66 + a12 * a33 * a41 * a55 * a66 + a13 * a31 - * a42 * a55 * a66 - a11 * a33 * a42 * a55 * a66 - a12 * a31 * a43 - * a55 * a66 + a11 * a32 * a43 * a55 * a66; - cofactor[20] = -a16 * a25 * a43 * a52 * a61 + a15 * a26 * a43 * a52 * a61 - + a16 * a23 * a45 * a52 * a61 - a13 * a26 * a45 * a52 * a61 - a15 - * a23 * a46 * a52 * a61 + a13 * a25 * a46 * a52 * a61 + a16 * a25 - * a42 * a53 * a61 - a15 * a26 * a42 * a53 * a61 - a16 * a22 * a45 - * a53 * a61 + a12 * a26 * a45 * a53 * a61 + a15 * a22 * a46 * a53 - * a61 - a12 * a25 * a46 * a53 * a61 - a16 * a23 * a42 * a55 * a61 - + a13 * a26 * a42 * a55 * a61 + a16 * a22 * a43 * a55 * a61 - a12 - * a26 * a43 * a55 * a61 - a13 * a22 * a46 * a55 * a61 + a12 * a23 - * a46 * a55 * a61 + a15 * a23 * a42 * a56 * a61 - a13 * a25 * a42 - * a56 * a61 - a15 * a22 * a43 * a56 * a61 + a12 * a25 * a43 * a56 - * a61 + a13 * a22 * a45 * a56 * a61 - a12 * a23 * a45 * a56 * a61 - + a16 * a25 * a43 * a51 * a62 - a15 * a26 * a43 * a51 * a62 - a16 - * a23 * a45 * a51 * a62 + a13 * a26 * a45 * a51 * a62 + a15 * a23 - * a46 * a51 * a62 - a13 * a25 * a46 * a51 * a62 - a16 * a25 * a41 - * a53 * a62 + a15 * a26 * a41 * a53 * a62 + a16 * a21 * a45 * a53 - * a62 - a11 * a26 * a45 * a53 * a62 - a15 * a21 * a46 * a53 * a62 - + a11 * a25 * a46 * a53 * a62 + a16 * a23 * a41 * a55 * a62 - a13 - * a26 * a41 * a55 * a62 - a16 * a21 * a43 * a55 * a62 + a11 * a26 - * a43 * a55 * a62 + a13 * a21 * a46 * a55 * a62 - a11 * a23 * a46 - * a55 * a62 - a15 * a23 * a41 * a56 * a62 + a13 * a25 * a41 * a56 - * a62 + a15 * a21 * a43 * a56 * a62 - a11 * a25 * a43 * a56 * a62 - - a13 * a21 * a45 * a56 * a62 + a11 * a23 * a45 * a56 * a62 - a16 - * a25 * a42 * a51 * a63 + a15 * a26 * a42 * a51 * a63 + a16 * a22 - * a45 * a51 * a63 - a12 * a26 * a45 * a51 * a63 - a15 * a22 * a46 - * a51 * a63 + a12 * a25 * a46 * a51 * a63 + a16 * a25 * a41 * a52 - * a63 - a15 * a26 * a41 * a52 * a63 - a16 * a21 * a45 * a52 * a63 - + a11 * a26 * a45 * a52 * a63 + a15 * a21 * a46 * a52 * a63 - a11 - * a25 * a46 * a52 * a63 - a16 * a22 * a41 * a55 * a63 + a12 * a26 - * a41 * a55 * a63 + a16 * a21 * a42 * a55 * a63 - a11 * a26 * a42 - * a55 * a63 - a12 * a21 * a46 * a55 * a63 + a11 * a22 * a46 * a55 - * a63 + a15 * a22 * a41 * a56 * a63 - a12 * a25 * a41 * a56 * a63 - - a15 * a21 * a42 * a56 * a63 + a11 * a25 * a42 * a56 * a63 + a12 - * a21 * a45 * a56 * a63 - a11 * a22 * a45 * a56 * a63 + a16 * a23 - * a42 * a51 * a65 - a13 * a26 * a42 * a51 * a65 - a16 * a22 * a43 - * a51 * a65 + a12 * a26 * a43 * a51 * a65 + a13 * a22 * a46 * a51 - * a65 - a12 * a23 * a46 * a51 * a65 - a16 * a23 * a41 * a52 * a65 - + a13 * a26 * a41 * a52 * a65 + a16 * a21 * a43 * a52 * a65 - a11 - * a26 * a43 * a52 * a65 - a13 * a21 * a46 * a52 * a65 + a11 * a23 - * a46 * a52 * a65 + a16 * a22 * a41 * a53 * a65 - a12 * a26 * a41 - * a53 * a65 - a16 * a21 * a42 * a53 * a65 + a11 * a26 * a42 * a53 - * a65 + a12 * a21 * a46 * a53 * a65 - a11 * a22 * a46 * a53 * a65 - - a13 * a22 * a41 * a56 * a65 + a12 * a23 * a41 * a56 * a65 + a13 - * a21 * a42 * a56 * a65 - a11 * a23 * a42 * a56 * a65 - a12 * a21 - * a43 * a56 * a65 + a11 * a22 * a43 * a56 * a65 - a15 * a23 * a42 - * a51 * a66 + a13 * a25 * a42 * a51 * a66 + a15 * a22 * a43 * a51 - * a66 - a12 * a25 * a43 * a51 * a66 - a13 * a22 * a45 * a51 * a66 - + a12 * a23 * a45 * a51 * a66 + a15 * a23 * a41 * a52 * a66 - a13 - * a25 * a41 * a52 * a66 - a15 * a21 * a43 * a52 * a66 + a11 * a25 - * a43 * a52 * a66 + a13 * a21 * a45 * a52 * a66 - a11 * a23 * a45 - * a52 * a66 - a15 * a22 * a41 * a53 * a66 + a12 * a25 * a41 * a53 - * a66 + a15 * a21 * a42 * a53 * a66 - a11 * a25 * a42 * a53 * a66 - - a12 * a21 * a45 * a53 * a66 + a11 * a22 * a45 * a53 * a66 + a13 - * a22 * a41 * a55 * a66 - a12 * a23 * a41 * a55 * a66 - a13 * a21 - * a42 * a55 * a66 + a11 * a23 * a42 * a55 * a66 + a12 * a21 * a43 - * a55 * a66 - a11 * a22 * a43 * a55 * a66; - cofactor[21] = a16 * a25 * a33 * a52 * a61 - a15 * a26 * a33 * a52 * a61 - - a16 * a23 * a35 * a52 * a61 + a13 * a26 * a35 * a52 * a61 + a15 - * a23 * a36 * a52 * a61 - a13 * a25 * a36 * a52 * a61 - a16 * a25 - * a32 * a53 * a61 + a15 * a26 * a32 * a53 * a61 + a16 * a22 * a35 - * a53 * a61 - a12 * a26 * a35 * a53 * a61 - a15 * a22 * a36 * a53 - * a61 + a12 * a25 * a36 * a53 * a61 + a16 * a23 * a32 * a55 * a61 - - a13 * a26 * a32 * a55 * a61 - a16 * a22 * a33 * a55 * a61 + a12 - * a26 * a33 * a55 * a61 + a13 * a22 * a36 * a55 * a61 - a12 * a23 - * a36 * a55 * a61 - a15 * a23 * a32 * a56 * a61 + a13 * a25 * a32 - * a56 * a61 + a15 * a22 * a33 * a56 * a61 - a12 * a25 * a33 * a56 - * a61 - a13 * a22 * a35 * a56 * a61 + a12 * a23 * a35 * a56 * a61 - - a16 * a25 * a33 * a51 * a62 + a15 * a26 * a33 * a51 * a62 + a16 - * a23 * a35 * a51 * a62 - a13 * a26 * a35 * a51 * a62 - a15 * a23 - * a36 * a51 * a62 + a13 * a25 * a36 * a51 * a62 + a16 * a25 * a31 - * a53 * a62 - a15 * a26 * a31 * a53 * a62 - a16 * a21 * a35 * a53 - * a62 + a11 * a26 * a35 * a53 * a62 + a15 * a21 * a36 * a53 * a62 - - a11 * a25 * a36 * a53 * a62 - a16 * a23 * a31 * a55 * a62 + a13 - * a26 * a31 * a55 * a62 + a16 * a21 * a33 * a55 * a62 - a11 * a26 - * a33 * a55 * a62 - a13 * a21 * a36 * a55 * a62 + a11 * a23 * a36 - * a55 * a62 + a15 * a23 * a31 * a56 * a62 - a13 * a25 * a31 * a56 - * a62 - a15 * a21 * a33 * a56 * a62 + a11 * a25 * a33 * a56 * a62 - + a13 * a21 * a35 * a56 * a62 - a11 * a23 * a35 * a56 * a62 + a16 - * a25 * a32 * a51 * a63 - a15 * a26 * a32 * a51 * a63 - a16 * a22 - * a35 * a51 * a63 + a12 * a26 * a35 * a51 * a63 + a15 * a22 * a36 - * a51 * a63 - a12 * a25 * a36 * a51 * a63 - a16 * a25 * a31 * a52 - * a63 + a15 * a26 * a31 * a52 * a63 + a16 * a21 * a35 * a52 * a63 - - a11 * a26 * a35 * a52 * a63 - a15 * a21 * a36 * a52 * a63 + a11 - * a25 * a36 * a52 * a63 + a16 * a22 * a31 * a55 * a63 - a12 * a26 - * a31 * a55 * a63 - a16 * a21 * a32 * a55 * a63 + a11 * a26 * a32 - * a55 * a63 + a12 * a21 * a36 * a55 * a63 - a11 * a22 * a36 * a55 - * a63 - a15 * a22 * a31 * a56 * a63 + a12 * a25 * a31 * a56 * a63 - + a15 * a21 * a32 * a56 * a63 - a11 * a25 * a32 * a56 * a63 - a12 - * a21 * a35 * a56 * a63 + a11 * a22 * a35 * a56 * a63 - a16 * a23 - * a32 * a51 * a65 + a13 * a26 * a32 * a51 * a65 + a16 * a22 * a33 - * a51 * a65 - a12 * a26 * a33 * a51 * a65 - a13 * a22 * a36 * a51 - * a65 + a12 * a23 * a36 * a51 * a65 + a16 * a23 * a31 * a52 * a65 - - a13 * a26 * a31 * a52 * a65 - a16 * a21 * a33 * a52 * a65 + a11 - * a26 * a33 * a52 * a65 + a13 * a21 * a36 * a52 * a65 - a11 * a23 - * a36 * a52 * a65 - a16 * a22 * a31 * a53 * a65 + a12 * a26 * a31 - * a53 * a65 + a16 * a21 * a32 * a53 * a65 - a11 * a26 * a32 * a53 - * a65 - a12 * a21 * a36 * a53 * a65 + a11 * a22 * a36 * a53 * a65 - + a13 * a22 * a31 * a56 * a65 - a12 * a23 * a31 * a56 * a65 - a13 - * a21 * a32 * a56 * a65 + a11 * a23 * a32 * a56 * a65 + a12 * a21 - * a33 * a56 * a65 - a11 * a22 * a33 * a56 * a65 + a15 * a23 * a32 - * a51 * a66 - a13 * a25 * a32 * a51 * a66 - a15 * a22 * a33 * a51 - * a66 + a12 * a25 * a33 * a51 * a66 + a13 * a22 * a35 * a51 * a66 - - a12 * a23 * a35 * a51 * a66 - a15 * a23 * a31 * a52 * a66 + a13 - * a25 * a31 * a52 * a66 + a15 * a21 * a33 * a52 * a66 - a11 * a25 - * a33 * a52 * a66 - a13 * a21 * a35 * a52 * a66 + a11 * a23 * a35 - * a52 * a66 + a15 * a22 * a31 * a53 * a66 - a12 * a25 * a31 * a53 - * a66 - a15 * a21 * a32 * a53 * a66 + a11 * a25 * a32 * a53 * a66 - + a12 * a21 * a35 * a53 * a66 - a11 * a22 * a35 * a53 * a66 - a13 - * a22 * a31 * a55 * a66 + a12 * a23 * a31 * a55 * a66 + a13 * a21 - * a32 * a55 * a66 - a11 * a23 * a32 * a55 * a66 - a12 * a21 * a33 - * a55 * a66 + a11 * a22 * a33 * a55 * a66; - cofactor[22] = -a16 * a25 * a33 * a42 * a61 + a15 * a26 * a33 * a42 * a61 - + a16 * a23 * a35 * a42 * a61 - a13 * a26 * a35 * a42 * a61 - a15 - * a23 * a36 * a42 * a61 + a13 * a25 * a36 * a42 * a61 + a16 * a25 - * a32 * a43 * a61 - a15 * a26 * a32 * a43 * a61 - a16 * a22 * a35 - * a43 * a61 + a12 * a26 * a35 * a43 * a61 + a15 * a22 * a36 * a43 - * a61 - a12 * a25 * a36 * a43 * a61 - a16 * a23 * a32 * a45 * a61 - + a13 * a26 * a32 * a45 * a61 + a16 * a22 * a33 * a45 * a61 - a12 - * a26 * a33 * a45 * a61 - a13 * a22 * a36 * a45 * a61 + a12 * a23 - * a36 * a45 * a61 + a15 * a23 * a32 * a46 * a61 - a13 * a25 * a32 - * a46 * a61 - a15 * a22 * a33 * a46 * a61 + a12 * a25 * a33 * a46 - * a61 + a13 * a22 * a35 * a46 * a61 - a12 * a23 * a35 * a46 * a61 - + a16 * a25 * a33 * a41 * a62 - a15 * a26 * a33 * a41 * a62 - a16 - * a23 * a35 * a41 * a62 + a13 * a26 * a35 * a41 * a62 + a15 * a23 - * a36 * a41 * a62 - a13 * a25 * a36 * a41 * a62 - a16 * a25 * a31 - * a43 * a62 + a15 * a26 * a31 * a43 * a62 + a16 * a21 * a35 * a43 - * a62 - a11 * a26 * a35 * a43 * a62 - a15 * a21 * a36 * a43 * a62 - + a11 * a25 * a36 * a43 * a62 + a16 * a23 * a31 * a45 * a62 - a13 - * a26 * a31 * a45 * a62 - a16 * a21 * a33 * a45 * a62 + a11 * a26 - * a33 * a45 * a62 + a13 * a21 * a36 * a45 * a62 - a11 * a23 * a36 - * a45 * a62 - a15 * a23 * a31 * a46 * a62 + a13 * a25 * a31 * a46 - * a62 + a15 * a21 * a33 * a46 * a62 - a11 * a25 * a33 * a46 * a62 - - a13 * a21 * a35 * a46 * a62 + a11 * a23 * a35 * a46 * a62 - a16 - * a25 * a32 * a41 * a63 + a15 * a26 * a32 * a41 * a63 + a16 * a22 - * a35 * a41 * a63 - a12 * a26 * a35 * a41 * a63 - a15 * a22 * a36 - * a41 * a63 + a12 * a25 * a36 * a41 * a63 + a16 * a25 * a31 * a42 - * a63 - a15 * a26 * a31 * a42 * a63 - a16 * a21 * a35 * a42 * a63 - + a11 * a26 * a35 * a42 * a63 + a15 * a21 * a36 * a42 * a63 - a11 - * a25 * a36 * a42 * a63 - a16 * a22 * a31 * a45 * a63 + a12 * a26 - * a31 * a45 * a63 + a16 * a21 * a32 * a45 * a63 - a11 * a26 * a32 - * a45 * a63 - a12 * a21 * a36 * a45 * a63 + a11 * a22 * a36 * a45 - * a63 + a15 * a22 * a31 * a46 * a63 - a12 * a25 * a31 * a46 * a63 - - a15 * a21 * a32 * a46 * a63 + a11 * a25 * a32 * a46 * a63 + a12 - * a21 * a35 * a46 * a63 - a11 * a22 * a35 * a46 * a63 + a16 * a23 - * a32 * a41 * a65 - a13 * a26 * a32 * a41 * a65 - a16 * a22 * a33 - * a41 * a65 + a12 * a26 * a33 * a41 * a65 + a13 * a22 * a36 * a41 - * a65 - a12 * a23 * a36 * a41 * a65 - a16 * a23 * a31 * a42 * a65 - + a13 * a26 * a31 * a42 * a65 + a16 * a21 * a33 * a42 * a65 - a11 - * a26 * a33 * a42 * a65 - a13 * a21 * a36 * a42 * a65 + a11 * a23 - * a36 * a42 * a65 + a16 * a22 * a31 * a43 * a65 - a12 * a26 * a31 - * a43 * a65 - a16 * a21 * a32 * a43 * a65 + a11 * a26 * a32 * a43 - * a65 + a12 * a21 * a36 * a43 * a65 - a11 * a22 * a36 * a43 * a65 - - a13 * a22 * a31 * a46 * a65 + a12 * a23 * a31 * a46 * a65 + a13 - * a21 * a32 * a46 * a65 - a11 * a23 * a32 * a46 * a65 - a12 * a21 - * a33 * a46 * a65 + a11 * a22 * a33 * a46 * a65 - a15 * a23 * a32 - * a41 * a66 + a13 * a25 * a32 * a41 * a66 + a15 * a22 * a33 * a41 - * a66 - a12 * a25 * a33 * a41 * a66 - a13 * a22 * a35 * a41 * a66 - + a12 * a23 * a35 * a41 * a66 + a15 * a23 * a31 * a42 * a66 - a13 - * a25 * a31 * a42 * a66 - a15 * a21 * a33 * a42 * a66 + a11 * a25 - * a33 * a42 * a66 + a13 * a21 * a35 * a42 * a66 - a11 * a23 * a35 - * a42 * a66 - a15 * a22 * a31 * a43 * a66 + a12 * a25 * a31 * a43 - * a66 + a15 * a21 * a32 * a43 * a66 - a11 * a25 * a32 * a43 * a66 - - a12 * a21 * a35 * a43 * a66 + a11 * a22 * a35 * a43 * a66 + a13 - * a22 * a31 * a45 * a66 - a12 * a23 * a31 * a45 * a66 - a13 * a21 - * a32 * a45 * a66 + a11 * a23 * a32 * a45 * a66 + a12 * a21 * a33 - * a45 * a66 - a11 * a22 * a33 * a45 * a66; - cofactor[23] = a16 * a25 * a33 * a42 * a51 - a15 * a26 * a33 * a42 * a51 - - a16 * a23 * a35 * a42 * a51 + a13 * a26 * a35 * a42 * a51 + a15 - * a23 * a36 * a42 * a51 - a13 * a25 * a36 * a42 * a51 - a16 * a25 - * a32 * a43 * a51 + a15 * a26 * a32 * a43 * a51 + a16 * a22 * a35 - * a43 * a51 - a12 * a26 * a35 * a43 * a51 - a15 * a22 * a36 * a43 - * a51 + a12 * a25 * a36 * a43 * a51 + a16 * a23 * a32 * a45 * a51 - - a13 * a26 * a32 * a45 * a51 - a16 * a22 * a33 * a45 * a51 + a12 - * a26 * a33 * a45 * a51 + a13 * a22 * a36 * a45 * a51 - a12 * a23 - * a36 * a45 * a51 - a15 * a23 * a32 * a46 * a51 + a13 * a25 * a32 - * a46 * a51 + a15 * a22 * a33 * a46 * a51 - a12 * a25 * a33 * a46 - * a51 - a13 * a22 * a35 * a46 * a51 + a12 * a23 * a35 * a46 * a51 - - a16 * a25 * a33 * a41 * a52 + a15 * a26 * a33 * a41 * a52 + a16 - * a23 * a35 * a41 * a52 - a13 * a26 * a35 * a41 * a52 - a15 * a23 - * a36 * a41 * a52 + a13 * a25 * a36 * a41 * a52 + a16 * a25 * a31 - * a43 * a52 - a15 * a26 * a31 * a43 * a52 - a16 * a21 * a35 * a43 - * a52 + a11 * a26 * a35 * a43 * a52 + a15 * a21 * a36 * a43 * a52 - - a11 * a25 * a36 * a43 * a52 - a16 * a23 * a31 * a45 * a52 + a13 - * a26 * a31 * a45 * a52 + a16 * a21 * a33 * a45 * a52 - a11 * a26 - * a33 * a45 * a52 - a13 * a21 * a36 * a45 * a52 + a11 * a23 * a36 - * a45 * a52 + a15 * a23 * a31 * a46 * a52 - a13 * a25 * a31 * a46 - * a52 - a15 * a21 * a33 * a46 * a52 + a11 * a25 * a33 * a46 * a52 - + a13 * a21 * a35 * a46 * a52 - a11 * a23 * a35 * a46 * a52 + a16 - * a25 * a32 * a41 * a53 - a15 * a26 * a32 * a41 * a53 - a16 * a22 - * a35 * a41 * a53 + a12 * a26 * a35 * a41 * a53 + a15 * a22 * a36 - * a41 * a53 - a12 * a25 * a36 * a41 * a53 - a16 * a25 * a31 * a42 - * a53 + a15 * a26 * a31 * a42 * a53 + a16 * a21 * a35 * a42 * a53 - - a11 * a26 * a35 * a42 * a53 - a15 * a21 * a36 * a42 * a53 + a11 - * a25 * a36 * a42 * a53 + a16 * a22 * a31 * a45 * a53 - a12 * a26 - * a31 * a45 * a53 - a16 * a21 * a32 * a45 * a53 + a11 * a26 * a32 - * a45 * a53 + a12 * a21 * a36 * a45 * a53 - a11 * a22 * a36 * a45 - * a53 - a15 * a22 * a31 * a46 * a53 + a12 * a25 * a31 * a46 * a53 - + a15 * a21 * a32 * a46 * a53 - a11 * a25 * a32 * a46 * a53 - a12 - * a21 * a35 * a46 * a53 + a11 * a22 * a35 * a46 * a53 - a16 * a23 - * a32 * a41 * a55 + a13 * a26 * a32 * a41 * a55 + a16 * a22 * a33 - * a41 * a55 - a12 * a26 * a33 * a41 * a55 - a13 * a22 * a36 * a41 - * a55 + a12 * a23 * a36 * a41 * a55 + a16 * a23 * a31 * a42 * a55 - - a13 * a26 * a31 * a42 * a55 - a16 * a21 * a33 * a42 * a55 + a11 - * a26 * a33 * a42 * a55 + a13 * a21 * a36 * a42 * a55 - a11 * a23 - * a36 * a42 * a55 - a16 * a22 * a31 * a43 * a55 + a12 * a26 * a31 - * a43 * a55 + a16 * a21 * a32 * a43 * a55 - a11 * a26 * a32 * a43 - * a55 - a12 * a21 * a36 * a43 * a55 + a11 * a22 * a36 * a43 * a55 - + a13 * a22 * a31 * a46 * a55 - a12 * a23 * a31 * a46 * a55 - a13 - * a21 * a32 * a46 * a55 + a11 * a23 * a32 * a46 * a55 + a12 * a21 - * a33 * a46 * a55 - a11 * a22 * a33 * a46 * a55 + a15 * a23 * a32 - * a41 * a56 - a13 * a25 * a32 * a41 * a56 - a15 * a22 * a33 * a41 - * a56 + a12 * a25 * a33 * a41 * a56 + a13 * a22 * a35 * a41 * a56 - - a12 * a23 * a35 * a41 * a56 - a15 * a23 * a31 * a42 * a56 + a13 - * a25 * a31 * a42 * a56 + a15 * a21 * a33 * a42 * a56 - a11 * a25 - * a33 * a42 * a56 - a13 * a21 * a35 * a42 * a56 + a11 * a23 * a35 - * a42 * a56 + a15 * a22 * a31 * a43 * a56 - a12 * a25 * a31 * a43 - * a56 - a15 * a21 * a32 * a43 * a56 + a11 * a25 * a32 * a43 * a56 - + a12 * a21 * a35 * a43 * a56 - a11 * a22 * a35 * a43 * a56 - a13 - * a22 * a31 * a45 * a56 + a12 * a23 * a31 * a45 * a56 + a13 * a21 - * a32 * a45 * a56 - a11 * a23 * a32 * a45 * a56 - a12 * a21 * a33 - * a45 * a56 + a11 * a22 * a33 * a45 * a56; - cofactor[24] = a26 * a34 * a43 * a52 * a61 - a24 * a36 * a43 * a52 * a61 - - a26 * a33 * a44 * a52 * a61 + a23 * a36 * a44 * a52 * a61 + a24 - * a33 * a46 * a52 * a61 - a23 * a34 * a46 * a52 * a61 - a26 * a34 - * a42 * a53 * a61 + a24 * a36 * a42 * a53 * a61 + a26 * a32 * a44 - * a53 * a61 - a22 * a36 * a44 * a53 * a61 - a24 * a32 * a46 * a53 - * a61 + a22 * a34 * a46 * a53 * a61 + a26 * a33 * a42 * a54 * a61 - - a23 * a36 * a42 * a54 * a61 - a26 * a32 * a43 * a54 * a61 + a22 - * a36 * a43 * a54 * a61 + a23 * a32 * a46 * a54 * a61 - a22 * a33 - * a46 * a54 * a61 - a24 * a33 * a42 * a56 * a61 + a23 * a34 * a42 - * a56 * a61 + a24 * a32 * a43 * a56 * a61 - a22 * a34 * a43 * a56 - * a61 - a23 * a32 * a44 * a56 * a61 + a22 * a33 * a44 * a56 * a61 - - a26 * a34 * a43 * a51 * a62 + a24 * a36 * a43 * a51 * a62 + a26 - * a33 * a44 * a51 * a62 - a23 * a36 * a44 * a51 * a62 - a24 * a33 - * a46 * a51 * a62 + a23 * a34 * a46 * a51 * a62 + a26 * a34 * a41 - * a53 * a62 - a24 * a36 * a41 * a53 * a62 - a26 * a31 * a44 * a53 - * a62 + a21 * a36 * a44 * a53 * a62 + a24 * a31 * a46 * a53 * a62 - - a21 * a34 * a46 * a53 * a62 - a26 * a33 * a41 * a54 * a62 + a23 - * a36 * a41 * a54 * a62 + a26 * a31 * a43 * a54 * a62 - a21 * a36 - * a43 * a54 * a62 - a23 * a31 * a46 * a54 * a62 + a21 * a33 * a46 - * a54 * a62 + a24 * a33 * a41 * a56 * a62 - a23 * a34 * a41 * a56 - * a62 - a24 * a31 * a43 * a56 * a62 + a21 * a34 * a43 * a56 * a62 - + a23 * a31 * a44 * a56 * a62 - a21 * a33 * a44 * a56 * a62 + a26 - * a34 * a42 * a51 * a63 - a24 * a36 * a42 * a51 * a63 - a26 * a32 - * a44 * a51 * a63 + a22 * a36 * a44 * a51 * a63 + a24 * a32 * a46 - * a51 * a63 - a22 * a34 * a46 * a51 * a63 - a26 * a34 * a41 * a52 - * a63 + a24 * a36 * a41 * a52 * a63 + a26 * a31 * a44 * a52 * a63 - - a21 * a36 * a44 * a52 * a63 - a24 * a31 * a46 * a52 * a63 + a21 - * a34 * a46 * a52 * a63 + a26 * a32 * a41 * a54 * a63 - a22 * a36 - * a41 * a54 * a63 - a26 * a31 * a42 * a54 * a63 + a21 * a36 * a42 - * a54 * a63 + a22 * a31 * a46 * a54 * a63 - a21 * a32 * a46 * a54 - * a63 - a24 * a32 * a41 * a56 * a63 + a22 * a34 * a41 * a56 * a63 - + a24 * a31 * a42 * a56 * a63 - a21 * a34 * a42 * a56 * a63 - a22 - * a31 * a44 * a56 * a63 + a21 * a32 * a44 * a56 * a63 - a26 * a33 - * a42 * a51 * a64 + a23 * a36 * a42 * a51 * a64 + a26 * a32 * a43 - * a51 * a64 - a22 * a36 * a43 * a51 * a64 - a23 * a32 * a46 * a51 - * a64 + a22 * a33 * a46 * a51 * a64 + a26 * a33 * a41 * a52 * a64 - - a23 * a36 * a41 * a52 * a64 - a26 * a31 * a43 * a52 * a64 + a21 - * a36 * a43 * a52 * a64 + a23 * a31 * a46 * a52 * a64 - a21 * a33 - * a46 * a52 * a64 - a26 * a32 * a41 * a53 * a64 + a22 * a36 * a41 - * a53 * a64 + a26 * a31 * a42 * a53 * a64 - a21 * a36 * a42 * a53 - * a64 - a22 * a31 * a46 * a53 * a64 + a21 * a32 * a46 * a53 * a64 - + a23 * a32 * a41 * a56 * a64 - a22 * a33 * a41 * a56 * a64 - a23 - * a31 * a42 * a56 * a64 + a21 * a33 * a42 * a56 * a64 + a22 * a31 - * a43 * a56 * a64 - a21 * a32 * a43 * a56 * a64 + a24 * a33 * a42 - * a51 * a66 - a23 * a34 * a42 * a51 * a66 - a24 * a32 * a43 * a51 - * a66 + a22 * a34 * a43 * a51 * a66 + a23 * a32 * a44 * a51 * a66 - - a22 * a33 * a44 * a51 * a66 - a24 * a33 * a41 * a52 * a66 + a23 - * a34 * a41 * a52 * a66 + a24 * a31 * a43 * a52 * a66 - a21 * a34 - * a43 * a52 * a66 - a23 * a31 * a44 * a52 * a66 + a21 * a33 * a44 - * a52 * a66 + a24 * a32 * a41 * a53 * a66 - a22 * a34 * a41 * a53 - * a66 - a24 * a31 * a42 * a53 * a66 + a21 * a34 * a42 * a53 * a66 - + a22 * a31 * a44 * a53 * a66 - a21 * a32 * a44 * a53 * a66 - a23 - * a32 * a41 * a54 * a66 + a22 * a33 * a41 * a54 * a66 + a23 * a31 - * a42 * a54 * a66 - a21 * a33 * a42 * a54 * a66 - a22 * a31 * a43 - * a54 * a66 + a21 * a32 * a43 * a54 * a66; - cofactor[25] = -a16 * a34 * a43 * a52 * a61 + a14 * a36 * a43 * a52 * a61 - + a16 * a33 * a44 * a52 * a61 - a13 * a36 * a44 * a52 * a61 - a14 - * a33 * a46 * a52 * a61 + a13 * a34 * a46 * a52 * a61 + a16 * a34 - * a42 * a53 * a61 - a14 * a36 * a42 * a53 * a61 - a16 * a32 * a44 - * a53 * a61 + a12 * a36 * a44 * a53 * a61 + a14 * a32 * a46 * a53 - * a61 - a12 * a34 * a46 * a53 * a61 - a16 * a33 * a42 * a54 * a61 - + a13 * a36 * a42 * a54 * a61 + a16 * a32 * a43 * a54 * a61 - a12 - * a36 * a43 * a54 * a61 - a13 * a32 * a46 * a54 * a61 + a12 * a33 - * a46 * a54 * a61 + a14 * a33 * a42 * a56 * a61 - a13 * a34 * a42 - * a56 * a61 - a14 * a32 * a43 * a56 * a61 + a12 * a34 * a43 * a56 - * a61 + a13 * a32 * a44 * a56 * a61 - a12 * a33 * a44 * a56 * a61 - + a16 * a34 * a43 * a51 * a62 - a14 * a36 * a43 * a51 * a62 - a16 - * a33 * a44 * a51 * a62 + a13 * a36 * a44 * a51 * a62 + a14 * a33 - * a46 * a51 * a62 - a13 * a34 * a46 * a51 * a62 - a16 * a34 * a41 - * a53 * a62 + a14 * a36 * a41 * a53 * a62 + a16 * a31 * a44 * a53 - * a62 - a11 * a36 * a44 * a53 * a62 - a14 * a31 * a46 * a53 * a62 - + a11 * a34 * a46 * a53 * a62 + a16 * a33 * a41 * a54 * a62 - a13 - * a36 * a41 * a54 * a62 - a16 * a31 * a43 * a54 * a62 + a11 * a36 - * a43 * a54 * a62 + a13 * a31 * a46 * a54 * a62 - a11 * a33 * a46 - * a54 * a62 - a14 * a33 * a41 * a56 * a62 + a13 * a34 * a41 * a56 - * a62 + a14 * a31 * a43 * a56 * a62 - a11 * a34 * a43 * a56 * a62 - - a13 * a31 * a44 * a56 * a62 + a11 * a33 * a44 * a56 * a62 - a16 - * a34 * a42 * a51 * a63 + a14 * a36 * a42 * a51 * a63 + a16 * a32 - * a44 * a51 * a63 - a12 * a36 * a44 * a51 * a63 - a14 * a32 * a46 - * a51 * a63 + a12 * a34 * a46 * a51 * a63 + a16 * a34 * a41 * a52 - * a63 - a14 * a36 * a41 * a52 * a63 - a16 * a31 * a44 * a52 * a63 - + a11 * a36 * a44 * a52 * a63 + a14 * a31 * a46 * a52 * a63 - a11 - * a34 * a46 * a52 * a63 - a16 * a32 * a41 * a54 * a63 + a12 * a36 - * a41 * a54 * a63 + a16 * a31 * a42 * a54 * a63 - a11 * a36 * a42 - * a54 * a63 - a12 * a31 * a46 * a54 * a63 + a11 * a32 * a46 * a54 - * a63 + a14 * a32 * a41 * a56 * a63 - a12 * a34 * a41 * a56 * a63 - - a14 * a31 * a42 * a56 * a63 + a11 * a34 * a42 * a56 * a63 + a12 - * a31 * a44 * a56 * a63 - a11 * a32 * a44 * a56 * a63 + a16 * a33 - * a42 * a51 * a64 - a13 * a36 * a42 * a51 * a64 - a16 * a32 * a43 - * a51 * a64 + a12 * a36 * a43 * a51 * a64 + a13 * a32 * a46 * a51 - * a64 - a12 * a33 * a46 * a51 * a64 - a16 * a33 * a41 * a52 * a64 - + a13 * a36 * a41 * a52 * a64 + a16 * a31 * a43 * a52 * a64 - a11 - * a36 * a43 * a52 * a64 - a13 * a31 * a46 * a52 * a64 + a11 * a33 - * a46 * a52 * a64 + a16 * a32 * a41 * a53 * a64 - a12 * a36 * a41 - * a53 * a64 - a16 * a31 * a42 * a53 * a64 + a11 * a36 * a42 * a53 - * a64 + a12 * a31 * a46 * a53 * a64 - a11 * a32 * a46 * a53 * a64 - - a13 * a32 * a41 * a56 * a64 + a12 * a33 * a41 * a56 * a64 + a13 - * a31 * a42 * a56 * a64 - a11 * a33 * a42 * a56 * a64 - a12 * a31 - * a43 * a56 * a64 + a11 * a32 * a43 * a56 * a64 - a14 * a33 * a42 - * a51 * a66 + a13 * a34 * a42 * a51 * a66 + a14 * a32 * a43 * a51 - * a66 - a12 * a34 * a43 * a51 * a66 - a13 * a32 * a44 * a51 * a66 - + a12 * a33 * a44 * a51 * a66 + a14 * a33 * a41 * a52 * a66 - a13 - * a34 * a41 * a52 * a66 - a14 * a31 * a43 * a52 * a66 + a11 * a34 - * a43 * a52 * a66 + a13 * a31 * a44 * a52 * a66 - a11 * a33 * a44 - * a52 * a66 - a14 * a32 * a41 * a53 * a66 + a12 * a34 * a41 * a53 - * a66 + a14 * a31 * a42 * a53 * a66 - a11 * a34 * a42 * a53 * a66 - - a12 * a31 * a44 * a53 * a66 + a11 * a32 * a44 * a53 * a66 + a13 - * a32 * a41 * a54 * a66 - a12 * a33 * a41 * a54 * a66 - a13 * a31 - * a42 * a54 * a66 + a11 * a33 * a42 * a54 * a66 + a12 * a31 * a43 - * a54 * a66 - a11 * a32 * a43 * a54 * a66; - cofactor[26] = a16 * a24 * a43 * a52 * a61 - a14 * a26 * a43 * a52 * a61 - - a16 * a23 * a44 * a52 * a61 + a13 * a26 * a44 * a52 * a61 + a14 - * a23 * a46 * a52 * a61 - a13 * a24 * a46 * a52 * a61 - a16 * a24 - * a42 * a53 * a61 + a14 * a26 * a42 * a53 * a61 + a16 * a22 * a44 - * a53 * a61 - a12 * a26 * a44 * a53 * a61 - a14 * a22 * a46 * a53 - * a61 + a12 * a24 * a46 * a53 * a61 + a16 * a23 * a42 * a54 * a61 - - a13 * a26 * a42 * a54 * a61 - a16 * a22 * a43 * a54 * a61 + a12 - * a26 * a43 * a54 * a61 + a13 * a22 * a46 * a54 * a61 - a12 * a23 - * a46 * a54 * a61 - a14 * a23 * a42 * a56 * a61 + a13 * a24 * a42 - * a56 * a61 + a14 * a22 * a43 * a56 * a61 - a12 * a24 * a43 * a56 - * a61 - a13 * a22 * a44 * a56 * a61 + a12 * a23 * a44 * a56 * a61 - - a16 * a24 * a43 * a51 * a62 + a14 * a26 * a43 * a51 * a62 + a16 - * a23 * a44 * a51 * a62 - a13 * a26 * a44 * a51 * a62 - a14 * a23 - * a46 * a51 * a62 + a13 * a24 * a46 * a51 * a62 + a16 * a24 * a41 - * a53 * a62 - a14 * a26 * a41 * a53 * a62 - a16 * a21 * a44 * a53 - * a62 + a11 * a26 * a44 * a53 * a62 + a14 * a21 * a46 * a53 * a62 - - a11 * a24 * a46 * a53 * a62 - a16 * a23 * a41 * a54 * a62 + a13 - * a26 * a41 * a54 * a62 + a16 * a21 * a43 * a54 * a62 - a11 * a26 - * a43 * a54 * a62 - a13 * a21 * a46 * a54 * a62 + a11 * a23 * a46 - * a54 * a62 + a14 * a23 * a41 * a56 * a62 - a13 * a24 * a41 * a56 - * a62 - a14 * a21 * a43 * a56 * a62 + a11 * a24 * a43 * a56 * a62 - + a13 * a21 * a44 * a56 * a62 - a11 * a23 * a44 * a56 * a62 + a16 - * a24 * a42 * a51 * a63 - a14 * a26 * a42 * a51 * a63 - a16 * a22 - * a44 * a51 * a63 + a12 * a26 * a44 * a51 * a63 + a14 * a22 * a46 - * a51 * a63 - a12 * a24 * a46 * a51 * a63 - a16 * a24 * a41 * a52 - * a63 + a14 * a26 * a41 * a52 * a63 + a16 * a21 * a44 * a52 * a63 - - a11 * a26 * a44 * a52 * a63 - a14 * a21 * a46 * a52 * a63 + a11 - * a24 * a46 * a52 * a63 + a16 * a22 * a41 * a54 * a63 - a12 * a26 - * a41 * a54 * a63 - a16 * a21 * a42 * a54 * a63 + a11 * a26 * a42 - * a54 * a63 + a12 * a21 * a46 * a54 * a63 - a11 * a22 * a46 * a54 - * a63 - a14 * a22 * a41 * a56 * a63 + a12 * a24 * a41 * a56 * a63 - + a14 * a21 * a42 * a56 * a63 - a11 * a24 * a42 * a56 * a63 - a12 - * a21 * a44 * a56 * a63 + a11 * a22 * a44 * a56 * a63 - a16 * a23 - * a42 * a51 * a64 + a13 * a26 * a42 * a51 * a64 + a16 * a22 * a43 - * a51 * a64 - a12 * a26 * a43 * a51 * a64 - a13 * a22 * a46 * a51 - * a64 + a12 * a23 * a46 * a51 * a64 + a16 * a23 * a41 * a52 * a64 - - a13 * a26 * a41 * a52 * a64 - a16 * a21 * a43 * a52 * a64 + a11 - * a26 * a43 * a52 * a64 + a13 * a21 * a46 * a52 * a64 - a11 * a23 - * a46 * a52 * a64 - a16 * a22 * a41 * a53 * a64 + a12 * a26 * a41 - * a53 * a64 + a16 * a21 * a42 * a53 * a64 - a11 * a26 * a42 * a53 - * a64 - a12 * a21 * a46 * a53 * a64 + a11 * a22 * a46 * a53 * a64 - + a13 * a22 * a41 * a56 * a64 - a12 * a23 * a41 * a56 * a64 - a13 - * a21 * a42 * a56 * a64 + a11 * a23 * a42 * a56 * a64 + a12 * a21 - * a43 * a56 * a64 - a11 * a22 * a43 * a56 * a64 + a14 * a23 * a42 - * a51 * a66 - a13 * a24 * a42 * a51 * a66 - a14 * a22 * a43 * a51 - * a66 + a12 * a24 * a43 * a51 * a66 + a13 * a22 * a44 * a51 * a66 - - a12 * a23 * a44 * a51 * a66 - a14 * a23 * a41 * a52 * a66 + a13 - * a24 * a41 * a52 * a66 + a14 * a21 * a43 * a52 * a66 - a11 * a24 - * a43 * a52 * a66 - a13 * a21 * a44 * a52 * a66 + a11 * a23 * a44 - * a52 * a66 + a14 * a22 * a41 * a53 * a66 - a12 * a24 * a41 * a53 - * a66 - a14 * a21 * a42 * a53 * a66 + a11 * a24 * a42 * a53 * a66 - + a12 * a21 * a44 * a53 * a66 - a11 * a22 * a44 * a53 * a66 - a13 - * a22 * a41 * a54 * a66 + a12 * a23 * a41 * a54 * a66 + a13 * a21 - * a42 * a54 * a66 - a11 * a23 * a42 * a54 * a66 - a12 * a21 * a43 - * a54 * a66 + a11 * a22 * a43 * a54 * a66; - cofactor[27] = -a16 * a24 * a33 * a52 * a61 + a14 * a26 * a33 * a52 * a61 - + a16 * a23 * a34 * a52 * a61 - a13 * a26 * a34 * a52 * a61 - a14 - * a23 * a36 * a52 * a61 + a13 * a24 * a36 * a52 * a61 + a16 * a24 - * a32 * a53 * a61 - a14 * a26 * a32 * a53 * a61 - a16 * a22 * a34 - * a53 * a61 + a12 * a26 * a34 * a53 * a61 + a14 * a22 * a36 * a53 - * a61 - a12 * a24 * a36 * a53 * a61 - a16 * a23 * a32 * a54 * a61 - + a13 * a26 * a32 * a54 * a61 + a16 * a22 * a33 * a54 * a61 - a12 - * a26 * a33 * a54 * a61 - a13 * a22 * a36 * a54 * a61 + a12 * a23 - * a36 * a54 * a61 + a14 * a23 * a32 * a56 * a61 - a13 * a24 * a32 - * a56 * a61 - a14 * a22 * a33 * a56 * a61 + a12 * a24 * a33 * a56 - * a61 + a13 * a22 * a34 * a56 * a61 - a12 * a23 * a34 * a56 * a61 - + a16 * a24 * a33 * a51 * a62 - a14 * a26 * a33 * a51 * a62 - a16 - * a23 * a34 * a51 * a62 + a13 * a26 * a34 * a51 * a62 + a14 * a23 - * a36 * a51 * a62 - a13 * a24 * a36 * a51 * a62 - a16 * a24 * a31 - * a53 * a62 + a14 * a26 * a31 * a53 * a62 + a16 * a21 * a34 * a53 - * a62 - a11 * a26 * a34 * a53 * a62 - a14 * a21 * a36 * a53 * a62 - + a11 * a24 * a36 * a53 * a62 + a16 * a23 * a31 * a54 * a62 - a13 - * a26 * a31 * a54 * a62 - a16 * a21 * a33 * a54 * a62 + a11 * a26 - * a33 * a54 * a62 + a13 * a21 * a36 * a54 * a62 - a11 * a23 * a36 - * a54 * a62 - a14 * a23 * a31 * a56 * a62 + a13 * a24 * a31 * a56 - * a62 + a14 * a21 * a33 * a56 * a62 - a11 * a24 * a33 * a56 * a62 - - a13 * a21 * a34 * a56 * a62 + a11 * a23 * a34 * a56 * a62 - a16 - * a24 * a32 * a51 * a63 + a14 * a26 * a32 * a51 * a63 + a16 * a22 - * a34 * a51 * a63 - a12 * a26 * a34 * a51 * a63 - a14 * a22 * a36 - * a51 * a63 + a12 * a24 * a36 * a51 * a63 + a16 * a24 * a31 * a52 - * a63 - a14 * a26 * a31 * a52 * a63 - a16 * a21 * a34 * a52 * a63 - + a11 * a26 * a34 * a52 * a63 + a14 * a21 * a36 * a52 * a63 - a11 - * a24 * a36 * a52 * a63 - a16 * a22 * a31 * a54 * a63 + a12 * a26 - * a31 * a54 * a63 + a16 * a21 * a32 * a54 * a63 - a11 * a26 * a32 - * a54 * a63 - a12 * a21 * a36 * a54 * a63 + a11 * a22 * a36 * a54 - * a63 + a14 * a22 * a31 * a56 * a63 - a12 * a24 * a31 * a56 * a63 - - a14 * a21 * a32 * a56 * a63 + a11 * a24 * a32 * a56 * a63 + a12 - * a21 * a34 * a56 * a63 - a11 * a22 * a34 * a56 * a63 + a16 * a23 - * a32 * a51 * a64 - a13 * a26 * a32 * a51 * a64 - a16 * a22 * a33 - * a51 * a64 + a12 * a26 * a33 * a51 * a64 + a13 * a22 * a36 * a51 - * a64 - a12 * a23 * a36 * a51 * a64 - a16 * a23 * a31 * a52 * a64 - + a13 * a26 * a31 * a52 * a64 + a16 * a21 * a33 * a52 * a64 - a11 - * a26 * a33 * a52 * a64 - a13 * a21 * a36 * a52 * a64 + a11 * a23 - * a36 * a52 * a64 + a16 * a22 * a31 * a53 * a64 - a12 * a26 * a31 - * a53 * a64 - a16 * a21 * a32 * a53 * a64 + a11 * a26 * a32 * a53 - * a64 + a12 * a21 * a36 * a53 * a64 - a11 * a22 * a36 * a53 * a64 - - a13 * a22 * a31 * a56 * a64 + a12 * a23 * a31 * a56 * a64 + a13 - * a21 * a32 * a56 * a64 - a11 * a23 * a32 * a56 * a64 - a12 * a21 - * a33 * a56 * a64 + a11 * a22 * a33 * a56 * a64 - a14 * a23 * a32 - * a51 * a66 + a13 * a24 * a32 * a51 * a66 + a14 * a22 * a33 * a51 - * a66 - a12 * a24 * a33 * a51 * a66 - a13 * a22 * a34 * a51 * a66 - + a12 * a23 * a34 * a51 * a66 + a14 * a23 * a31 * a52 * a66 - a13 - * a24 * a31 * a52 * a66 - a14 * a21 * a33 * a52 * a66 + a11 * a24 - * a33 * a52 * a66 + a13 * a21 * a34 * a52 * a66 - a11 * a23 * a34 - * a52 * a66 - a14 * a22 * a31 * a53 * a66 + a12 * a24 * a31 * a53 - * a66 + a14 * a21 * a32 * a53 * a66 - a11 * a24 * a32 * a53 * a66 - - a12 * a21 * a34 * a53 * a66 + a11 * a22 * a34 * a53 * a66 + a13 - * a22 * a31 * a54 * a66 - a12 * a23 * a31 * a54 * a66 - a13 * a21 - * a32 * a54 * a66 + a11 * a23 * a32 * a54 * a66 + a12 * a21 * a33 - * a54 * a66 - a11 * a22 * a33 * a54 * a66; - cofactor[28] = a16 * a24 * a33 * a42 * a61 - a14 * a26 * a33 * a42 * a61 - - a16 * a23 * a34 * a42 * a61 + a13 * a26 * a34 * a42 * a61 + a14 - * a23 * a36 * a42 * a61 - a13 * a24 * a36 * a42 * a61 - a16 * a24 - * a32 * a43 * a61 + a14 * a26 * a32 * a43 * a61 + a16 * a22 * a34 - * a43 * a61 - a12 * a26 * a34 * a43 * a61 - a14 * a22 * a36 * a43 - * a61 + a12 * a24 * a36 * a43 * a61 + a16 * a23 * a32 * a44 * a61 - - a13 * a26 * a32 * a44 * a61 - a16 * a22 * a33 * a44 * a61 + a12 - * a26 * a33 * a44 * a61 + a13 * a22 * a36 * a44 * a61 - a12 * a23 - * a36 * a44 * a61 - a14 * a23 * a32 * a46 * a61 + a13 * a24 * a32 - * a46 * a61 + a14 * a22 * a33 * a46 * a61 - a12 * a24 * a33 * a46 - * a61 - a13 * a22 * a34 * a46 * a61 + a12 * a23 * a34 * a46 * a61 - - a16 * a24 * a33 * a41 * a62 + a14 * a26 * a33 * a41 * a62 + a16 - * a23 * a34 * a41 * a62 - a13 * a26 * a34 * a41 * a62 - a14 * a23 - * a36 * a41 * a62 + a13 * a24 * a36 * a41 * a62 + a16 * a24 * a31 - * a43 * a62 - a14 * a26 * a31 * a43 * a62 - a16 * a21 * a34 * a43 - * a62 + a11 * a26 * a34 * a43 * a62 + a14 * a21 * a36 * a43 * a62 - - a11 * a24 * a36 * a43 * a62 - a16 * a23 * a31 * a44 * a62 + a13 - * a26 * a31 * a44 * a62 + a16 * a21 * a33 * a44 * a62 - a11 * a26 - * a33 * a44 * a62 - a13 * a21 * a36 * a44 * a62 + a11 * a23 * a36 - * a44 * a62 + a14 * a23 * a31 * a46 * a62 - a13 * a24 * a31 * a46 - * a62 - a14 * a21 * a33 * a46 * a62 + a11 * a24 * a33 * a46 * a62 - + a13 * a21 * a34 * a46 * a62 - a11 * a23 * a34 * a46 * a62 + a16 - * a24 * a32 * a41 * a63 - a14 * a26 * a32 * a41 * a63 - a16 * a22 - * a34 * a41 * a63 + a12 * a26 * a34 * a41 * a63 + a14 * a22 * a36 - * a41 * a63 - a12 * a24 * a36 * a41 * a63 - a16 * a24 * a31 * a42 - * a63 + a14 * a26 * a31 * a42 * a63 + a16 * a21 * a34 * a42 * a63 - - a11 * a26 * a34 * a42 * a63 - a14 * a21 * a36 * a42 * a63 + a11 - * a24 * a36 * a42 * a63 + a16 * a22 * a31 * a44 * a63 - a12 * a26 - * a31 * a44 * a63 - a16 * a21 * a32 * a44 * a63 + a11 * a26 * a32 - * a44 * a63 + a12 * a21 * a36 * a44 * a63 - a11 * a22 * a36 * a44 - * a63 - a14 * a22 * a31 * a46 * a63 + a12 * a24 * a31 * a46 * a63 - + a14 * a21 * a32 * a46 * a63 - a11 * a24 * a32 * a46 * a63 - a12 - * a21 * a34 * a46 * a63 + a11 * a22 * a34 * a46 * a63 - a16 * a23 - * a32 * a41 * a64 + a13 * a26 * a32 * a41 * a64 + a16 * a22 * a33 - * a41 * a64 - a12 * a26 * a33 * a41 * a64 - a13 * a22 * a36 * a41 - * a64 + a12 * a23 * a36 * a41 * a64 + a16 * a23 * a31 * a42 * a64 - - a13 * a26 * a31 * a42 * a64 - a16 * a21 * a33 * a42 * a64 + a11 - * a26 * a33 * a42 * a64 + a13 * a21 * a36 * a42 * a64 - a11 * a23 - * a36 * a42 * a64 - a16 * a22 * a31 * a43 * a64 + a12 * a26 * a31 - * a43 * a64 + a16 * a21 * a32 * a43 * a64 - a11 * a26 * a32 * a43 - * a64 - a12 * a21 * a36 * a43 * a64 + a11 * a22 * a36 * a43 * a64 - + a13 * a22 * a31 * a46 * a64 - a12 * a23 * a31 * a46 * a64 - a13 - * a21 * a32 * a46 * a64 + a11 * a23 * a32 * a46 * a64 + a12 * a21 - * a33 * a46 * a64 - a11 * a22 * a33 * a46 * a64 + a14 * a23 * a32 - * a41 * a66 - a13 * a24 * a32 * a41 * a66 - a14 * a22 * a33 * a41 - * a66 + a12 * a24 * a33 * a41 * a66 + a13 * a22 * a34 * a41 * a66 - - a12 * a23 * a34 * a41 * a66 - a14 * a23 * a31 * a42 * a66 + a13 - * a24 * a31 * a42 * a66 + a14 * a21 * a33 * a42 * a66 - a11 * a24 - * a33 * a42 * a66 - a13 * a21 * a34 * a42 * a66 + a11 * a23 * a34 - * a42 * a66 + a14 * a22 * a31 * a43 * a66 - a12 * a24 * a31 * a43 - * a66 - a14 * a21 * a32 * a43 * a66 + a11 * a24 * a32 * a43 * a66 - + a12 * a21 * a34 * a43 * a66 - a11 * a22 * a34 * a43 * a66 - a13 - * a22 * a31 * a44 * a66 + a12 * a23 * a31 * a44 * a66 + a13 * a21 - * a32 * a44 * a66 - a11 * a23 * a32 * a44 * a66 - a12 * a21 * a33 - * a44 * a66 + a11 * a22 * a33 * a44 * a66; - cofactor[29] = -a16 * a24 * a33 * a42 * a51 + a14 * a26 * a33 * a42 * a51 - + a16 * a23 * a34 * a42 * a51 - a13 * a26 * a34 * a42 * a51 - a14 - * a23 * a36 * a42 * a51 + a13 * a24 * a36 * a42 * a51 + a16 * a24 - * a32 * a43 * a51 - a14 * a26 * a32 * a43 * a51 - a16 * a22 * a34 - * a43 * a51 + a12 * a26 * a34 * a43 * a51 + a14 * a22 * a36 * a43 - * a51 - a12 * a24 * a36 * a43 * a51 - a16 * a23 * a32 * a44 * a51 - + a13 * a26 * a32 * a44 * a51 + a16 * a22 * a33 * a44 * a51 - a12 - * a26 * a33 * a44 * a51 - a13 * a22 * a36 * a44 * a51 + a12 * a23 - * a36 * a44 * a51 + a14 * a23 * a32 * a46 * a51 - a13 * a24 * a32 - * a46 * a51 - a14 * a22 * a33 * a46 * a51 + a12 * a24 * a33 * a46 - * a51 + a13 * a22 * a34 * a46 * a51 - a12 * a23 * a34 * a46 * a51 - + a16 * a24 * a33 * a41 * a52 - a14 * a26 * a33 * a41 * a52 - a16 - * a23 * a34 * a41 * a52 + a13 * a26 * a34 * a41 * a52 + a14 * a23 - * a36 * a41 * a52 - a13 * a24 * a36 * a41 * a52 - a16 * a24 * a31 - * a43 * a52 + a14 * a26 * a31 * a43 * a52 + a16 * a21 * a34 * a43 - * a52 - a11 * a26 * a34 * a43 * a52 - a14 * a21 * a36 * a43 * a52 - + a11 * a24 * a36 * a43 * a52 + a16 * a23 * a31 * a44 * a52 - a13 - * a26 * a31 * a44 * a52 - a16 * a21 * a33 * a44 * a52 + a11 * a26 - * a33 * a44 * a52 + a13 * a21 * a36 * a44 * a52 - a11 * a23 * a36 - * a44 * a52 - a14 * a23 * a31 * a46 * a52 + a13 * a24 * a31 * a46 - * a52 + a14 * a21 * a33 * a46 * a52 - a11 * a24 * a33 * a46 * a52 - - a13 * a21 * a34 * a46 * a52 + a11 * a23 * a34 * a46 * a52 - a16 - * a24 * a32 * a41 * a53 + a14 * a26 * a32 * a41 * a53 + a16 * a22 - * a34 * a41 * a53 - a12 * a26 * a34 * a41 * a53 - a14 * a22 * a36 - * a41 * a53 + a12 * a24 * a36 * a41 * a53 + a16 * a24 * a31 * a42 - * a53 - a14 * a26 * a31 * a42 * a53 - a16 * a21 * a34 * a42 * a53 - + a11 * a26 * a34 * a42 * a53 + a14 * a21 * a36 * a42 * a53 - a11 - * a24 * a36 * a42 * a53 - a16 * a22 * a31 * a44 * a53 + a12 * a26 - * a31 * a44 * a53 + a16 * a21 * a32 * a44 * a53 - a11 * a26 * a32 - * a44 * a53 - a12 * a21 * a36 * a44 * a53 + a11 * a22 * a36 * a44 - * a53 + a14 * a22 * a31 * a46 * a53 - a12 * a24 * a31 * a46 * a53 - - a14 * a21 * a32 * a46 * a53 + a11 * a24 * a32 * a46 * a53 + a12 - * a21 * a34 * a46 * a53 - a11 * a22 * a34 * a46 * a53 + a16 * a23 - * a32 * a41 * a54 - a13 * a26 * a32 * a41 * a54 - a16 * a22 * a33 - * a41 * a54 + a12 * a26 * a33 * a41 * a54 + a13 * a22 * a36 * a41 - * a54 - a12 * a23 * a36 * a41 * a54 - a16 * a23 * a31 * a42 * a54 - + a13 * a26 * a31 * a42 * a54 + a16 * a21 * a33 * a42 * a54 - a11 - * a26 * a33 * a42 * a54 - a13 * a21 * a36 * a42 * a54 + a11 * a23 - * a36 * a42 * a54 + a16 * a22 * a31 * a43 * a54 - a12 * a26 * a31 - * a43 * a54 - a16 * a21 * a32 * a43 * a54 + a11 * a26 * a32 * a43 - * a54 + a12 * a21 * a36 * a43 * a54 - a11 * a22 * a36 * a43 * a54 - - a13 * a22 * a31 * a46 * a54 + a12 * a23 * a31 * a46 * a54 + a13 - * a21 * a32 * a46 * a54 - a11 * a23 * a32 * a46 * a54 - a12 * a21 - * a33 * a46 * a54 + a11 * a22 * a33 * a46 * a54 - a14 * a23 * a32 - * a41 * a56 + a13 * a24 * a32 * a41 * a56 + a14 * a22 * a33 * a41 - * a56 - a12 * a24 * a33 * a41 * a56 - a13 * a22 * a34 * a41 * a56 - + a12 * a23 * a34 * a41 * a56 + a14 * a23 * a31 * a42 * a56 - a13 - * a24 * a31 * a42 * a56 - a14 * a21 * a33 * a42 * a56 + a11 * a24 - * a33 * a42 * a56 + a13 * a21 * a34 * a42 * a56 - a11 * a23 * a34 - * a42 * a56 - a14 * a22 * a31 * a43 * a56 + a12 * a24 * a31 * a43 - * a56 + a14 * a21 * a32 * a43 * a56 - a11 * a24 * a32 * a43 * a56 - - a12 * a21 * a34 * a43 * a56 + a11 * a22 * a34 * a43 * a56 + a13 - * a22 * a31 * a44 * a56 - a12 * a23 * a31 * a44 * a56 - a13 * a21 - * a32 * a44 * a56 + a11 * a23 * a32 * a44 * a56 + a12 * a21 * a33 - * a44 * a56 - a11 * a22 * a33 * a44 * a56; - cofactor[30] = -a25 * a34 * a43 * a52 * a61 + a24 * a35 * a43 * a52 * a61 - + a25 * a33 * a44 * a52 * a61 - a23 * a35 * a44 * a52 * a61 - a24 - * a33 * a45 * a52 * a61 + a23 * a34 * a45 * a52 * a61 + a25 * a34 - * a42 * a53 * a61 - a24 * a35 * a42 * a53 * a61 - a25 * a32 * a44 - * a53 * a61 + a22 * a35 * a44 * a53 * a61 + a24 * a32 * a45 * a53 - * a61 - a22 * a34 * a45 * a53 * a61 - a25 * a33 * a42 * a54 * a61 - + a23 * a35 * a42 * a54 * a61 + a25 * a32 * a43 * a54 * a61 - a22 - * a35 * a43 * a54 * a61 - a23 * a32 * a45 * a54 * a61 + a22 * a33 - * a45 * a54 * a61 + a24 * a33 * a42 * a55 * a61 - a23 * a34 * a42 - * a55 * a61 - a24 * a32 * a43 * a55 * a61 + a22 * a34 * a43 * a55 - * a61 + a23 * a32 * a44 * a55 * a61 - a22 * a33 * a44 * a55 * a61 - + a25 * a34 * a43 * a51 * a62 - a24 * a35 * a43 * a51 * a62 - a25 - * a33 * a44 * a51 * a62 + a23 * a35 * a44 * a51 * a62 + a24 * a33 - * a45 * a51 * a62 - a23 * a34 * a45 * a51 * a62 - a25 * a34 * a41 - * a53 * a62 + a24 * a35 * a41 * a53 * a62 + a25 * a31 * a44 * a53 - * a62 - a21 * a35 * a44 * a53 * a62 - a24 * a31 * a45 * a53 * a62 - + a21 * a34 * a45 * a53 * a62 + a25 * a33 * a41 * a54 * a62 - a23 - * a35 * a41 * a54 * a62 - a25 * a31 * a43 * a54 * a62 + a21 * a35 - * a43 * a54 * a62 + a23 * a31 * a45 * a54 * a62 - a21 * a33 * a45 - * a54 * a62 - a24 * a33 * a41 * a55 * a62 + a23 * a34 * a41 * a55 - * a62 + a24 * a31 * a43 * a55 * a62 - a21 * a34 * a43 * a55 * a62 - - a23 * a31 * a44 * a55 * a62 + a21 * a33 * a44 * a55 * a62 - a25 - * a34 * a42 * a51 * a63 + a24 * a35 * a42 * a51 * a63 + a25 * a32 - * a44 * a51 * a63 - a22 * a35 * a44 * a51 * a63 - a24 * a32 * a45 - * a51 * a63 + a22 * a34 * a45 * a51 * a63 + a25 * a34 * a41 * a52 - * a63 - a24 * a35 * a41 * a52 * a63 - a25 * a31 * a44 * a52 * a63 - + a21 * a35 * a44 * a52 * a63 + a24 * a31 * a45 * a52 * a63 - a21 - * a34 * a45 * a52 * a63 - a25 * a32 * a41 * a54 * a63 + a22 * a35 - * a41 * a54 * a63 + a25 * a31 * a42 * a54 * a63 - a21 * a35 * a42 - * a54 * a63 - a22 * a31 * a45 * a54 * a63 + a21 * a32 * a45 * a54 - * a63 + a24 * a32 * a41 * a55 * a63 - a22 * a34 * a41 * a55 * a63 - - a24 * a31 * a42 * a55 * a63 + a21 * a34 * a42 * a55 * a63 + a22 - * a31 * a44 * a55 * a63 - a21 * a32 * a44 * a55 * a63 + a25 * a33 - * a42 * a51 * a64 - a23 * a35 * a42 * a51 * a64 - a25 * a32 * a43 - * a51 * a64 + a22 * a35 * a43 * a51 * a64 + a23 * a32 * a45 * a51 - * a64 - a22 * a33 * a45 * a51 * a64 - a25 * a33 * a41 * a52 * a64 - + a23 * a35 * a41 * a52 * a64 + a25 * a31 * a43 * a52 * a64 - a21 - * a35 * a43 * a52 * a64 - a23 * a31 * a45 * a52 * a64 + a21 * a33 - * a45 * a52 * a64 + a25 * a32 * a41 * a53 * a64 - a22 * a35 * a41 - * a53 * a64 - a25 * a31 * a42 * a53 * a64 + a21 * a35 * a42 * a53 - * a64 + a22 * a31 * a45 * a53 * a64 - a21 * a32 * a45 * a53 * a64 - - a23 * a32 * a41 * a55 * a64 + a22 * a33 * a41 * a55 * a64 + a23 - * a31 * a42 * a55 * a64 - a21 * a33 * a42 * a55 * a64 - a22 * a31 - * a43 * a55 * a64 + a21 * a32 * a43 * a55 * a64 - a24 * a33 * a42 - * a51 * a65 + a23 * a34 * a42 * a51 * a65 + a24 * a32 * a43 * a51 - * a65 - a22 * a34 * a43 * a51 * a65 - a23 * a32 * a44 * a51 * a65 - + a22 * a33 * a44 * a51 * a65 + a24 * a33 * a41 * a52 * a65 - a23 - * a34 * a41 * a52 * a65 - a24 * a31 * a43 * a52 * a65 + a21 * a34 - * a43 * a52 * a65 + a23 * a31 * a44 * a52 * a65 - a21 * a33 * a44 - * a52 * a65 - a24 * a32 * a41 * a53 * a65 + a22 * a34 * a41 * a53 - * a65 + a24 * a31 * a42 * a53 * a65 - a21 * a34 * a42 * a53 * a65 - - a22 * a31 * a44 * a53 * a65 + a21 * a32 * a44 * a53 * a65 + a23 - * a32 * a41 * a54 * a65 - a22 * a33 * a41 * a54 * a65 - a23 * a31 - * a42 * a54 * a65 + a21 * a33 * a42 * a54 * a65 + a22 * a31 * a43 - * a54 * a65 - a21 * a32 * a43 * a54 * a65; - cofactor[31] = a15 * a34 * a43 * a52 * a61 - a14 * a35 * a43 * a52 * a61 - - a15 * a33 * a44 * a52 * a61 + a13 * a35 * a44 * a52 * a61 + a14 - * a33 * a45 * a52 * a61 - a13 * a34 * a45 * a52 * a61 - a15 * a34 - * a42 * a53 * a61 + a14 * a35 * a42 * a53 * a61 + a15 * a32 * a44 - * a53 * a61 - a12 * a35 * a44 * a53 * a61 - a14 * a32 * a45 * a53 - * a61 + a12 * a34 * a45 * a53 * a61 + a15 * a33 * a42 * a54 * a61 - - a13 * a35 * a42 * a54 * a61 - a15 * a32 * a43 * a54 * a61 + a12 - * a35 * a43 * a54 * a61 + a13 * a32 * a45 * a54 * a61 - a12 * a33 - * a45 * a54 * a61 - a14 * a33 * a42 * a55 * a61 + a13 * a34 * a42 - * a55 * a61 + a14 * a32 * a43 * a55 * a61 - a12 * a34 * a43 * a55 - * a61 - a13 * a32 * a44 * a55 * a61 + a12 * a33 * a44 * a55 * a61 - - a15 * a34 * a43 * a51 * a62 + a14 * a35 * a43 * a51 * a62 + a15 - * a33 * a44 * a51 * a62 - a13 * a35 * a44 * a51 * a62 - a14 * a33 - * a45 * a51 * a62 + a13 * a34 * a45 * a51 * a62 + a15 * a34 * a41 - * a53 * a62 - a14 * a35 * a41 * a53 * a62 - a15 * a31 * a44 * a53 - * a62 + a11 * a35 * a44 * a53 * a62 + a14 * a31 * a45 * a53 * a62 - - a11 * a34 * a45 * a53 * a62 - a15 * a33 * a41 * a54 * a62 + a13 - * a35 * a41 * a54 * a62 + a15 * a31 * a43 * a54 * a62 - a11 * a35 - * a43 * a54 * a62 - a13 * a31 * a45 * a54 * a62 + a11 * a33 * a45 - * a54 * a62 + a14 * a33 * a41 * a55 * a62 - a13 * a34 * a41 * a55 - * a62 - a14 * a31 * a43 * a55 * a62 + a11 * a34 * a43 * a55 * a62 - + a13 * a31 * a44 * a55 * a62 - a11 * a33 * a44 * a55 * a62 + a15 - * a34 * a42 * a51 * a63 - a14 * a35 * a42 * a51 * a63 - a15 * a32 - * a44 * a51 * a63 + a12 * a35 * a44 * a51 * a63 + a14 * a32 * a45 - * a51 * a63 - a12 * a34 * a45 * a51 * a63 - a15 * a34 * a41 * a52 - * a63 + a14 * a35 * a41 * a52 * a63 + a15 * a31 * a44 * a52 * a63 - - a11 * a35 * a44 * a52 * a63 - a14 * a31 * a45 * a52 * a63 + a11 - * a34 * a45 * a52 * a63 + a15 * a32 * a41 * a54 * a63 - a12 * a35 - * a41 * a54 * a63 - a15 * a31 * a42 * a54 * a63 + a11 * a35 * a42 - * a54 * a63 + a12 * a31 * a45 * a54 * a63 - a11 * a32 * a45 * a54 - * a63 - a14 * a32 * a41 * a55 * a63 + a12 * a34 * a41 * a55 * a63 - + a14 * a31 * a42 * a55 * a63 - a11 * a34 * a42 * a55 * a63 - a12 - * a31 * a44 * a55 * a63 + a11 * a32 * a44 * a55 * a63 - a15 * a33 - * a42 * a51 * a64 + a13 * a35 * a42 * a51 * a64 + a15 * a32 * a43 - * a51 * a64 - a12 * a35 * a43 * a51 * a64 - a13 * a32 * a45 * a51 - * a64 + a12 * a33 * a45 * a51 * a64 + a15 * a33 * a41 * a52 * a64 - - a13 * a35 * a41 * a52 * a64 - a15 * a31 * a43 * a52 * a64 + a11 - * a35 * a43 * a52 * a64 + a13 * a31 * a45 * a52 * a64 - a11 * a33 - * a45 * a52 * a64 - a15 * a32 * a41 * a53 * a64 + a12 * a35 * a41 - * a53 * a64 + a15 * a31 * a42 * a53 * a64 - a11 * a35 * a42 * a53 - * a64 - a12 * a31 * a45 * a53 * a64 + a11 * a32 * a45 * a53 * a64 - + a13 * a32 * a41 * a55 * a64 - a12 * a33 * a41 * a55 * a64 - a13 - * a31 * a42 * a55 * a64 + a11 * a33 * a42 * a55 * a64 + a12 * a31 - * a43 * a55 * a64 - a11 * a32 * a43 * a55 * a64 + a14 * a33 * a42 - * a51 * a65 - a13 * a34 * a42 * a51 * a65 - a14 * a32 * a43 * a51 - * a65 + a12 * a34 * a43 * a51 * a65 + a13 * a32 * a44 * a51 * a65 - - a12 * a33 * a44 * a51 * a65 - a14 * a33 * a41 * a52 * a65 + a13 - * a34 * a41 * a52 * a65 + a14 * a31 * a43 * a52 * a65 - a11 * a34 - * a43 * a52 * a65 - a13 * a31 * a44 * a52 * a65 + a11 * a33 * a44 - * a52 * a65 + a14 * a32 * a41 * a53 * a65 - a12 * a34 * a41 * a53 - * a65 - a14 * a31 * a42 * a53 * a65 + a11 * a34 * a42 * a53 * a65 - + a12 * a31 * a44 * a53 * a65 - a11 * a32 * a44 * a53 * a65 - a13 - * a32 * a41 * a54 * a65 + a12 * a33 * a41 * a54 * a65 + a13 * a31 - * a42 * a54 * a65 - a11 * a33 * a42 * a54 * a65 - a12 * a31 * a43 - * a54 * a65 + a11 * a32 * a43 * a54 * a65; - cofactor[32] = -a15 * a24 * a43 * a52 * a61 + a14 * a25 * a43 * a52 * a61 - + a15 * a23 * a44 * a52 * a61 - a13 * a25 * a44 * a52 * a61 - a14 - * a23 * a45 * a52 * a61 + a13 * a24 * a45 * a52 * a61 + a15 * a24 - * a42 * a53 * a61 - a14 * a25 * a42 * a53 * a61 - a15 * a22 * a44 - * a53 * a61 + a12 * a25 * a44 * a53 * a61 + a14 * a22 * a45 * a53 - * a61 - a12 * a24 * a45 * a53 * a61 - a15 * a23 * a42 * a54 * a61 - + a13 * a25 * a42 * a54 * a61 + a15 * a22 * a43 * a54 * a61 - a12 - * a25 * a43 * a54 * a61 - a13 * a22 * a45 * a54 * a61 + a12 * a23 - * a45 * a54 * a61 + a14 * a23 * a42 * a55 * a61 - a13 * a24 * a42 - * a55 * a61 - a14 * a22 * a43 * a55 * a61 + a12 * a24 * a43 * a55 - * a61 + a13 * a22 * a44 * a55 * a61 - a12 * a23 * a44 * a55 * a61 - + a15 * a24 * a43 * a51 * a62 - a14 * a25 * a43 * a51 * a62 - a15 - * a23 * a44 * a51 * a62 + a13 * a25 * a44 * a51 * a62 + a14 * a23 - * a45 * a51 * a62 - a13 * a24 * a45 * a51 * a62 - a15 * a24 * a41 - * a53 * a62 + a14 * a25 * a41 * a53 * a62 + a15 * a21 * a44 * a53 - * a62 - a11 * a25 * a44 * a53 * a62 - a14 * a21 * a45 * a53 * a62 - + a11 * a24 * a45 * a53 * a62 + a15 * a23 * a41 * a54 * a62 - a13 - * a25 * a41 * a54 * a62 - a15 * a21 * a43 * a54 * a62 + a11 * a25 - * a43 * a54 * a62 + a13 * a21 * a45 * a54 * a62 - a11 * a23 * a45 - * a54 * a62 - a14 * a23 * a41 * a55 * a62 + a13 * a24 * a41 * a55 - * a62 + a14 * a21 * a43 * a55 * a62 - a11 * a24 * a43 * a55 * a62 - - a13 * a21 * a44 * a55 * a62 + a11 * a23 * a44 * a55 * a62 - a15 - * a24 * a42 * a51 * a63 + a14 * a25 * a42 * a51 * a63 + a15 * a22 - * a44 * a51 * a63 - a12 * a25 * a44 * a51 * a63 - a14 * a22 * a45 - * a51 * a63 + a12 * a24 * a45 * a51 * a63 + a15 * a24 * a41 * a52 - * a63 - a14 * a25 * a41 * a52 * a63 - a15 * a21 * a44 * a52 * a63 - + a11 * a25 * a44 * a52 * a63 + a14 * a21 * a45 * a52 * a63 - a11 - * a24 * a45 * a52 * a63 - a15 * a22 * a41 * a54 * a63 + a12 * a25 - * a41 * a54 * a63 + a15 * a21 * a42 * a54 * a63 - a11 * a25 * a42 - * a54 * a63 - a12 * a21 * a45 * a54 * a63 + a11 * a22 * a45 * a54 - * a63 + a14 * a22 * a41 * a55 * a63 - a12 * a24 * a41 * a55 * a63 - - a14 * a21 * a42 * a55 * a63 + a11 * a24 * a42 * a55 * a63 + a12 - * a21 * a44 * a55 * a63 - a11 * a22 * a44 * a55 * a63 + a15 * a23 - * a42 * a51 * a64 - a13 * a25 * a42 * a51 * a64 - a15 * a22 * a43 - * a51 * a64 + a12 * a25 * a43 * a51 * a64 + a13 * a22 * a45 * a51 - * a64 - a12 * a23 * a45 * a51 * a64 - a15 * a23 * a41 * a52 * a64 - + a13 * a25 * a41 * a52 * a64 + a15 * a21 * a43 * a52 * a64 - a11 - * a25 * a43 * a52 * a64 - a13 * a21 * a45 * a52 * a64 + a11 * a23 - * a45 * a52 * a64 + a15 * a22 * a41 * a53 * a64 - a12 * a25 * a41 - * a53 * a64 - a15 * a21 * a42 * a53 * a64 + a11 * a25 * a42 * a53 - * a64 + a12 * a21 * a45 * a53 * a64 - a11 * a22 * a45 * a53 * a64 - - a13 * a22 * a41 * a55 * a64 + a12 * a23 * a41 * a55 * a64 + a13 - * a21 * a42 * a55 * a64 - a11 * a23 * a42 * a55 * a64 - a12 * a21 - * a43 * a55 * a64 + a11 * a22 * a43 * a55 * a64 - a14 * a23 * a42 - * a51 * a65 + a13 * a24 * a42 * a51 * a65 + a14 * a22 * a43 * a51 - * a65 - a12 * a24 * a43 * a51 * a65 - a13 * a22 * a44 * a51 * a65 - + a12 * a23 * a44 * a51 * a65 + a14 * a23 * a41 * a52 * a65 - a13 - * a24 * a41 * a52 * a65 - a14 * a21 * a43 * a52 * a65 + a11 * a24 - * a43 * a52 * a65 + a13 * a21 * a44 * a52 * a65 - a11 * a23 * a44 - * a52 * a65 - a14 * a22 * a41 * a53 * a65 + a12 * a24 * a41 * a53 - * a65 + a14 * a21 * a42 * a53 * a65 - a11 * a24 * a42 * a53 * a65 - - a12 * a21 * a44 * a53 * a65 + a11 * a22 * a44 * a53 * a65 + a13 - * a22 * a41 * a54 * a65 - a12 * a23 * a41 * a54 * a65 - a13 * a21 - * a42 * a54 * a65 + a11 * a23 * a42 * a54 * a65 + a12 * a21 * a43 - * a54 * a65 - a11 * a22 * a43 * a54 * a65; - cofactor[33] = a15 * a24 * a33 * a52 * a61 - a14 * a25 * a33 * a52 * a61 - - a15 * a23 * a34 * a52 * a61 + a13 * a25 * a34 * a52 * a61 + a14 - * a23 * a35 * a52 * a61 - a13 * a24 * a35 * a52 * a61 - a15 * a24 - * a32 * a53 * a61 + a14 * a25 * a32 * a53 * a61 + a15 * a22 * a34 - * a53 * a61 - a12 * a25 * a34 * a53 * a61 - a14 * a22 * a35 * a53 - * a61 + a12 * a24 * a35 * a53 * a61 + a15 * a23 * a32 * a54 * a61 - - a13 * a25 * a32 * a54 * a61 - a15 * a22 * a33 * a54 * a61 + a12 - * a25 * a33 * a54 * a61 + a13 * a22 * a35 * a54 * a61 - a12 * a23 - * a35 * a54 * a61 - a14 * a23 * a32 * a55 * a61 + a13 * a24 * a32 - * a55 * a61 + a14 * a22 * a33 * a55 * a61 - a12 * a24 * a33 * a55 - * a61 - a13 * a22 * a34 * a55 * a61 + a12 * a23 * a34 * a55 * a61 - - a15 * a24 * a33 * a51 * a62 + a14 * a25 * a33 * a51 * a62 + a15 - * a23 * a34 * a51 * a62 - a13 * a25 * a34 * a51 * a62 - a14 * a23 - * a35 * a51 * a62 + a13 * a24 * a35 * a51 * a62 + a15 * a24 * a31 - * a53 * a62 - a14 * a25 * a31 * a53 * a62 - a15 * a21 * a34 * a53 - * a62 + a11 * a25 * a34 * a53 * a62 + a14 * a21 * a35 * a53 * a62 - - a11 * a24 * a35 * a53 * a62 - a15 * a23 * a31 * a54 * a62 + a13 - * a25 * a31 * a54 * a62 + a15 * a21 * a33 * a54 * a62 - a11 * a25 - * a33 * a54 * a62 - a13 * a21 * a35 * a54 * a62 + a11 * a23 * a35 - * a54 * a62 + a14 * a23 * a31 * a55 * a62 - a13 * a24 * a31 * a55 - * a62 - a14 * a21 * a33 * a55 * a62 + a11 * a24 * a33 * a55 * a62 - + a13 * a21 * a34 * a55 * a62 - a11 * a23 * a34 * a55 * a62 + a15 - * a24 * a32 * a51 * a63 - a14 * a25 * a32 * a51 * a63 - a15 * a22 - * a34 * a51 * a63 + a12 * a25 * a34 * a51 * a63 + a14 * a22 * a35 - * a51 * a63 - a12 * a24 * a35 * a51 * a63 - a15 * a24 * a31 * a52 - * a63 + a14 * a25 * a31 * a52 * a63 + a15 * a21 * a34 * a52 * a63 - - a11 * a25 * a34 * a52 * a63 - a14 * a21 * a35 * a52 * a63 + a11 - * a24 * a35 * a52 * a63 + a15 * a22 * a31 * a54 * a63 - a12 * a25 - * a31 * a54 * a63 - a15 * a21 * a32 * a54 * a63 + a11 * a25 * a32 - * a54 * a63 + a12 * a21 * a35 * a54 * a63 - a11 * a22 * a35 * a54 - * a63 - a14 * a22 * a31 * a55 * a63 + a12 * a24 * a31 * a55 * a63 - + a14 * a21 * a32 * a55 * a63 - a11 * a24 * a32 * a55 * a63 - a12 - * a21 * a34 * a55 * a63 + a11 * a22 * a34 * a55 * a63 - a15 * a23 - * a32 * a51 * a64 + a13 * a25 * a32 * a51 * a64 + a15 * a22 * a33 - * a51 * a64 - a12 * a25 * a33 * a51 * a64 - a13 * a22 * a35 * a51 - * a64 + a12 * a23 * a35 * a51 * a64 + a15 * a23 * a31 * a52 * a64 - - a13 * a25 * a31 * a52 * a64 - a15 * a21 * a33 * a52 * a64 + a11 - * a25 * a33 * a52 * a64 + a13 * a21 * a35 * a52 * a64 - a11 * a23 - * a35 * a52 * a64 - a15 * a22 * a31 * a53 * a64 + a12 * a25 * a31 - * a53 * a64 + a15 * a21 * a32 * a53 * a64 - a11 * a25 * a32 * a53 - * a64 - a12 * a21 * a35 * a53 * a64 + a11 * a22 * a35 * a53 * a64 - + a13 * a22 * a31 * a55 * a64 - a12 * a23 * a31 * a55 * a64 - a13 - * a21 * a32 * a55 * a64 + a11 * a23 * a32 * a55 * a64 + a12 * a21 - * a33 * a55 * a64 - a11 * a22 * a33 * a55 * a64 + a14 * a23 * a32 - * a51 * a65 - a13 * a24 * a32 * a51 * a65 - a14 * a22 * a33 * a51 - * a65 + a12 * a24 * a33 * a51 * a65 + a13 * a22 * a34 * a51 * a65 - - a12 * a23 * a34 * a51 * a65 - a14 * a23 * a31 * a52 * a65 + a13 - * a24 * a31 * a52 * a65 + a14 * a21 * a33 * a52 * a65 - a11 * a24 - * a33 * a52 * a65 - a13 * a21 * a34 * a52 * a65 + a11 * a23 * a34 - * a52 * a65 + a14 * a22 * a31 * a53 * a65 - a12 * a24 * a31 * a53 - * a65 - a14 * a21 * a32 * a53 * a65 + a11 * a24 * a32 * a53 * a65 - + a12 * a21 * a34 * a53 * a65 - a11 * a22 * a34 * a53 * a65 - a13 - * a22 * a31 * a54 * a65 + a12 * a23 * a31 * a54 * a65 + a13 * a21 - * a32 * a54 * a65 - a11 * a23 * a32 * a54 * a65 - a12 * a21 * a33 - * a54 * a65 + a11 * a22 * a33 * a54 * a65; - cofactor[34] = -a15 * a24 * a33 * a42 * a61 + a14 * a25 * a33 * a42 * a61 - + a15 * a23 * a34 * a42 * a61 - a13 * a25 * a34 * a42 * a61 - a14 - * a23 * a35 * a42 * a61 + a13 * a24 * a35 * a42 * a61 + a15 * a24 - * a32 * a43 * a61 - a14 * a25 * a32 * a43 * a61 - a15 * a22 * a34 - * a43 * a61 + a12 * a25 * a34 * a43 * a61 + a14 * a22 * a35 * a43 - * a61 - a12 * a24 * a35 * a43 * a61 - a15 * a23 * a32 * a44 * a61 - + a13 * a25 * a32 * a44 * a61 + a15 * a22 * a33 * a44 * a61 - a12 - * a25 * a33 * a44 * a61 - a13 * a22 * a35 * a44 * a61 + a12 * a23 - * a35 * a44 * a61 + a14 * a23 * a32 * a45 * a61 - a13 * a24 * a32 - * a45 * a61 - a14 * a22 * a33 * a45 * a61 + a12 * a24 * a33 * a45 - * a61 + a13 * a22 * a34 * a45 * a61 - a12 * a23 * a34 * a45 * a61 - + a15 * a24 * a33 * a41 * a62 - a14 * a25 * a33 * a41 * a62 - a15 - * a23 * a34 * a41 * a62 + a13 * a25 * a34 * a41 * a62 + a14 * a23 - * a35 * a41 * a62 - a13 * a24 * a35 * a41 * a62 - a15 * a24 * a31 - * a43 * a62 + a14 * a25 * a31 * a43 * a62 + a15 * a21 * a34 * a43 - * a62 - a11 * a25 * a34 * a43 * a62 - a14 * a21 * a35 * a43 * a62 - + a11 * a24 * a35 * a43 * a62 + a15 * a23 * a31 * a44 * a62 - a13 - * a25 * a31 * a44 * a62 - a15 * a21 * a33 * a44 * a62 + a11 * a25 - * a33 * a44 * a62 + a13 * a21 * a35 * a44 * a62 - a11 * a23 * a35 - * a44 * a62 - a14 * a23 * a31 * a45 * a62 + a13 * a24 * a31 * a45 - * a62 + a14 * a21 * a33 * a45 * a62 - a11 * a24 * a33 * a45 * a62 - - a13 * a21 * a34 * a45 * a62 + a11 * a23 * a34 * a45 * a62 - a15 - * a24 * a32 * a41 * a63 + a14 * a25 * a32 * a41 * a63 + a15 * a22 - * a34 * a41 * a63 - a12 * a25 * a34 * a41 * a63 - a14 * a22 * a35 - * a41 * a63 + a12 * a24 * a35 * a41 * a63 + a15 * a24 * a31 * a42 - * a63 - a14 * a25 * a31 * a42 * a63 - a15 * a21 * a34 * a42 * a63 - + a11 * a25 * a34 * a42 * a63 + a14 * a21 * a35 * a42 * a63 - a11 - * a24 * a35 * a42 * a63 - a15 * a22 * a31 * a44 * a63 + a12 * a25 - * a31 * a44 * a63 + a15 * a21 * a32 * a44 * a63 - a11 * a25 * a32 - * a44 * a63 - a12 * a21 * a35 * a44 * a63 + a11 * a22 * a35 * a44 - * a63 + a14 * a22 * a31 * a45 * a63 - a12 * a24 * a31 * a45 * a63 - - a14 * a21 * a32 * a45 * a63 + a11 * a24 * a32 * a45 * a63 + a12 - * a21 * a34 * a45 * a63 - a11 * a22 * a34 * a45 * a63 + a15 * a23 - * a32 * a41 * a64 - a13 * a25 * a32 * a41 * a64 - a15 * a22 * a33 - * a41 * a64 + a12 * a25 * a33 * a41 * a64 + a13 * a22 * a35 * a41 - * a64 - a12 * a23 * a35 * a41 * a64 - a15 * a23 * a31 * a42 * a64 - + a13 * a25 * a31 * a42 * a64 + a15 * a21 * a33 * a42 * a64 - a11 - * a25 * a33 * a42 * a64 - a13 * a21 * a35 * a42 * a64 + a11 * a23 - * a35 * a42 * a64 + a15 * a22 * a31 * a43 * a64 - a12 * a25 * a31 - * a43 * a64 - a15 * a21 * a32 * a43 * a64 + a11 * a25 * a32 * a43 - * a64 + a12 * a21 * a35 * a43 * a64 - a11 * a22 * a35 * a43 * a64 - - a13 * a22 * a31 * a45 * a64 + a12 * a23 * a31 * a45 * a64 + a13 - * a21 * a32 * a45 * a64 - a11 * a23 * a32 * a45 * a64 - a12 * a21 - * a33 * a45 * a64 + a11 * a22 * a33 * a45 * a64 - a14 * a23 * a32 - * a41 * a65 + a13 * a24 * a32 * a41 * a65 + a14 * a22 * a33 * a41 - * a65 - a12 * a24 * a33 * a41 * a65 - a13 * a22 * a34 * a41 * a65 - + a12 * a23 * a34 * a41 * a65 + a14 * a23 * a31 * a42 * a65 - a13 - * a24 * a31 * a42 * a65 - a14 * a21 * a33 * a42 * a65 + a11 * a24 - * a33 * a42 * a65 + a13 * a21 * a34 * a42 * a65 - a11 * a23 * a34 - * a42 * a65 - a14 * a22 * a31 * a43 * a65 + a12 * a24 * a31 * a43 - * a65 + a14 * a21 * a32 * a43 * a65 - a11 * a24 * a32 * a43 * a65 - - a12 * a21 * a34 * a43 * a65 + a11 * a22 * a34 * a43 * a65 + a13 - * a22 * a31 * a44 * a65 - a12 * a23 * a31 * a44 * a65 - a13 * a21 - * a32 * a44 * a65 + a11 * a23 * a32 * a44 * a65 + a12 * a21 * a33 - * a44 * a65 - a11 * a22 * a33 * a44 * a65; - cofactor[35] = a15 * a24 * a33 * a42 * a51 - a14 * a25 * a33 * a42 * a51 - - a15 * a23 * a34 * a42 * a51 + a13 * a25 * a34 * a42 * a51 + a14 - * a23 * a35 * a42 * a51 - a13 * a24 * a35 * a42 * a51 - a15 * a24 - * a32 * a43 * a51 + a14 * a25 * a32 * a43 * a51 + a15 * a22 * a34 - * a43 * a51 - a12 * a25 * a34 * a43 * a51 - a14 * a22 * a35 * a43 - * a51 + a12 * a24 * a35 * a43 * a51 + a15 * a23 * a32 * a44 * a51 - - a13 * a25 * a32 * a44 * a51 - a15 * a22 * a33 * a44 * a51 + a12 - * a25 * a33 * a44 * a51 + a13 * a22 * a35 * a44 * a51 - a12 * a23 - * a35 * a44 * a51 - a14 * a23 * a32 * a45 * a51 + a13 * a24 * a32 - * a45 * a51 + a14 * a22 * a33 * a45 * a51 - a12 * a24 * a33 * a45 - * a51 - a13 * a22 * a34 * a45 * a51 + a12 * a23 * a34 * a45 * a51 - - a15 * a24 * a33 * a41 * a52 + a14 * a25 * a33 * a41 * a52 + a15 - * a23 * a34 * a41 * a52 - a13 * a25 * a34 * a41 * a52 - a14 * a23 - * a35 * a41 * a52 + a13 * a24 * a35 * a41 * a52 + a15 * a24 * a31 - * a43 * a52 - a14 * a25 * a31 * a43 * a52 - a15 * a21 * a34 * a43 - * a52 + a11 * a25 * a34 * a43 * a52 + a14 * a21 * a35 * a43 * a52 - - a11 * a24 * a35 * a43 * a52 - a15 * a23 * a31 * a44 * a52 + a13 - * a25 * a31 * a44 * a52 + a15 * a21 * a33 * a44 * a52 - a11 * a25 - * a33 * a44 * a52 - a13 * a21 * a35 * a44 * a52 + a11 * a23 * a35 - * a44 * a52 + a14 * a23 * a31 * a45 * a52 - a13 * a24 * a31 * a45 - * a52 - a14 * a21 * a33 * a45 * a52 + a11 * a24 * a33 * a45 * a52 - + a13 * a21 * a34 * a45 * a52 - a11 * a23 * a34 * a45 * a52 + a15 - * a24 * a32 * a41 * a53 - a14 * a25 * a32 * a41 * a53 - a15 * a22 - * a34 * a41 * a53 + a12 * a25 * a34 * a41 * a53 + a14 * a22 * a35 - * a41 * a53 - a12 * a24 * a35 * a41 * a53 - a15 * a24 * a31 * a42 - * a53 + a14 * a25 * a31 * a42 * a53 + a15 * a21 * a34 * a42 * a53 - - a11 * a25 * a34 * a42 * a53 - a14 * a21 * a35 * a42 * a53 + a11 - * a24 * a35 * a42 * a53 + a15 * a22 * a31 * a44 * a53 - a12 * a25 - * a31 * a44 * a53 - a15 * a21 * a32 * a44 * a53 + a11 * a25 * a32 - * a44 * a53 + a12 * a21 * a35 * a44 * a53 - a11 * a22 * a35 * a44 - * a53 - a14 * a22 * a31 * a45 * a53 + a12 * a24 * a31 * a45 * a53 - + a14 * a21 * a32 * a45 * a53 - a11 * a24 * a32 * a45 * a53 - a12 - * a21 * a34 * a45 * a53 + a11 * a22 * a34 * a45 * a53 - a15 * a23 - * a32 * a41 * a54 + a13 * a25 * a32 * a41 * a54 + a15 * a22 * a33 - * a41 * a54 - a12 * a25 * a33 * a41 * a54 - a13 * a22 * a35 * a41 - * a54 + a12 * a23 * a35 * a41 * a54 + a15 * a23 * a31 * a42 * a54 - - a13 * a25 * a31 * a42 * a54 - a15 * a21 * a33 * a42 * a54 + a11 - * a25 * a33 * a42 * a54 + a13 * a21 * a35 * a42 * a54 - a11 * a23 - * a35 * a42 * a54 - a15 * a22 * a31 * a43 * a54 + a12 * a25 * a31 - * a43 * a54 + a15 * a21 * a32 * a43 * a54 - a11 * a25 * a32 * a43 - * a54 - a12 * a21 * a35 * a43 * a54 + a11 * a22 * a35 * a43 * a54 - + a13 * a22 * a31 * a45 * a54 - a12 * a23 * a31 * a45 * a54 - a13 - * a21 * a32 * a45 * a54 + a11 * a23 * a32 * a45 * a54 + a12 * a21 - * a33 * a45 * a54 - a11 * a22 * a33 * a45 * a54 + a14 * a23 * a32 - * a41 * a55 - a13 * a24 * a32 * a41 * a55 - a14 * a22 * a33 * a41 - * a55 + a12 * a24 * a33 * a41 * a55 + a13 * a22 * a34 * a41 * a55 - - a12 * a23 * a34 * a41 * a55 - a14 * a23 * a31 * a42 * a55 + a13 - * a24 * a31 * a42 * a55 + a14 * a21 * a33 * a42 * a55 - a11 * a24 - * a33 * a42 * a55 - a13 * a21 * a34 * a42 * a55 + a11 * a23 * a34 - * a42 * a55 + a14 * a22 * a31 * a43 * a55 - a12 * a24 * a31 * a43 - * a55 - a14 * a21 * a32 * a43 * a55 + a11 * a24 * a32 * a43 * a55 - + a12 * a21 * a34 * a43 * a55 - a11 * a22 * a34 * a43 * a55 - a13 - * a22 * a31 * a44 * a55 + a12 * a23 * a31 * a44 * a55 + a13 * a21 - * a32 * a44 * a55 - a11 * a23 * a32 * a44 * a55 - a12 * a21 * a33 - * a44 * a55 + a11 * a22 * a33 * a44 * a55; - - for (int i = 1; i <= 6; ++i) { - for (int j = 1; j <= 6; ++j) { - ainv[j + i * 6] = cofactor[i + j * 6 - 7] / det; - } - } -/* ainv = transpose(cofactor) ! / det */ - *ok_flag__ = 0; - return 0; -} - -int cmx_inv6_v1(const double const a[6][6], double *ainv, int*ok_flag__) -{ - double cofactor[36] /* was [6][6] */; - - /* Parameter adjustments */ - ainv -= 7; -// a -= 7; - - /* Function Body */ - const double eps = 1e-10; - const double - det = -(a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][6-1]* - a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]* - a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]* - a[4-1][4-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]* - a[5-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] - + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][4-1]* - a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][6-1]* - a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]* - a[4-1][5-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]* - a[5-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] - - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][6-1]* - a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][4-1]* - a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]* - a[4-1][2-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]* - a[5-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] - + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][2-1]* - a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][6-1]* - a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]* - a[4-1][5-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]* - a[5-1][3-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] - - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][4-1]* - a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][5-1]* - a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]* - a[4-1][2-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]* - a[5-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] - + - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][2-1]* - a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]* - a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]* - a[4-1][5-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]* - a[5-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] - - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][5-1]* - a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][2-1]* - a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]* - a[4-1][2-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]* - a[5-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] - + - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][4-1]* - a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][6-1]* - a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]* - a[4-1][3-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]* - a[5-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] - - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][4-1]* - a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][2-1]* - a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]* - a[4-1][6-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]* - a[5-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] - + - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][3-1]* - a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][5-1]* - a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]* - a[4-1][3-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]* - a[5-1][6-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] - - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][3-1]* - a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][3-1]* - a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]* - a[4-1][5-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]* - a[5-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1])*a[6-1][1-1] - + (a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1])*a[6-1][2-1] - - (a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]* - a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]* - a[4-1][2-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]* - a[5-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] - + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][5-1]* - a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]* - a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]* - a[4-1][5-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]* - a[5-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] - + - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][2-1]* - a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]* - a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]* - a[4-1][1-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]* - a[5-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] - + - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][6-1]* - a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]* - a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]* - a[4-1][5-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]* - a[5-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] - + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][4-1]* - a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]* - a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]* - a[4-1][6-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]* - a[5-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] - + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][6-1]* - a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]* - a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]* - a[4-1][2-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]* - a[5-1][4-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] - + - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][1-1]* - a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]* - a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]* - a[4-1][6-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]* - a[5-1][4-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] - + - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][4-1]* - a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][4-1]* - a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]* - a[4-1][2-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]* - a[5-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] - + - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][1-1]* - a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]* - a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]* - a[4-1][6-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]* - a[5-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] - + - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][5-1]* - a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]* - a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]* - a[4-1][2-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]* - a[5-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] - + - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][2-1]* - a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]* - a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]* - a[4-1][4-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]* - a[5-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] - - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1])*a[6-1][3-1] - + (a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] - - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][5-1]* - a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]* - a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]* - a[4-1][3-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]* - a[5-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] - - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][2-1]* - a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]* - a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]* - a[4-1][6-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]* - a[5-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] - - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][6-1]* - a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]* - a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]* - a[4-1][3-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]* - a[5-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] - - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][3-1]* - a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]* - a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]* - a[4-1][5-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]* - a[5-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] - + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][6-1]* - a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]* - a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]* - a[4-1][1-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]* - a[5-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] - - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][1-1]* - a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]* - a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]* - a[4-1][5-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]* - a[5-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] - + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][2-1]* - a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][3-1]* - a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]* - a[4-1][1-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]* - a[5-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] - - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][1-1]* - a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]* - a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]* - a[4-1][3-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]* - a[5-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] - + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][3-1]* - a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]* - a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]* - a[4-1][1-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]* - a[5-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] - - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][3-1]* - a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]* - a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]* - a[4-1][2-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]* - a[5-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] - + - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][3-1]* - a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]* - a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]* - a[4-1][5-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1])*a[6-1][4-1] - - (a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1])*a[6-1][5-1] - + (a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][4-1]* - a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]* - a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]* - a[4-1][2-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]* - a[5-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] - - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][5-1]* - a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]* - a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]* - a[4-1][4-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]* - a[5-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] - - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][2-1]* - a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]* - a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]* - a[4-1][1-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]* - a[5-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] - - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][4-1]* - a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]* - a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]* - a[4-1][4-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]* - a[5-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] - - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][1-1]* - a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]* - a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]* - a[4-1][1-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]* - a[5-1][3-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] - - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][5-1]* - a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]* - a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]* - a[4-1][4-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]* - a[5-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] - - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][2-1]* - a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]* - a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]* - a[4-1][5-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]* - a[5-1][4-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] - - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][5-1]* - a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]* - a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]* - a[4-1][2-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]* - a[5-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] - - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][1-1]* - a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]* - a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]* - a[4-1][5-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]* - a[5-1][4-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] - - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][3-1]* - a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]* - a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]* - a[4-1][2-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]* - a[5-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] - - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][1-1]* - a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]* - a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]* - a[4-1][4-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]* - a[5-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]) * - a[6-1][6-1]; - - if (fabs(det) <= eps) { - *ok_flag__ = -1; - return 0; - } - cofactor[0] = a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - - - a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - + a[2-1][5-1]* - a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - - a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - - a[2-1][6-1]*a[3-1][5-1]* - a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - + a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - + a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]* - a[5-1][4-1]*a[6-1][2-1] - - a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]* - a[6-1][2-1] - + a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - + a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - - - a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - - a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - + a[2-1][3-1]* - a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - + a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - - a[2-1][3-1]*a[3-1][4-1]* - a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - + a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]* - a[5-1][6-1]*a[6-1][2-1] - + a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - - a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]* - a[6-1][2-1] - - a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - - - a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - + a[2-1][6-1]* - a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - - a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - - a[2-1][5-1]*a[3-1][4-1]* - a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - + a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - + a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]* - a[5-1][4-1]*a[6-1][3-1] - - a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - - a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]* - a[6-1][3-1] - + a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - - - a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - - a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - + a[2-1][4-1]* - a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - + a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - - a[2-1][2-1]*a[3-1][6-1]* - a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - - a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - + a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]* - a[5-1][5-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - - a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]* - a[6-1][3-1] - - a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - + a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - + - a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - - a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - + a[2-1][6-1]* - a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - - a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - - a[2-1][6-1]*a[3-1][3-1]* - a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - + a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - + a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]* - a[5-1][2-1]*a[6-1][4-1] - - a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - - a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]* - a[6-1][4-1] - + a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - + a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - - - a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - - a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - + a[2-1][2-1]* - a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - + a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - - a[2-1][3-1]*a[3-1][6-1]* - a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - - a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - + a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]* - a[5-1][5-1]*a[6-1][4-1] - + a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - - a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]* - a[6-1][4-1] - - a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - + a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - + - a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - - a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - - a[2-1][3-1]* - a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - + a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - - a[2-1][6-1]*a[3-1][4-1]* - a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - + a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]* - a[5-1][2-1]*a[6-1][5-1] - - a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - - a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]* - a[6-1][5-1] - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - + a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - - - a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - - a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - + a[2-1][2-1]* - a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - + a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - - a[2-1][2-1]*a[3-1][4-1]* - a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - - a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - + a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]* - a[5-1][4-1]*a[6-1][5-1] - + a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - - a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]* - a[6-1][5-1] - - a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - + a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - + - a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - - a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - - a[2-1][4-1]* - a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - + a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - + a[2-1][3-1]*a[3-1][2-1]* - a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - - a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - + a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]* - a[5-1][2-1]*a[6-1][6-1] - - a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - - a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]* - a[6-1][6-1] - + a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - + a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - - - a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - - a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - + a[2-1][4-1]* - a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - + a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - - a[2-1][2-1]*a[3-1][5-1]* - a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - - a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - + a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]* - a[5-1][3-1]*a[6-1][6-1] - + a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - - a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]* - a[6-1][6-1] - - a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - + a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - + - a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - - a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - - a[2-1][4-1]* - a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - + a[2-1][4-1]*a[3-1][2-1]* - a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - - a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - - a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]* - a[5-1][5-1]*a[6-1][6-1] - + a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[1] = -a[1-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[2] = a[1-1][6-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - - - a[1-1][6-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][5-1]* - a[2-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][5-1]* - a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[4-1][5-1]* - a[5-1][4-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][4-1]* - a[6-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - - - a[1-1][4-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][3-1]* - a[2-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]* - a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[4-1][3-1]* - a[5-1][6-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][6-1]* - a[6-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - - - a[1-1][6-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][6-1]* - a[2-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][4-1]* - a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][5-1]*a[4-1][2-1]* - a[5-1][4-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][4-1]* - a[6-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - - - a[1-1][2-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][4-1]* - a[2-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]* - a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[4-1][6-1]* - a[5-1][5-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][6-1]* - a[6-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - + - a[1-1][4-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][6-1]* - a[2-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][3-1]* - a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][3-1]*a[4-1][6-1]* - a[5-1][2-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][3-1]* - a[6-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - - - a[1-1][2-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][2-1]* - a[2-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]* - a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[4-1][3-1]* - a[5-1][5-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][5-1]* - a[6-1][4-1] - - a[1-1][5-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - + - a[1-1][5-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][3-1]* - a[2-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][4-1]* - a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[4-1][4-1]* - a[5-1][2-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][2-1]* - a[6-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - - - a[1-1][4-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][2-1]* - a[2-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]* - a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[4-1][2-1]* - a[5-1][4-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][4-1]* - a[6-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - + - a[1-1][4-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][4-1]* - a[2-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]* - a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][5-1]*a[2-1][4-1]*a[4-1][3-1]* - a[5-1][2-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][2-1]* - a[6-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - - - a[1-1][3-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][4-1]* - a[2-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]* - a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[4-1][5-1]* - a[5-1][3-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][4-1]* - a[6-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - + - a[1-1][3-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][4-1]* - a[2-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]* - a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[4-1][4-1]* - a[5-1][5-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[3] = -a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[4] = a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][2-1] - - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][2-1] - + a[1-1][5-1]* - a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][5-1]* - a[3-1][3-1]*a[4-1][4-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]* - a[4-1][4-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]* - a[6-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][2-1] - - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][2-1] - + a[1-1][3-1]* - a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]* - a[3-1][6-1]*a[4-1][5-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]* - a[4-1][6-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]* - a[6-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][2-1] - - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][3-1] - + a[1-1][6-1]* - a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][4-1]* - a[3-1][6-1]*a[4-1][2-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]* - a[4-1][4-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]* - a[6-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][3-1] - - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][3-1] - + a[1-1][4-1]* - a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]* - a[3-1][4-1]*a[4-1][5-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]* - a[4-1][5-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]* - a[6-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][3-1] - + - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][3-1] - + a[1-1][6-1]* - a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][3-1]* - a[3-1][5-1]*a[4-1][2-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]* - a[4-1][2-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]* - a[6-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][4-1] - - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][4-1] - + a[1-1][2-1]* - a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]* - a[3-1][2-1]*a[4-1][5-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]* - a[4-1][5-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]* - a[6-1][4-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][4-1] - + - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][4-1] - - a[1-1][3-1]* - a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][4-1]* - a[3-1][3-1]*a[4-1][2-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]* - a[4-1][2-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]* - a[6-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][5-1] - - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][5-1] - + a[1-1][2-1]* - a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]* - a[3-1][6-1]*a[4-1][3-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]* - a[4-1][4-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]* - a[6-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][5-1] - + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][5-1] - - a[1-1][4-1]* - a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]* - a[3-1][4-1]*a[4-1][6-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][5-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]* - a[4-1][2-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]* - a[6-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][6-1] - - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][6-1] - + a[1-1][4-1]* - a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]* - a[3-1][4-1]*a[4-1][3-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]* - a[4-1][3-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]* - a[6-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][6-1] - + - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][6-1] - - a[1-1][4-1]* - a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]* - a[3-1][3-1]*a[4-1][5-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]* - a[4-1][5-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][6-1]; - cofactor[5] = -a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]; - cofactor[6] = -a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - + a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - - a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - - a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - + a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - + a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - - a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - - a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - + a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - - a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - - a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - - a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - - a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - - a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - - a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - + a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - + a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - - a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - + a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - - a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - - a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - - a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - - a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - + a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - - a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - - a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - + a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - + a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - - a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - - a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - + a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - + a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - - a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - - a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - + a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - - a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - - a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - + a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - - a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - + a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - + a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - - a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - - a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - + a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - + a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - - a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - - a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - + a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - + a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - - a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - - a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - + a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - + a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - - a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - - a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - + a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - + a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - - a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - - a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - + a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - + a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - - a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - + a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - - a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - - a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - + a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - + a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - - a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - - a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - + a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - - a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - - a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - + a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - + a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - - a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - - a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - + a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - + a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - - a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - - a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - + a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - - a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - - a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - + a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - - a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - + a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - + a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - - a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - - a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - + a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - - a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - - a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - + a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - + a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - - a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - - a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - + a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - + a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - - a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - - a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - + a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - + a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - - a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - - a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - + a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - + a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1] - - a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[7] = a[1-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - - - a[1-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][5-1]* - a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][6-1]*a[3-1][5-1]* - a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][6-1]*a[3-1][3-1]*a[4-1][5-1]* - a[5-1][4-1]*a[6-1][1-1] - - a[1-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]* - a[6-1][1-1] - + a[1-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - - - a[1-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][3-1]* - a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][3-1]*a[3-1][4-1]* - a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][4-1]*a[3-1][5-1]*a[4-1][3-1]* - a[5-1][6-1]*a[6-1][1-1] - + a[1-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]* - a[6-1][1-1] - - a[1-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - - - a[1-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][6-1]* - a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][5-1]*a[3-1][4-1]* - a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][6-1]*a[3-1][5-1]*a[4-1][1-1]* - a[5-1][4-1]*a[6-1][3-1] - - a[1-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]* - a[6-1][3-1] - + a[1-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - - - a[1-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][4-1]* - a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][1-1]*a[3-1][6-1]* - a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][1-1]*a[3-1][4-1]*a[4-1][6-1]* - a[5-1][5-1]*a[6-1][3-1] - + a[1-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]* - a[6-1][3-1] - - a[1-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - + - a[1-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][6-1]* - a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][6-1]*a[3-1][3-1]* - a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][5-1]*a[3-1][3-1]*a[4-1][6-1]* - a[5-1][1-1]*a[6-1][4-1] - - a[1-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]* - a[6-1][4-1] - + a[1-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - - - a[1-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][1-1]* - a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][3-1]*a[3-1][6-1]* - a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][1-1]*a[3-1][6-1]*a[4-1][3-1]* - a[5-1][5-1]*a[6-1][4-1] - + a[1-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]* - a[6-1][4-1] - - a[1-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - + - a[1-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][3-1]* - a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][6-1]*a[3-1][4-1]* - a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][6-1]*a[3-1][3-1]*a[4-1][4-1]* - a[5-1][1-1]*a[6-1][5-1] - - a[1-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]* - a[6-1][5-1] - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - - - a[1-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][1-1]* - a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][1-1]*a[3-1][4-1]* - a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][3-1]*a[3-1][6-1]*a[4-1][1-1]* - a[5-1][4-1]*a[6-1][5-1] - + a[1-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]* - a[6-1][5-1] - - a[1-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - + - a[1-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][4-1]* - a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][3-1]*a[3-1][1-1]* - a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][5-1]*a[3-1][4-1]*a[4-1][3-1]* - a[5-1][1-1]*a[6-1][6-1] - - a[1-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]* - a[6-1][6-1] - + a[1-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - - - a[1-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][4-1]* - a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][1-1]*a[3-1][5-1]* - a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][1-1]*a[3-1][4-1]*a[4-1][5-1]* - a[5-1][3-1]*a[6-1][6-1] - + a[1-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]* - a[6-1][6-1] - - a[1-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - + - a[1-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][4-1]* - a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][4-1]*a[3-1][1-1]* - a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][3-1]*a[3-1][1-1]*a[4-1][4-1]* - a[5-1][5-1]*a[6-1][6-1] - + a[1-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[8] = -a[1-1][6-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][5-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[9] = a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][5-1]* - a[2-1][4-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]* - a[3-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]* - a[5-1][4-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][4-1]* - a[6-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][3-1]* - a[2-1][6-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]* - a[3-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]* - a[5-1][6-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][6-1]* - a[6-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][6-1]* - a[2-1][4-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][4-1]* - a[3-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]* - a[5-1][4-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][4-1]* - a[6-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][4-1]* - a[2-1][6-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]* - a[3-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]* - a[5-1][5-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][6-1]* - a[6-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - + - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][6-1]* - a[2-1][5-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][3-1]* - a[3-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]* - a[5-1][1-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][3-1]* - a[6-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][1-1]* - a[2-1][5-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]* - a[3-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]* - a[5-1][5-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][5-1]* - a[6-1][4-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - + - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][3-1]* - a[2-1][1-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][4-1]* - a[3-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]* - a[5-1][1-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][1-1]* - a[6-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][1-1]* - a[2-1][6-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]* - a[3-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]* - a[5-1][4-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][4-1]* - a[6-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - + - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][4-1]* - a[2-1][1-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]* - a[3-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]* - a[5-1][1-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][1-1]* - a[6-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][4-1]* - a[2-1][5-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]* - a[3-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]* - a[5-1][3-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][4-1]* - a[6-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - + - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][4-1]* - a[2-1][3-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]* - a[3-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]* - a[5-1][5-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[10] = -a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][5-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][6-1]; - cofactor[11] = a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]; - cofactor[12] = a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - - a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - - a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - - a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - - a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - + a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - - a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - - a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - + a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - + a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - - a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - - a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - - a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - - a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - + a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - - a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - - a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - + a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - - a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - + a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - + a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - - a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - + a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - + a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - - a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - + a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - + a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - - a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - - a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - + a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - - a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - - a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - + a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - + a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - - a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - + a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - + a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - - a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - + a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - - a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - - a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - + a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - + a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - - a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - - a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - + a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - + a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - - a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - - a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - + a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - + a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - - a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - - a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - + a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - + a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - - a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - - a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - + a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - + a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - - a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - - a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - + a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - - a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - + a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - - a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - - a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - + a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - + a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - - a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - - a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - + a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - + a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - - a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - - a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - + a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - + a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - - a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - - a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - + a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - + a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - - a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - - a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - + a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - + a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - - a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - + a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - - a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - - a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - + a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - + a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - - a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - - a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - + a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - + a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - - a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - - a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - + a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - + a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - - a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - - a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - + a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - + a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - - a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - - a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - + a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - + a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - - a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - - a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1] - + a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[13] = -a[1-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[14] = a[1-1][6-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][5-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[15] = -a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[16] = a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][5-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][6-1]; - cofactor[17] = -a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][6-1]; - cofactor[18] = -a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - + a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - - a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - - a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - + a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - + a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - - a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - - a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - + a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - - a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - - a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - - a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - - a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - - a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - - a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - + a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - + a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - - a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - + a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - - a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - + a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - + a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - - a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - - a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - + a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - + a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - - a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - + a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - + a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - - a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - - a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - + a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - + a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - - a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - + a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - + a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - - a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - - a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - + a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - - a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - + a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - - a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - - a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - + a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - + a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - - a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - - a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - + a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - - a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - - a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - + a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - + a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - - a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - - a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - + a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - - a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - - a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - + a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - + a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - - a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - + a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - - a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - - a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - + a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - + a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - - a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - - a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - + a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - + a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - - a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - - a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - + a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - + a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - - a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - - a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - + a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - + a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - - a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - - a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - + a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - + a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - - a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - - a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - + a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - - a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - + a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - + a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - - a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - - a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - + a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - + a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - - a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - - a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - + a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - + a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - - a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - - a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - + a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - + a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - - a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - - a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - + a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - + a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - - a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - - a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - + a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - + a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - - a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[19] = a[1-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[20] = -a[1-1][6-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][5-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[21] = a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][5-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][6-1]; - cofactor[22] = -a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][5-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][6-1]; - cofactor[23] = a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][5-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][6-1]; - cofactor[24] = a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - - a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - - a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - + a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - + a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - - a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - - a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - + a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - - a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - - a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - + a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - + a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - - a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - - a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - + a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - + a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - - a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - - a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - + a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - - a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - - a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - + a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - - a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - + a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - - a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - - a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - + a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - - a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - - a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - + a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - + a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - - a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - - a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - + a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - + a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - - a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - - a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - + a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - + a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - - a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - - a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - + a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - + a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - - a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - + a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - - a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - - a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - + a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - + a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - - a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - - a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - + a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - + a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - - a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - - a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - + a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - + a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - - a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - - a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - + a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - + a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - - a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - - a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - + a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - + a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - - a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - - a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - + a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - - a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - + a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - + a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - - a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - - a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - + a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - + a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - - a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - - a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - + a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - + a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - - a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - - a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - + a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - + a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - - a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - - a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - + a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - + a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - - a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - - a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - + a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - + a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - - a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - + a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - - a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - - a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - + a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - + a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - - a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - - a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - + a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - - a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - - a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - + a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - + a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - - a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - - a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - + a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - + a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - - a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - - a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - + a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - + a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - - a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - - a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - + a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1]; - cofactor[25] = -a[1-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1]; - cofactor[26] = a[1-1][6-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[4-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[4-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][4-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][6-1]; - cofactor[27] = -a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][6-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][6-1]*a[6-1][4-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][6-1]; - cofactor[28] = a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][1-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][2-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[6-1][3-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[6-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[6-1][4-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][6-1]; - cofactor[29] = -a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][1-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][2-1] - - a[1-1][6-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][6-1]*a[5-1][3-1] - + a[1-1][6-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][6-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][6-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][6-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][6-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][6-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][6-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][6-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][6-1]*a[5-1][4-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][6-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][6-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][6-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][6-1]; - cofactor[30] = -a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - + a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - - a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - - a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - - a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - - a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - + a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - + a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - - a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - - a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - + a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - - a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - - a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - + a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - + a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - - a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - - a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - - a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - + a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - - a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - + a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - + a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - - a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - + a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - + a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - - a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - - a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - + a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - + a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - - a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - + a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - + a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - - a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - - a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - + a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - - a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - - a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - + a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - - a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - + a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - - a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - - a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - + a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - - a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - - a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - + a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - + a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - - a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - - a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - + a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - - a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - - a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - + a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - + a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - - a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - - a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - + a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - + a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - - a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - + a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - - a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - - a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - + a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - + a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - - a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - - a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - + a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - + a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - - a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - - a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - + a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - + a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - - a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - - a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - + a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - + a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - - a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - - a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - + a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - + a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - - a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - - a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - + a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - - a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - + a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - + a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - - a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - - a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - + a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - + a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - - a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - - a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - + a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - + a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - - a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - - a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - + a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - + a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - - a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - - a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - + a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - + a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - - a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - - a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - + a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - + a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - - a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1]; - cofactor[31] = a[1-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1]; - - cofactor[32] = -a[1-1][5-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[4-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[4-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - - - a[1-1][4-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[4-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[4-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[4-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[4-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[4-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[4-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[4-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[4-1][3-1]*a[5-1][4-1]*a[6-1][5-1]; - cofactor[33] = a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][4-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][5-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][1-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[5-1][2-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[5-1][3-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][5-1]*a[6-1][4-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][1-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][1-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[5-1][2-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[5-1][2-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[5-1][3-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[5-1][3-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[5-1][4-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[5-1][4-1]*a[6-1][5-1]; - cofactor[34] = -a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][1-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][2-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[6-1][3-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[6-1][3-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[6-1][4-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[6-1][4-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[6-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[6-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[6-1][4-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[6-1][5-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[6-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[6-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[6-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[6-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[6-1][5-1]; - cofactor[35] = a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][1-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][1-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][1-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][2-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][2-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][2-1] - + a[1-1][5-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][3-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][4-1]*a[5-1][3-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][5-1]*a[5-1][3-1] - - a[1-1][5-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][1-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][5-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][5-1]*a[4-1][2-1]*a[5-1][4-1] - - a[1-1][5-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][5-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][5-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][5-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][5-1]*a[4-1][3-1]*a[5-1][4-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][5-1]*a[5-1][4-1] - + a[1-1][4-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][1-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][1-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][4-1]*a[3-1][3-1]*a[4-1][2-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][3-1]*a[3-1][4-1]*a[4-1][2-1]*a[5-1][5-1] - + a[1-1][4-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][4-1]*a[3-1][1-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][4-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][4-1]*a[3-1][2-1]*a[4-1][3-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][1-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][2-1]*a[3-1][4-1]*a[4-1][3-1]*a[5-1][5-1] - - a[1-1][3-1]*a[2-1][2-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][2-1]*a[2-1][3-1]*a[3-1][1-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][3-1]*a[2-1][1-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][1-1]*a[2-1][3-1]*a[3-1][2-1]*a[4-1][4-1]*a[5-1][5-1] - - a[1-1][2-1]*a[2-1][1-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1] - + a[1-1][1-1]*a[2-1][2-1]*a[3-1][3-1]*a[4-1][4-1]*a[5-1][5-1]; - - const double jinv = 1/det; - - for (int i = 1; i <= 6; ++i) { - for (int j = 1; j <= 6; ++j) { - ainv[j + i*6] = cofactor[i + j*6 - 7] *jinv; - } - } - *ok_flag__ = 0; - return 0; -} -#endif - -#define a11 a[ 0] -#define a12 a[6] -#define a13 a[12] -#define a14 a[18] -#define a15 a[24] -#define a16 a[30] -#define a21 a[ 1] -#define a22 a[7] -#define a23 a[13] -#define a24 a[19] -#define a25 a[25] -#define a26 a[31] -#define a31 a[ 2] -#define a32 a[8] -#define a33 a[14] -#define a34 a[20] -#define a35 a[26] -#define a36 a[32] -#define a41 a[3] -#define a42 a[9] -#define a43 a[15] -#define a44 a[21] -#define a45 a[27] -#define a46 a[33] -#define a51 a[4] -#define a52 a[10] -#define a53 a[16] -#define a54 a[22] -#define a55 a[28] -#define a56 a[34] -#define a61 a[5] -#define a62 a[11] -#define a63 a[17] -#define a64 a[23] -#define a65 a[29] -#define a66 a[35] - -int cmx_inv6(const double a[36], double *ainv, int*ok_flag__) -{ - double cofactor[36]; - - /* Parameter adjustments */ -// ainv -= 7; -// a -= 7; - - /* Function Body */ - const double eps = 1e-10; - const double - det = - ( a16*a25*a34*a43*a52 - - a15*a26*a34*a43*a52 - - a16*a24*a35*a43*a52 - + a14*a26*a35*a43*a52 - + a15*a24*a36*a43*a52 - - a14*a25*a36*a43*a52 - - a16*a25*a33*a44*a52 - + a15*a26*a33*a44*a52 - + a16*a23*a35*a44*a52 - - a13*a26*a35*a44*a52 - - a15*a23*a36*a44*a52 - + a13*a25*a36*a44*a52 - + a16*a24*a33*a45*a52 - - a14*a26*a33*a45*a52 - - a16*a23*a34*a45*a52 - + a13*a26*a34*a45*a52 - + a14*a23*a36*a45*a52 - - a13*a24*a36*a45*a52 - - a15*a24*a33*a46*a52 - + a14*a25*a33*a46*a52 - + a15*a23*a34*a46*a52 - - a13*a25*a34*a46*a52 - - a14*a23*a35*a46*a52 - + a13*a24*a35*a46*a52 - - a16*a25*a34*a42*a53 - + a15*a26*a34*a42*a53 - + a16*a24*a35*a42*a53 - - a14*a26*a35*a42*a53 - - a15*a24*a36*a42*a53 - + a14*a25*a36*a42*a53 - + a16*a25*a32*a44*a53 - - a15*a26*a32*a44*a53 - - a16*a22*a35*a44*a53 - + - a12*a26*a35*a44*a53 - + a15*a22*a36*a44*a53 - - a12*a25*a36*a44*a53 - - a16*a24*a32*a45*a53 - + a14*a26*a32*a45*a53 - + a16*a22*a34*a45*a53 - - a12*a26*a34*a45*a53 - - a14*a22*a36*a45*a53 - + a12*a24*a36*a45*a53 - + a15*a24*a32*a46*a53 - - a14*a25*a32*a46*a53 - - - a15*a22*a34*a46*a53 - + a12*a25*a34*a46*a53 - + a14*a22*a35*a46*a53 - - a12*a24*a35*a46*a53 - + a16*a25*a33*a42*a54 - - a15*a26*a33*a42*a54 - - a16*a23*a35*a42*a54 - + a13*a26*a35*a42*a54 - + a15*a23*a36*a42*a54 - - a13*a25*a36*a42*a54 - - a16*a25*a32*a43*a54 - + - a15*a26*a32*a43*a54 - + a16*a22*a35*a43*a54 - - a12*a26*a35*a43*a54 - - a15*a22*a36*a43*a54 - + a12*a25*a36*a43*a54 - + a16*a23*a32*a45*a54 - - a13*a26*a32*a45*a54 - - a16*a22*a33*a45*a54 - + a12*a26*a33*a45*a54 - + a13*a22*a36*a45*a54 - - a12*a23*a36*a45*a54 - - - a15*a23*a32*a46*a54 - + a13*a25*a32*a46*a54 - + a15*a22*a33*a46*a54 - - a12*a25*a33*a46*a54 - - a13*a22*a35*a46*a54 - + a12*a23*a35*a46*a54 - - a16*a24*a33*a42*a55 - + a14*a26*a33*a42*a55 - + a16*a23*a34*a42*a55 - - a13*a26*a34*a42*a55 - - a14*a23*a36*a42*a55 - + a13*a24*a36*a42*a55 - + a16*a24*a32*a43*a55 - - a14*a26*a32*a43*a55 - - a16*a22*a34*a43*a55 - + a12*a26*a34*a43*a55 - + a14*a22*a36*a43*a55 - - a12*a24*a36*a43*a55 - - a16*a23*a32*a44*a55 - + a13*a26*a32*a44*a55 - + a16*a22*a33*a44*a55 - - a12*a26*a33*a44*a55 - - a13*a22*a36*a44*a55 - + a12*a23*a36*a44*a55 - + a14*a23*a32*a46*a55 - - a13*a24*a32*a46*a55 - - a14*a22*a33*a46*a55 - + a12*a24*a33*a46*a55 - + a13*a22*a34*a46*a55 - - a12*a23*a34*a46*a55 - + a15*a24*a33*a42*a56 - - a14*a25*a33*a42*a56 - - a15*a23*a34*a42*a56 - + a13*a25*a34*a42*a56 - + a14*a23*a35*a42*a56 - - a13*a24*a35*a42*a56 - - a15*a24*a32*a43*a56 - + a14*a25*a32*a43*a56 - + a15*a22*a34*a43*a56 - - a12*a25*a34*a43*a56 - - a14*a22*a35*a43*a56 - + a12*a24*a35*a43*a56 - + a15*a23*a32*a44*a56 - - a13*a25*a32*a44*a56 - - a15*a22*a33*a44*a56 - + a12*a25*a33*a44*a56 - + a13*a22*a35*a44*a56 - - a12*a23*a35*a44*a56 - - a14*a23*a32*a45*a56 - + a13*a24*a32*a45*a56 - + a14*a22*a33*a45*a56 - - a12*a24*a33*a45*a56 - - a13*a22*a34*a45*a56 - + a12*a23*a34*a45*a56)*a61 - - + (a16*a25*a34*a43*a51 - - a15*a26*a34*a43*a51 - - a16*a24*a35*a43*a51 - + a14*a26*a35*a43*a51 - + a15*a24*a36*a43*a51 - - a14*a25*a36*a43*a51 - - a16*a25*a33*a44*a51 - + a15*a26*a33*a44*a51 - + a16*a23*a35*a44*a51 - - a13*a26*a35*a44*a51 - - a15*a23*a36*a44*a51 - + a13*a25*a36*a44*a51 - + a16*a24*a33*a45*a51 - - a14*a26*a33*a45*a51 - - a16*a23*a34*a45*a51 - + a13*a26*a34*a45*a51 - + a14*a23*a36*a45*a51 - - a13*a24*a36*a45*a51 - - a15*a24*a33*a46*a51 - + a14*a25*a33*a46*a51 - + a15*a23*a34*a46*a51 - - a13*a25*a34*a46*a51 - - a14*a23*a35*a46*a51 - + a13*a24*a35*a46*a51 - - a16*a25*a34*a41*a53 - + a15*a26*a34*a41*a53 - + a16*a24*a35*a41*a53 - - a14*a26*a35*a41*a53 - - a15*a24*a36*a41*a53 - + a14*a25*a36*a41*a53 - + a16*a25*a31*a44*a53 - - a15*a26*a31*a44*a53 - - a16*a21*a35*a44*a53 - + a11*a26*a35*a44*a53 - + a15*a21*a36*a44*a53 - - a11*a25*a36*a44*a53 - - a16*a24*a31*a45*a53 - + a14*a26*a31*a45*a53 - + a16*a21*a34*a45*a53 - - a11*a26*a34*a45*a53 - - a14*a21*a36*a45*a53 - + a11*a24*a36*a45*a53 - + a15*a24*a31*a46*a53 - - a14*a25*a31*a46*a53 - - a15*a21*a34*a46*a53 - + a11*a25*a34*a46*a53 - + a14*a21*a35*a46*a53 - - a11*a24*a35*a46*a53 - + a16*a25*a33*a41*a54 - - a15*a26*a33*a41*a54 - - a16*a23*a35*a41*a54 - + a13*a26*a35*a41*a54 - + a15*a23*a36*a41*a54 - - a13*a25*a36*a41*a54 - - a16*a25*a31*a43*a54 - + a15*a26*a31*a43*a54 - + a16*a21*a35*a43*a54 - - a11*a26*a35*a43*a54 - - a15*a21*a36*a43*a54 - + a11*a25*a36*a43*a54 - + a16*a23*a31*a45*a54 - - a13*a26*a31*a45*a54 - - a16*a21*a33*a45*a54 - + a11*a26*a33*a45*a54 - + a13*a21*a36*a45*a54 - - a11*a23*a36*a45*a54 - - a15*a23*a31*a46*a54 - + a13*a25*a31*a46*a54 - + a15*a21*a33*a46*a54 - - a11*a25*a33*a46*a54 - - a13*a21*a35*a46*a54 - + a11*a23*a35*a46*a54 - - a16*a24*a33*a41*a55 - + a14*a26*a33*a41*a55 - + a16*a23*a34*a41*a55 - - a13*a26*a34*a41*a55 - - a14*a23*a36*a41*a55 - + a13*a24*a36*a41*a55 - + a16*a24*a31*a43*a55 - - a14*a26*a31*a43*a55 - - a16*a21*a34*a43*a55 - + a11*a26*a34*a43*a55 - + a14*a21*a36*a43*a55 - - a11*a24*a36*a43*a55 - - a16*a23*a31*a44*a55 - + a13*a26*a31*a44*a55 - + a16*a21*a33*a44*a55 - - a11*a26*a33*a44*a55 - - a13*a21*a36*a44*a55 - + a11*a23*a36*a44*a55 - + a14*a23*a31*a46*a55 - - a13*a24*a31*a46*a55 - - a14*a21*a33*a46*a55 - + a11*a24*a33*a46*a55 - + a13*a21*a34*a46*a55 - - a11*a23*a34*a46*a55 - + a15*a24*a33*a41*a56 - - a14*a25*a33*a41*a56 - - a15*a23*a34*a41*a56 - + a13*a25*a34*a41*a56 - + a14*a23*a35*a41*a56 - - a13*a24*a35*a41*a56 - - a15*a24*a31*a43*a56 - + a14*a25*a31*a43*a56 - + a15*a21*a34*a43*a56 - - a11*a25*a34*a43*a56 - - a14*a21*a35*a43*a56 - + a11*a24*a35*a43*a56 - + a15*a23*a31*a44*a56 - - a13*a25*a31*a44*a56 - - a15*a21*a33*a44*a56 - + a11*a25*a33*a44*a56 - + a13*a21*a35*a44*a56 - - a11*a23*a35*a44*a56 - - a14*a23*a31*a45*a56 - + a13*a24*a31*a45*a56 - + a14*a21*a33*a45*a56 - - a11*a24*a33*a45*a56 - - a13*a21*a34*a45*a56 - + a11*a23*a34*a45*a56)*a62 - - (a16*a25*a34*a42*a51 - - a15*a26*a34*a42*a51 - - a16*a24*a35*a42*a51 - + a14*a26*a35*a42*a51 - + a15*a24*a36*a42*a51 - - a14*a25*a36*a42*a51 - - a16*a25*a32*a44*a51 - + a15*a26*a32*a44*a51 - + - a16*a22*a35*a44*a51 - - a12*a26*a35*a44*a51 - - a15*a22*a36*a44*a51 - + a12*a25*a36*a44*a51 - + a16*a24*a32*a45*a51 - - a14*a26*a32*a45*a51 - - a16*a22*a34*a45*a51 - + a12*a26*a34*a45*a51 - + a14*a22*a36*a45*a51 - - a12*a24*a36*a45*a51 - - a15*a24*a32*a46*a51 - + - a14*a25*a32*a46*a51 - + a15*a22*a34*a46*a51 - - a12*a25*a34*a46*a51 - - a14*a22*a35*a46*a51 - + a12*a24*a35*a46*a51 - - a16*a25*a34*a41*a52 - + a15*a26*a34*a41*a52 - + a16*a24*a35*a41*a52 - - a14*a26*a35*a41*a52 - - a15*a24*a36*a41*a52 - + a14*a25*a36*a41*a52 - + - a16*a25*a31*a44*a52 - - a15*a26*a31*a44*a52 - - a16*a21*a35*a44*a52 - + a11*a26*a35*a44*a52 - + a15*a21*a36*a44*a52 - - a11*a25*a36*a44*a52 - - a16*a24*a31*a45*a52 - + a14*a26*a31*a45*a52 - + a16*a21*a34*a45*a52 - - a11*a26*a34*a45*a52 - - a14*a21*a36*a45*a52 - + - a11*a24*a36*a45*a52 - + a15*a24*a31*a46*a52 - - a14*a25*a31*a46*a52 - - a15*a21*a34*a46*a52 - + a11*a25*a34*a46*a52 - + a14*a21*a35*a46*a52 - - a11*a24*a35*a46*a52 - + a16*a25*a32*a41*a54 - - a15*a26*a32*a41*a54 - - a16*a22*a35*a41*a54 - + a12*a26*a35*a41*a54 - + - a15*a22*a36*a41*a54 - - a12*a25*a36*a41*a54 - - a16*a25*a31*a42*a54 - + a15*a26*a31*a42*a54 - + a16*a21*a35*a42*a54 - - a11*a26*a35*a42*a54 - - a15*a21*a36*a42*a54 - + a11*a25*a36*a42*a54 - + a16*a22*a31*a45*a54 - - a12*a26*a31*a45*a54 - - a16*a21*a32*a45*a54 - + - a11*a26*a32*a45*a54 - + a12*a21*a36*a45*a54 - - a11*a22*a36*a45*a54 - - a15*a22*a31*a46*a54 - + a12*a25*a31*a46*a54 - + a15*a21*a32*a46*a54 - - a11*a25*a32*a46*a54 - - a12*a21*a35*a46*a54 - + a11*a22*a35*a46*a54 - - a16*a24*a32*a41*a55 - + a14*a26*a32*a41*a55 - + - a16*a22*a34*a41*a55 - - a12*a26*a34*a41*a55 - - a14*a22*a36*a41*a55 - + a12*a24*a36*a41*a55 - + a16*a24*a31*a42*a55 - - a14*a26*a31*a42*a55 - - a16*a21*a34*a42*a55 - + a11*a26*a34*a42*a55 - + a14*a21*a36*a42*a55 - - a11*a24*a36*a42*a55 - - a16*a22*a31*a44*a55 - + - a12*a26*a31*a44*a55 - + a16*a21*a32*a44*a55 - - a11*a26*a32*a44*a55 - - a12*a21*a36*a44*a55 - + a11*a22*a36*a44*a55 - + a14*a22*a31*a46*a55 - - a12*a24*a31*a46*a55 - - a14*a21*a32*a46*a55 - + a11*a24*a32*a46*a55 - + a12*a21*a34*a46*a55 - - a11*a22*a34*a46*a55 - + - a15*a24*a32*a41*a56 - - a14*a25*a32*a41*a56 - - a15*a22*a34*a41*a56 - + a12*a25*a34*a41*a56 - + a14*a22*a35*a41*a56 - - a12*a24*a35*a41*a56 - - a15*a24*a31*a42*a56 - + a14*a25*a31*a42*a56 - + a15*a21*a34*a42*a56 - - a11*a25*a34*a42*a56 - - a14*a21*a35*a42*a56 - + - a11*a24*a35*a42*a56 - + a15*a22*a31*a44*a56 - - a12*a25*a31*a44*a56 - - a15*a21*a32*a44*a56 - + a11*a25*a32*a44*a56 - + a12*a21*a35*a44*a56 - - a11*a22*a35*a44*a56 - - a14*a22*a31*a45*a56 - + a12*a24*a31*a45*a56 - + a14*a21*a32*a45*a56 - - a11*a24*a32*a45*a56 - - - a12*a21*a34*a45*a56 - + a11*a22*a34*a45*a56)*a63 - + (a16*a25*a33*a42*a51 - - a15*a26*a33*a42*a51 - - - a16*a23*a35*a42*a51 - + a13*a26*a35*a42*a51 - + a15*a23*a36*a42*a51 - - a13*a25*a36*a42*a51 - - a16*a25*a32*a43*a51 - + a15*a26*a32*a43*a51 - + a16*a22*a35*a43*a51 - - a12*a26*a35*a43*a51 - - a15*a22*a36*a43*a51 - + a12*a25*a36*a43*a51 - + a16*a23*a32*a45*a51 - - - a13*a26*a32*a45*a51 - - a16*a22*a33*a45*a51 - + a12*a26*a33*a45*a51 - + a13*a22*a36*a45*a51 - - a12*a23*a36*a45*a51 - - a15*a23*a32*a46*a51 - + a13*a25*a32*a46*a51 - + a15*a22*a33*a46*a51 - - a12*a25*a33*a46*a51 - - a13*a22*a35*a46*a51 - + a12*a23*a35*a46*a51 - - - a16*a25*a33*a41*a52 - + a15*a26*a33*a41*a52 - + a16*a23*a35*a41*a52 - - a13*a26*a35*a41*a52 - - a15*a23*a36*a41*a52 - + a13*a25*a36*a41*a52 - + a16*a25*a31*a43*a52 - - a15*a26*a31*a43*a52 - - a16*a21*a35*a43*a52 - + a11*a26*a35*a43*a52 - + a15*a21*a36*a43*a52 - - a11*a25*a36*a43*a52 - - a16*a23*a31*a45*a52 - + a13*a26*a31*a45*a52 - + a16*a21*a33*a45*a52 - - a11*a26*a33*a45*a52 - - a13*a21*a36*a45*a52 - + a11*a23*a36*a45*a52 - + a15*a23*a31*a46*a52 - - a13*a25*a31*a46*a52 - - a15*a21*a33*a46*a52 - + a11*a25*a33*a46*a52 - + a13*a21*a35*a46*a52 - - a11*a23*a35*a46*a52 - + a16*a25*a32*a41*a53 - - a15*a26*a32*a41*a53 - - a16*a22*a35*a41*a53 - + a12*a26*a35*a41*a53 - + a15*a22*a36*a41*a53 - - a12*a25*a36*a41*a53 - - a16*a25*a31*a42*a53 - + a15*a26*a31*a42*a53 - + a16*a21*a35*a42*a53 - - a11*a26*a35*a42*a53 - - a15*a21*a36*a42*a53 - + a11*a25*a36*a42*a53 - + a16*a22*a31*a45*a53 - - a12*a26*a31*a45*a53 - - a16*a21*a32*a45*a53 - + a11*a26*a32*a45*a53 - + a12*a21*a36*a45*a53 - - a11*a22*a36*a45*a53 - - a15*a22*a31*a46*a53 - + a12*a25*a31*a46*a53 - + a15*a21*a32*a46*a53 - - a11*a25*a32*a46*a53 - - a12*a21*a35*a46*a53 - + a11*a22*a35*a46*a53 - - a16*a23*a32*a41*a55 - + a13*a26*a32*a41*a55 - + a16*a22*a33*a41*a55 - - a12*a26*a33*a41*a55 - - a13*a22*a36*a41*a55 - + a12*a23*a36*a41*a55 - + a16*a23*a31*a42*a55 - - a13*a26*a31*a42*a55 - - a16*a21*a33*a42*a55 - + a11*a26*a33*a42*a55 - + a13*a21*a36*a42*a55 - - a11*a23*a36*a42*a55 - - a16*a22*a31*a43*a55 - + a12*a26*a31*a43*a55 - + a16*a21*a32*a43*a55 - - a11*a26*a32*a43*a55 - - a12*a21*a36*a43*a55 - + a11*a22*a36*a43*a55 - + a13*a22*a31*a46*a55 - - a12*a23*a31*a46*a55 - - a13*a21*a32*a46*a55 - + a11*a23*a32*a46*a55 - + a12*a21*a33*a46*a55 - - a11*a22*a33*a46*a55 - + a15*a23*a32*a41*a56 - - a13*a25*a32*a41*a56 - - a15*a22*a33*a41*a56 - + a12*a25*a33*a41*a56 - + a13*a22*a35*a41*a56 - - a12*a23*a35*a41*a56 - - a15*a23*a31*a42*a56 - + a13*a25*a31*a42*a56 - + a15*a21*a33*a42*a56 - - a11*a25*a33*a42*a56 - - a13*a21*a35*a42*a56 - + a11*a23*a35*a42*a56 - + a15*a22*a31*a43*a56 - - a12*a25*a31*a43*a56 - - a15*a21*a32*a43*a56 - + a11*a25*a32*a43*a56 - + a12*a21*a35*a43*a56 - - a11*a22*a35*a43*a56 - - a13*a22*a31*a45*a56 - + a12*a23*a31*a45*a56 - + a13*a21*a32*a45*a56 - - a11*a23*a32*a45*a56 - - a12*a21*a33*a45*a56 - + a11*a22*a33*a45*a56)*a64 - - - (a16*a24*a33*a42*a51 - - a14*a26*a33*a42*a51 - - a16*a23*a34*a42*a51 - + a13*a26*a34*a42*a51 - + a14*a23*a36*a42*a51 - - a13*a24*a36*a42*a51 - - a16*a24*a32*a43*a51 - + a14*a26*a32*a43*a51 - + a16*a22*a34*a43*a51 - - a12*a26*a34*a43*a51 - - a14*a22*a36*a43*a51 - + a12*a24*a36*a43*a51 - + a16*a23*a32*a44*a51 - - a13*a26*a32*a44*a51 - - a16*a22*a33*a44*a51 - + a12*a26*a33*a44*a51 - + a13*a22*a36*a44*a51 - - a12*a23*a36*a44*a51 - - a14*a23*a32*a46*a51 - + a13*a24*a32*a46*a51 - + a14*a22*a33*a46*a51 - - a12*a24*a33*a46*a51 - - a13*a22*a34*a46*a51 - + a12*a23*a34*a46*a51 - - a16*a24*a33*a41*a52 - + a14*a26*a33*a41*a52 - + a16*a23*a34*a41*a52 - - a13*a26*a34*a41*a52 - - a14*a23*a36*a41*a52 - + a13*a24*a36*a41*a52 - + a16*a24*a31*a43*a52 - - a14*a26*a31*a43*a52 - - a16*a21*a34*a43*a52 - + a11*a26*a34*a43*a52 - + a14*a21*a36*a43*a52 - - a11*a24*a36*a43*a52 - - a16*a23*a31*a44*a52 - + a13*a26*a31*a44*a52 - + a16*a21*a33*a44*a52 - - a11*a26*a33*a44*a52 - - a13*a21*a36*a44*a52 - + a11*a23*a36*a44*a52 - + a14*a23*a31*a46*a52 - - a13*a24*a31*a46*a52 - - a14*a21*a33*a46*a52 - + a11*a24*a33*a46*a52 - + a13*a21*a34*a46*a52 - - a11*a23*a34*a46*a52 - + a16*a24*a32*a41*a53 - - a14*a26*a32*a41*a53 - - a16*a22*a34*a41*a53 - + a12*a26*a34*a41*a53 - + a14*a22*a36*a41*a53 - - a12*a24*a36*a41*a53 - - a16*a24*a31*a42*a53 - + a14*a26*a31*a42*a53 - + a16*a21*a34*a42*a53 - - a11*a26*a34*a42*a53 - - a14*a21*a36*a42*a53 - + a11*a24*a36*a42*a53 - + a16*a22*a31*a44*a53 - - a12*a26*a31*a44*a53 - - a16*a21*a32*a44*a53 - + a11*a26*a32*a44*a53 - + a12*a21*a36*a44*a53 - - a11*a22*a36*a44*a53 - - a14*a22*a31*a46*a53 - + a12*a24*a31*a46*a53 - + a14*a21*a32*a46*a53 - - a11*a24*a32*a46*a53 - - a12*a21*a34*a46*a53 - + a11*a22*a34*a46*a53 - - a16*a23*a32*a41*a54 - + a13*a26*a32*a41*a54 - + a16*a22*a33*a41*a54 - - a12*a26*a33*a41*a54 - - a13*a22*a36*a41*a54 - + a12*a23*a36*a41*a54 - + a16*a23*a31*a42*a54 - - a13*a26*a31*a42*a54 - - a16*a21*a33*a42*a54 - + a11*a26*a33*a42*a54 - + a13*a21*a36*a42*a54 - - a11*a23*a36*a42*a54 - - a16*a22*a31*a43*a54 - + a12*a26*a31*a43*a54 - + a16*a21*a32*a43*a54 - - a11*a26*a32*a43*a54 - - a12*a21*a36*a43*a54 - + a11*a22*a36*a43*a54 - + a13*a22*a31*a46*a54 - - a12*a23*a31*a46*a54 - - a13*a21*a32*a46*a54 - + a11*a23*a32*a46*a54 - + a12*a21*a33*a46*a54 - - a11*a22*a33*a46*a54 - + a14*a23*a32*a41*a56 - - a13*a24*a32*a41*a56 - - a14*a22*a33*a41*a56 - + a12*a24*a33*a41*a56 - + a13*a22*a34*a41*a56 - - a12*a23*a34*a41*a56 - - a14*a23*a31*a42*a56 - + a13*a24*a31*a42*a56 - + a14*a21*a33*a42*a56 - - a11*a24*a33*a42*a56 - - a13*a21*a34*a42*a56 - + a11*a23*a34*a42*a56 - + a14*a22*a31*a43*a56 - - a12*a24*a31*a43*a56 - - a14*a21*a32*a43*a56 - + a11*a24*a32*a43*a56 - + a12*a21*a34*a43*a56 - - a11*a22*a34*a43*a56 - - a13*a22*a31*a44*a56 - + a12*a23*a31*a44*a56 - + a13*a21*a32*a44*a56 - - a11*a23*a32*a44*a56 - - a12*a21*a33*a44*a56 - + a11*a22*a33*a44*a56)*a65 - + (a15*a24*a33*a42*a51 - - a14*a25*a33*a42*a51 - - a15*a23*a34*a42*a51 - + a13*a25*a34*a42*a51 - + a14*a23*a35*a42*a51 - - a13*a24*a35*a42*a51 - - a15*a24*a32*a43*a51 - + a14*a25*a32*a43*a51 - + a15*a22*a34*a43*a51 - - a12*a25*a34*a43*a51 - - a14*a22*a35*a43*a51 - + a12*a24*a35*a43*a51 - + a15*a23*a32*a44*a51 - - a13*a25*a32*a44*a51 - - a15*a22*a33*a44*a51 - + a12*a25*a33*a44*a51 - + a13*a22*a35*a44*a51 - - a12*a23*a35*a44*a51 - - a14*a23*a32*a45*a51 - + a13*a24*a32*a45*a51 - + a14*a22*a33*a45*a51 - - - a12*a24*a33*a45*a51 - - a13*a22*a34*a45*a51 - + a12*a23*a34*a45*a51 - - a15*a24*a33*a41*a52 - + a14*a25*a33*a41*a52 - + a15*a23*a34*a41*a52 - - a13*a25*a34*a41*a52 - - a14*a23*a35*a41*a52 - + a13*a24*a35*a41*a52 - + a15*a24*a31*a43*a52 - - a14*a25*a31*a43*a52 - - - a15*a21*a34*a43*a52 - + a11*a25*a34*a43*a52 - + a14*a21*a35*a43*a52 - - a11*a24*a35*a43*a52 - - a15*a23*a31*a44*a52 - + a13*a25*a31*a44*a52 - + a15*a21*a33*a44*a52 - - a11*a25*a33*a44*a52 - - a13*a21*a35*a44*a52 - + a11*a23*a35*a44*a52 - + a14*a23*a31*a45*a52 - - - a13*a24*a31*a45*a52 - - a14*a21*a33*a45*a52 - + a11*a24*a33*a45*a52 - + a13*a21*a34*a45*a52 - - a11*a23*a34*a45*a52 - + a15*a24*a32*a41*a53 - - a14*a25*a32*a41*a53 - - a15*a22*a34*a41*a53 - + a12*a25*a34*a41*a53 - + a14*a22*a35*a41*a53 - - a12*a24*a35*a41*a53 - - - a15*a24*a31*a42*a53 - + a14*a25*a31*a42*a53 - + a15*a21*a34*a42*a53 - - a11*a25*a34*a42*a53 - - a14*a21*a35*a42*a53 - + a11*a24*a35*a42*a53 - + a15*a22*a31*a44*a53 - - a12*a25*a31*a44*a53 - - a15*a21*a32*a44*a53 - + a11*a25*a32*a44*a53 - + a12*a21*a35*a44*a53 - - - a11*a22*a35*a44*a53 - - a14*a22*a31*a45*a53 - + a12*a24*a31*a45*a53 - + a14*a21*a32*a45*a53 - - a11*a24*a32*a45*a53 - - a12*a21*a34*a45*a53 - + a11*a22*a34*a45*a53 - - a15*a23*a32*a41*a54 - + a13*a25*a32*a41*a54 - + a15*a22*a33*a41*a54 - - a12*a25*a33*a41*a54 - - - a13*a22*a35*a41*a54 - + a12*a23*a35*a41*a54 - + a15*a23*a31*a42*a54 - - a13*a25*a31*a42*a54 - - a15*a21*a33*a42*a54 - + a11*a25*a33*a42*a54 - + a13*a21*a35*a42*a54 - - a11*a23*a35*a42*a54 - - a15*a22*a31*a43*a54 - + a12*a25*a31*a43*a54 - + a15*a21*a32*a43*a54 - - - a11*a25*a32*a43*a54 - - a12*a21*a35*a43*a54 - + a11*a22*a35*a43*a54 - + a13*a22*a31*a45*a54 - - a12*a23*a31*a45*a54 - - a13*a21*a32*a45*a54 - + a11*a23*a32*a45*a54 - + a12*a21*a33*a45*a54 - - a11*a22*a33*a45*a54 - + a14*a23*a32*a41*a55 - - a13*a24*a32*a41*a55 - - - a14*a22*a33*a41*a55 - + a12*a24*a33*a41*a55 - + a13*a22*a34*a41*a55 - - a12*a23*a34*a41*a55 - - a14*a23*a31*a42*a55 - + a13*a24*a31*a42*a55 - + a14*a21*a33*a42*a55 - - a11*a24*a33*a42*a55 - - a13*a21*a34*a42*a55 - + a11*a23*a34*a42*a55 - + a14*a22*a31*a43*a55 - - a12*a24*a31*a43*a55 - - a14*a21*a32*a43*a55 - + a11*a24*a32*a43*a55 - + a12*a21*a34*a43*a55 - - a11*a22*a34*a43*a55 - - a13*a22*a31*a44*a55 - + a12*a23*a31*a44*a55 - + a13*a21*a32*a44*a55 - - a11*a23*a32*a44*a55 - - a12*a21*a33*a44*a55 - + a11*a22*a33*a44*a55)*a66; - - if (fabs(det) <= eps) { - // printf("inv6: det = %lf\n", det); - *ok_flag__ = -1; - // return -1; - } - cofactor[0] = a26*a35*a44*a53*a62 - - a25*a36*a44*a53*a62 - - - a26*a34*a45*a53*a62 - + a24*a36*a45*a53*a62 - + a25* - a34*a46*a53*a62 - - a24*a35*a46*a53*a62 - - a26*a35* - a43*a54*a62 - + a25*a36*a43*a54*a62 - + a26*a33*a45* - a54*a62 - - a23*a36*a45*a54*a62 - - a25*a33*a46*a54* - a62 - + a23*a35*a46*a54*a62 - + a26*a34*a43*a55*a62 - - - a24*a36*a43*a55*a62 - - a26*a33*a44*a55*a62 - + a23* - a36*a44*a55*a62 - + a24*a33*a46*a55*a62 - - a23*a34* - a46*a55*a62 - - a25*a34*a43*a56*a62 - + a24*a35*a43* - a56*a62 - + a25*a33*a44*a56*a62 - - a23*a35*a44*a56* - a62 - - a24*a33*a45*a56*a62 - + a23*a34*a45*a56*a62 - - - a26*a35*a44*a52*a63 - + a25*a36*a44*a52*a63 - + a26* - a34*a45*a52*a63 - - a24*a36*a45*a52*a63 - - a25*a34* - a46*a52*a63 - + a24*a35*a46*a52*a63 - + a26*a35*a42* - a54*a63 - - a25*a36*a42*a54*a63 - - a26*a32*a45*a54* - a63 - + a22*a36*a45*a54*a63 - + a25*a32*a46*a54*a63 - - - a22*a35*a46*a54*a63 - - a26*a34*a42*a55*a63 - + a24* - a36*a42*a55*a63 - + a26*a32*a44*a55*a63 - - a22*a36* - a44*a55*a63 - - a24*a32*a46*a55*a63 - + a22*a34*a46* - a55*a63 - + a25*a34*a42*a56*a63 - - a24*a35*a42*a56* - a63 - - a25*a32*a44*a56*a63 - + a22*a35*a44*a56*a63 - + - a24*a32*a45*a56*a63 - - a22*a34*a45*a56*a63 - + a26* - a35*a43*a52*a64 - - a25*a36*a43*a52*a64 - - a26*a33* - a45*a52*a64 - + a23*a36*a45*a52*a64 - + a25*a33*a46* - a52*a64 - - a23*a35*a46*a52*a64 - - a26*a35*a42*a53* - a64 - + a25*a36*a42*a53*a64 - + a26*a32*a45*a53*a64 - - - a22*a36*a45*a53*a64 - - a25*a32*a46*a53*a64 - + a22* - a35*a46*a53*a64 - + a26*a33*a42*a55*a64 - - a23*a36* - a42*a55*a64 - - a26*a32*a43*a55*a64 - + a22*a36*a43* - a55*a64 - + a23*a32*a46*a55*a64 - - a22*a33*a46*a55* - a64 - - a25*a33*a42*a56*a64 - + a23*a35*a42*a56*a64 - + - a25*a32*a43*a56*a64 - - a22*a35*a43*a56*a64 - - a23* - a32*a45*a56*a64 - + a22*a33*a45*a56*a64 - - a26*a34* - a43*a52*a65 - + a24*a36*a43*a52*a65 - + a26*a33*a44* - a52*a65 - - a23*a36*a44*a52*a65 - - a24*a33*a46*a52* - a65 - + a23*a34*a46*a52*a65 - + a26*a34*a42*a53*a65 - - - a24*a36*a42*a53*a65 - - a26*a32*a44*a53*a65 - + a22* - a36*a44*a53*a65 - + a24*a32*a46*a53*a65 - - a22*a34* - a46*a53*a65 - - a26*a33*a42*a54*a65 - + a23*a36*a42* - a54*a65 - + a26*a32*a43*a54*a65 - - a22*a36*a43*a54* - a65 - - a23*a32*a46*a54*a65 - + a22*a33*a46*a54*a65 - + - a24*a33*a42*a56*a65 - - a23*a34*a42*a56*a65 - - a24* - a32*a43*a56*a65 - + a22*a34*a43*a56*a65 - + a23*a32* - a44*a56*a65 - - a22*a33*a44*a56*a65 - + a25*a34*a43* - a52*a66 - - a24*a35*a43*a52*a66 - - a25*a33*a44*a52* - a66 - + a23*a35*a44*a52*a66 - + a24*a33*a45*a52*a66 - - - a23*a34*a45*a52*a66 - - a25*a34*a42*a53*a66 - + a24* - a35*a42*a53*a66 - + a25*a32*a44*a53*a66 - - a22*a35* - a44*a53*a66 - - a24*a32*a45*a53*a66 - + a22*a34*a45* - a53*a66 - + a25*a33*a42*a54*a66 - - a23*a35*a42*a54* - a66 - - a25*a32*a43*a54*a66 - + a22*a35*a43*a54*a66 - + - a23*a32*a45*a54*a66 - - a22*a33*a45*a54*a66 - - a24* - a33*a42*a55*a66 - + a23*a34*a42*a55*a66 - + a24*a32* - a43*a55*a66 - - a22*a34*a43*a55*a66 - - a23*a32*a44* - a55*a66 - + a22*a33*a44*a55*a66; - cofactor[1] = -a16*a35*a44*a53*a62 - + a15*a36*a44*a53*a62 - + a16*a34*a45*a53*a62 - - a14*a36*a45*a53*a62 - - a15*a34*a46*a53*a62 - + a14*a35*a46*a53*a62 - + a16*a35*a43*a54*a62 - - a15*a36*a43*a54*a62 - - a16*a33*a45*a54*a62 - + a13*a36*a45*a54*a62 - + a15*a33*a46*a54*a62 - - a13*a35*a46*a54*a62 - - a16*a34*a43*a55*a62 - + a14*a36*a43*a55*a62 - + a16*a33*a44*a55*a62 - - a13*a36*a44*a55*a62 - - a14*a33*a46*a55*a62 - + a13*a34*a46*a55*a62 - + a15*a34*a43*a56*a62 - - a14*a35*a43*a56*a62 - - a15*a33*a44*a56*a62 - + a13*a35*a44*a56*a62 - + a14*a33*a45*a56*a62 - - a13*a34*a45*a56*a62 - + a16*a35*a44*a52*a63 - - a15*a36*a44*a52*a63 - - a16*a34*a45*a52*a63 - + a14*a36*a45*a52*a63 - + a15*a34*a46*a52*a63 - - a14*a35*a46*a52*a63 - - a16*a35*a42*a54*a63 - + a15*a36*a42*a54*a63 - + a16*a32*a45*a54*a63 - - a12*a36*a45*a54*a63 - - a15*a32*a46*a54*a63 - + a12*a35*a46*a54*a63 - + a16*a34*a42*a55*a63 - - a14*a36*a42*a55*a63 - - a16*a32*a44*a55*a63 - + a12*a36*a44*a55*a63 - + a14*a32*a46*a55*a63 - - a12*a34*a46*a55*a63 - - a15*a34*a42*a56*a63 - + a14*a35*a42*a56*a63 - + a15*a32*a44*a56*a63 - - a12*a35*a44*a56*a63 - - a14*a32*a45*a56*a63 - + a12*a34*a45*a56*a63 - - a16*a35*a43*a52*a64 - + a15*a36*a43*a52*a64 - + a16*a33*a45*a52*a64 - - a13*a36*a45*a52*a64 - - a15*a33*a46*a52*a64 - + a13*a35*a46*a52*a64 - + a16*a35*a42*a53*a64 - - a15*a36*a42*a53*a64 - - a16*a32*a45*a53*a64 - + a12*a36*a45*a53*a64 - + a15*a32*a46*a53*a64 - - a12*a35*a46*a53*a64 - - a16*a33*a42*a55*a64 - + a13*a36*a42*a55*a64 - + a16*a32*a43*a55*a64 - - a12*a36*a43*a55*a64 - - a13*a32*a46*a55*a64 - + a12*a33*a46*a55*a64 - + a15*a33*a42*a56*a64 - - a13*a35*a42*a56*a64 - - a15*a32*a43*a56*a64 - + a12*a35*a43*a56*a64 - + a13*a32*a45*a56*a64 - - a12*a33*a45*a56*a64 - + a16*a34*a43*a52*a65 - - a14*a36*a43*a52*a65 - - a16*a33*a44*a52*a65 - + a13*a36*a44*a52*a65 - + a14*a33*a46*a52*a65 - - a13*a34*a46*a52*a65 - - a16*a34*a42*a53*a65 - + a14*a36*a42*a53*a65 - + a16*a32*a44*a53*a65 - - a12*a36*a44*a53*a65 - - a14*a32*a46*a53*a65 - + a12*a34*a46*a53*a65 - + a16*a33*a42*a54*a65 - - a13*a36*a42*a54*a65 - - a16*a32*a43*a54*a65 - + a12*a36*a43*a54*a65 - + a13*a32*a46*a54*a65 - - a12*a33*a46*a54*a65 - - a14*a33*a42*a56*a65 - + a13*a34*a42*a56*a65 - + a14*a32*a43*a56*a65 - - a12*a34*a43*a56*a65 - - a13*a32*a44*a56*a65 - + a12*a33*a44*a56*a65 - - a15*a34*a43*a52*a66 - + a14*a35*a43*a52*a66 - + a15*a33*a44*a52*a66 - - a13*a35*a44*a52*a66 - - a14*a33*a45*a52*a66 - + a13*a34*a45*a52*a66 - + a15*a34*a42*a53*a66 - - a14*a35*a42*a53*a66 - - a15*a32*a44*a53*a66 - + a12*a35*a44*a53*a66 - + a14*a32*a45*a53*a66 - - a12*a34*a45*a53*a66 - - a15*a33*a42*a54*a66 - + a13*a35*a42*a54*a66 - + a15*a32*a43*a54*a66 - - a12*a35*a43*a54*a66 - - a13*a32*a45*a54*a66 - + a12*a33*a45*a54*a66 - + a14*a33*a42*a55*a66 - - a13*a34*a42*a55*a66 - - a14*a32*a43*a55*a66 - + a12*a34*a43*a55*a66 - + a13*a32*a44*a55*a66 - - a12*a33*a44*a55*a66; - cofactor[2] = a16*a25*a44*a53*a62 - - a15*a26*a44*a53*a62 - - - a16*a24*a45*a53*a62 - + a14*a26*a45*a53*a62 - + a15* - a24*a46*a53*a62 - - a14*a25*a46*a53*a62 - - a16*a25* - a43*a54*a62 - + a15*a26*a43*a54*a62 - + a16*a23*a45* - a54*a62 - - a13*a26*a45*a54*a62 - - a15*a23*a46*a54* - a62 - + a13*a25*a46*a54*a62 - + a16*a24*a43*a55*a62 - - - a14*a26*a43*a55*a62 - - a16*a23*a44*a55*a62 - + a13* - a26*a44*a55*a62 - + a14*a23*a46*a55*a62 - - a13*a24* - a46*a55*a62 - - a15*a24*a43*a56*a62 - + a14*a25*a43* - a56*a62 - + a15*a23*a44*a56*a62 - - a13*a25*a44*a56* - a62 - - a14*a23*a45*a56*a62 - + a13*a24*a45*a56*a62 - - - a16*a25*a44*a52*a63 - + a15*a26*a44*a52*a63 - + a16* - a24*a45*a52*a63 - - a14*a26*a45*a52*a63 - - a15*a24* - a46*a52*a63 - + a14*a25*a46*a52*a63 - + a16*a25*a42* - a54*a63 - - a15*a26*a42*a54*a63 - - a16*a22*a45*a54* - a63 - + a12*a26*a45*a54*a63 - + a15*a22*a46*a54*a63 - - - a12*a25*a46*a54*a63 - - a16*a24*a42*a55*a63 - + a14* - a26*a42*a55*a63 - + a16*a22*a44*a55*a63 - - a12*a26* - a44*a55*a63 - - a14*a22*a46*a55*a63 - + a12*a24*a46* - a55*a63 - + a15*a24*a42*a56*a63 - - a14*a25*a42*a56* - a63 - - a15*a22*a44*a56*a63 - + a12*a25*a44*a56*a63 - + - a14*a22*a45*a56*a63 - - a12*a24*a45*a56*a63 - + a16* - a25*a43*a52*a64 - - a15*a26*a43*a52*a64 - - a16*a23* - a45*a52*a64 - + a13*a26*a45*a52*a64 - + a15*a23*a46* - a52*a64 - - a13*a25*a46*a52*a64 - - a16*a25*a42*a53* - a64 - + a15*a26*a42*a53*a64 - + a16*a22*a45*a53*a64 - - - a12*a26*a45*a53*a64 - - a15*a22*a46*a53*a64 - + a12* - a25*a46*a53*a64 - + a16*a23*a42*a55*a64 - - a13*a26* - a42*a55*a64 - - a16*a22*a43*a55*a64 - + a12*a26*a43* - a55*a64 - + a13*a22*a46*a55*a64 - - a12*a23*a46*a55* - a64 - - a15*a23*a42*a56*a64 - + a13*a25*a42*a56*a64 - + - a15*a22*a43*a56*a64 - - a12*a25*a43*a56*a64 - - a13* - a22*a45*a56*a64 - + a12*a23*a45*a56*a64 - - a16*a24* - a43*a52*a65 - + a14*a26*a43*a52*a65 - + a16*a23*a44* - a52*a65 - - a13*a26*a44*a52*a65 - - a14*a23*a46*a52* - a65 - + a13*a24*a46*a52*a65 - + a16*a24*a42*a53*a65 - - - a14*a26*a42*a53*a65 - - a16*a22*a44*a53*a65 - + a12* - a26*a44*a53*a65 - + a14*a22*a46*a53*a65 - - a12*a24* - a46*a53*a65 - - a16*a23*a42*a54*a65 - + a13*a26*a42* - a54*a65 - + a16*a22*a43*a54*a65 - - a12*a26*a43*a54* - a65 - - a13*a22*a46*a54*a65 - + a12*a23*a46*a54*a65 - + - a14*a23*a42*a56*a65 - - a13*a24*a42*a56*a65 - - a14* - a22*a43*a56*a65 - + a12*a24*a43*a56*a65 - + a13*a22* - a44*a56*a65 - - a12*a23*a44*a56*a65 - + a15*a24*a43* - a52*a66 - - a14*a25*a43*a52*a66 - - a15*a23*a44*a52* - a66 - + a13*a25*a44*a52*a66 - + a14*a23*a45*a52*a66 - - - a13*a24*a45*a52*a66 - - a15*a24*a42*a53*a66 - + a14* - a25*a42*a53*a66 - + a15*a22*a44*a53*a66 - - a12*a25* - a44*a53*a66 - - a14*a22*a45*a53*a66 - + a12*a24*a45* - a53*a66 - + a15*a23*a42*a54*a66 - - a13*a25*a42*a54* - a66 - - a15*a22*a43*a54*a66 - + a12*a25*a43*a54*a66 - + - a13*a22*a45*a54*a66 - - a12*a23*a45*a54*a66 - - a14* - a23*a42*a55*a66 - + a13*a24*a42*a55*a66 - + a14*a22* - a43*a55*a66 - - a12*a24*a43*a55*a66 - - a13*a22*a44* - a55*a66 - + a12*a23*a44*a55*a66; - cofactor[3] = -a16*a25*a34*a53*a62 - + a15*a26*a34*a53*a62 - + a16*a24*a35*a53*a62 - - a14*a26*a35*a53*a62 - - a15*a24*a36*a53*a62 - + a14*a25*a36*a53*a62 - + a16*a25*a33*a54*a62 - - a15*a26*a33*a54*a62 - - a16*a23*a35*a54*a62 - + a13*a26*a35*a54*a62 - + a15*a23*a36*a54*a62 - - a13*a25*a36*a54*a62 - - a16*a24*a33*a55*a62 - + a14*a26*a33*a55*a62 - + a16*a23*a34*a55*a62 - - a13*a26*a34*a55*a62 - - a14*a23*a36*a55*a62 - + a13*a24*a36*a55*a62 - + a15*a24*a33*a56*a62 - - a14*a25*a33*a56*a62 - - a15*a23*a34*a56*a62 - + a13*a25*a34*a56*a62 - + a14*a23*a35*a56*a62 - - a13*a24*a35*a56*a62 - + a16*a25*a34*a52*a63 - - a15*a26*a34*a52*a63 - - a16*a24*a35*a52*a63 - + a14*a26*a35*a52*a63 - + a15*a24*a36*a52*a63 - - a14*a25*a36*a52*a63 - - a16*a25*a32*a54*a63 - + a15*a26*a32*a54*a63 - + a16*a22*a35*a54*a63 - - a12*a26*a35*a54*a63 - - a15*a22*a36*a54*a63 - + a12*a25*a36*a54*a63 - + a16*a24*a32*a55*a63 - - a14*a26*a32*a55*a63 - - a16*a22*a34*a55*a63 - + a12*a26*a34*a55*a63 - + a14*a22*a36*a55*a63 - - a12*a24*a36*a55*a63 - - a15*a24*a32*a56*a63 - + a14*a25*a32*a56*a63 - + a15*a22*a34*a56*a63 - - a12*a25*a34*a56*a63 - - a14*a22*a35*a56*a63 - + a12*a24*a35*a56*a63 - - a16*a25*a33*a52*a64 - + a15*a26*a33*a52*a64 - + a16*a23*a35*a52*a64 - - a13*a26*a35*a52*a64 - - a15*a23*a36*a52*a64 - + a13*a25*a36*a52*a64 - + a16*a25*a32*a53*a64 - - a15*a26*a32*a53*a64 - - a16*a22*a35*a53*a64 - + a12*a26*a35*a53*a64 - + a15*a22*a36*a53*a64 - - a12*a25*a36*a53*a64 - - a16*a23*a32*a55*a64 - + a13*a26*a32*a55*a64 - + a16*a22*a33*a55*a64 - - a12*a26*a33*a55*a64 - - a13*a22*a36*a55*a64 - + a12*a23*a36*a55*a64 - + a15*a23*a32*a56*a64 - - a13*a25*a32*a56*a64 - - a15*a22*a33*a56*a64 - + a12*a25*a33*a56*a64 - + a13*a22*a35*a56*a64 - - a12*a23*a35*a56*a64 - + a16*a24*a33*a52*a65 - - a14*a26*a33*a52*a65 - - a16*a23*a34*a52*a65 - + a13*a26*a34*a52*a65 - + a14*a23*a36*a52*a65 - - a13*a24*a36*a52*a65 - - a16*a24*a32*a53*a65 - + a14*a26*a32*a53*a65 - + a16*a22*a34*a53*a65 - - a12*a26*a34*a53*a65 - - a14*a22*a36*a53*a65 - + a12*a24*a36*a53*a65 - + a16*a23*a32*a54*a65 - - a13*a26*a32*a54*a65 - - a16*a22*a33*a54*a65 - + a12*a26*a33*a54*a65 - + a13*a22*a36*a54*a65 - - a12*a23*a36*a54*a65 - - a14*a23*a32*a56*a65 - + a13*a24*a32*a56*a65 - + a14*a22*a33*a56*a65 - - a12*a24*a33*a56*a65 - - a13*a22*a34*a56*a65 - + a12*a23*a34*a56*a65 - - a15*a24*a33*a52*a66 - + a14*a25*a33*a52*a66 - + a15*a23*a34*a52*a66 - - a13*a25*a34*a52*a66 - - a14*a23*a35*a52*a66 - + a13*a24*a35*a52*a66 - + a15*a24*a32*a53*a66 - - a14*a25*a32*a53*a66 - - a15*a22*a34*a53*a66 - + a12*a25*a34*a53*a66 - + a14*a22*a35*a53*a66 - - a12*a24*a35*a53*a66 - - a15*a23*a32*a54*a66 - + a13*a25*a32*a54*a66 - + a15*a22*a33*a54*a66 - - a12*a25*a33*a54*a66 - - a13*a22*a35*a54*a66 - + a12*a23*a35*a54*a66 - + a14*a23*a32*a55*a66 - - a13*a24*a32*a55*a66 - - a14*a22*a33*a55*a66 - + a12*a24*a33*a55*a66 - + a13*a22*a34*a55*a66 - - a12*a23*a34*a55*a66; - cofactor[4] = a16*a25*a34*a43*a62 - - a15*a26*a34*a43*a62 - - - a16*a24*a35*a43*a62 - + a14*a26*a35*a43*a62 - + a15* - a24*a36*a43*a62 - - a14*a25*a36*a43*a62 - - a16*a25* - a33*a44*a62 - + a15*a26*a33*a44*a62 - + a16*a23*a35* - a44*a62 - - a13*a26*a35*a44*a62 - - a15*a23*a36*a44* - a62 - + a13*a25*a36*a44*a62 - + a16*a24*a33*a45*a62 - - - a14*a26*a33*a45*a62 - - a16*a23*a34*a45*a62 - + a13* - a26*a34*a45*a62 - + a14*a23*a36*a45*a62 - - a13*a24* - a36*a45*a62 - - a15*a24*a33*a46*a62 - + a14*a25*a33* - a46*a62 - + a15*a23*a34*a46*a62 - - a13*a25*a34*a46* - a62 - - a14*a23*a35*a46*a62 - + a13*a24*a35*a46*a62 - - - a16*a25*a34*a42*a63 - + a15*a26*a34*a42*a63 - + a16* - a24*a35*a42*a63 - - a14*a26*a35*a42*a63 - - a15*a24* - a36*a42*a63 - + a14*a25*a36*a42*a63 - + a16*a25*a32* - a44*a63 - - a15*a26*a32*a44*a63 - - a16*a22*a35*a44* - a63 - + a12*a26*a35*a44*a63 - + a15*a22*a36*a44*a63 - - - a12*a25*a36*a44*a63 - - a16*a24*a32*a45*a63 - + a14* - a26*a32*a45*a63 - + a16*a22*a34*a45*a63 - - a12*a26* - a34*a45*a63 - - a14*a22*a36*a45*a63 - + a12*a24*a36* - a45*a63 - + a15*a24*a32*a46*a63 - - a14*a25*a32*a46* - a63 - - a15*a22*a34*a46*a63 - + a12*a25*a34*a46*a63 - + - a14*a22*a35*a46*a63 - - a12*a24*a35*a46*a63 - + a16* - a25*a33*a42*a64 - - a15*a26*a33*a42*a64 - - a16*a23* - a35*a42*a64 - + a13*a26*a35*a42*a64 - + a15*a23*a36* - a42*a64 - - a13*a25*a36*a42*a64 - - a16*a25*a32*a43* - a64 - + a15*a26*a32*a43*a64 - + a16*a22*a35*a43*a64 - - - a12*a26*a35*a43*a64 - - a15*a22*a36*a43*a64 - + a12* - a25*a36*a43*a64 - + a16*a23*a32*a45*a64 - - a13*a26* - a32*a45*a64 - - a16*a22*a33*a45*a64 - + a12*a26*a33* - a45*a64 - + a13*a22*a36*a45*a64 - - a12*a23*a36*a45* - a64 - - a15*a23*a32*a46*a64 - + a13*a25*a32*a46*a64 - + - a15*a22*a33*a46*a64 - - a12*a25*a33*a46*a64 - - a13* - a22*a35*a46*a64 - + a12*a23*a35*a46*a64 - - a16*a24* - a33*a42*a65 - + a14*a26*a33*a42*a65 - + a16*a23*a34* - a42*a65 - - a13*a26*a34*a42*a65 - - a14*a23*a36*a42* - a65 - + a13*a24*a36*a42*a65 - + a16*a24*a32*a43*a65 - - - a14*a26*a32*a43*a65 - - a16*a22*a34*a43*a65 - + a12* - a26*a34*a43*a65 - + a14*a22*a36*a43*a65 - - a12*a24* - a36*a43*a65 - - a16*a23*a32*a44*a65 - + a13*a26*a32* - a44*a65 - + a16*a22*a33*a44*a65 - - a12*a26*a33*a44* - a65 - - a13*a22*a36*a44*a65 - + a12*a23*a36*a44*a65 - + - a14*a23*a32*a46*a65 - - a13*a24*a32*a46*a65 - - a14* - a22*a33*a46*a65 - + a12*a24*a33*a46*a65 - + a13*a22* - a34*a46*a65 - - a12*a23*a34*a46*a65 - + a15*a24*a33* - a42*a66 - - a14*a25*a33*a42*a66 - - a15*a23*a34*a42* - a66 - + a13*a25*a34*a42*a66 - + a14*a23*a35*a42*a66 - - - a13*a24*a35*a42*a66 - - a15*a24*a32*a43*a66 - + a14* - a25*a32*a43*a66 - + a15*a22*a34*a43*a66 - - a12*a25* - a34*a43*a66 - - a14*a22*a35*a43*a66 - + a12*a24*a35* - a43*a66 - + a15*a23*a32*a44*a66 - - a13*a25*a32*a44* - a66 - - a15*a22*a33*a44*a66 - + a12*a25*a33*a44*a66 - + - a13*a22*a35*a44*a66 - - a12*a23*a35*a44*a66 - - a14* - a23*a32*a45*a66 - + a13*a24*a32*a45*a66 - + a14*a22* - a33*a45*a66 - - a12*a24*a33*a45*a66 - - a13*a22*a34* - a45*a66 - + a12*a23*a34*a45*a66; - cofactor[5] = -a16*a25*a34*a43*a52 - + a15*a26*a34*a43*a52 - + a16*a24*a35*a43*a52 - - a14*a26*a35*a43*a52 - - a15*a24*a36*a43*a52 - + a14*a25*a36*a43*a52 - + a16*a25*a33*a44*a52 - - a15*a26*a33*a44*a52 - - a16*a23*a35*a44*a52 - + a13*a26*a35*a44*a52 - + a15*a23*a36*a44*a52 - - a13*a25*a36*a44*a52 - - a16*a24*a33*a45*a52 - + a14*a26*a33*a45*a52 - + a16*a23*a34*a45*a52 - - a13*a26*a34*a45*a52 - - a14*a23*a36*a45*a52 - + a13*a24*a36*a45*a52 - + a15*a24*a33*a46*a52 - - a14*a25*a33*a46*a52 - - a15*a23*a34*a46*a52 - + a13*a25*a34*a46*a52 - + a14*a23*a35*a46*a52 - - a13*a24*a35*a46*a52 - + a16*a25*a34*a42*a53 - - a15*a26*a34*a42*a53 - - a16*a24*a35*a42*a53 - + a14*a26*a35*a42*a53 - + a15*a24*a36*a42*a53 - - a14*a25*a36*a42*a53 - - a16*a25*a32*a44*a53 - + a15*a26*a32*a44*a53 - + a16*a22*a35*a44*a53 - - a12*a26*a35*a44*a53 - - a15*a22*a36*a44*a53 - + a12*a25*a36*a44*a53 - + a16*a24*a32*a45*a53 - - a14*a26*a32*a45*a53 - - a16*a22*a34*a45*a53 - + a12*a26*a34*a45*a53 - + a14*a22*a36*a45*a53 - - a12*a24*a36*a45*a53 - - a15*a24*a32*a46*a53 - + a14*a25*a32*a46*a53 - + a15*a22*a34*a46*a53 - - a12*a25*a34*a46*a53 - - a14*a22*a35*a46*a53 - + a12*a24*a35*a46*a53 - - a16*a25*a33*a42*a54 - + a15*a26*a33*a42*a54 - + a16*a23*a35*a42*a54 - - a13*a26*a35*a42*a54 - - a15*a23*a36*a42*a54 - + a13*a25*a36*a42*a54 - + a16*a25*a32*a43*a54 - - a15*a26*a32*a43*a54 - - a16*a22*a35*a43*a54 - + a12*a26*a35*a43*a54 - + a15*a22*a36*a43*a54 - - a12*a25*a36*a43*a54 - - a16*a23*a32*a45*a54 - + a13*a26*a32*a45*a54 - + a16*a22*a33*a45*a54 - - a12*a26*a33*a45*a54 - - a13*a22*a36*a45*a54 - + a12*a23*a36*a45*a54 - + a15*a23*a32*a46*a54 - - a13*a25*a32*a46*a54 - - a15*a22*a33*a46*a54 - + a12*a25*a33*a46*a54 - + a13*a22*a35*a46*a54 - - a12*a23*a35*a46*a54 - + a16*a24*a33*a42*a55 - - a14*a26*a33*a42*a55 - - a16*a23*a34*a42*a55 - + a13*a26*a34*a42*a55 - + a14*a23*a36*a42*a55 - - a13*a24*a36*a42*a55 - - a16*a24*a32*a43*a55 - + a14*a26*a32*a43*a55 - + a16*a22*a34*a43*a55 - - a12*a26*a34*a43*a55 - - a14*a22*a36*a43*a55 - + a12*a24*a36*a43*a55 - + a16*a23*a32*a44*a55 - - a13*a26*a32*a44*a55 - - a16*a22*a33*a44*a55 - + a12*a26*a33*a44*a55 - + a13*a22*a36*a44*a55 - - a12*a23*a36*a44*a55 - - a14*a23*a32*a46*a55 - + a13*a24*a32*a46*a55 - + a14*a22*a33*a46*a55 - - a12*a24*a33*a46*a55 - - a13*a22*a34*a46*a55 - + a12*a23*a34*a46*a55 - - a15*a24*a33*a42*a56 - + a14*a25*a33*a42*a56 - + a15*a23*a34*a42*a56 - - a13*a25*a34*a42*a56 - - a14*a23*a35*a42*a56 - + a13*a24*a35*a42*a56 - + a15*a24*a32*a43*a56 - - a14*a25*a32*a43*a56 - - a15*a22*a34*a43*a56 - + a12*a25*a34*a43*a56 - + a14*a22*a35*a43*a56 - - a12*a24*a35*a43*a56 - - a15*a23*a32*a44*a56 - + a13*a25*a32*a44*a56 - + a15*a22*a33*a44*a56 - - a12*a25*a33*a44*a56 - - a13*a22*a35*a44*a56 - + a12*a23*a35*a44*a56 - + a14*a23*a32*a45*a56 - - a13*a24*a32*a45*a56 - - a14*a22*a33*a45*a56 - + a12*a24*a33*a45*a56 - + a13*a22*a34*a45*a56 - - a12*a23*a34*a45*a56; - cofactor[6] = -a26*a35*a44*a53*a61 - + a25*a36*a44*a53*a61 - + a26*a34*a45*a53*a61 - - a24*a36*a45*a53*a61 - - a25*a34*a46*a53*a61 - + a24*a35*a46*a53*a61 - + a26*a35*a43*a54*a61 - - a25*a36*a43*a54*a61 - - a26*a33*a45*a54*a61 - + a23*a36*a45*a54*a61 - + a25*a33*a46*a54*a61 - - a23*a35*a46*a54*a61 - - a26*a34*a43*a55*a61 - + a24*a36*a43*a55*a61 - + a26*a33*a44*a55*a61 - - a23*a36*a44*a55*a61 - - a24*a33*a46*a55*a61 - + a23*a34*a46*a55*a61 - + a25*a34*a43*a56*a61 - - a24*a35*a43*a56*a61 - - a25*a33*a44*a56*a61 - + a23*a35*a44*a56*a61 - + a24*a33*a45*a56*a61 - - a23*a34*a45*a56*a61 - + a26*a35*a44*a51*a63 - - a25*a36*a44*a51*a63 - - a26*a34*a45*a51*a63 - + a24*a36*a45*a51*a63 - + a25*a34*a46*a51*a63 - - a24*a35*a46*a51*a63 - - a26*a35*a41*a54*a63 - + a25*a36*a41*a54*a63 - + a26*a31*a45*a54*a63 - - a21*a36*a45*a54*a63 - - a25*a31*a46*a54*a63 - + a21*a35*a46*a54*a63 - + a26*a34*a41*a55*a63 - - a24*a36*a41*a55*a63 - - a26*a31*a44*a55*a63 - + a21*a36*a44*a55*a63 - + a24*a31*a46*a55*a63 - - a21*a34*a46*a55*a63 - - a25*a34*a41*a56*a63 - + a24*a35*a41*a56*a63 - + a25*a31*a44*a56*a63 - - a21*a35*a44*a56*a63 - - a24*a31*a45*a56*a63 - + a21*a34*a45*a56*a63 - - a26*a35*a43*a51*a64 - + a25*a36*a43*a51*a64 - + a26*a33*a45*a51*a64 - - a23*a36*a45*a51*a64 - - a25*a33*a46*a51*a64 - + a23*a35*a46*a51*a64 - + a26*a35*a41*a53*a64 - - a25*a36*a41*a53*a64 - - a26*a31*a45*a53*a64 - + a21*a36*a45*a53*a64 - + a25*a31*a46*a53*a64 - - a21*a35*a46*a53*a64 - - a26*a33*a41*a55*a64 - + a23*a36*a41*a55*a64 - + a26*a31*a43*a55*a64 - - a21*a36*a43*a55*a64 - - a23*a31*a46*a55*a64 - + a21*a33*a46*a55*a64 - + a25*a33*a41*a56*a64 - - a23*a35*a41*a56*a64 - - a25*a31*a43*a56*a64 - + a21*a35*a43*a56*a64 - + a23*a31*a45*a56*a64 - - a21*a33*a45*a56*a64 - + a26*a34*a43*a51*a65 - - a24*a36*a43*a51*a65 - - a26*a33*a44*a51*a65 - + a23*a36*a44*a51*a65 - + a24*a33*a46*a51*a65 - - a23*a34*a46*a51*a65 - - a26*a34*a41*a53*a65 - + a24*a36*a41*a53*a65 - + a26*a31*a44*a53*a65 - - a21*a36*a44*a53*a65 - - a24*a31*a46*a53*a65 - + a21*a34*a46*a53*a65 - + a26*a33*a41*a54*a65 - - a23*a36*a41*a54*a65 - - a26*a31*a43*a54*a65 - + a21*a36*a43*a54*a65 - + a23*a31*a46*a54*a65 - - a21*a33*a46*a54*a65 - - a24*a33*a41*a56*a65 - + a23*a34*a41*a56*a65 - + a24*a31*a43*a56*a65 - - a21*a34*a43*a56*a65 - - a23*a31*a44*a56*a65 - + a21*a33*a44*a56*a65 - - a25*a34*a43*a51*a66 - + a24*a35*a43*a51*a66 - + a25*a33*a44*a51*a66 - - a23*a35*a44*a51*a66 - - a24*a33*a45*a51*a66 - + a23*a34*a45*a51*a66 - + a25*a34*a41*a53*a66 - - a24*a35*a41*a53*a66 - - a25*a31*a44*a53*a66 - + a21*a35*a44*a53*a66 - + a24*a31*a45*a53*a66 - - a21*a34*a45*a53*a66 - - a25*a33*a41*a54*a66 - + a23*a35*a41*a54*a66 - + a25*a31*a43*a54*a66 - - a21*a35*a43*a54*a66 - - a23*a31*a45*a54*a66 - + a21*a33*a45*a54*a66 - + a24*a33*a41*a55*a66 - - a23*a34*a41*a55*a66 - - a24*a31*a43*a55*a66 - + a21*a34*a43*a55*a66 - + a23*a31*a44*a55*a66 - - a21*a33*a44*a55*a66; - cofactor[7] = a16*a35*a44*a53*a61 - - a15*a36*a44*a53*a61 - - - a16*a34*a45*a53*a61 - + a14*a36*a45*a53*a61 - + a15* - a34*a46*a53*a61 - - a14*a35*a46*a53*a61 - - a16*a35* - a43*a54*a61 - + a15*a36*a43*a54*a61 - + a16*a33*a45* - a54*a61 - - a13*a36*a45*a54*a61 - - a15*a33*a46*a54* - a61 - + a13*a35*a46*a54*a61 - + a16*a34*a43*a55*a61 - - - a14*a36*a43*a55*a61 - - a16*a33*a44*a55*a61 - + a13* - a36*a44*a55*a61 - + a14*a33*a46*a55*a61 - - a13*a34* - a46*a55*a61 - - a15*a34*a43*a56*a61 - + a14*a35*a43* - a56*a61 - + a15*a33*a44*a56*a61 - - a13*a35*a44*a56* - a61 - - a14*a33*a45*a56*a61 - + a13*a34*a45*a56*a61 - - - a16*a35*a44*a51*a63 - + a15*a36*a44*a51*a63 - + a16* - a34*a45*a51*a63 - - a14*a36*a45*a51*a63 - - a15*a34* - a46*a51*a63 - + a14*a35*a46*a51*a63 - + a16*a35*a41* - a54*a63 - - a15*a36*a41*a54*a63 - - a16*a31*a45*a54* - a63 - + a11*a36*a45*a54*a63 - + a15*a31*a46*a54*a63 - - - a11*a35*a46*a54*a63 - - a16*a34*a41*a55*a63 - + a14* - a36*a41*a55*a63 - + a16*a31*a44*a55*a63 - - a11*a36* - a44*a55*a63 - - a14*a31*a46*a55*a63 - + a11*a34*a46* - a55*a63 - + a15*a34*a41*a56*a63 - - a14*a35*a41*a56* - a63 - - a15*a31*a44*a56*a63 - + a11*a35*a44*a56*a63 - + - a14*a31*a45*a56*a63 - - a11*a34*a45*a56*a63 - + a16* - a35*a43*a51*a64 - - a15*a36*a43*a51*a64 - - a16*a33* - a45*a51*a64 - + a13*a36*a45*a51*a64 - + a15*a33*a46* - a51*a64 - - a13*a35*a46*a51*a64 - - a16*a35*a41*a53* - a64 - + a15*a36*a41*a53*a64 - + a16*a31*a45*a53*a64 - - - a11*a36*a45*a53*a64 - - a15*a31*a46*a53*a64 - + a11* - a35*a46*a53*a64 - + a16*a33*a41*a55*a64 - - a13*a36* - a41*a55*a64 - - a16*a31*a43*a55*a64 - + a11*a36*a43* - a55*a64 - + a13*a31*a46*a55*a64 - - a11*a33*a46*a55* - a64 - - a15*a33*a41*a56*a64 - + a13*a35*a41*a56*a64 - + - a15*a31*a43*a56*a64 - - a11*a35*a43*a56*a64 - - a13* - a31*a45*a56*a64 - + a11*a33*a45*a56*a64 - - a16*a34* - a43*a51*a65 - + a14*a36*a43*a51*a65 - + a16*a33*a44* - a51*a65 - - a13*a36*a44*a51*a65 - - a14*a33*a46*a51* - a65 - + a13*a34*a46*a51*a65 - + a16*a34*a41*a53*a65 - - - a14*a36*a41*a53*a65 - - a16*a31*a44*a53*a65 - + a11* - a36*a44*a53*a65 - + a14*a31*a46*a53*a65 - - a11*a34* - a46*a53*a65 - - a16*a33*a41*a54*a65 - + a13*a36*a41* - a54*a65 - + a16*a31*a43*a54*a65 - - a11*a36*a43*a54* - a65 - - a13*a31*a46*a54*a65 - + a11*a33*a46*a54*a65 - + - a14*a33*a41*a56*a65 - - a13*a34*a41*a56*a65 - - a14* - a31*a43*a56*a65 - + a11*a34*a43*a56*a65 - + a13*a31* - a44*a56*a65 - - a11*a33*a44*a56*a65 - + a15*a34*a43* - a51*a66 - - a14*a35*a43*a51*a66 - - a15*a33*a44*a51* - a66 - + a13*a35*a44*a51*a66 - + a14*a33*a45*a51*a66 - - - a13*a34*a45*a51*a66 - - a15*a34*a41*a53*a66 - + a14* - a35*a41*a53*a66 - + a15*a31*a44*a53*a66 - - a11*a35* - a44*a53*a66 - - a14*a31*a45*a53*a66 - + a11*a34*a45* - a53*a66 - + a15*a33*a41*a54*a66 - - a13*a35*a41*a54* - a66 - - a15*a31*a43*a54*a66 - + a11*a35*a43*a54*a66 - + - a13*a31*a45*a54*a66 - - a11*a33*a45*a54*a66 - - a14* - a33*a41*a55*a66 - + a13*a34*a41*a55*a66 - + a14*a31* - a43*a55*a66 - - a11*a34*a43*a55*a66 - - a13*a31*a44* - a55*a66 - + a11*a33*a44*a55*a66; - cofactor[8] = -a16*a25*a44*a53*a61 - + a15*a26*a44*a53*a61 - + a16*a24*a45*a53*a61 - - a14*a26*a45*a53*a61 - - a15*a24*a46*a53*a61 - + a14*a25*a46*a53*a61 - + a16*a25*a43*a54*a61 - - a15*a26*a43*a54*a61 - - a16*a23*a45*a54*a61 - + a13*a26*a45*a54*a61 - + a15*a23*a46*a54*a61 - - a13*a25*a46*a54*a61 - - a16*a24*a43*a55*a61 - + a14*a26*a43*a55*a61 - + a16*a23*a44*a55*a61 - - a13*a26*a44*a55*a61 - - a14*a23*a46*a55*a61 - + a13*a24*a46*a55*a61 - + a15*a24*a43*a56*a61 - - a14*a25*a43*a56*a61 - - a15*a23*a44*a56*a61 - + a13*a25*a44*a56*a61 - + a14*a23*a45*a56*a61 - - a13*a24*a45*a56*a61 - + a16*a25*a44*a51*a63 - - a15*a26*a44*a51*a63 - - a16*a24*a45*a51*a63 - + a14*a26*a45*a51*a63 - + a15*a24*a46*a51*a63 - - a14*a25*a46*a51*a63 - - a16*a25*a41*a54*a63 - + a15*a26*a41*a54*a63 - + a16*a21*a45*a54*a63 - - a11*a26*a45*a54*a63 - - a15*a21*a46*a54*a63 - + a11*a25*a46*a54*a63 - + a16*a24*a41*a55*a63 - - a14*a26*a41*a55*a63 - - a16*a21*a44*a55*a63 - + a11*a26*a44*a55*a63 - + a14*a21*a46*a55*a63 - - a11*a24*a46*a55*a63 - - a15*a24*a41*a56*a63 - + a14*a25*a41*a56*a63 - + a15*a21*a44*a56*a63 - - a11*a25*a44*a56*a63 - - a14*a21*a45*a56*a63 - + a11*a24*a45*a56*a63 - - a16*a25*a43*a51*a64 - + a15*a26*a43*a51*a64 - + a16*a23*a45*a51*a64 - - a13*a26*a45*a51*a64 - - a15*a23*a46*a51*a64 - + a13*a25*a46*a51*a64 - + a16*a25*a41*a53*a64 - - a15*a26*a41*a53*a64 - - a16*a21*a45*a53*a64 - + a11*a26*a45*a53*a64 - + a15*a21*a46*a53*a64 - - a11*a25*a46*a53*a64 - - a16*a23*a41*a55*a64 - + a13*a26*a41*a55*a64 - + a16*a21*a43*a55*a64 - - a11*a26*a43*a55*a64 - - a13*a21*a46*a55*a64 - + a11*a23*a46*a55*a64 - + a15*a23*a41*a56*a64 - - a13*a25*a41*a56*a64 - - a15*a21*a43*a56*a64 - + a11*a25*a43*a56*a64 - + a13*a21*a45*a56*a64 - - a11*a23*a45*a56*a64 - + a16*a24*a43*a51*a65 - - a14*a26*a43*a51*a65 - - a16*a23*a44*a51*a65 - + a13*a26*a44*a51*a65 - + a14*a23*a46*a51*a65 - - a13*a24*a46*a51*a65 - - a16*a24*a41*a53*a65 - + a14*a26*a41*a53*a65 - + a16*a21*a44*a53*a65 - - a11*a26*a44*a53*a65 - - a14*a21*a46*a53*a65 - + a11*a24*a46*a53*a65 - + a16*a23*a41*a54*a65 - - a13*a26*a41*a54*a65 - - a16*a21*a43*a54*a65 - + a11*a26*a43*a54*a65 - + a13*a21*a46*a54*a65 - - a11*a23*a46*a54*a65 - - a14*a23*a41*a56*a65 - + a13*a24*a41*a56*a65 - + a14*a21*a43*a56*a65 - - a11*a24*a43*a56*a65 - - a13*a21*a44*a56*a65 - + a11*a23*a44*a56*a65 - - a15*a24*a43*a51*a66 - + a14*a25*a43*a51*a66 - + a15*a23*a44*a51*a66 - - a13*a25*a44*a51*a66 - - a14*a23*a45*a51*a66 - + a13*a24*a45*a51*a66 - + a15*a24*a41*a53*a66 - - a14*a25*a41*a53*a66 - - a15*a21*a44*a53*a66 - + a11*a25*a44*a53*a66 - + a14*a21*a45*a53*a66 - - a11*a24*a45*a53*a66 - - a15*a23*a41*a54*a66 - + a13*a25*a41*a54*a66 - + a15*a21*a43*a54*a66 - - a11*a25*a43*a54*a66 - - a13*a21*a45*a54*a66 - + a11*a23*a45*a54*a66 - + a14*a23*a41*a55*a66 - - a13*a24*a41*a55*a66 - - a14*a21*a43*a55*a66 - + a11*a24*a43*a55*a66 - + a13*a21*a44*a55*a66 - - a11*a23*a44*a55*a66; - cofactor[9] = a16*a25*a34*a53*a61 - - a15*a26*a34*a53*a61 - - - a16*a24*a35*a53*a61 - + a14*a26*a35*a53*a61 - + a15* - a24*a36*a53*a61 - - a14*a25*a36*a53*a61 - - a16*a25* - a33*a54*a61 - + a15*a26*a33*a54*a61 - + a16*a23*a35* - a54*a61 - - a13*a26*a35*a54*a61 - - a15*a23*a36*a54* - a61 - + a13*a25*a36*a54*a61 - + a16*a24*a33*a55*a61 - - - a14*a26*a33*a55*a61 - - a16*a23*a34*a55*a61 - + a13* - a26*a34*a55*a61 - + a14*a23*a36*a55*a61 - - a13*a24* - a36*a55*a61 - - a15*a24*a33*a56*a61 - + a14*a25*a33* - a56*a61 - + a15*a23*a34*a56*a61 - - a13*a25*a34*a56* - a61 - - a14*a23*a35*a56*a61 - + a13*a24*a35*a56*a61 - - - a16*a25*a34*a51*a63 - + a15*a26*a34*a51*a63 - + a16* - a24*a35*a51*a63 - - a14*a26*a35*a51*a63 - - a15*a24* - a36*a51*a63 - + a14*a25*a36*a51*a63 - + a16*a25*a31* - a54*a63 - - a15*a26*a31*a54*a63 - - a16*a21*a35*a54* - a63 - + a11*a26*a35*a54*a63 - + a15*a21*a36*a54*a63 - - - a11*a25*a36*a54*a63 - - a16*a24*a31*a55*a63 - + a14* - a26*a31*a55*a63 - + a16*a21*a34*a55*a63 - - a11*a26* - a34*a55*a63 - - a14*a21*a36*a55*a63 - + a11*a24*a36* - a55*a63 - + a15*a24*a31*a56*a63 - - a14*a25*a31*a56* - a63 - - a15*a21*a34*a56*a63 - + a11*a25*a34*a56*a63 - + - a14*a21*a35*a56*a63 - - a11*a24*a35*a56*a63 - + a16* - a25*a33*a51*a64 - - a15*a26*a33*a51*a64 - - a16*a23* - a35*a51*a64 - + a13*a26*a35*a51*a64 - + a15*a23*a36* - a51*a64 - - a13*a25*a36*a51*a64 - - a16*a25*a31*a53* - a64 - + a15*a26*a31*a53*a64 - + a16*a21*a35*a53*a64 - - - a11*a26*a35*a53*a64 - - a15*a21*a36*a53*a64 - + a11* - a25*a36*a53*a64 - + a16*a23*a31*a55*a64 - - a13*a26* - a31*a55*a64 - - a16*a21*a33*a55*a64 - + a11*a26*a33* - a55*a64 - + a13*a21*a36*a55*a64 - - a11*a23*a36*a55* - a64 - - a15*a23*a31*a56*a64 - + a13*a25*a31*a56*a64 - + - a15*a21*a33*a56*a64 - - a11*a25*a33*a56*a64 - - a13* - a21*a35*a56*a64 - + a11*a23*a35*a56*a64 - - a16*a24* - a33*a51*a65 - + a14*a26*a33*a51*a65 - + a16*a23*a34* - a51*a65 - - a13*a26*a34*a51*a65 - - a14*a23*a36*a51* - a65 - + a13*a24*a36*a51*a65 - + a16*a24*a31*a53*a65 - - - a14*a26*a31*a53*a65 - - a16*a21*a34*a53*a65 - + a11* - a26*a34*a53*a65 - + a14*a21*a36*a53*a65 - - a11*a24* - a36*a53*a65 - - a16*a23*a31*a54*a65 - + a13*a26*a31* - a54*a65 - + a16*a21*a33*a54*a65 - - a11*a26*a33*a54* - a65 - - a13*a21*a36*a54*a65 - + a11*a23*a36*a54*a65 - + - a14*a23*a31*a56*a65 - - a13*a24*a31*a56*a65 - - a14* - a21*a33*a56*a65 - + a11*a24*a33*a56*a65 - + a13*a21* - a34*a56*a65 - - a11*a23*a34*a56*a65 - + a15*a24*a33* - a51*a66 - - a14*a25*a33*a51*a66 - - a15*a23*a34*a51* - a66 - + a13*a25*a34*a51*a66 - + a14*a23*a35*a51*a66 - - - a13*a24*a35*a51*a66 - - a15*a24*a31*a53*a66 - + a14* - a25*a31*a53*a66 - + a15*a21*a34*a53*a66 - - a11*a25* - a34*a53*a66 - - a14*a21*a35*a53*a66 - + a11*a24*a35* - a53*a66 - + a15*a23*a31*a54*a66 - - a13*a25*a31*a54* - a66 - - a15*a21*a33*a54*a66 - + a11*a25*a33*a54*a66 - + - a13*a21*a35*a54*a66 - - a11*a23*a35*a54*a66 - - a14* - a23*a31*a55*a66 - + a13*a24*a31*a55*a66 - + a14*a21* - a33*a55*a66 - - a11*a24*a33*a55*a66 - - a13*a21*a34* - a55*a66 - + a11*a23*a34*a55*a66; - cofactor[10] = -a16*a25*a34*a43*a61 - + a15*a26*a34*a43*a61 - + a16*a24*a35*a43*a61 - - a14*a26*a35*a43*a61 - - a15*a24*a36*a43*a61 - + a14*a25*a36*a43*a61 - + a16*a25*a33*a44*a61 - - a15*a26*a33*a44*a61 - - a16*a23*a35*a44*a61 - + a13*a26*a35*a44*a61 - + a15*a23*a36*a44*a61 - - a13*a25*a36*a44*a61 - - a16*a24*a33*a45*a61 - + a14*a26*a33*a45*a61 - + a16*a23*a34*a45*a61 - - a13*a26*a34*a45*a61 - - a14*a23*a36*a45*a61 - + a13*a24*a36*a45*a61 - + a15*a24*a33*a46*a61 - - a14*a25*a33*a46*a61 - - a15*a23*a34*a46*a61 - + a13*a25*a34*a46*a61 - + a14*a23*a35*a46*a61 - - a13*a24*a35*a46*a61 - + a16*a25*a34*a41*a63 - - a15*a26*a34*a41*a63 - - a16*a24*a35*a41*a63 - + a14*a26*a35*a41*a63 - + a15*a24*a36*a41*a63 - - a14*a25*a36*a41*a63 - - a16*a25*a31*a44*a63 - + a15*a26*a31*a44*a63 - + a16*a21*a35*a44*a63 - - a11*a26*a35*a44*a63 - - a15*a21*a36*a44*a63 - + a11*a25*a36*a44*a63 - + a16*a24*a31*a45*a63 - - a14*a26*a31*a45*a63 - - a16*a21*a34*a45*a63 - + a11*a26*a34*a45*a63 - + a14*a21*a36*a45*a63 - - a11*a24*a36*a45*a63 - - a15*a24*a31*a46*a63 - + a14*a25*a31*a46*a63 - + a15*a21*a34*a46*a63 - - a11*a25*a34*a46*a63 - - a14*a21*a35*a46*a63 - + a11*a24*a35*a46*a63 - - a16*a25*a33*a41*a64 - + a15*a26*a33*a41*a64 - + a16*a23*a35*a41*a64 - - a13*a26*a35*a41*a64 - - a15*a23*a36*a41*a64 - + a13*a25*a36*a41*a64 - + a16*a25*a31*a43*a64 - - a15*a26*a31*a43*a64 - - a16*a21*a35*a43*a64 - + a11*a26*a35*a43*a64 - + a15*a21*a36*a43*a64 - - a11*a25*a36*a43*a64 - - a16*a23*a31*a45*a64 - + a13*a26*a31*a45*a64 - + a16*a21*a33*a45*a64 - - a11*a26*a33*a45*a64 - - a13*a21*a36*a45*a64 - + a11*a23*a36*a45*a64 - + a15*a23*a31*a46*a64 - - a13*a25*a31*a46*a64 - - a15*a21*a33*a46*a64 - + a11*a25*a33*a46*a64 - + a13*a21*a35*a46*a64 - - a11*a23*a35*a46*a64 - + a16*a24*a33*a41*a65 - - a14*a26*a33*a41*a65 - - a16*a23*a34*a41*a65 - + a13*a26*a34*a41*a65 - + a14*a23*a36*a41*a65 - - a13*a24*a36*a41*a65 - - a16*a24*a31*a43*a65 - + a14*a26*a31*a43*a65 - + a16*a21*a34*a43*a65 - - a11*a26*a34*a43*a65 - - a14*a21*a36*a43*a65 - + a11*a24*a36*a43*a65 - + a16*a23*a31*a44*a65 - - a13*a26*a31*a44*a65 - - a16*a21*a33*a44*a65 - + a11*a26*a33*a44*a65 - + a13*a21*a36*a44*a65 - - a11*a23*a36*a44*a65 - - a14*a23*a31*a46*a65 - + a13*a24*a31*a46*a65 - + a14*a21*a33*a46*a65 - - a11*a24*a33*a46*a65 - - a13*a21*a34*a46*a65 - + a11*a23*a34*a46*a65 - - a15*a24*a33*a41*a66 - + a14*a25*a33*a41*a66 - + a15*a23*a34*a41*a66 - - a13*a25*a34*a41*a66 - - a14*a23*a35*a41*a66 - + a13*a24*a35*a41*a66 - + a15*a24*a31*a43*a66 - - a14*a25*a31*a43*a66 - - a15*a21*a34*a43*a66 - + a11*a25*a34*a43*a66 - + a14*a21*a35*a43*a66 - - a11*a24*a35*a43*a66 - - a15*a23*a31*a44*a66 - + a13*a25*a31*a44*a66 - + a15*a21*a33*a44*a66 - - a11*a25*a33*a44*a66 - - a13*a21*a35*a44*a66 - + a11*a23*a35*a44*a66 - + a14*a23*a31*a45*a66 - - a13*a24*a31*a45*a66 - - a14*a21*a33*a45*a66 - + a11*a24*a33*a45*a66 - + a13*a21*a34*a45*a66 - - a11*a23*a34*a45*a66; - cofactor[11] = a16*a25*a34*a43*a51 - - a15*a26*a34*a43*a51 - - a16*a24*a35*a43*a51 - + a14*a26*a35*a43*a51 - + a15*a24*a36*a43*a51 - - a14*a25*a36*a43*a51 - - a16*a25*a33*a44*a51 - + a15*a26*a33*a44*a51 - + a16*a23*a35*a44*a51 - - a13*a26*a35*a44*a51 - - a15*a23*a36*a44*a51 - + a13*a25*a36*a44*a51 - + a16*a24*a33*a45*a51 - - a14*a26*a33*a45*a51 - - a16*a23*a34*a45*a51 - + a13*a26*a34*a45*a51 - + a14*a23*a36*a45*a51 - - a13*a24*a36*a45*a51 - - a15*a24*a33*a46*a51 - + a14*a25*a33*a46*a51 - + a15*a23*a34*a46*a51 - - a13*a25*a34*a46*a51 - - a14*a23*a35*a46*a51 - + a13*a24*a35*a46*a51 - - a16*a25*a34*a41*a53 - + a15*a26*a34*a41*a53 - + a16*a24*a35*a41*a53 - - a14*a26*a35*a41*a53 - - a15*a24*a36*a41*a53 - + a14*a25*a36*a41*a53 - + a16*a25*a31*a44*a53 - - a15*a26*a31*a44*a53 - - a16*a21*a35*a44*a53 - + a11*a26*a35*a44*a53 - + a15*a21*a36*a44*a53 - - a11*a25*a36*a44*a53 - - a16*a24*a31*a45*a53 - + a14*a26*a31*a45*a53 - + a16*a21*a34*a45*a53 - - a11*a26*a34*a45*a53 - - a14*a21*a36*a45*a53 - + a11*a24*a36*a45*a53 - + a15*a24*a31*a46*a53 - - a14*a25*a31*a46*a53 - - a15*a21*a34*a46*a53 - + a11*a25*a34*a46*a53 - + a14*a21*a35*a46*a53 - - a11*a24*a35*a46*a53 - + a16*a25*a33*a41*a54 - - a15*a26*a33*a41*a54 - - a16*a23*a35*a41*a54 - + a13*a26*a35*a41*a54 - + a15*a23*a36*a41*a54 - - a13*a25*a36*a41*a54 - - a16*a25*a31*a43*a54 - + a15*a26*a31*a43*a54 - + a16*a21*a35*a43*a54 - - a11*a26*a35*a43*a54 - - a15*a21*a36*a43*a54 - + a11*a25*a36*a43*a54 - + a16*a23*a31*a45*a54 - - a13*a26*a31*a45*a54 - - a16*a21*a33*a45*a54 - + a11*a26*a33*a45*a54 - + a13*a21*a36*a45*a54 - - a11*a23*a36*a45*a54 - - a15*a23*a31*a46*a54 - + a13*a25*a31*a46*a54 - + a15*a21*a33*a46*a54 - - a11*a25*a33*a46*a54 - - a13*a21*a35*a46*a54 - + a11*a23*a35*a46*a54 - - a16*a24*a33*a41*a55 - + a14*a26*a33*a41*a55 - + a16*a23*a34*a41*a55 - - a13*a26*a34*a41*a55 - - a14*a23*a36*a41*a55 - + a13*a24*a36*a41*a55 - + a16*a24*a31*a43*a55 - - a14*a26*a31*a43*a55 - - a16*a21*a34*a43*a55 - + a11*a26*a34*a43*a55 - + a14*a21*a36*a43*a55 - - a11*a24*a36*a43*a55 - - a16*a23*a31*a44*a55 - + a13*a26*a31*a44*a55 - + a16*a21*a33*a44*a55 - - a11*a26*a33*a44*a55 - - a13*a21*a36*a44*a55 - + a11*a23*a36*a44*a55 - + a14*a23*a31*a46*a55 - - a13*a24*a31*a46*a55 - - a14*a21*a33*a46*a55 - + a11*a24*a33*a46*a55 - + a13*a21*a34*a46*a55 - - a11*a23*a34*a46*a55 - + a15*a24*a33*a41*a56 - - a14*a25*a33*a41*a56 - - a15*a23*a34*a41*a56 - + a13*a25*a34*a41*a56 - + a14*a23*a35*a41*a56 - - a13*a24*a35*a41*a56 - - a15*a24*a31*a43*a56 - + a14*a25*a31*a43*a56 - + a15*a21*a34*a43*a56 - - a11*a25*a34*a43*a56 - - a14*a21*a35*a43*a56 - + a11*a24*a35*a43*a56 - + a15*a23*a31*a44*a56 - - a13*a25*a31*a44*a56 - - a15*a21*a33*a44*a56 - + a11*a25*a33*a44*a56 - + a13*a21*a35*a44*a56 - - a11*a23*a35*a44*a56 - - a14*a23*a31*a45*a56 - + a13*a24*a31*a45*a56 - + a14*a21*a33*a45*a56 - - a11*a24*a33*a45*a56 - - a13*a21*a34*a45*a56 - + a11*a23*a34*a45*a56; - cofactor[12] = a26*a35*a44*a52*a61 - - a25*a36*a44*a52*a61 - - a26*a34*a45*a52*a61 - + a24*a36*a45*a52*a61 - + a25*a34*a46*a52*a61 - - a24*a35*a46*a52*a61 - - a26*a35*a42*a54*a61 - + a25*a36*a42*a54*a61 - + a26*a32*a45*a54*a61 - - a22*a36*a45*a54*a61 - - a25*a32*a46*a54*a61 - + a22*a35*a46*a54*a61 - + a26*a34*a42*a55*a61 - - a24*a36*a42*a55*a61 - - a26*a32*a44*a55*a61 - + a22*a36*a44*a55*a61 - + a24*a32*a46*a55*a61 - - a22*a34*a46*a55*a61 - - a25*a34*a42*a56*a61 - + a24*a35*a42*a56*a61 - + a25*a32*a44*a56*a61 - - a22*a35*a44*a56*a61 - - a24*a32*a45*a56*a61 - + a22*a34*a45*a56*a61 - - a26*a35*a44*a51*a62 - + a25*a36*a44*a51*a62 - + a26*a34*a45*a51*a62 - - a24*a36*a45*a51*a62 - - a25*a34*a46*a51*a62 - + a24*a35*a46*a51*a62 - + a26*a35*a41*a54*a62 - - a25*a36*a41*a54*a62 - - a26*a31*a45*a54*a62 - + a21*a36*a45*a54*a62 - + a25*a31*a46*a54*a62 - - a21*a35*a46*a54*a62 - - a26*a34*a41*a55*a62 - + a24*a36*a41*a55*a62 - + a26*a31*a44*a55*a62 - - a21*a36*a44*a55*a62 - - a24*a31*a46*a55*a62 - + a21*a34*a46*a55*a62 - + a25*a34*a41*a56*a62 - - a24*a35*a41*a56*a62 - - a25*a31*a44*a56*a62 - + a21*a35*a44*a56*a62 - + a24*a31*a45*a56*a62 - - a21*a34*a45*a56*a62 - + a26*a35*a42*a51*a64 - - a25*a36*a42*a51*a64 - - a26*a32*a45*a51*a64 - + a22*a36*a45*a51*a64 - + a25*a32*a46*a51*a64 - - a22*a35*a46*a51*a64 - - a26*a35*a41*a52*a64 - + a25*a36*a41*a52*a64 - + a26*a31*a45*a52*a64 - - a21*a36*a45*a52*a64 - - a25*a31*a46*a52*a64 - + a21*a35*a46*a52*a64 - + a26*a32*a41*a55*a64 - - a22*a36*a41*a55*a64 - - a26*a31*a42*a55*a64 - + a21*a36*a42*a55*a64 - + a22*a31*a46*a55*a64 - - a21*a32*a46*a55*a64 - - a25*a32*a41*a56*a64 - + a22*a35*a41*a56*a64 - + a25*a31*a42*a56*a64 - - a21*a35*a42*a56*a64 - - a22*a31*a45*a56*a64 - + a21*a32*a45*a56*a64 - - a26*a34*a42*a51*a65 - + a24*a36*a42*a51*a65 - + a26*a32*a44*a51*a65 - - a22*a36*a44*a51*a65 - - a24*a32*a46*a51*a65 - + a22*a34*a46*a51*a65 - + a26*a34*a41*a52*a65 - - a24*a36*a41*a52*a65 - - a26*a31*a44*a52*a65 - + a21*a36*a44*a52*a65 - + a24*a31*a46*a52*a65 - - a21*a34*a46*a52*a65 - - a26*a32*a41*a54*a65 - + a22*a36*a41*a54*a65 - + a26*a31*a42*a54*a65 - - a21*a36*a42*a54*a65 - - a22*a31*a46*a54*a65 - + a21*a32*a46*a54*a65 - + a24*a32*a41*a56*a65 - - a22*a34*a41*a56*a65 - - a24*a31*a42*a56*a65 - + a21*a34*a42*a56*a65 - + a22*a31*a44*a56*a65 - - a21*a32*a44*a56*a65 - + a25*a34*a42*a51*a66 - - a24*a35*a42*a51*a66 - - a25*a32*a44*a51*a66 - + a22*a35*a44*a51*a66 - + a24*a32*a45*a51*a66 - - a22*a34*a45*a51*a66 - - a25*a34*a41*a52*a66 - + a24*a35*a41*a52*a66 - + a25*a31*a44*a52*a66 - - a21*a35*a44*a52*a66 - - a24*a31*a45*a52*a66 - + a21*a34*a45*a52*a66 - + a25*a32*a41*a54*a66 - - a22*a35*a41*a54*a66 - - a25*a31*a42*a54*a66 - + a21*a35*a42*a54*a66 - + a22*a31*a45*a54*a66 - - a21*a32*a45*a54*a66 - - a24*a32*a41*a55*a66 - + a22*a34*a41*a55*a66 - + a24*a31*a42*a55*a66 - - a21*a34*a42*a55*a66 - - a22*a31*a44*a55*a66 - + a21*a32*a44*a55*a66; - cofactor[13] = -a16*a35*a44*a52*a61 - + a15*a36*a44*a52*a61 - + a16*a34*a45*a52*a61 - - a14*a36*a45*a52*a61 - - a15*a34*a46*a52*a61 - + a14*a35*a46*a52*a61 - + a16*a35*a42*a54*a61 - - a15*a36*a42*a54*a61 - - a16*a32*a45*a54*a61 - + a12*a36*a45*a54*a61 - + a15*a32*a46*a54*a61 - - a12*a35*a46*a54*a61 - - a16*a34*a42*a55*a61 - + a14*a36*a42*a55*a61 - + a16*a32*a44*a55*a61 - - a12*a36*a44*a55*a61 - - a14*a32*a46*a55*a61 - + a12*a34*a46*a55*a61 - + a15*a34*a42*a56*a61 - - a14*a35*a42*a56*a61 - - a15*a32*a44*a56*a61 - + a12*a35*a44*a56*a61 - + a14*a32*a45*a56*a61 - - a12*a34*a45*a56*a61 - + a16*a35*a44*a51*a62 - - a15*a36*a44*a51*a62 - - a16*a34*a45*a51*a62 - + a14*a36*a45*a51*a62 - + a15*a34*a46*a51*a62 - - a14*a35*a46*a51*a62 - - a16*a35*a41*a54*a62 - + a15*a36*a41*a54*a62 - + a16*a31*a45*a54*a62 - - a11*a36*a45*a54*a62 - - a15*a31*a46*a54*a62 - + a11*a35*a46*a54*a62 - + a16*a34*a41*a55*a62 - - a14*a36*a41*a55*a62 - - a16*a31*a44*a55*a62 - + a11*a36*a44*a55*a62 - + a14*a31*a46*a55*a62 - - a11*a34*a46*a55*a62 - - a15*a34*a41*a56*a62 - + a14*a35*a41*a56*a62 - + a15*a31*a44*a56*a62 - - a11*a35*a44*a56*a62 - - a14*a31*a45*a56*a62 - + a11*a34*a45*a56*a62 - - a16*a35*a42*a51*a64 - + a15*a36*a42*a51*a64 - + a16*a32*a45*a51*a64 - - a12*a36*a45*a51*a64 - - a15*a32*a46*a51*a64 - + a12*a35*a46*a51*a64 - + a16*a35*a41*a52*a64 - - a15*a36*a41*a52*a64 - - a16*a31*a45*a52*a64 - + a11*a36*a45*a52*a64 - + a15*a31*a46*a52*a64 - - a11*a35*a46*a52*a64 - - a16*a32*a41*a55*a64 - + a12*a36*a41*a55*a64 - + a16*a31*a42*a55*a64 - - a11*a36*a42*a55*a64 - - a12*a31*a46*a55*a64 - + a11*a32*a46*a55*a64 - + a15*a32*a41*a56*a64 - - a12*a35*a41*a56*a64 - - a15*a31*a42*a56*a64 - + a11*a35*a42*a56*a64 - + a12*a31*a45*a56*a64 - - a11*a32*a45*a56*a64 - + a16*a34*a42*a51*a65 - - a14*a36*a42*a51*a65 - - a16*a32*a44*a51*a65 - + a12*a36*a44*a51*a65 - + a14*a32*a46*a51*a65 - - a12*a34*a46*a51*a65 - - a16*a34*a41*a52*a65 - + a14*a36*a41*a52*a65 - + a16*a31*a44*a52*a65 - - a11*a36*a44*a52*a65 - - a14*a31*a46*a52*a65 - + a11*a34*a46*a52*a65 - + a16*a32*a41*a54*a65 - - a12*a36*a41*a54*a65 - - a16*a31*a42*a54*a65 - + a11*a36*a42*a54*a65 - + a12*a31*a46*a54*a65 - - a11*a32*a46*a54*a65 - - a14*a32*a41*a56*a65 - + a12*a34*a41*a56*a65 - + a14*a31*a42*a56*a65 - - a11*a34*a42*a56*a65 - - a12*a31*a44*a56*a65 - + a11*a32*a44*a56*a65 - - a15*a34*a42*a51*a66 - + a14*a35*a42*a51*a66 - + a15*a32*a44*a51*a66 - - a12*a35*a44*a51*a66 - - a14*a32*a45*a51*a66 - + a12*a34*a45*a51*a66 - + a15*a34*a41*a52*a66 - - a14*a35*a41*a52*a66 - - a15*a31*a44*a52*a66 - + a11*a35*a44*a52*a66 - + a14*a31*a45*a52*a66 - - a11*a34*a45*a52*a66 - - a15*a32*a41*a54*a66 - + a12*a35*a41*a54*a66 - + a15*a31*a42*a54*a66 - - a11*a35*a42*a54*a66 - - a12*a31*a45*a54*a66 - + a11*a32*a45*a54*a66 - + a14*a32*a41*a55*a66 - - a12*a34*a41*a55*a66 - - a14*a31*a42*a55*a66 - + a11*a34*a42*a55*a66 - + a12*a31*a44*a55*a66 - - a11*a32*a44*a55*a66; - cofactor[14] = a16*a25*a44*a52*a61 - - a15*a26*a44*a52*a61 - - a16*a24*a45*a52*a61 - + a14*a26*a45*a52*a61 - + a15*a24*a46*a52*a61 - - a14*a25*a46*a52*a61 - - a16*a25*a42*a54*a61 - + a15*a26*a42*a54*a61 - + a16*a22*a45*a54*a61 - - a12*a26*a45*a54*a61 - - a15*a22*a46*a54*a61 - + a12*a25*a46*a54*a61 - + a16*a24*a42*a55*a61 - - a14*a26*a42*a55*a61 - - a16*a22*a44*a55*a61 - + a12*a26*a44*a55*a61 - + a14*a22*a46*a55*a61 - - a12*a24*a46*a55*a61 - - a15*a24*a42*a56*a61 - + a14*a25*a42*a56*a61 - + a15*a22*a44*a56*a61 - - a12*a25*a44*a56*a61 - - a14*a22*a45*a56*a61 - + a12*a24*a45*a56*a61 - - a16*a25*a44*a51*a62 - + a15*a26*a44*a51*a62 - + a16*a24*a45*a51*a62 - - a14*a26*a45*a51*a62 - - a15*a24*a46*a51*a62 - + a14*a25*a46*a51*a62 - + a16*a25*a41*a54*a62 - - a15*a26*a41*a54*a62 - - a16*a21*a45*a54*a62 - + a11*a26*a45*a54*a62 - + a15*a21*a46*a54*a62 - - a11*a25*a46*a54*a62 - - a16*a24*a41*a55*a62 - + a14*a26*a41*a55*a62 - + a16*a21*a44*a55*a62 - - a11*a26*a44*a55*a62 - - a14*a21*a46*a55*a62 - + a11*a24*a46*a55*a62 - + a15*a24*a41*a56*a62 - - a14*a25*a41*a56*a62 - - a15*a21*a44*a56*a62 - + a11*a25*a44*a56*a62 - + a14*a21*a45*a56*a62 - - a11*a24*a45*a56*a62 - + a16*a25*a42*a51*a64 - - a15*a26*a42*a51*a64 - - a16*a22*a45*a51*a64 - + a12*a26*a45*a51*a64 - + a15*a22*a46*a51*a64 - - a12*a25*a46*a51*a64 - - a16*a25*a41*a52*a64 - + a15*a26*a41*a52*a64 - + a16*a21*a45*a52*a64 - - a11*a26*a45*a52*a64 - - a15*a21*a46*a52*a64 - + a11*a25*a46*a52*a64 - + a16*a22*a41*a55*a64 - - a12*a26*a41*a55*a64 - - a16*a21*a42*a55*a64 - + a11*a26*a42*a55*a64 - + a12*a21*a46*a55*a64 - - a11*a22*a46*a55*a64 - - a15*a22*a41*a56*a64 - + a12*a25*a41*a56*a64 - + a15*a21*a42*a56*a64 - - a11*a25*a42*a56*a64 - - a12*a21*a45*a56*a64 - + a11*a22*a45*a56*a64 - - a16*a24*a42*a51*a65 - + a14*a26*a42*a51*a65 - + a16*a22*a44*a51*a65 - - a12*a26*a44*a51*a65 - - a14*a22*a46*a51*a65 - + a12*a24*a46*a51*a65 - + a16*a24*a41*a52*a65 - - a14*a26*a41*a52*a65 - - a16*a21*a44*a52*a65 - + a11*a26*a44*a52*a65 - + a14*a21*a46*a52*a65 - - a11*a24*a46*a52*a65 - - a16*a22*a41*a54*a65 - + a12*a26*a41*a54*a65 - + a16*a21*a42*a54*a65 - - a11*a26*a42*a54*a65 - - a12*a21*a46*a54*a65 - + a11*a22*a46*a54*a65 - + a14*a22*a41*a56*a65 - - a12*a24*a41*a56*a65 - - a14*a21*a42*a56*a65 - + a11*a24*a42*a56*a65 - + a12*a21*a44*a56*a65 - - a11*a22*a44*a56*a65 - + a15*a24*a42*a51*a66 - - a14*a25*a42*a51*a66 - - a15*a22*a44*a51*a66 - + a12*a25*a44*a51*a66 - + a14*a22*a45*a51*a66 - - a12*a24*a45*a51*a66 - - a15*a24*a41*a52*a66 - + a14*a25*a41*a52*a66 - + a15*a21*a44*a52*a66 - - a11*a25*a44*a52*a66 - - a14*a21*a45*a52*a66 - + a11*a24*a45*a52*a66 - + a15*a22*a41*a54*a66 - - a12*a25*a41*a54*a66 - - a15*a21*a42*a54*a66 - + a11*a25*a42*a54*a66 - + a12*a21*a45*a54*a66 - - a11*a22*a45*a54*a66 - - a14*a22*a41*a55*a66 - + a12*a24*a41*a55*a66 - + a14*a21*a42*a55*a66 - - a11*a24*a42*a55*a66 - - a12*a21*a44*a55*a66 - + a11*a22*a44*a55*a66; - cofactor[15] = -a16*a25*a34*a52*a61 - + a15*a26*a34*a52*a61 - + a16*a24*a35*a52*a61 - - a14*a26*a35*a52*a61 - - a15*a24*a36*a52*a61 - + a14*a25*a36*a52*a61 - + a16*a25*a32*a54*a61 - - a15*a26*a32*a54*a61 - - a16*a22*a35*a54*a61 - + a12*a26*a35*a54*a61 - + a15*a22*a36*a54*a61 - - a12*a25*a36*a54*a61 - - a16*a24*a32*a55*a61 - + a14*a26*a32*a55*a61 - + a16*a22*a34*a55*a61 - - a12*a26*a34*a55*a61 - - a14*a22*a36*a55*a61 - + a12*a24*a36*a55*a61 - + a15*a24*a32*a56*a61 - - a14*a25*a32*a56*a61 - - a15*a22*a34*a56*a61 - + a12*a25*a34*a56*a61 - + a14*a22*a35*a56*a61 - - a12*a24*a35*a56*a61 - + a16*a25*a34*a51*a62 - - a15*a26*a34*a51*a62 - - a16*a24*a35*a51*a62 - + a14*a26*a35*a51*a62 - + a15*a24*a36*a51*a62 - - a14*a25*a36*a51*a62 - - a16*a25*a31*a54*a62 - + a15*a26*a31*a54*a62 - + a16*a21*a35*a54*a62 - - a11*a26*a35*a54*a62 - - a15*a21*a36*a54*a62 - + a11*a25*a36*a54*a62 - + a16*a24*a31*a55*a62 - - a14*a26*a31*a55*a62 - - a16*a21*a34*a55*a62 - + a11*a26*a34*a55*a62 - + a14*a21*a36*a55*a62 - - a11*a24*a36*a55*a62 - - a15*a24*a31*a56*a62 - + a14*a25*a31*a56*a62 - + a15*a21*a34*a56*a62 - - a11*a25*a34*a56*a62 - - a14*a21*a35*a56*a62 - + a11*a24*a35*a56*a62 - - a16*a25*a32*a51*a64 - + a15*a26*a32*a51*a64 - + a16*a22*a35*a51*a64 - - a12*a26*a35*a51*a64 - - a15*a22*a36*a51*a64 - + a12*a25*a36*a51*a64 - + a16*a25*a31*a52*a64 - - a15*a26*a31*a52*a64 - - a16*a21*a35*a52*a64 - + a11*a26*a35*a52*a64 - + a15*a21*a36*a52*a64 - - a11*a25*a36*a52*a64 - - a16*a22*a31*a55*a64 - + a12*a26*a31*a55*a64 - + a16*a21*a32*a55*a64 - - a11*a26*a32*a55*a64 - - a12*a21*a36*a55*a64 - + a11*a22*a36*a55*a64 - + a15*a22*a31*a56*a64 - - a12*a25*a31*a56*a64 - - a15*a21*a32*a56*a64 - + a11*a25*a32*a56*a64 - + a12*a21*a35*a56*a64 - - a11*a22*a35*a56*a64 - + a16*a24*a32*a51*a65 - - a14*a26*a32*a51*a65 - - a16*a22*a34*a51*a65 - + a12*a26*a34*a51*a65 - + a14*a22*a36*a51*a65 - - a12*a24*a36*a51*a65 - - a16*a24*a31*a52*a65 - + a14*a26*a31*a52*a65 - + a16*a21*a34*a52*a65 - - a11*a26*a34*a52*a65 - - a14*a21*a36*a52*a65 - + a11*a24*a36*a52*a65 - + a16*a22*a31*a54*a65 - - a12*a26*a31*a54*a65 - - a16*a21*a32*a54*a65 - + a11*a26*a32*a54*a65 - + a12*a21*a36*a54*a65 - - a11*a22*a36*a54*a65 - - a14*a22*a31*a56*a65 - + a12*a24*a31*a56*a65 - + a14*a21*a32*a56*a65 - - a11*a24*a32*a56*a65 - - a12*a21*a34*a56*a65 - + a11*a22*a34*a56*a65 - - a15*a24*a32*a51*a66 - + a14*a25*a32*a51*a66 - + a15*a22*a34*a51*a66 - - a12*a25*a34*a51*a66 - - a14*a22*a35*a51*a66 - + a12*a24*a35*a51*a66 - + a15*a24*a31*a52*a66 - - a14*a25*a31*a52*a66 - - a15*a21*a34*a52*a66 - + a11*a25*a34*a52*a66 - + a14*a21*a35*a52*a66 - - a11*a24*a35*a52*a66 - - a15*a22*a31*a54*a66 - + a12*a25*a31*a54*a66 - + a15*a21*a32*a54*a66 - - a11*a25*a32*a54*a66 - - a12*a21*a35*a54*a66 - + a11*a22*a35*a54*a66 - + a14*a22*a31*a55*a66 - - a12*a24*a31*a55*a66 - - a14*a21*a32*a55*a66 - + a11*a24*a32*a55*a66 - + a12*a21*a34*a55*a66 - - a11*a22*a34*a55*a66; - cofactor[16] = a16*a25*a34*a42*a61 - - a15*a26*a34*a42*a61 - - a16*a24*a35*a42*a61 - + a14*a26*a35*a42*a61 - + a15*a24*a36*a42*a61 - - a14*a25*a36*a42*a61 - - a16*a25*a32*a44*a61 - + a15*a26*a32*a44*a61 - + a16*a22*a35*a44*a61 - - a12*a26*a35*a44*a61 - - a15*a22*a36*a44*a61 - + a12*a25*a36*a44*a61 - + a16*a24*a32*a45*a61 - - a14*a26*a32*a45*a61 - - a16*a22*a34*a45*a61 - + a12*a26*a34*a45*a61 - + a14*a22*a36*a45*a61 - - a12*a24*a36*a45*a61 - - a15*a24*a32*a46*a61 - + a14*a25*a32*a46*a61 - + a15*a22*a34*a46*a61 - - a12*a25*a34*a46*a61 - - a14*a22*a35*a46*a61 - + a12*a24*a35*a46*a61 - - a16*a25*a34*a41*a62 - + a15*a26*a34*a41*a62 - + a16*a24*a35*a41*a62 - - a14*a26*a35*a41*a62 - - a15*a24*a36*a41*a62 - + a14*a25*a36*a41*a62 - + a16*a25*a31*a44*a62 - - a15*a26*a31*a44*a62 - - a16*a21*a35*a44*a62 - + a11*a26*a35*a44*a62 - + a15*a21*a36*a44*a62 - - a11*a25*a36*a44*a62 - - a16*a24*a31*a45*a62 - + a14*a26*a31*a45*a62 - + a16*a21*a34*a45*a62 - - a11*a26*a34*a45*a62 - - a14*a21*a36*a45*a62 - + a11*a24*a36*a45*a62 - + a15*a24*a31*a46*a62 - - a14*a25*a31*a46*a62 - - a15*a21*a34*a46*a62 - + a11*a25*a34*a46*a62 - + a14*a21*a35*a46*a62 - - a11*a24*a35*a46*a62 - + a16*a25*a32*a41*a64 - - a15*a26*a32*a41*a64 - - a16*a22*a35*a41*a64 - + a12*a26*a35*a41*a64 - + a15*a22*a36*a41*a64 - - a12*a25*a36*a41*a64 - - a16*a25*a31*a42*a64 - + a15*a26*a31*a42*a64 - + a16*a21*a35*a42*a64 - - a11*a26*a35*a42*a64 - - a15*a21*a36*a42*a64 - + a11*a25*a36*a42*a64 - + a16*a22*a31*a45*a64 - - a12*a26*a31*a45*a64 - - a16*a21*a32*a45*a64 - + a11*a26*a32*a45*a64 - + a12*a21*a36*a45*a64 - - a11*a22*a36*a45*a64 - - a15*a22*a31*a46*a64 - + a12*a25*a31*a46*a64 - + a15*a21*a32*a46*a64 - - a11*a25*a32*a46*a64 - - a12*a21*a35*a46*a64 - + a11*a22*a35*a46*a64 - - a16*a24*a32*a41*a65 - + a14*a26*a32*a41*a65 - + a16*a22*a34*a41*a65 - - a12*a26*a34*a41*a65 - - a14*a22*a36*a41*a65 - + a12*a24*a36*a41*a65 - + a16*a24*a31*a42*a65 - - a14*a26*a31*a42*a65 - - a16*a21*a34*a42*a65 - + a11*a26*a34*a42*a65 - + a14*a21*a36*a42*a65 - - a11*a24*a36*a42*a65 - - a16*a22*a31*a44*a65 - + a12*a26*a31*a44*a65 - + a16*a21*a32*a44*a65 - - a11*a26*a32*a44*a65 - - a12*a21*a36*a44*a65 - + a11*a22*a36*a44*a65 - + a14*a22*a31*a46*a65 - - a12*a24*a31*a46*a65 - - a14*a21*a32*a46*a65 - + a11*a24*a32*a46*a65 - + a12*a21*a34*a46*a65 - - a11*a22*a34*a46*a65 - + a15*a24*a32*a41*a66 - - a14*a25*a32*a41*a66 - - a15*a22*a34*a41*a66 - + a12*a25*a34*a41*a66 - + a14*a22*a35*a41*a66 - - a12*a24*a35*a41*a66 - - a15*a24*a31*a42*a66 - + a14*a25*a31*a42*a66 - + a15*a21*a34*a42*a66 - - a11*a25*a34*a42*a66 - - a14*a21*a35*a42*a66 - + a11*a24*a35*a42*a66 - + a15*a22*a31*a44*a66 - - a12*a25*a31*a44*a66 - - a15*a21*a32*a44*a66 - + a11*a25*a32*a44*a66 - + a12*a21*a35*a44*a66 - - a11*a22*a35*a44*a66 - - a14*a22*a31*a45*a66 - + a12*a24*a31*a45*a66 - + a14*a21*a32*a45*a66 - - a11*a24*a32*a45*a66 - - a12*a21*a34*a45*a66 - + a11*a22*a34*a45*a66; - cofactor[17] = -a16*a25*a34*a42*a51 - + a15*a26*a34*a42*a51 - + a16*a24*a35*a42*a51 - - a14*a26*a35*a42*a51 - - a15*a24*a36*a42*a51 - + a14*a25*a36*a42*a51 - + a16*a25*a32*a44*a51 - - a15*a26*a32*a44*a51 - - a16*a22*a35*a44*a51 - + a12*a26*a35*a44*a51 - + a15*a22*a36*a44*a51 - - a12*a25*a36*a44*a51 - - a16*a24*a32*a45*a51 - + a14*a26*a32*a45*a51 - + a16*a22*a34*a45*a51 - - a12*a26*a34*a45*a51 - - a14*a22*a36*a45*a51 - + a12*a24*a36*a45*a51 - + a15*a24*a32*a46*a51 - - a14*a25*a32*a46*a51 - - a15*a22*a34*a46*a51 - + a12*a25*a34*a46*a51 - + a14*a22*a35*a46*a51 - - a12*a24*a35*a46*a51 - + a16*a25*a34*a41*a52 - - a15*a26*a34*a41*a52 - - a16*a24*a35*a41*a52 - + a14*a26*a35*a41*a52 - + a15*a24*a36*a41*a52 - - a14*a25*a36*a41*a52 - - a16*a25*a31*a44*a52 - + a15*a26*a31*a44*a52 - + a16*a21*a35*a44*a52 - - a11*a26*a35*a44*a52 - - a15*a21*a36*a44*a52 - + a11*a25*a36*a44*a52 - + a16*a24*a31*a45*a52 - - a14*a26*a31*a45*a52 - - a16*a21*a34*a45*a52 - + a11*a26*a34*a45*a52 - + a14*a21*a36*a45*a52 - - a11*a24*a36*a45*a52 - - a15*a24*a31*a46*a52 - + a14*a25*a31*a46*a52 - + a15*a21*a34*a46*a52 - - a11*a25*a34*a46*a52 - - a14*a21*a35*a46*a52 - + a11*a24*a35*a46*a52 - - a16*a25*a32*a41*a54 - + a15*a26*a32*a41*a54 - + a16*a22*a35*a41*a54 - - a12*a26*a35*a41*a54 - - a15*a22*a36*a41*a54 - + a12*a25*a36*a41*a54 - + a16*a25*a31*a42*a54 - - a15*a26*a31*a42*a54 - - a16*a21*a35*a42*a54 - + a11*a26*a35*a42*a54 - + a15*a21*a36*a42*a54 - - a11*a25*a36*a42*a54 - - a16*a22*a31*a45*a54 - + a12*a26*a31*a45*a54 - + a16*a21*a32*a45*a54 - - a11*a26*a32*a45*a54 - - a12*a21*a36*a45*a54 - + a11*a22*a36*a45*a54 - + a15*a22*a31*a46*a54 - - a12*a25*a31*a46*a54 - - a15*a21*a32*a46*a54 - + a11*a25*a32*a46*a54 - + a12*a21*a35*a46*a54 - - a11*a22*a35*a46*a54 - + a16*a24*a32*a41*a55 - - a14*a26*a32*a41*a55 - - a16*a22*a34*a41*a55 - + a12*a26*a34*a41*a55 - + a14*a22*a36*a41*a55 - - a12*a24*a36*a41*a55 - - a16*a24*a31*a42*a55 - + a14*a26*a31*a42*a55 - + a16*a21*a34*a42*a55 - - a11*a26*a34*a42*a55 - - a14*a21*a36*a42*a55 - + a11*a24*a36*a42*a55 - + a16*a22*a31*a44*a55 - - a12*a26*a31*a44*a55 - - a16*a21*a32*a44*a55 - + a11*a26*a32*a44*a55 - + a12*a21*a36*a44*a55 - - a11*a22*a36*a44*a55 - - a14*a22*a31*a46*a55 - + a12*a24*a31*a46*a55 - + a14*a21*a32*a46*a55 - - a11*a24*a32*a46*a55 - - a12*a21*a34*a46*a55 - + a11*a22*a34*a46*a55 - - a15*a24*a32*a41*a56 - + a14*a25*a32*a41*a56 - + a15*a22*a34*a41*a56 - - a12*a25*a34*a41*a56 - - a14*a22*a35*a41*a56 - + a12*a24*a35*a41*a56 - + a15*a24*a31*a42*a56 - - a14*a25*a31*a42*a56 - - a15*a21*a34*a42*a56 - + a11*a25*a34*a42*a56 - + a14*a21*a35*a42*a56 - - a11*a24*a35*a42*a56 - - a15*a22*a31*a44*a56 - + a12*a25*a31*a44*a56 - + a15*a21*a32*a44*a56 - - a11*a25*a32*a44*a56 - - a12*a21*a35*a44*a56 - + a11*a22*a35*a44*a56 - + a14*a22*a31*a45*a56 - - a12*a24*a31*a45*a56 - - a14*a21*a32*a45*a56 - + a11*a24*a32*a45*a56 - + a12*a21*a34*a45*a56 - - a11*a22*a34*a45*a56; - cofactor[18] = -a26*a35*a43*a52*a61 - + a25*a36*a43*a52*a61 - + a26*a33*a45*a52*a61 - - a23*a36*a45*a52*a61 - - a25*a33*a46*a52*a61 - + a23*a35*a46*a52*a61 - + a26*a35*a42*a53*a61 - - a25*a36*a42*a53*a61 - - a26*a32*a45*a53*a61 - + a22*a36*a45*a53*a61 - + a25*a32*a46*a53*a61 - - a22*a35*a46*a53*a61 - - a26*a33*a42*a55*a61 - + a23*a36*a42*a55*a61 - + a26*a32*a43*a55*a61 - - a22*a36*a43*a55*a61 - - a23*a32*a46*a55*a61 - + a22*a33*a46*a55*a61 - + a25*a33*a42*a56*a61 - - a23*a35*a42*a56*a61 - - a25*a32*a43*a56*a61 - + a22*a35*a43*a56*a61 - + a23*a32*a45*a56*a61 - - a22*a33*a45*a56*a61 - + a26*a35*a43*a51*a62 - - a25*a36*a43*a51*a62 - - a26*a33*a45*a51*a62 - + a23*a36*a45*a51*a62 - + a25*a33*a46*a51*a62 - - a23*a35*a46*a51*a62 - - a26*a35*a41*a53*a62 - + a25*a36*a41*a53*a62 - + a26*a31*a45*a53*a62 - - a21*a36*a45*a53*a62 - - a25*a31*a46*a53*a62 - + a21*a35*a46*a53*a62 - + a26*a33*a41*a55*a62 - - a23*a36*a41*a55*a62 - - a26*a31*a43*a55*a62 - + a21*a36*a43*a55*a62 - + a23*a31*a46*a55*a62 - - a21*a33*a46*a55*a62 - - a25*a33*a41*a56*a62 - + a23*a35*a41*a56*a62 - + a25*a31*a43*a56*a62 - - a21*a35*a43*a56*a62 - - a23*a31*a45*a56*a62 - + a21*a33*a45*a56*a62 - - a26*a35*a42*a51*a63 - + a25*a36*a42*a51*a63 - + a26*a32*a45*a51*a63 - - a22*a36*a45*a51*a63 - - a25*a32*a46*a51*a63 - + a22*a35*a46*a51*a63 - + a26*a35*a41*a52*a63 - - a25*a36*a41*a52*a63 - - a26*a31*a45*a52*a63 - + a21*a36*a45*a52*a63 - + a25*a31*a46*a52*a63 - - a21*a35*a46*a52*a63 - - a26*a32*a41*a55*a63 - + a22*a36*a41*a55*a63 - + a26*a31*a42*a55*a63 - - a21*a36*a42*a55*a63 - - a22*a31*a46*a55*a63 - + a21*a32*a46*a55*a63 - + a25*a32*a41*a56*a63 - - a22*a35*a41*a56*a63 - - a25*a31*a42*a56*a63 - + a21*a35*a42*a56*a63 - + a22*a31*a45*a56*a63 - - a21*a32*a45*a56*a63 - + a26*a33*a42*a51*a65 - - a23*a36*a42*a51*a65 - - a26*a32*a43*a51*a65 - + a22*a36*a43*a51*a65 - + a23*a32*a46*a51*a65 - - a22*a33*a46*a51*a65 - - a26*a33*a41*a52*a65 - + a23*a36*a41*a52*a65 - + a26*a31*a43*a52*a65 - - a21*a36*a43*a52*a65 - - a23*a31*a46*a52*a65 - + a21*a33*a46*a52*a65 - + a26*a32*a41*a53*a65 - - a22*a36*a41*a53*a65 - - a26*a31*a42*a53*a65 - + a21*a36*a42*a53*a65 - + a22*a31*a46*a53*a65 - - a21*a32*a46*a53*a65 - - a23*a32*a41*a56*a65 - + a22*a33*a41*a56*a65 - + a23*a31*a42*a56*a65 - - a21*a33*a42*a56*a65 - - a22*a31*a43*a56*a65 - + a21*a32*a43*a56*a65 - - a25*a33*a42*a51*a66 - + a23*a35*a42*a51*a66 - + a25*a32*a43*a51*a66 - - a22*a35*a43*a51*a66 - - a23*a32*a45*a51*a66 - + a22*a33*a45*a51*a66 - + a25*a33*a41*a52*a66 - - a23*a35*a41*a52*a66 - - a25*a31*a43*a52*a66 - + a21*a35*a43*a52*a66 - + a23*a31*a45*a52*a66 - - a21*a33*a45*a52*a66 - - a25*a32*a41*a53*a66 - + a22*a35*a41*a53*a66 - + a25*a31*a42*a53*a66 - - a21*a35*a42*a53*a66 - - a22*a31*a45*a53*a66 - + a21*a32*a45*a53*a66 - + a23*a32*a41*a55*a66 - - a22*a33*a41*a55*a66 - - a23*a31*a42*a55*a66 - + a21*a33*a42*a55*a66 - + a22*a31*a43*a55*a66 - - a21*a32*a43*a55*a66; - cofactor[19] = a16*a35*a43*a52*a61 - - a15*a36*a43*a52*a61 - - a16*a33*a45*a52*a61 - + a13*a36*a45*a52*a61 - + a15*a33*a46*a52*a61 - - a13*a35*a46*a52*a61 - - a16*a35*a42*a53*a61 - + a15*a36*a42*a53*a61 - + a16*a32*a45*a53*a61 - - a12*a36*a45*a53*a61 - - a15*a32*a46*a53*a61 - + a12*a35*a46*a53*a61 - + a16*a33*a42*a55*a61 - - a13*a36*a42*a55*a61 - - a16*a32*a43*a55*a61 - + a12*a36*a43*a55*a61 - + a13*a32*a46*a55*a61 - - a12*a33*a46*a55*a61 - - a15*a33*a42*a56*a61 - + a13*a35*a42*a56*a61 - + a15*a32*a43*a56*a61 - - a12*a35*a43*a56*a61 - - a13*a32*a45*a56*a61 - + a12*a33*a45*a56*a61 - - a16*a35*a43*a51*a62 - + a15*a36*a43*a51*a62 - + a16*a33*a45*a51*a62 - - a13*a36*a45*a51*a62 - - a15*a33*a46*a51*a62 - + a13*a35*a46*a51*a62 - + a16*a35*a41*a53*a62 - - a15*a36*a41*a53*a62 - - a16*a31*a45*a53*a62 - + a11*a36*a45*a53*a62 - + a15*a31*a46*a53*a62 - - a11*a35*a46*a53*a62 - - a16*a33*a41*a55*a62 - + a13*a36*a41*a55*a62 - + a16*a31*a43*a55*a62 - - a11*a36*a43*a55*a62 - - a13*a31*a46*a55*a62 - + a11*a33*a46*a55*a62 - + a15*a33*a41*a56*a62 - - a13*a35*a41*a56*a62 - - a15*a31*a43*a56*a62 - + a11*a35*a43*a56*a62 - + a13*a31*a45*a56*a62 - - a11*a33*a45*a56*a62 - + a16*a35*a42*a51*a63 - - a15*a36*a42*a51*a63 - - a16*a32*a45*a51*a63 - + a12*a36*a45*a51*a63 - + a15*a32*a46*a51*a63 - - a12*a35*a46*a51*a63 - - a16*a35*a41*a52*a63 - + a15*a36*a41*a52*a63 - + a16*a31*a45*a52*a63 - - a11*a36*a45*a52*a63 - - a15*a31*a46*a52*a63 - + a11*a35*a46*a52*a63 - + a16*a32*a41*a55*a63 - - a12*a36*a41*a55*a63 - - a16*a31*a42*a55*a63 - + a11*a36*a42*a55*a63 - + a12*a31*a46*a55*a63 - - a11*a32*a46*a55*a63 - - a15*a32*a41*a56*a63 - + a12*a35*a41*a56*a63 - + a15*a31*a42*a56*a63 - - a11*a35*a42*a56*a63 - - a12*a31*a45*a56*a63 - + a11*a32*a45*a56*a63 - - a16*a33*a42*a51*a65 - + a13*a36*a42*a51*a65 - + a16*a32*a43*a51*a65 - - a12*a36*a43*a51*a65 - - a13*a32*a46*a51*a65 - + a12*a33*a46*a51*a65 - + a16*a33*a41*a52*a65 - - a13*a36*a41*a52*a65 - - a16*a31*a43*a52*a65 - + a11*a36*a43*a52*a65 - + a13*a31*a46*a52*a65 - - a11*a33*a46*a52*a65 - - a16*a32*a41*a53*a65 - + a12*a36*a41*a53*a65 - + a16*a31*a42*a53*a65 - - a11*a36*a42*a53*a65 - - a12*a31*a46*a53*a65 - + a11*a32*a46*a53*a65 - + a13*a32*a41*a56*a65 - - a12*a33*a41*a56*a65 - - a13*a31*a42*a56*a65 - + a11*a33*a42*a56*a65 - + a12*a31*a43*a56*a65 - - a11*a32*a43*a56*a65 - + a15*a33*a42*a51*a66 - - a13*a35*a42*a51*a66 - - a15*a32*a43*a51*a66 - + a12*a35*a43*a51*a66 - + a13*a32*a45*a51*a66 - - a12*a33*a45*a51*a66 - - a15*a33*a41*a52*a66 - + a13*a35*a41*a52*a66 - + a15*a31*a43*a52*a66 - - a11*a35*a43*a52*a66 - - a13*a31*a45*a52*a66 - + a11*a33*a45*a52*a66 - + a15*a32*a41*a53*a66 - - a12*a35*a41*a53*a66 - - a15*a31*a42*a53*a66 - + a11*a35*a42*a53*a66 - + a12*a31*a45*a53*a66 - - a11*a32*a45*a53*a66 - - a13*a32*a41*a55*a66 - + a12*a33*a41*a55*a66 - + a13*a31*a42*a55*a66 - - a11*a33*a42*a55*a66 - - a12*a31*a43*a55*a66 - + a11*a32*a43*a55*a66; - cofactor[20] = -a16*a25*a43*a52*a61 - + a15*a26*a43*a52*a61 - + a16*a23*a45*a52*a61 - - a13*a26*a45*a52*a61 - - a15*a23*a46*a52*a61 - + a13*a25*a46*a52*a61 - + a16*a25*a42*a53*a61 - - a15*a26*a42*a53*a61 - - a16*a22*a45*a53*a61 - + a12*a26*a45*a53*a61 - + a15*a22*a46*a53*a61 - - a12*a25*a46*a53*a61 - - a16*a23*a42*a55*a61 - + a13*a26*a42*a55*a61 - + a16*a22*a43*a55*a61 - - a12*a26*a43*a55*a61 - - a13*a22*a46*a55*a61 - + a12*a23*a46*a55*a61 - + a15*a23*a42*a56*a61 - - a13*a25*a42*a56*a61 - - a15*a22*a43*a56*a61 - + a12*a25*a43*a56*a61 - + a13*a22*a45*a56*a61 - - a12*a23*a45*a56*a61 - + a16*a25*a43*a51*a62 - - a15*a26*a43*a51*a62 - - a16*a23*a45*a51*a62 - + a13*a26*a45*a51*a62 - + a15*a23*a46*a51*a62 - - a13*a25*a46*a51*a62 - - a16*a25*a41*a53*a62 - + a15*a26*a41*a53*a62 - + a16*a21*a45*a53*a62 - - a11*a26*a45*a53*a62 - - a15*a21*a46*a53*a62 - + a11*a25*a46*a53*a62 - + a16*a23*a41*a55*a62 - - a13*a26*a41*a55*a62 - - a16*a21*a43*a55*a62 - + a11*a26*a43*a55*a62 - + a13*a21*a46*a55*a62 - - a11*a23*a46*a55*a62 - - a15*a23*a41*a56*a62 - + a13*a25*a41*a56*a62 - + a15*a21*a43*a56*a62 - - a11*a25*a43*a56*a62 - - a13*a21*a45*a56*a62 - + a11*a23*a45*a56*a62 - - a16*a25*a42*a51*a63 - + a15*a26*a42*a51*a63 - + a16*a22*a45*a51*a63 - - a12*a26*a45*a51*a63 - - a15*a22*a46*a51*a63 - + a12*a25*a46*a51*a63 - + a16*a25*a41*a52*a63 - - a15*a26*a41*a52*a63 - - a16*a21*a45*a52*a63 - + a11*a26*a45*a52*a63 - + a15*a21*a46*a52*a63 - - a11*a25*a46*a52*a63 - - a16*a22*a41*a55*a63 - + a12*a26*a41*a55*a63 - + a16*a21*a42*a55*a63 - - a11*a26*a42*a55*a63 - - a12*a21*a46*a55*a63 - + a11*a22*a46*a55*a63 - + a15*a22*a41*a56*a63 - - a12*a25*a41*a56*a63 - - a15*a21*a42*a56*a63 - + a11*a25*a42*a56*a63 - + a12*a21*a45*a56*a63 - - a11*a22*a45*a56*a63 - + a16*a23*a42*a51*a65 - - a13*a26*a42*a51*a65 - - a16*a22*a43*a51*a65 - + a12*a26*a43*a51*a65 - + a13*a22*a46*a51*a65 - - a12*a23*a46*a51*a65 - - a16*a23*a41*a52*a65 - + a13*a26*a41*a52*a65 - + a16*a21*a43*a52*a65 - - a11*a26*a43*a52*a65 - - a13*a21*a46*a52*a65 - + a11*a23*a46*a52*a65 - + a16*a22*a41*a53*a65 - - a12*a26*a41*a53*a65 - - a16*a21*a42*a53*a65 - + a11*a26*a42*a53*a65 - + a12*a21*a46*a53*a65 - - a11*a22*a46*a53*a65 - - a13*a22*a41*a56*a65 - + a12*a23*a41*a56*a65 - + a13*a21*a42*a56*a65 - - a11*a23*a42*a56*a65 - - a12*a21*a43*a56*a65 - + a11*a22*a43*a56*a65 - - a15*a23*a42*a51*a66 - + a13*a25*a42*a51*a66 - + a15*a22*a43*a51*a66 - - a12*a25*a43*a51*a66 - - a13*a22*a45*a51*a66 - + a12*a23*a45*a51*a66 - + a15*a23*a41*a52*a66 - - a13*a25*a41*a52*a66 - - a15*a21*a43*a52*a66 - + a11*a25*a43*a52*a66 - + a13*a21*a45*a52*a66 - - a11*a23*a45*a52*a66 - - a15*a22*a41*a53*a66 - + a12*a25*a41*a53*a66 - + a15*a21*a42*a53*a66 - - a11*a25*a42*a53*a66 - - a12*a21*a45*a53*a66 - + a11*a22*a45*a53*a66 - + a13*a22*a41*a55*a66 - - a12*a23*a41*a55*a66 - - a13*a21*a42*a55*a66 - + a11*a23*a42*a55*a66 - + a12*a21*a43*a55*a66 - - a11*a22*a43*a55*a66; - cofactor[21] = a16*a25*a33*a52*a61 - - a15*a26*a33*a52*a61 - - a16*a23*a35*a52*a61 - + a13*a26*a35*a52*a61 - + a15*a23*a36*a52*a61 - - a13*a25*a36*a52*a61 - - a16*a25*a32*a53*a61 - + a15*a26*a32*a53*a61 - + a16*a22*a35*a53*a61 - - a12*a26*a35*a53*a61 - - a15*a22*a36*a53*a61 - + a12*a25*a36*a53*a61 - + a16*a23*a32*a55*a61 - - a13*a26*a32*a55*a61 - - a16*a22*a33*a55*a61 - + a12*a26*a33*a55*a61 - + a13*a22*a36*a55*a61 - - a12*a23*a36*a55*a61 - - a15*a23*a32*a56*a61 - + a13*a25*a32*a56*a61 - + a15*a22*a33*a56*a61 - - a12*a25*a33*a56*a61 - - a13*a22*a35*a56*a61 - + a12*a23*a35*a56*a61 - - a16*a25*a33*a51*a62 - + a15*a26*a33*a51*a62 - + a16*a23*a35*a51*a62 - - a13*a26*a35*a51*a62 - - a15*a23*a36*a51*a62 - + a13*a25*a36*a51*a62 - + a16*a25*a31*a53*a62 - - a15*a26*a31*a53*a62 - - a16*a21*a35*a53*a62 - + a11*a26*a35*a53*a62 - + a15*a21*a36*a53*a62 - - a11*a25*a36*a53*a62 - - a16*a23*a31*a55*a62 - + a13*a26*a31*a55*a62 - + a16*a21*a33*a55*a62 - - a11*a26*a33*a55*a62 - - a13*a21*a36*a55*a62 - + a11*a23*a36*a55*a62 - + a15*a23*a31*a56*a62 - - a13*a25*a31*a56*a62 - - a15*a21*a33*a56*a62 - + a11*a25*a33*a56*a62 - + a13*a21*a35*a56*a62 - - a11*a23*a35*a56*a62 - + a16*a25*a32*a51*a63 - - a15*a26*a32*a51*a63 - - a16*a22*a35*a51*a63 - + a12*a26*a35*a51*a63 - + a15*a22*a36*a51*a63 - - a12*a25*a36*a51*a63 - - a16*a25*a31*a52*a63 - + a15*a26*a31*a52*a63 - + a16*a21*a35*a52*a63 - - a11*a26*a35*a52*a63 - - a15*a21*a36*a52*a63 - + a11*a25*a36*a52*a63 - + a16*a22*a31*a55*a63 - - a12*a26*a31*a55*a63 - - a16*a21*a32*a55*a63 - + a11*a26*a32*a55*a63 - + a12*a21*a36*a55*a63 - - a11*a22*a36*a55*a63 - - a15*a22*a31*a56*a63 - + a12*a25*a31*a56*a63 - + a15*a21*a32*a56*a63 - - a11*a25*a32*a56*a63 - - a12*a21*a35*a56*a63 - + a11*a22*a35*a56*a63 - - a16*a23*a32*a51*a65 - + a13*a26*a32*a51*a65 - + a16*a22*a33*a51*a65 - - a12*a26*a33*a51*a65 - - a13*a22*a36*a51*a65 - + a12*a23*a36*a51*a65 - + a16*a23*a31*a52*a65 - - a13*a26*a31*a52*a65 - - a16*a21*a33*a52*a65 - + a11*a26*a33*a52*a65 - + a13*a21*a36*a52*a65 - - a11*a23*a36*a52*a65 - - a16*a22*a31*a53*a65 - + a12*a26*a31*a53*a65 - + a16*a21*a32*a53*a65 - - a11*a26*a32*a53*a65 - - a12*a21*a36*a53*a65 - + a11*a22*a36*a53*a65 - + a13*a22*a31*a56*a65 - - a12*a23*a31*a56*a65 - - a13*a21*a32*a56*a65 - + a11*a23*a32*a56*a65 - + a12*a21*a33*a56*a65 - - a11*a22*a33*a56*a65 - + a15*a23*a32*a51*a66 - - a13*a25*a32*a51*a66 - - a15*a22*a33*a51*a66 - + a12*a25*a33*a51*a66 - + a13*a22*a35*a51*a66 - - a12*a23*a35*a51*a66 - - a15*a23*a31*a52*a66 - + a13*a25*a31*a52*a66 - + a15*a21*a33*a52*a66 - - a11*a25*a33*a52*a66 - - a13*a21*a35*a52*a66 - + a11*a23*a35*a52*a66 - + a15*a22*a31*a53*a66 - - a12*a25*a31*a53*a66 - - a15*a21*a32*a53*a66 - + a11*a25*a32*a53*a66 - + a12*a21*a35*a53*a66 - - a11*a22*a35*a53*a66 - - a13*a22*a31*a55*a66 - + a12*a23*a31*a55*a66 - + a13*a21*a32*a55*a66 - - a11*a23*a32*a55*a66 - - a12*a21*a33*a55*a66 - + a11*a22*a33*a55*a66; - cofactor[22] = -a16*a25*a33*a42*a61 - + a15*a26*a33*a42*a61 - + a16*a23*a35*a42*a61 - - a13*a26*a35*a42*a61 - - a15*a23*a36*a42*a61 - + a13*a25*a36*a42*a61 - + a16*a25*a32*a43*a61 - - a15*a26*a32*a43*a61 - - a16*a22*a35*a43*a61 - + a12*a26*a35*a43*a61 - + a15*a22*a36*a43*a61 - - a12*a25*a36*a43*a61 - - a16*a23*a32*a45*a61 - + a13*a26*a32*a45*a61 - + a16*a22*a33*a45*a61 - - a12*a26*a33*a45*a61 - - a13*a22*a36*a45*a61 - + a12*a23*a36*a45*a61 - + a15*a23*a32*a46*a61 - - a13*a25*a32*a46*a61 - - a15*a22*a33*a46*a61 - + a12*a25*a33*a46*a61 - + a13*a22*a35*a46*a61 - - a12*a23*a35*a46*a61 - + a16*a25*a33*a41*a62 - - a15*a26*a33*a41*a62 - - a16*a23*a35*a41*a62 - + a13*a26*a35*a41*a62 - + a15*a23*a36*a41*a62 - - a13*a25*a36*a41*a62 - - a16*a25*a31*a43*a62 - + a15*a26*a31*a43*a62 - + a16*a21*a35*a43*a62 - - a11*a26*a35*a43*a62 - - a15*a21*a36*a43*a62 - + a11*a25*a36*a43*a62 - + a16*a23*a31*a45*a62 - - a13*a26*a31*a45*a62 - - a16*a21*a33*a45*a62 - + a11*a26*a33*a45*a62 - + a13*a21*a36*a45*a62 - - a11*a23*a36*a45*a62 - - a15*a23*a31*a46*a62 - + a13*a25*a31*a46*a62 - + a15*a21*a33*a46*a62 - - a11*a25*a33*a46*a62 - - a13*a21*a35*a46*a62 - + a11*a23*a35*a46*a62 - - a16*a25*a32*a41*a63 - + a15*a26*a32*a41*a63 - + a16*a22*a35*a41*a63 - - a12*a26*a35*a41*a63 - - a15*a22*a36*a41*a63 - + a12*a25*a36*a41*a63 - + a16*a25*a31*a42*a63 - - a15*a26*a31*a42*a63 - - a16*a21*a35*a42*a63 - + a11*a26*a35*a42*a63 - + a15*a21*a36*a42*a63 - - a11*a25*a36*a42*a63 - - a16*a22*a31*a45*a63 - + a12*a26*a31*a45*a63 - + a16*a21*a32*a45*a63 - - a11*a26*a32*a45*a63 - - a12*a21*a36*a45*a63 - + a11*a22*a36*a45*a63 - + a15*a22*a31*a46*a63 - - a12*a25*a31*a46*a63 - - a15*a21*a32*a46*a63 - + a11*a25*a32*a46*a63 - + a12*a21*a35*a46*a63 - - a11*a22*a35*a46*a63 - + a16*a23*a32*a41*a65 - - a13*a26*a32*a41*a65 - - a16*a22*a33*a41*a65 - + a12*a26*a33*a41*a65 - + a13*a22*a36*a41*a65 - - a12*a23*a36*a41*a65 - - a16*a23*a31*a42*a65 - + a13*a26*a31*a42*a65 - + a16*a21*a33*a42*a65 - - a11*a26*a33*a42*a65 - - a13*a21*a36*a42*a65 - + a11*a23*a36*a42*a65 - + a16*a22*a31*a43*a65 - - a12*a26*a31*a43*a65 - - a16*a21*a32*a43*a65 - + a11*a26*a32*a43*a65 - + a12*a21*a36*a43*a65 - - a11*a22*a36*a43*a65 - - a13*a22*a31*a46*a65 - + a12*a23*a31*a46*a65 - + a13*a21*a32*a46*a65 - - a11*a23*a32*a46*a65 - - a12*a21*a33*a46*a65 - + a11*a22*a33*a46*a65 - - a15*a23*a32*a41*a66 - + a13*a25*a32*a41*a66 - + a15*a22*a33*a41*a66 - - a12*a25*a33*a41*a66 - - a13*a22*a35*a41*a66 - + a12*a23*a35*a41*a66 - + a15*a23*a31*a42*a66 - - a13*a25*a31*a42*a66 - - a15*a21*a33*a42*a66 - + a11*a25*a33*a42*a66 - + a13*a21*a35*a42*a66 - - a11*a23*a35*a42*a66 - - a15*a22*a31*a43*a66 - + a12*a25*a31*a43*a66 - + a15*a21*a32*a43*a66 - - a11*a25*a32*a43*a66 - - a12*a21*a35*a43*a66 - + a11*a22*a35*a43*a66 - + a13*a22*a31*a45*a66 - - a12*a23*a31*a45*a66 - - a13*a21*a32*a45*a66 - + a11*a23*a32*a45*a66 - + a12*a21*a33*a45*a66 - - a11*a22*a33*a45*a66; - cofactor[23] = a16*a25*a33*a42*a51 - - a15*a26*a33*a42*a51 - - a16*a23*a35*a42*a51 - + a13*a26*a35*a42*a51 - + a15*a23*a36*a42*a51 - - a13*a25*a36*a42*a51 - - a16*a25*a32*a43*a51 - + a15*a26*a32*a43*a51 - + a16*a22*a35*a43*a51 - - a12*a26*a35*a43*a51 - - a15*a22*a36*a43*a51 - + a12*a25*a36*a43*a51 - + a16*a23*a32*a45*a51 - - a13*a26*a32*a45*a51 - - a16*a22*a33*a45*a51 - + a12*a26*a33*a45*a51 - + a13*a22*a36*a45*a51 - - a12*a23*a36*a45*a51 - - a15*a23*a32*a46*a51 - + a13*a25*a32*a46*a51 - + a15*a22*a33*a46*a51 - - a12*a25*a33*a46*a51 - - a13*a22*a35*a46*a51 - + a12*a23*a35*a46*a51 - - a16*a25*a33*a41*a52 - + a15*a26*a33*a41*a52 - + a16*a23*a35*a41*a52 - - a13*a26*a35*a41*a52 - - a15*a23*a36*a41*a52 - + a13*a25*a36*a41*a52 - + a16*a25*a31*a43*a52 - - a15*a26*a31*a43*a52 - - a16*a21*a35*a43*a52 - + a11*a26*a35*a43*a52 - + a15*a21*a36*a43*a52 - - a11*a25*a36*a43*a52 - - a16*a23*a31*a45*a52 - + a13*a26*a31*a45*a52 - + a16*a21*a33*a45*a52 - - a11*a26*a33*a45*a52 - - a13*a21*a36*a45*a52 - + a11*a23*a36*a45*a52 - + a15*a23*a31*a46*a52 - - a13*a25*a31*a46*a52 - - a15*a21*a33*a46*a52 - + a11*a25*a33*a46*a52 - + a13*a21*a35*a46*a52 - - a11*a23*a35*a46*a52 - + a16*a25*a32*a41*a53 - - a15*a26*a32*a41*a53 - - a16*a22*a35*a41*a53 - + a12*a26*a35*a41*a53 - + a15*a22*a36*a41*a53 - - a12*a25*a36*a41*a53 - - a16*a25*a31*a42*a53 - + a15*a26*a31*a42*a53 - + a16*a21*a35*a42*a53 - - a11*a26*a35*a42*a53 - - a15*a21*a36*a42*a53 - + a11*a25*a36*a42*a53 - + a16*a22*a31*a45*a53 - - a12*a26*a31*a45*a53 - - a16*a21*a32*a45*a53 - + a11*a26*a32*a45*a53 - + a12*a21*a36*a45*a53 - - a11*a22*a36*a45*a53 - - a15*a22*a31*a46*a53 - + a12*a25*a31*a46*a53 - + a15*a21*a32*a46*a53 - - a11*a25*a32*a46*a53 - - a12*a21*a35*a46*a53 - + a11*a22*a35*a46*a53 - - a16*a23*a32*a41*a55 - + a13*a26*a32*a41*a55 - + a16*a22*a33*a41*a55 - - a12*a26*a33*a41*a55 - - a13*a22*a36*a41*a55 - + a12*a23*a36*a41*a55 - + a16*a23*a31*a42*a55 - - a13*a26*a31*a42*a55 - - a16*a21*a33*a42*a55 - + a11*a26*a33*a42*a55 - + a13*a21*a36*a42*a55 - - a11*a23*a36*a42*a55 - - a16*a22*a31*a43*a55 - + a12*a26*a31*a43*a55 - + a16*a21*a32*a43*a55 - - a11*a26*a32*a43*a55 - - a12*a21*a36*a43*a55 - + a11*a22*a36*a43*a55 - + a13*a22*a31*a46*a55 - - a12*a23*a31*a46*a55 - - a13*a21*a32*a46*a55 - + a11*a23*a32*a46*a55 - + a12*a21*a33*a46*a55 - - a11*a22*a33*a46*a55 - + a15*a23*a32*a41*a56 - - a13*a25*a32*a41*a56 - - a15*a22*a33*a41*a56 - + a12*a25*a33*a41*a56 - + a13*a22*a35*a41*a56 - - a12*a23*a35*a41*a56 - - a15*a23*a31*a42*a56 - + a13*a25*a31*a42*a56 - + a15*a21*a33*a42*a56 - - a11*a25*a33*a42*a56 - - a13*a21*a35*a42*a56 - + a11*a23*a35*a42*a56 - + a15*a22*a31*a43*a56 - - a12*a25*a31*a43*a56 - - a15*a21*a32*a43*a56 - + a11*a25*a32*a43*a56 - + a12*a21*a35*a43*a56 - - a11*a22*a35*a43*a56 - - a13*a22*a31*a45*a56 - + a12*a23*a31*a45*a56 - + a13*a21*a32*a45*a56 - - a11*a23*a32*a45*a56 - - a12*a21*a33*a45*a56 - + a11*a22*a33*a45*a56; - cofactor[24] = a26*a34*a43*a52*a61 - - a24*a36*a43*a52*a61 - - a26*a33*a44*a52*a61 - + a23*a36*a44*a52*a61 - + a24*a33*a46*a52*a61 - - a23*a34*a46*a52*a61 - - a26*a34*a42*a53*a61 - + a24*a36*a42*a53*a61 - + a26*a32*a44*a53*a61 - - a22*a36*a44*a53*a61 - - a24*a32*a46*a53*a61 - + a22*a34*a46*a53*a61 - + a26*a33*a42*a54*a61 - - a23*a36*a42*a54*a61 - - a26*a32*a43*a54*a61 - + a22*a36*a43*a54*a61 - + a23*a32*a46*a54*a61 - - a22*a33*a46*a54*a61 - - a24*a33*a42*a56*a61 - + a23*a34*a42*a56*a61 - + a24*a32*a43*a56*a61 - - a22*a34*a43*a56*a61 - - a23*a32*a44*a56*a61 - + a22*a33*a44*a56*a61 - - a26*a34*a43*a51*a62 - + a24*a36*a43*a51*a62 - + a26*a33*a44*a51*a62 - - a23*a36*a44*a51*a62 - - a24*a33*a46*a51*a62 - + a23*a34*a46*a51*a62 - + a26*a34*a41*a53*a62 - - a24*a36*a41*a53*a62 - - a26*a31*a44*a53*a62 - + a21*a36*a44*a53*a62 - + a24*a31*a46*a53*a62 - - a21*a34*a46*a53*a62 - - a26*a33*a41*a54*a62 - + a23*a36*a41*a54*a62 - + a26*a31*a43*a54*a62 - - a21*a36*a43*a54*a62 - - a23*a31*a46*a54*a62 - + a21*a33*a46*a54*a62 - + a24*a33*a41*a56*a62 - - a23*a34*a41*a56*a62 - - a24*a31*a43*a56*a62 - + a21*a34*a43*a56*a62 - + a23*a31*a44*a56*a62 - - a21*a33*a44*a56*a62 - + a26*a34*a42*a51*a63 - - a24*a36*a42*a51*a63 - - a26*a32*a44*a51*a63 - + a22*a36*a44*a51*a63 - + a24*a32*a46*a51*a63 - - a22*a34*a46*a51*a63 - - a26*a34*a41*a52*a63 - + a24*a36*a41*a52*a63 - + a26*a31*a44*a52*a63 - - a21*a36*a44*a52*a63 - - a24*a31*a46*a52*a63 - + a21*a34*a46*a52*a63 - + a26*a32*a41*a54*a63 - - a22*a36*a41*a54*a63 - - a26*a31*a42*a54*a63 - + a21*a36*a42*a54*a63 - + a22*a31*a46*a54*a63 - - a21*a32*a46*a54*a63 - - a24*a32*a41*a56*a63 - + a22*a34*a41*a56*a63 - + a24*a31*a42*a56*a63 - - a21*a34*a42*a56*a63 - - a22*a31*a44*a56*a63 - + a21*a32*a44*a56*a63 - - a26*a33*a42*a51*a64 - + a23*a36*a42*a51*a64 - + a26*a32*a43*a51*a64 - - a22*a36*a43*a51*a64 - - a23*a32*a46*a51*a64 - + a22*a33*a46*a51*a64 - + a26*a33*a41*a52*a64 - - a23*a36*a41*a52*a64 - - a26*a31*a43*a52*a64 - + a21*a36*a43*a52*a64 - + a23*a31*a46*a52*a64 - - a21*a33*a46*a52*a64 - - a26*a32*a41*a53*a64 - + a22*a36*a41*a53*a64 - + a26*a31*a42*a53*a64 - - a21*a36*a42*a53*a64 - - a22*a31*a46*a53*a64 - + a21*a32*a46*a53*a64 - + a23*a32*a41*a56*a64 - - a22*a33*a41*a56*a64 - - a23*a31*a42*a56*a64 - + a21*a33*a42*a56*a64 - + a22*a31*a43*a56*a64 - - a21*a32*a43*a56*a64 - + a24*a33*a42*a51*a66 - - a23*a34*a42*a51*a66 - - a24*a32*a43*a51*a66 - + a22*a34*a43*a51*a66 - + a23*a32*a44*a51*a66 - - a22*a33*a44*a51*a66 - - a24*a33*a41*a52*a66 - + a23*a34*a41*a52*a66 - + a24*a31*a43*a52*a66 - - a21*a34*a43*a52*a66 - - a23*a31*a44*a52*a66 - + a21*a33*a44*a52*a66 - + a24*a32*a41*a53*a66 - - a22*a34*a41*a53*a66 - - a24*a31*a42*a53*a66 - + a21*a34*a42*a53*a66 - + a22*a31*a44*a53*a66 - - a21*a32*a44*a53*a66 - - a23*a32*a41*a54*a66 - + a22*a33*a41*a54*a66 - + a23*a31*a42*a54*a66 - - a21*a33*a42*a54*a66 - - a22*a31*a43*a54*a66 - + a21*a32*a43*a54*a66; - cofactor[25] = -a16*a34*a43*a52*a61 - + a14*a36*a43*a52*a61 - + a16*a33*a44*a52*a61 - - a13*a36*a44*a52*a61 - - a14*a33*a46*a52*a61 - + a13*a34*a46*a52*a61 - + a16*a34*a42*a53*a61 - - a14*a36*a42*a53*a61 - - a16*a32*a44*a53*a61 - + a12*a36*a44*a53*a61 - + a14*a32*a46*a53*a61 - - a12*a34*a46*a53*a61 - - a16*a33*a42*a54*a61 - + a13*a36*a42*a54*a61 - + a16*a32*a43*a54*a61 - - a12*a36*a43*a54*a61 - - a13*a32*a46*a54*a61 - + a12*a33*a46*a54*a61 - + a14*a33*a42*a56*a61 - - a13*a34*a42*a56*a61 - - a14*a32*a43*a56*a61 - + a12*a34*a43*a56*a61 - + a13*a32*a44*a56*a61 - - a12*a33*a44*a56*a61 - + a16*a34*a43*a51*a62 - - a14*a36*a43*a51*a62 - - a16*a33*a44*a51*a62 - + a13*a36*a44*a51*a62 - + a14*a33*a46*a51*a62 - - a13*a34*a46*a51*a62 - - a16*a34*a41*a53*a62 - + a14*a36*a41*a53*a62 - + a16*a31*a44*a53*a62 - - a11*a36*a44*a53*a62 - - a14*a31*a46*a53*a62 - + a11*a34*a46*a53*a62 - + a16*a33*a41*a54*a62 - - a13*a36*a41*a54*a62 - - a16*a31*a43*a54*a62 - + a11*a36*a43*a54*a62 - + a13*a31*a46*a54*a62 - - a11*a33*a46*a54*a62 - - a14*a33*a41*a56*a62 - + a13*a34*a41*a56*a62 - + a14*a31*a43*a56*a62 - - a11*a34*a43*a56*a62 - - a13*a31*a44*a56*a62 - + a11*a33*a44*a56*a62 - - a16*a34*a42*a51*a63 - + a14*a36*a42*a51*a63 - + a16*a32*a44*a51*a63 - - a12*a36*a44*a51*a63 - - a14*a32*a46*a51*a63 - + a12*a34*a46*a51*a63 - + a16*a34*a41*a52*a63 - - a14*a36*a41*a52*a63 - - a16*a31*a44*a52*a63 - + a11*a36*a44*a52*a63 - + a14*a31*a46*a52*a63 - - a11*a34*a46*a52*a63 - - a16*a32*a41*a54*a63 - + a12*a36*a41*a54*a63 - + a16*a31*a42*a54*a63 - - a11*a36*a42*a54*a63 - - a12*a31*a46*a54*a63 - + a11*a32*a46*a54*a63 - + a14*a32*a41*a56*a63 - - a12*a34*a41*a56*a63 - - a14*a31*a42*a56*a63 - + a11*a34*a42*a56*a63 - + a12*a31*a44*a56*a63 - - a11*a32*a44*a56*a63 - + a16*a33*a42*a51*a64 - - a13*a36*a42*a51*a64 - - a16*a32*a43*a51*a64 - + a12*a36*a43*a51*a64 - + a13*a32*a46*a51*a64 - - a12*a33*a46*a51*a64 - - a16*a33*a41*a52*a64 - + a13*a36*a41*a52*a64 - + a16*a31*a43*a52*a64 - - a11*a36*a43*a52*a64 - - a13*a31*a46*a52*a64 - + a11*a33*a46*a52*a64 - + a16*a32*a41*a53*a64 - - a12*a36*a41*a53*a64 - - a16*a31*a42*a53*a64 - + a11*a36*a42*a53*a64 - + a12*a31*a46*a53*a64 - - a11*a32*a46*a53*a64 - - a13*a32*a41*a56*a64 - + a12*a33*a41*a56*a64 - + a13*a31*a42*a56*a64 - - a11*a33*a42*a56*a64 - - a12*a31*a43*a56*a64 - + a11*a32*a43*a56*a64 - - a14*a33*a42*a51*a66 - + a13*a34*a42*a51*a66 - + a14*a32*a43*a51*a66 - - a12*a34*a43*a51*a66 - - a13*a32*a44*a51*a66 - + a12*a33*a44*a51*a66 - + a14*a33*a41*a52*a66 - - a13*a34*a41*a52*a66 - - a14*a31*a43*a52*a66 - + a11*a34*a43*a52*a66 - + a13*a31*a44*a52*a66 - - a11*a33*a44*a52*a66 - - a14*a32*a41*a53*a66 - + a12*a34*a41*a53*a66 - + a14*a31*a42*a53*a66 - - a11*a34*a42*a53*a66 - - a12*a31*a44*a53*a66 - + a11*a32*a44*a53*a66 - + a13*a32*a41*a54*a66 - - a12*a33*a41*a54*a66 - - a13*a31*a42*a54*a66 - + a11*a33*a42*a54*a66 - + a12*a31*a43*a54*a66 - - a11*a32*a43*a54*a66; - cofactor[26] = a16*a24*a43*a52*a61 - - a14*a26*a43*a52*a61 - - a16*a23*a44*a52*a61 - + a13*a26*a44*a52*a61 - + a14*a23*a46*a52*a61 - - a13*a24*a46*a52*a61 - - a16*a24*a42*a53*a61 - + a14*a26*a42*a53*a61 - + a16*a22*a44*a53*a61 - - a12*a26*a44*a53*a61 - - a14*a22*a46*a53*a61 - + a12*a24*a46*a53*a61 - + a16*a23*a42*a54*a61 - - a13*a26*a42*a54*a61 - - a16*a22*a43*a54*a61 - + a12*a26*a43*a54*a61 - + a13*a22*a46*a54*a61 - - a12*a23*a46*a54*a61 - - a14*a23*a42*a56*a61 - + a13*a24*a42*a56*a61 - + a14*a22*a43*a56*a61 - - a12*a24*a43*a56*a61 - - a13*a22*a44*a56*a61 - + a12*a23*a44*a56*a61 - - a16*a24*a43*a51*a62 - + a14*a26*a43*a51*a62 - + a16*a23*a44*a51*a62 - - a13*a26*a44*a51*a62 - - a14*a23*a46*a51*a62 - + a13*a24*a46*a51*a62 - + a16*a24*a41*a53*a62 - - a14*a26*a41*a53*a62 - - a16*a21*a44*a53*a62 - + a11*a26*a44*a53*a62 - + a14*a21*a46*a53*a62 - - a11*a24*a46*a53*a62 - - a16*a23*a41*a54*a62 - + a13*a26*a41*a54*a62 - + a16*a21*a43*a54*a62 - - a11*a26*a43*a54*a62 - - a13*a21*a46*a54*a62 - + a11*a23*a46*a54*a62 - + a14*a23*a41*a56*a62 - - a13*a24*a41*a56*a62 - - a14*a21*a43*a56*a62 - + a11*a24*a43*a56*a62 - + a13*a21*a44*a56*a62 - - a11*a23*a44*a56*a62 - + a16*a24*a42*a51*a63 - - a14*a26*a42*a51*a63 - - a16*a22*a44*a51*a63 - + a12*a26*a44*a51*a63 - + a14*a22*a46*a51*a63 - - a12*a24*a46*a51*a63 - - a16*a24*a41*a52*a63 - + a14*a26*a41*a52*a63 - + a16*a21*a44*a52*a63 - - a11*a26*a44*a52*a63 - - a14*a21*a46*a52*a63 - + a11*a24*a46*a52*a63 - + a16*a22*a41*a54*a63 - - a12*a26*a41*a54*a63 - - a16*a21*a42*a54*a63 - + a11*a26*a42*a54*a63 - + a12*a21*a46*a54*a63 - - a11*a22*a46*a54*a63 - - a14*a22*a41*a56*a63 - + a12*a24*a41*a56*a63 - + a14*a21*a42*a56*a63 - - a11*a24*a42*a56*a63 - - a12*a21*a44*a56*a63 - + a11*a22*a44*a56*a63 - - a16*a23*a42*a51*a64 - + a13*a26*a42*a51*a64 - + a16*a22*a43*a51*a64 - - a12*a26*a43*a51*a64 - - a13*a22*a46*a51*a64 - + a12*a23*a46*a51*a64 - + a16*a23*a41*a52*a64 - - a13*a26*a41*a52*a64 - - a16*a21*a43*a52*a64 - + a11*a26*a43*a52*a64 - + a13*a21*a46*a52*a64 - - a11*a23*a46*a52*a64 - - a16*a22*a41*a53*a64 - + a12*a26*a41*a53*a64 - + a16*a21*a42*a53*a64 - - a11*a26*a42*a53*a64 - - a12*a21*a46*a53*a64 - + a11*a22*a46*a53*a64 - + a13*a22*a41*a56*a64 - - a12*a23*a41*a56*a64 - - a13*a21*a42*a56*a64 - + a11*a23*a42*a56*a64 - + a12*a21*a43*a56*a64 - - a11*a22*a43*a56*a64 - + a14*a23*a42*a51*a66 - - a13*a24*a42*a51*a66 - - a14*a22*a43*a51*a66 - + a12*a24*a43*a51*a66 - + a13*a22*a44*a51*a66 - - a12*a23*a44*a51*a66 - - a14*a23*a41*a52*a66 - + a13*a24*a41*a52*a66 - + a14*a21*a43*a52*a66 - - a11*a24*a43*a52*a66 - - a13*a21*a44*a52*a66 - + a11*a23*a44*a52*a66 - + a14*a22*a41*a53*a66 - - a12*a24*a41*a53*a66 - - a14*a21*a42*a53*a66 - + a11*a24*a42*a53*a66 - + a12*a21*a44*a53*a66 - - a11*a22*a44*a53*a66 - - a13*a22*a41*a54*a66 - + a12*a23*a41*a54*a66 - + a13*a21*a42*a54*a66 - - a11*a23*a42*a54*a66 - - a12*a21*a43*a54*a66 - + a11*a22*a43*a54*a66; - cofactor[27] = -a16*a24*a33*a52*a61 - + a14*a26*a33*a52*a61 - + a16*a23*a34*a52*a61 - - a13*a26*a34*a52*a61 - - a14*a23*a36*a52*a61 - + a13*a24*a36*a52*a61 - + a16*a24*a32*a53*a61 - - a14*a26*a32*a53*a61 - - a16*a22*a34*a53*a61 - + a12*a26*a34*a53*a61 - + a14*a22*a36*a53*a61 - - a12*a24*a36*a53*a61 - - a16*a23*a32*a54*a61 - + a13*a26*a32*a54*a61 - + a16*a22*a33*a54*a61 - - a12*a26*a33*a54*a61 - - a13*a22*a36*a54*a61 - + a12*a23*a36*a54*a61 - + a14*a23*a32*a56*a61 - - a13*a24*a32*a56*a61 - - a14*a22*a33*a56*a61 - + a12*a24*a33*a56*a61 - + a13*a22*a34*a56*a61 - - a12*a23*a34*a56*a61 - + a16*a24*a33*a51*a62 - - a14*a26*a33*a51*a62 - - a16*a23*a34*a51*a62 - + a13*a26*a34*a51*a62 - + a14*a23*a36*a51*a62 - - a13*a24*a36*a51*a62 - - a16*a24*a31*a53*a62 - + a14*a26*a31*a53*a62 - + a16*a21*a34*a53*a62 - - a11*a26*a34*a53*a62 - - a14*a21*a36*a53*a62 - + a11*a24*a36*a53*a62 - + a16*a23*a31*a54*a62 - - a13*a26*a31*a54*a62 - - a16*a21*a33*a54*a62 - + a11*a26*a33*a54*a62 - + a13*a21*a36*a54*a62 - - a11*a23*a36*a54*a62 - - a14*a23*a31*a56*a62 - + a13*a24*a31*a56*a62 - + a14*a21*a33*a56*a62 - - a11*a24*a33*a56*a62 - - a13*a21*a34*a56*a62 - + a11*a23*a34*a56*a62 - - a16*a24*a32*a51*a63 - + a14*a26*a32*a51*a63 - + a16*a22*a34*a51*a63 - - a12*a26*a34*a51*a63 - - a14*a22*a36*a51*a63 - + a12*a24*a36*a51*a63 - + a16*a24*a31*a52*a63 - - a14*a26*a31*a52*a63 - - a16*a21*a34*a52*a63 - + a11*a26*a34*a52*a63 - + a14*a21*a36*a52*a63 - - a11*a24*a36*a52*a63 - - a16*a22*a31*a54*a63 - + a12*a26*a31*a54*a63 - + a16*a21*a32*a54*a63 - - a11*a26*a32*a54*a63 - - a12*a21*a36*a54*a63 - + a11*a22*a36*a54*a63 - + a14*a22*a31*a56*a63 - - a12*a24*a31*a56*a63 - - a14*a21*a32*a56*a63 - + a11*a24*a32*a56*a63 - + a12*a21*a34*a56*a63 - - a11*a22*a34*a56*a63 - + a16*a23*a32*a51*a64 - - a13*a26*a32*a51*a64 - - a16*a22*a33*a51*a64 - + a12*a26*a33*a51*a64 - + a13*a22*a36*a51*a64 - - a12*a23*a36*a51*a64 - - a16*a23*a31*a52*a64 - + a13*a26*a31*a52*a64 - + a16*a21*a33*a52*a64 - - a11*a26*a33*a52*a64 - - a13*a21*a36*a52*a64 - + a11*a23*a36*a52*a64 - + a16*a22*a31*a53*a64 - - a12*a26*a31*a53*a64 - - a16*a21*a32*a53*a64 - + a11*a26*a32*a53*a64 - + a12*a21*a36*a53*a64 - - a11*a22*a36*a53*a64 - - a13*a22*a31*a56*a64 - + a12*a23*a31*a56*a64 - + a13*a21*a32*a56*a64 - - a11*a23*a32*a56*a64 - - a12*a21*a33*a56*a64 - + a11*a22*a33*a56*a64 - - a14*a23*a32*a51*a66 - + a13*a24*a32*a51*a66 - + a14*a22*a33*a51*a66 - - a12*a24*a33*a51*a66 - - a13*a22*a34*a51*a66 - + a12*a23*a34*a51*a66 - + a14*a23*a31*a52*a66 - - a13*a24*a31*a52*a66 - - a14*a21*a33*a52*a66 - + a11*a24*a33*a52*a66 - + a13*a21*a34*a52*a66 - - a11*a23*a34*a52*a66 - - a14*a22*a31*a53*a66 - + a12*a24*a31*a53*a66 - + a14*a21*a32*a53*a66 - - a11*a24*a32*a53*a66 - - a12*a21*a34*a53*a66 - + a11*a22*a34*a53*a66 - + a13*a22*a31*a54*a66 - - a12*a23*a31*a54*a66 - - a13*a21*a32*a54*a66 - + a11*a23*a32*a54*a66 - + a12*a21*a33*a54*a66 - - a11*a22*a33*a54*a66; - cofactor[28] = a16*a24*a33*a42*a61 - - a14*a26*a33*a42*a61 - - a16*a23*a34*a42*a61 - + a13*a26*a34*a42*a61 - + a14*a23*a36*a42*a61 - - a13*a24*a36*a42*a61 - - a16*a24*a32*a43*a61 - + a14*a26*a32*a43*a61 - + a16*a22*a34*a43*a61 - - a12*a26*a34*a43*a61 - - a14*a22*a36*a43*a61 - + a12*a24*a36*a43*a61 - + a16*a23*a32*a44*a61 - - a13*a26*a32*a44*a61 - - a16*a22*a33*a44*a61 - + a12*a26*a33*a44*a61 - + a13*a22*a36*a44*a61 - - a12*a23*a36*a44*a61 - - a14*a23*a32*a46*a61 - + a13*a24*a32*a46*a61 - + a14*a22*a33*a46*a61 - - a12*a24*a33*a46*a61 - - a13*a22*a34*a46*a61 - + a12*a23*a34*a46*a61 - - a16*a24*a33*a41*a62 - + a14*a26*a33*a41*a62 - + a16*a23*a34*a41*a62 - - a13*a26*a34*a41*a62 - - a14*a23*a36*a41*a62 - + a13*a24*a36*a41*a62 - + a16*a24*a31*a43*a62 - - a14*a26*a31*a43*a62 - - a16*a21*a34*a43*a62 - + a11*a26*a34*a43*a62 - + a14*a21*a36*a43*a62 - - a11*a24*a36*a43*a62 - - a16*a23*a31*a44*a62 - + a13*a26*a31*a44*a62 - + a16*a21*a33*a44*a62 - - a11*a26*a33*a44*a62 - - a13*a21*a36*a44*a62 - + a11*a23*a36*a44*a62 - + a14*a23*a31*a46*a62 - - a13*a24*a31*a46*a62 - - a14*a21*a33*a46*a62 - + a11*a24*a33*a46*a62 - + a13*a21*a34*a46*a62 - - a11*a23*a34*a46*a62 - + a16*a24*a32*a41*a63 - - a14*a26*a32*a41*a63 - - a16*a22*a34*a41*a63 - + a12*a26*a34*a41*a63 - + a14*a22*a36*a41*a63 - - a12*a24*a36*a41*a63 - - a16*a24*a31*a42*a63 - + a14*a26*a31*a42*a63 - + a16*a21*a34*a42*a63 - - a11*a26*a34*a42*a63 - - a14*a21*a36*a42*a63 - + a11*a24*a36*a42*a63 - + a16*a22*a31*a44*a63 - - a12*a26*a31*a44*a63 - - a16*a21*a32*a44*a63 - + a11*a26*a32*a44*a63 - + a12*a21*a36*a44*a63 - - a11*a22*a36*a44*a63 - - a14*a22*a31*a46*a63 - + a12*a24*a31*a46*a63 - + a14*a21*a32*a46*a63 - - a11*a24*a32*a46*a63 - - a12*a21*a34*a46*a63 - + a11*a22*a34*a46*a63 - - a16*a23*a32*a41*a64 - + a13*a26*a32*a41*a64 - + a16*a22*a33*a41*a64 - - a12*a26*a33*a41*a64 - - a13*a22*a36*a41*a64 - + a12*a23*a36*a41*a64 - + a16*a23*a31*a42*a64 - - a13*a26*a31*a42*a64 - - a16*a21*a33*a42*a64 - + a11*a26*a33*a42*a64 - + a13*a21*a36*a42*a64 - - a11*a23*a36*a42*a64 - - a16*a22*a31*a43*a64 - + a12*a26*a31*a43*a64 - + a16*a21*a32*a43*a64 - - a11*a26*a32*a43*a64 - - a12*a21*a36*a43*a64 - + a11*a22*a36*a43*a64 - + a13*a22*a31*a46*a64 - - a12*a23*a31*a46*a64 - - a13*a21*a32*a46*a64 - + a11*a23*a32*a46*a64 - + a12*a21*a33*a46*a64 - - a11*a22*a33*a46*a64 - + a14*a23*a32*a41*a66 - - a13*a24*a32*a41*a66 - - a14*a22*a33*a41*a66 - + a12*a24*a33*a41*a66 - + a13*a22*a34*a41*a66 - - a12*a23*a34*a41*a66 - - a14*a23*a31*a42*a66 - + a13*a24*a31*a42*a66 - + a14*a21*a33*a42*a66 - - a11*a24*a33*a42*a66 - - a13*a21*a34*a42*a66 - + a11*a23*a34*a42*a66 - + a14*a22*a31*a43*a66 - - a12*a24*a31*a43*a66 - - a14*a21*a32*a43*a66 - + a11*a24*a32*a43*a66 - + a12*a21*a34*a43*a66 - - a11*a22*a34*a43*a66 - - a13*a22*a31*a44*a66 - + a12*a23*a31*a44*a66 - + a13*a21*a32*a44*a66 - - a11*a23*a32*a44*a66 - - a12*a21*a33*a44*a66 - + a11*a22*a33*a44*a66; - cofactor[29] = -a16*a24*a33*a42*a51 - + a14*a26*a33*a42*a51 - + a16*a23*a34*a42*a51 - - a13*a26*a34*a42*a51 - - a14*a23*a36*a42*a51 - + a13*a24*a36*a42*a51 - + a16*a24*a32*a43*a51 - - a14*a26*a32*a43*a51 - - a16*a22*a34*a43*a51 - + a12*a26*a34*a43*a51 - + a14*a22*a36*a43*a51 - - a12*a24*a36*a43*a51 - - a16*a23*a32*a44*a51 - + a13*a26*a32*a44*a51 - + a16*a22*a33*a44*a51 - - a12*a26*a33*a44*a51 - - a13*a22*a36*a44*a51 - + a12*a23*a36*a44*a51 - + a14*a23*a32*a46*a51 - - a13*a24*a32*a46*a51 - - a14*a22*a33*a46*a51 - + a12*a24*a33*a46*a51 - + a13*a22*a34*a46*a51 - - a12*a23*a34*a46*a51 - + a16*a24*a33*a41*a52 - - a14*a26*a33*a41*a52 - - a16*a23*a34*a41*a52 - + a13*a26*a34*a41*a52 - + a14*a23*a36*a41*a52 - - a13*a24*a36*a41*a52 - - a16*a24*a31*a43*a52 - + a14*a26*a31*a43*a52 - + a16*a21*a34*a43*a52 - - a11*a26*a34*a43*a52 - - a14*a21*a36*a43*a52 - + a11*a24*a36*a43*a52 - + a16*a23*a31*a44*a52 - - a13*a26*a31*a44*a52 - - a16*a21*a33*a44*a52 - + a11*a26*a33*a44*a52 - + a13*a21*a36*a44*a52 - - a11*a23*a36*a44*a52 - - a14*a23*a31*a46*a52 - + a13*a24*a31*a46*a52 - + a14*a21*a33*a46*a52 - - a11*a24*a33*a46*a52 - - a13*a21*a34*a46*a52 - + a11*a23*a34*a46*a52 - - a16*a24*a32*a41*a53 - + a14*a26*a32*a41*a53 - + a16*a22*a34*a41*a53 - - a12*a26*a34*a41*a53 - - a14*a22*a36*a41*a53 - + a12*a24*a36*a41*a53 - + a16*a24*a31*a42*a53 - - a14*a26*a31*a42*a53 - - a16*a21*a34*a42*a53 - + a11*a26*a34*a42*a53 - + a14*a21*a36*a42*a53 - - a11*a24*a36*a42*a53 - - a16*a22*a31*a44*a53 - + a12*a26*a31*a44*a53 - + a16*a21*a32*a44*a53 - - a11*a26*a32*a44*a53 - - a12*a21*a36*a44*a53 - + a11*a22*a36*a44*a53 - + a14*a22*a31*a46*a53 - - a12*a24*a31*a46*a53 - - a14*a21*a32*a46*a53 - + a11*a24*a32*a46*a53 - + a12*a21*a34*a46*a53 - - a11*a22*a34*a46*a53 - + a16*a23*a32*a41*a54 - - a13*a26*a32*a41*a54 - - a16*a22*a33*a41*a54 - + a12*a26*a33*a41*a54 - + a13*a22*a36*a41*a54 - - a12*a23*a36*a41*a54 - - a16*a23*a31*a42*a54 - + a13*a26*a31*a42*a54 - + a16*a21*a33*a42*a54 - - a11*a26*a33*a42*a54 - - a13*a21*a36*a42*a54 - + a11*a23*a36*a42*a54 - + a16*a22*a31*a43*a54 - - a12*a26*a31*a43*a54 - - a16*a21*a32*a43*a54 - + a11*a26*a32*a43*a54 - + a12*a21*a36*a43*a54 - - a11*a22*a36*a43*a54 - - a13*a22*a31*a46*a54 - + a12*a23*a31*a46*a54 - + a13*a21*a32*a46*a54 - - a11*a23*a32*a46*a54 - - a12*a21*a33*a46*a54 - + a11*a22*a33*a46*a54 - - a14*a23*a32*a41*a56 - + a13*a24*a32*a41*a56 - + a14*a22*a33*a41*a56 - - a12*a24*a33*a41*a56 - - a13*a22*a34*a41*a56 - + a12*a23*a34*a41*a56 - + a14*a23*a31*a42*a56 - - a13*a24*a31*a42*a56 - - a14*a21*a33*a42*a56 - + a11*a24*a33*a42*a56 - + a13*a21*a34*a42*a56 - - a11*a23*a34*a42*a56 - - a14*a22*a31*a43*a56 - + a12*a24*a31*a43*a56 - + a14*a21*a32*a43*a56 - - a11*a24*a32*a43*a56 - - a12*a21*a34*a43*a56 - + a11*a22*a34*a43*a56 - + a13*a22*a31*a44*a56 - - a12*a23*a31*a44*a56 - - a13*a21*a32*a44*a56 - + a11*a23*a32*a44*a56 - + a12*a21*a33*a44*a56 - - a11*a22*a33*a44*a56; - cofactor[30] = -a25*a34*a43*a52*a61 - + a24*a35*a43*a52*a61 - + a25*a33*a44*a52*a61 - - a23*a35*a44*a52*a61 - - a24*a33*a45*a52*a61 - + a23*a34*a45*a52*a61 - + a25*a34*a42*a53*a61 - - a24*a35*a42*a53*a61 - - a25*a32*a44*a53*a61 - + a22*a35*a44*a53*a61 - + a24*a32*a45*a53*a61 - - a22*a34*a45*a53*a61 - - a25*a33*a42*a54*a61 - + a23*a35*a42*a54*a61 - + a25*a32*a43*a54*a61 - - a22*a35*a43*a54*a61 - - a23*a32*a45*a54*a61 - + a22*a33*a45*a54*a61 - + a24*a33*a42*a55*a61 - - a23*a34*a42*a55*a61 - - a24*a32*a43*a55*a61 - + a22*a34*a43*a55*a61 - + a23*a32*a44*a55*a61 - - a22*a33*a44*a55*a61 - + a25*a34*a43*a51*a62 - - a24*a35*a43*a51*a62 - - a25*a33*a44*a51*a62 - + a23*a35*a44*a51*a62 - + a24*a33*a45*a51*a62 - - a23*a34*a45*a51*a62 - - a25*a34*a41*a53*a62 - + a24*a35*a41*a53*a62 - + a25*a31*a44*a53*a62 - - a21*a35*a44*a53*a62 - - a24*a31*a45*a53*a62 - + a21*a34*a45*a53*a62 - + a25*a33*a41*a54*a62 - - a23*a35*a41*a54*a62 - - a25*a31*a43*a54*a62 - + a21*a35*a43*a54*a62 - + a23*a31*a45*a54*a62 - - a21*a33*a45*a54*a62 - - a24*a33*a41*a55*a62 - + a23*a34*a41*a55*a62 - + a24*a31*a43*a55*a62 - - a21*a34*a43*a55*a62 - - a23*a31*a44*a55*a62 - + a21*a33*a44*a55*a62 - - a25*a34*a42*a51*a63 - + a24*a35*a42*a51*a63 - + a25*a32*a44*a51*a63 - - a22*a35*a44*a51*a63 - - a24*a32*a45*a51*a63 - + a22*a34*a45*a51*a63 - + a25*a34*a41*a52*a63 - - a24*a35*a41*a52*a63 - - a25*a31*a44*a52*a63 - + a21*a35*a44*a52*a63 - + a24*a31*a45*a52*a63 - - a21*a34*a45*a52*a63 - - a25*a32*a41*a54*a63 - + a22*a35*a41*a54*a63 - + a25*a31*a42*a54*a63 - - a21*a35*a42*a54*a63 - - a22*a31*a45*a54*a63 - + a21*a32*a45*a54*a63 - + a24*a32*a41*a55*a63 - - a22*a34*a41*a55*a63 - - a24*a31*a42*a55*a63 - + a21*a34*a42*a55*a63 - + a22*a31*a44*a55*a63 - - a21*a32*a44*a55*a63 - + a25*a33*a42*a51*a64 - - a23*a35*a42*a51*a64 - - a25*a32*a43*a51*a64 - + a22*a35*a43*a51*a64 - + a23*a32*a45*a51*a64 - - a22*a33*a45*a51*a64 - - a25*a33*a41*a52*a64 - + a23*a35*a41*a52*a64 - + a25*a31*a43*a52*a64 - - a21*a35*a43*a52*a64 - - a23*a31*a45*a52*a64 - + a21*a33*a45*a52*a64 - + a25*a32*a41*a53*a64 - - a22*a35*a41*a53*a64 - - a25*a31*a42*a53*a64 - + a21*a35*a42*a53*a64 - + a22*a31*a45*a53*a64 - - a21*a32*a45*a53*a64 - - a23*a32*a41*a55*a64 - + a22*a33*a41*a55*a64 - + a23*a31*a42*a55*a64 - - a21*a33*a42*a55*a64 - - a22*a31*a43*a55*a64 - + a21*a32*a43*a55*a64 - - a24*a33*a42*a51*a65 - + a23*a34*a42*a51*a65 - + a24*a32*a43*a51*a65 - - a22*a34*a43*a51*a65 - - a23*a32*a44*a51*a65 - + a22*a33*a44*a51*a65 - + a24*a33*a41*a52*a65 - - a23*a34*a41*a52*a65 - - a24*a31*a43*a52*a65 - + a21*a34*a43*a52*a65 - + a23*a31*a44*a52*a65 - - a21*a33*a44*a52*a65 - - a24*a32*a41*a53*a65 - + a22*a34*a41*a53*a65 - + a24*a31*a42*a53*a65 - - a21*a34*a42*a53*a65 - - a22*a31*a44*a53*a65 - + a21*a32*a44*a53*a65 - + a23*a32*a41*a54*a65 - - a22*a33*a41*a54*a65 - - a23*a31*a42*a54*a65 - + a21*a33*a42*a54*a65 - + a22*a31*a43*a54*a65 - - a21*a32*a43*a54*a65; - cofactor[31] = a15*a34*a43*a52*a61 - - a14*a35*a43*a52*a61 - - a15*a33*a44*a52*a61 - + a13*a35*a44*a52*a61 - + a14*a33*a45*a52*a61 - - a13*a34*a45*a52*a61 - - a15*a34*a42*a53*a61 - + a14*a35*a42*a53*a61 - + a15*a32*a44*a53*a61 - - a12*a35*a44*a53*a61 - - a14*a32*a45*a53*a61 - + a12*a34*a45*a53*a61 - + a15*a33*a42*a54*a61 - - a13*a35*a42*a54*a61 - - a15*a32*a43*a54*a61 - + a12*a35*a43*a54*a61 - + a13*a32*a45*a54*a61 - - a12*a33*a45*a54*a61 - - a14*a33*a42*a55*a61 - + a13*a34*a42*a55*a61 - + a14*a32*a43*a55*a61 - - a12*a34*a43*a55*a61 - - a13*a32*a44*a55*a61 - + a12*a33*a44*a55*a61 - - a15*a34*a43*a51*a62 - + a14*a35*a43*a51*a62 - + a15*a33*a44*a51*a62 - - a13*a35*a44*a51*a62 - - a14*a33*a45*a51*a62 - + a13*a34*a45*a51*a62 - + a15*a34*a41*a53*a62 - - a14*a35*a41*a53*a62 - - a15*a31*a44*a53*a62 - + a11*a35*a44*a53*a62 - + a14*a31*a45*a53*a62 - - a11*a34*a45*a53*a62 - - a15*a33*a41*a54*a62 - + a13*a35*a41*a54*a62 - + a15*a31*a43*a54*a62 - - a11*a35*a43*a54*a62 - - a13*a31*a45*a54*a62 - + a11*a33*a45*a54*a62 - + a14*a33*a41*a55*a62 - - a13*a34*a41*a55*a62 - - a14*a31*a43*a55*a62 - + a11*a34*a43*a55*a62 - + a13*a31*a44*a55*a62 - - a11*a33*a44*a55*a62 - + a15*a34*a42*a51*a63 - - a14*a35*a42*a51*a63 - - a15*a32*a44*a51*a63 - + a12*a35*a44*a51*a63 - + a14*a32*a45*a51*a63 - - a12*a34*a45*a51*a63 - - a15*a34*a41*a52*a63 - + a14*a35*a41*a52*a63 - + a15*a31*a44*a52*a63 - - a11*a35*a44*a52*a63 - - a14*a31*a45*a52*a63 - + a11*a34*a45*a52*a63 - + a15*a32*a41*a54*a63 - - a12*a35*a41*a54*a63 - - a15*a31*a42*a54*a63 - + a11*a35*a42*a54*a63 - + a12*a31*a45*a54*a63 - - a11*a32*a45*a54*a63 - - a14*a32*a41*a55*a63 - + a12*a34*a41*a55*a63 - + a14*a31*a42*a55*a63 - - a11*a34*a42*a55*a63 - - a12*a31*a44*a55*a63 - + a11*a32*a44*a55*a63 - - a15*a33*a42*a51*a64 - + a13*a35*a42*a51*a64 - + a15*a32*a43*a51*a64 - - a12*a35*a43*a51*a64 - - a13*a32*a45*a51*a64 - + a12*a33*a45*a51*a64 - + a15*a33*a41*a52*a64 - - a13*a35*a41*a52*a64 - - a15*a31*a43*a52*a64 - + a11*a35*a43*a52*a64 - + a13*a31*a45*a52*a64 - - a11*a33*a45*a52*a64 - - a15*a32*a41*a53*a64 - + a12*a35*a41*a53*a64 - + a15*a31*a42*a53*a64 - - a11*a35*a42*a53*a64 - - a12*a31*a45*a53*a64 - + a11*a32*a45*a53*a64 - + a13*a32*a41*a55*a64 - - a12*a33*a41*a55*a64 - - a13*a31*a42*a55*a64 - + a11*a33*a42*a55*a64 - + a12*a31*a43*a55*a64 - - a11*a32*a43*a55*a64 - + a14*a33*a42*a51*a65 - - a13*a34*a42*a51*a65 - - a14*a32*a43*a51*a65 - + a12*a34*a43*a51*a65 - + a13*a32*a44*a51*a65 - - a12*a33*a44*a51*a65 - - a14*a33*a41*a52*a65 - + a13*a34*a41*a52*a65 - + a14*a31*a43*a52*a65 - - a11*a34*a43*a52*a65 - - a13*a31*a44*a52*a65 - + a11*a33*a44*a52*a65 - + a14*a32*a41*a53*a65 - - a12*a34*a41*a53*a65 - - a14*a31*a42*a53*a65 - + a11*a34*a42*a53*a65 - + a12*a31*a44*a53*a65 - - a11*a32*a44*a53*a65 - - a13*a32*a41*a54*a65 - + a12*a33*a41*a54*a65 - + a13*a31*a42*a54*a65 - - a11*a33*a42*a54*a65 - - a12*a31*a43*a54*a65 - + a11*a32*a43*a54*a65; - - cofactor[32] = -a15*a24*a43*a52*a61 - + a14*a25*a43*a52*a61 - + a15*a23*a44*a52*a61 - - a13*a25*a44*a52*a61 - - a14*a23*a45*a52*a61 - + a13*a24*a45*a52*a61 - + a15*a24*a42*a53*a61 - - a14*a25*a42*a53*a61 - - a15*a22*a44*a53*a61 - + a12*a25*a44*a53*a61 - + a14*a22*a45*a53*a61 - - a12*a24*a45*a53*a61 - - a15*a23*a42*a54*a61 - + a13*a25*a42*a54*a61 - + a15*a22*a43*a54*a61 - - a12*a25*a43*a54*a61 - - a13*a22*a45*a54*a61 - + a12*a23*a45*a54*a61 - + a14*a23*a42*a55*a61 - - a13*a24*a42*a55*a61 - - a14*a22*a43*a55*a61 - + a12*a24*a43*a55*a61 - + a13*a22*a44*a55*a61 - - a12*a23*a44*a55*a61 - + a15*a24*a43*a51*a62 - - a14*a25*a43*a51*a62 - - a15*a23*a44*a51*a62 - + a13*a25*a44*a51*a62 - + a14*a23*a45*a51*a62 - - a13*a24*a45*a51*a62 - - a15*a24*a41*a53*a62 - + a14*a25*a41*a53*a62 - + a15*a21*a44*a53*a62 - - a11*a25*a44*a53*a62 - - a14*a21*a45*a53*a62 - + a11*a24*a45*a53*a62 - + a15*a23*a41*a54*a62 - - a13*a25*a41*a54*a62 - - a15*a21*a43*a54*a62 - + a11*a25*a43*a54*a62 - + a13*a21*a45*a54*a62 - - a11*a23*a45*a54*a62 - - a14*a23*a41*a55*a62 - + a13*a24*a41*a55*a62 - + a14*a21*a43*a55*a62 - - a11*a24*a43*a55*a62 - - a13*a21*a44*a55*a62 - + a11*a23*a44*a55*a62 - - a15*a24*a42*a51*a63 - + a14*a25*a42*a51*a63 - + a15*a22*a44*a51*a63 - - a12*a25*a44*a51*a63 - - a14*a22*a45*a51*a63 - + a12*a24*a45*a51*a63 - + a15*a24*a41*a52*a63 - - a14*a25*a41*a52*a63 - - a15*a21*a44*a52*a63 - + a11*a25*a44*a52*a63 - + a14*a21*a45*a52*a63 - - a11*a24*a45*a52*a63 - - a15*a22*a41*a54*a63 - + a12*a25*a41*a54*a63 - + a15*a21*a42*a54*a63 - - a11*a25*a42*a54*a63 - - a12*a21*a45*a54*a63 - + a11*a22*a45*a54*a63 - + a14*a22*a41*a55*a63 - - a12*a24*a41*a55*a63 - - a14*a21*a42*a55*a63 - + a11*a24*a42*a55*a63 - + a12*a21*a44*a55*a63 - - a11*a22*a44*a55*a63 - + a15*a23*a42*a51*a64 - - a13*a25*a42*a51*a64 - - a15*a22*a43*a51*a64 - + a12*a25*a43*a51*a64 - + a13*a22*a45*a51*a64 - - a12*a23*a45*a51*a64 - - a15*a23*a41*a52*a64 - + a13*a25*a41*a52*a64 - + a15*a21*a43*a52*a64 - - a11*a25*a43*a52*a64 - - a13*a21*a45*a52*a64 - + a11*a23*a45*a52*a64 - + a15*a22*a41*a53*a64 - - a12*a25*a41*a53*a64 - - a15*a21*a42*a53*a64 - + a11*a25*a42*a53*a64 - + a12*a21*a45*a53*a64 - - a11*a22*a45*a53*a64 - - a13*a22*a41*a55*a64 - + a12*a23*a41*a55*a64 - + a13*a21*a42*a55*a64 - - a11*a23*a42*a55*a64 - - a12*a21*a43*a55*a64 - + a11*a22*a43*a55*a64 - - - a14*a23*a42*a51*a65 - + a13*a24*a42*a51*a65 - + a14*a22*a43*a51*a65 - - a12*a24*a43*a51*a65 - - a13*a22*a44*a51*a65 - + a12*a23*a44*a51*a65 - + a14*a23*a41*a52*a65 - - a13*a24*a41*a52*a65 - - a14*a21*a43*a52*a65 - + a11*a24*a43*a52*a65 - + a13*a21*a44*a52*a65 - - a11*a23*a44*a52*a65 - - a14*a22*a41*a53*a65 - + a12*a24*a41*a53*a65 - + a14*a21*a42*a53*a65 - - a11*a24*a42*a53*a65 - - a12*a21*a44*a53*a65 - + a11*a22*a44*a53*a65 - + a13*a22*a41*a54*a65 - - a12*a23*a41*a54*a65 - - a13*a21*a42*a54*a65 - + a11*a23*a42*a54*a65 - + a12*a21*a43*a54*a65 - - a11*a22*a43*a54*a65; - cofactor[33] = a15*a24*a33*a52*a61 - - a14*a25*a33*a52*a61 - - a15*a23*a34*a52*a61 - + a13*a25*a34*a52*a61 - + a14*a23*a35*a52*a61 - - a13*a24*a35*a52*a61 - - a15*a24*a32*a53*a61 - + a14*a25*a32*a53*a61 - + a15*a22*a34*a53*a61 - - a12*a25*a34*a53*a61 - - a14*a22*a35*a53*a61 - + a12*a24*a35*a53*a61 - + a15*a23*a32*a54*a61 - - a13*a25*a32*a54*a61 - - a15*a22*a33*a54*a61 - + a12*a25*a33*a54*a61 - + a13*a22*a35*a54*a61 - - a12*a23*a35*a54*a61 - - a14*a23*a32*a55*a61 - + a13*a24*a32*a55*a61 - + a14*a22*a33*a55*a61 - - a12*a24*a33*a55*a61 - - a13*a22*a34*a55*a61 - + a12*a23*a34*a55*a61 - - a15*a24*a33*a51*a62 - + a14*a25*a33*a51*a62 - + a15*a23*a34*a51*a62 - - a13*a25*a34*a51*a62 - - a14*a23*a35*a51*a62 - + a13*a24*a35*a51*a62 - + a15*a24*a31*a53*a62 - - a14*a25*a31*a53*a62 - - a15*a21*a34*a53*a62 - + a11*a25*a34*a53*a62 - + a14*a21*a35*a53*a62 - - a11*a24*a35*a53*a62 - - a15*a23*a31*a54*a62 - + a13*a25*a31*a54*a62 - + a15*a21*a33*a54*a62 - - a11*a25*a33*a54*a62 - - a13*a21*a35*a54*a62 - + a11*a23*a35*a54*a62 - + a14*a23*a31*a55*a62 - - a13*a24*a31*a55*a62 - - a14*a21*a33*a55*a62 - + a11*a24*a33*a55*a62 - + a13*a21*a34*a55*a62 - - a11*a23*a34*a55*a62 - + a15*a24*a32*a51*a63 - - a14*a25*a32*a51*a63 - - a15*a22*a34*a51*a63 - + a12*a25*a34*a51*a63 - + a14*a22*a35*a51*a63 - - a12*a24*a35*a51*a63 - - a15*a24*a31*a52*a63 - + a14*a25*a31*a52*a63 - + a15*a21*a34*a52*a63 - - a11*a25*a34*a52*a63 - - a14*a21*a35*a52*a63 - + a11*a24*a35*a52*a63 - + a15*a22*a31*a54*a63 - - a12*a25*a31*a54*a63 - - a15*a21*a32*a54*a63 - + a11*a25*a32*a54*a63 - + a12*a21*a35*a54*a63 - - a11*a22*a35*a54*a63 - - a14*a22*a31*a55*a63 - + a12*a24*a31*a55*a63 - + a14*a21*a32*a55*a63 - - a11*a24*a32*a55*a63 - - a12*a21*a34*a55*a63 - + a11*a22*a34*a55*a63 - - a15*a23*a32*a51*a64 - + a13*a25*a32*a51*a64 - + a15*a22*a33*a51*a64 - - a12*a25*a33*a51*a64 - - a13*a22*a35*a51*a64 - + a12*a23*a35*a51*a64 - + a15*a23*a31*a52*a64 - - a13*a25*a31*a52*a64 - - a15*a21*a33*a52*a64 - + a11*a25*a33*a52*a64 - + a13*a21*a35*a52*a64 - - a11*a23*a35*a52*a64 - - a15*a22*a31*a53*a64 - + a12*a25*a31*a53*a64 - + a15*a21*a32*a53*a64 - - a11*a25*a32*a53*a64 - - a12*a21*a35*a53*a64 - + a11*a22*a35*a53*a64 - + a13*a22*a31*a55*a64 - - a12*a23*a31*a55*a64 - - a13*a21*a32*a55*a64 - + a11*a23*a32*a55*a64 - + a12*a21*a33*a55*a64 - - a11*a22*a33*a55*a64 - + a14*a23*a32*a51*a65 - - a13*a24*a32*a51*a65 - - a14*a22*a33*a51*a65 - + a12*a24*a33*a51*a65 - + a13*a22*a34*a51*a65 - - a12*a23*a34*a51*a65 - - a14*a23*a31*a52*a65 - + a13*a24*a31*a52*a65 - + a14*a21*a33*a52*a65 - - a11*a24*a33*a52*a65 - - a13*a21*a34*a52*a65 - + a11*a23*a34*a52*a65 - + a14*a22*a31*a53*a65 - - a12*a24*a31*a53*a65 - - a14*a21*a32*a53*a65 - + a11*a24*a32*a53*a65 - + a12*a21*a34*a53*a65 - - a11*a22*a34*a53*a65 - - a13*a22*a31*a54*a65 - + a12*a23*a31*a54*a65 - + a13*a21*a32*a54*a65 - - a11*a23*a32*a54*a65 - - a12*a21*a33*a54*a65 - + a11*a22*a33*a54*a65; - cofactor[34] = -a15*a24*a33*a42*a61 - + a14*a25*a33*a42*a61 - + a15*a23*a34*a42*a61 - - a13*a25*a34*a42*a61 - - a14*a23*a35*a42*a61 - + a13*a24*a35*a42*a61 - + a15*a24*a32*a43*a61 - - a14*a25*a32*a43*a61 - - a15*a22*a34*a43*a61 - + a12*a25*a34*a43*a61 - + a14*a22*a35*a43*a61 - - a12*a24*a35*a43*a61 - - a15*a23*a32*a44*a61 - + a13*a25*a32*a44*a61 - + a15*a22*a33*a44*a61 - - a12*a25*a33*a44*a61 - - a13*a22*a35*a44*a61 - + a12*a23*a35*a44*a61 - + a14*a23*a32*a45*a61 - - a13*a24*a32*a45*a61 - - a14*a22*a33*a45*a61 - + a12*a24*a33*a45*a61 - + a13*a22*a34*a45*a61 - - a12*a23*a34*a45*a61 - + a15*a24*a33*a41*a62 - - a14*a25*a33*a41*a62 - - a15*a23*a34*a41*a62 - + a13*a25*a34*a41*a62 - + a14*a23*a35*a41*a62 - - a13*a24*a35*a41*a62 - - a15*a24*a31*a43*a62 - + a14*a25*a31*a43*a62 - + a15*a21*a34*a43*a62 - - a11*a25*a34*a43*a62 - - a14*a21*a35*a43*a62 - + a11*a24*a35*a43*a62 - + a15*a23*a31*a44*a62 - - a13*a25*a31*a44*a62 - - a15*a21*a33*a44*a62 - + a11*a25*a33*a44*a62 - + a13*a21*a35*a44*a62 - - a11*a23*a35*a44*a62 - - a14*a23*a31*a45*a62 - + a13*a24*a31*a45*a62 - + a14*a21*a33*a45*a62 - - a11*a24*a33*a45*a62 - - a13*a21*a34*a45*a62 - + a11*a23*a34*a45*a62 - - a15*a24*a32*a41*a63 - + a14*a25*a32*a41*a63 - + a15*a22*a34*a41*a63 - - a12*a25*a34*a41*a63 - - a14*a22*a35*a41*a63 - + a12*a24*a35*a41*a63 - + a15*a24*a31*a42*a63 - - a14*a25*a31*a42*a63 - - a15*a21*a34*a42*a63 - + a11*a25*a34*a42*a63 - + a14*a21*a35*a42*a63 - - a11*a24*a35*a42*a63 - - a15*a22*a31*a44*a63 - + a12*a25*a31*a44*a63 - + a15*a21*a32*a44*a63 - - a11*a25*a32*a44*a63 - - a12*a21*a35*a44*a63 - + a11*a22*a35*a44*a63 - + a14*a22*a31*a45*a63 - - a12*a24*a31*a45*a63 - - a14*a21*a32*a45*a63 - + a11*a24*a32*a45*a63 - + a12*a21*a34*a45*a63 - - a11*a22*a34*a45*a63 - + a15*a23*a32*a41*a64 - - a13*a25*a32*a41*a64 - - a15*a22*a33*a41*a64 - + a12*a25*a33*a41*a64 - + a13*a22*a35*a41*a64 - - a12*a23*a35*a41*a64 - - a15*a23*a31*a42*a64 - + a13*a25*a31*a42*a64 - + a15*a21*a33*a42*a64 - - a11*a25*a33*a42*a64 - - a13*a21*a35*a42*a64 - + a11*a23*a35*a42*a64 - + a15*a22*a31*a43*a64 - - a12*a25*a31*a43*a64 - - a15*a21*a32*a43*a64 - + a11*a25*a32*a43*a64 - + a12*a21*a35*a43*a64 - - a11*a22*a35*a43*a64 - - a13*a22*a31*a45*a64 - + a12*a23*a31*a45*a64 - + a13*a21*a32*a45*a64 - - a11*a23*a32*a45*a64 - - a12*a21*a33*a45*a64 - + a11*a22*a33*a45*a64 - - a14*a23*a32*a41*a65 - + a13*a24*a32*a41*a65 - + a14*a22*a33*a41*a65 - - a12*a24*a33*a41*a65 - - a13*a22*a34*a41*a65 - + a12*a23*a34*a41*a65 - + a14*a23*a31*a42*a65 - - a13*a24*a31*a42*a65 - - a14*a21*a33*a42*a65 - + a11*a24*a33*a42*a65 - + a13*a21*a34*a42*a65 - - a11*a23*a34*a42*a65 - - a14*a22*a31*a43*a65 - + a12*a24*a31*a43*a65 - + a14*a21*a32*a43*a65 - - a11*a24*a32*a43*a65 - - a12*a21*a34*a43*a65 - + a11*a22*a34*a43*a65 - + a13*a22*a31*a44*a65 - - a12*a23*a31*a44*a65 - - a13*a21*a32*a44*a65 - + a11*a23*a32*a44*a65 - + a12*a21*a33*a44*a65 - - a11*a22*a33*a44*a65; - cofactor[35] = a15*a24*a33*a42*a51 - - a14*a25*a33*a42*a51 - - a15*a23*a34*a42*a51 - + a13*a25*a34*a42*a51 - + a14*a23*a35*a42*a51 - - a13*a24*a35*a42*a51 - - a15*a24*a32*a43*a51 - + a14*a25*a32*a43*a51 - + a15*a22*a34*a43*a51 - - a12*a25*a34*a43*a51 - - a14*a22*a35*a43*a51 - + a12*a24*a35*a43*a51 - + a15*a23*a32*a44*a51 - - a13*a25*a32*a44*a51 - - a15*a22*a33*a44*a51 - + a12*a25*a33*a44*a51 - + a13*a22*a35*a44*a51 - - a12*a23*a35*a44*a51 - - a14*a23*a32*a45*a51 - + a13*a24*a32*a45*a51 - + a14*a22*a33*a45*a51 - - a12*a24*a33*a45*a51 - - a13*a22*a34*a45*a51 - + a12*a23*a34*a45*a51 - - a15*a24*a33*a41*a52 - + a14*a25*a33*a41*a52 - + a15*a23*a34*a41*a52 - - a13*a25*a34*a41*a52 - - a14*a23*a35*a41*a52 - + a13*a24*a35*a41*a52 - + a15*a24*a31*a43*a52 - - a14*a25*a31*a43*a52 - - a15*a21*a34*a43*a52 - + a11*a25*a34*a43*a52 - + a14*a21*a35*a43*a52 - - a11*a24*a35*a43*a52 - - a15*a23*a31*a44*a52 - + a13*a25*a31*a44*a52 - + a15*a21*a33*a44*a52 - - a11*a25*a33*a44*a52 - - a13*a21*a35*a44*a52 - + a11*a23*a35*a44*a52 - + a14*a23*a31*a45*a52 - - a13*a24*a31*a45*a52 - - a14*a21*a33*a45*a52 - + a11*a24*a33*a45*a52 - + a13*a21*a34*a45*a52 - - a11*a23*a34*a45*a52 - + a15*a24*a32*a41*a53 - - a14*a25*a32*a41*a53 - - a15*a22*a34*a41*a53 - + a12*a25*a34*a41*a53 - + a14*a22*a35*a41*a53 - - a12*a24*a35*a41*a53 - - a15*a24*a31*a42*a53 - + a14*a25*a31*a42*a53 - + a15*a21*a34*a42*a53 - - a11*a25*a34*a42*a53 - - a14*a21*a35*a42*a53 - + a11*a24*a35*a42*a53 - + a15*a22*a31*a44*a53 - - a12*a25*a31*a44*a53 - - a15*a21*a32*a44*a53 - + a11*a25*a32*a44*a53 - + a12*a21*a35*a44*a53 - - a11*a22*a35*a44*a53 - - a14*a22*a31*a45*a53 - + a12*a24*a31*a45*a53 - + a14*a21*a32*a45*a53 - - a11*a24*a32*a45*a53 - - a12*a21*a34*a45*a53 - + a11*a22*a34*a45*a53 - - a15*a23*a32*a41*a54 - + a13*a25*a32*a41*a54 - + a15*a22*a33*a41*a54 - - a12*a25*a33*a41*a54 - - a13*a22*a35*a41*a54 - + a12*a23*a35*a41*a54 - + a15*a23*a31*a42*a54 - - a13*a25*a31*a42*a54 - - a15*a21*a33*a42*a54 - + a11*a25*a33*a42*a54 - + a13*a21*a35*a42*a54 - - a11*a23*a35*a42*a54 - - a15*a22*a31*a43*a54 - + a12*a25*a31*a43*a54 - + a15*a21*a32*a43*a54 - - a11*a25*a32*a43*a54 - - a12*a21*a35*a43*a54 - + a11*a22*a35*a43*a54 - + a13*a22*a31*a45*a54 - - a12*a23*a31*a45*a54 - - a13*a21*a32*a45*a54 - + a11*a23*a32*a45*a54 - + a12*a21*a33*a45*a54 - - a11*a22*a33*a45*a54 - + a14*a23*a32*a41*a55 - - a13*a24*a32*a41*a55 - - a14*a22*a33*a41*a55 - + a12*a24*a33*a41*a55 - + a13*a22*a34*a41*a55 - - a12*a23*a34*a41*a55 - - a14*a23*a31*a42*a55 - + a13*a24*a31*a42*a55 - + a14*a21*a33*a42*a55 - - a11*a24*a33*a42*a55 - - a13*a21*a34*a42*a55 - + a11*a23*a34*a42*a55 - + a14*a22*a31*a43*a55 - - a12*a24*a31*a43*a55 - - a14*a21*a32*a43*a55 - + a11*a24*a32*a43*a55 - + a12*a21*a34*a43*a55 - - a11*a22*a34*a43*a55 - - a13*a22*a31*a44*a55 - + a12*a23*a31*a44*a55 - + a13*a21*a32*a44*a55 - - a11*a23*a32*a44*a55 - - a12*a21*a33*a44*a55 - + a11*a22*a33*a44*a55; - -/* ainv = transpose(cofactor) ! / det */ - const double jinv = 1/det; - ainv[0] = cofactor[0]*jinv; - ainv[1] = cofactor[6]*jinv; - ainv[2] = cofactor[12]*jinv; - ainv[3] = cofactor[18]*jinv; - ainv[4] = cofactor[24]*jinv; - ainv[5] = cofactor[30]*jinv; - ainv[6] = cofactor[1]*jinv; - ainv[7] = cofactor[7]*jinv; - ainv[8] = cofactor[13]*jinv; - ainv[9] = cofactor[19]*jinv; - ainv[10] = cofactor[25]*jinv; - ainv[11] = cofactor[31]*jinv; - ainv[12] = cofactor[2]*jinv; - ainv[13] = cofactor[8]*jinv; - ainv[14] = cofactor[14]*jinv; - ainv[15] = cofactor[20]*jinv; - ainv[16] = cofactor[26]*jinv; - ainv[17] = cofactor[32]*jinv; - ainv[18] = cofactor[3]*jinv; - ainv[19] = cofactor[9]*jinv; - ainv[20] = cofactor[15]*jinv; - ainv[21] = cofactor[21]*jinv; - ainv[22] = cofactor[27]*jinv; - ainv[23] = cofactor[33]*jinv; - ainv[24] = cofactor[4]*jinv; - ainv[25] = cofactor[10]*jinv; - ainv[26] = cofactor[16]*jinv; - ainv[27] = cofactor[22]*jinv; - ainv[28] = cofactor[28]*jinv; - ainv[29] = cofactor[34]*jinv; - ainv[30] = cofactor[5]*jinv; - ainv[31] = cofactor[11]*jinv; - ainv[32] = cofactor[17]*jinv; - ainv[33] = cofactor[23]*jinv; - ainv[34] = cofactor[29]*jinv; - ainv[35] = cofactor[35]*jinv; - - *ok_flag__ = 0; - return 0; -} From ac53534f9dffd8c7c1c10930e1da0bf3c9702d2e Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 10:43:48 -0700 Subject: [PATCH 123/261] clean up, add new base class --- .../Frame/FrameTransform.h | 152 +++++++++++++++ .../Frame/FrameTransform.tpp | 181 ++++++++++++++++++ 2 files changed, 333 insertions(+) create mode 100644 SRC/coordTransformation/Frame/FrameTransform.h create mode 100644 SRC/coordTransformation/Frame/FrameTransform.tpp diff --git a/SRC/coordTransformation/Frame/FrameTransform.h b/SRC/coordTransformation/Frame/FrameTransform.h new file mode 100644 index 0000000000..3a3e54af78 --- /dev/null +++ b/SRC/coordTransformation/Frame/FrameTransform.h @@ -0,0 +1,152 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// +// +// Written: cmp +// +#ifndef FrameTransform_h +#define FrameTransform_h + +#include +#include +#include +#include +#include +#include +#include // TODO: remove this include +// class CrdTransf; + +#define MAYBE_STATIC static + +using OpenSees::VectorND; +using OpenSees::MatrixND; +using OpenSees::Matrix3D; +class Information; +class Response; +class Node; + +enum { + CRDTR_TAG_CorotFrameTransfWarping3d, + CRDTR_TAG_CorotFrameTransf3d, + CRDTR_TAG_LinearFrameTransf3d, + CRDTR_TAG_PDeltaFrameTransf3d +}; + +enum { + OffsetGlobal = 0, // 1<<0, + OffsetLocal = 1, // 1<<1, + OffsetNormalized = 2, // 1<<2, + + LogIter = 1<<3, + LogIncr = 1<<4, + LogInit = 1<<5, + LogDefault = 1<<6 +}; + +namespace OpenSees { + +template +class FrameTransform : public TaggedObject +{ +public: + constexpr static int ndm = 3; + +public: + FrameTransform(int tag) : TaggedObject(tag) {} + + virtual FrameTransform *getCopy() const =0; + + virtual VectorND getStateVariation() =0; + + virtual Vector3D getNodePosition(int tag) =0; + virtual Vector3D getNodeRotationLogarithm(int tag) =0; +#if 0 + virtual Versor getNodeRotation(int tag); + virtual Vector3D getNodeRotationVariation(int tag); + virtual VectorND getNodeRotationIncrement(int tag); + + virtual VectorND getNodeLogarithm(int tag) =0; + virtual VectorND getNodeVariation(int tag) =0; + virtual VectorND getNodeVelocity(int tag); + virtual VectorND getNodeLocation(int tag); +#endif + virtual int initialize(std::array& nodes)=0; + virtual int update() =0; + virtual int commit() =0; + virtual int revertToLastCommit() =0; + virtual int revertToStart() =0; + + virtual double getInitialLength() =0; + virtual double getDeformedLength() =0; + virtual const std::array *getRigidOffsets() const =0; + + virtual VectorND pushResponse(VectorND&pl) =0; + virtual MatrixND pushResponse(MatrixND& kl, const VectorND& pl) =0; + + VectorND pushConstant(const VectorND&pl); + MatrixND pushConstant(const MatrixND& kl); + + // + virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const =0; + + // Recorders + virtual Response *setResponse(const char **argv, int argc, + OPS_Stream &theHandler) { + return nullptr; + } + virtual int getResponse(int responseID, Information &) { + return -1; + } + + // Sensitivity + // virtual const Vector &getBasicDisplTotalGrad(int grad)=0; + // virtual const Vector &getBasicDisplFixedGrad()=0; + // virtual const Vector &getGlobalResistingForceShapeSensitivity(const Vector &pb, const Vector &p0, int grad)=0; + virtual bool isShapeSensitivity() {return false;} + virtual double getLengthGrad() {return 0.0;} + virtual double getd1overLdh() {return 0.0;} + + static int + Orient(const Vector3D& dx, const Vector3D& vz, Matrix3D &R) { + + // calculate the element local x axis components wrt to the global coordinates + + Vector3D e1 = dx/dx.norm(); + + // + Vector3D e2 = vz.cross(e1); + + const double ynorm = e2.norm(); + + if (ynorm == 0.0) + return -1; + + e2 /= ynorm; + + Vector3D e3 = e1.cross(e2); + + for (int i = 0; i < 3; i++) { + R(i,0) = e1[i]; + R(i,1) = e2[i]; + R(i,2) = e3[i]; + } + return 0; + } +protected: + +}; +} +#include "FrameTransform.tpp" + +#endif // include guard diff --git a/SRC/coordTransformation/Frame/FrameTransform.tpp b/SRC/coordTransformation/Frame/FrameTransform.tpp new file mode 100644 index 0000000000..ce30bd1f82 --- /dev/null +++ b/SRC/coordTransformation/Frame/FrameTransform.tpp @@ -0,0 +1,181 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// +// +#pragma once +#include "FrameTransform.h" +#include + +namespace OpenSees { + +template +static VectorND +pushLocal(const Vector& q, double L) +{ + + VectorND<12> pl; + + double q0 = q(0); + double q1 = q(1); + double q2 = q(2); + double q3 = q(3); + double q4 = q(4); + double q5 = q(5); + + double oneOverL = 1.0 / L; + + pl[0] = -q0; // Ni + pl[1] = oneOverL * (q1 + q2); // Viy + pl[2] = -oneOverL * (q3 + q4); // Viz + pl[3] = -q5; // Ti + pl[4] = q3; + pl[5] = q1; // Mzi + pl[6] = q0; // Nj + pl[7] = -pl[1]; // Vjy + pl[8] = -pl[2]; // Vjz + pl[9] = q5; // Tj + pl[10] = q4; + pl[11] = q2; // Mzj + + return pl; +} + + +template +VectorND +FrameTransform::pushConstant(const VectorND& pl) +{ + Matrix3D R; + Vector3D x, y, z; + getLocalAxes(x, y, z); + for (int i=0; i<3; i++) { + R(i,0) = x[i]; + R(i,1) = y[i]; + R(i,2) = z[i]; + } + + constexpr int N = nn * ndf; + const std::array *offset = this->getRigidOffsets(); + + // + // Initialize + // + VectorND pg = pl; + + // (A) First pass: just do the direct transformations + for (int i=0; i= 6) + if (offset) { + const std::array& offsets = *offset; + for (int i=0; i +MatrixND +FrameTransform::pushConstant(const MatrixND& kl) +{ + // + // Do diag(R)*M*diag(R)' + // + static MatrixND Kg; + Kg = kl; + + Matrix3D R; + Vector3D x, y, z; + getLocalAxes(x, y, z); + for (int i=0; i<3; i++) { + R(i,0) = x[i]; + R(i,1) = y[i]; + R(i,2) = z[i]; + } + + const Matrix3D RT = R.transpose(); + for (int i=0; i *offset = this->getRigidOffsets(); + if (offset) [[unlikely]] { + const std::array& offsets = *offset; + for (int i=0; i(i*ndf+3, j*ndf), offsets[j], -1.0); + Kg.assemble(KmnW, i*ndf+3, j*ndf+3, 1.0); + } + { + Matrix3D WKnm{}; + WKnm.addSpinMatrixProduct(offsets[i], Kg.template extract<3,3>(i*ndf, j*ndf+3), 1.0); + Kg.assemble(WKnm, i*ndf+3, j*ndf+3, 1.0); + } + { + Matrix3D WKnn{}; + { + Matrix3D Knn = Kg.template extract<3,3>(i*ndf, j*ndf); + { + Matrix3D KnnW{}; + KnnW.addMatrixSpinProduct(Knn, offsets[j], -1.0); + Kg.assemble(KnnW, i*ndf, j*ndf+3, 1.0); + } + WKnn.addSpinMatrixProduct(offsets[i], Knn, 1.0); + Kg.assemble(WKnn, i*ndf+3, j*ndf, 1.0); + } + Matrix3D WKmmW{}; + WKmmW.addMatrixSpinProduct(WKnn, offsets[j], -1.0); + Kg.assemble(WKmmW, i*ndf+3, j*ndf+3, 1.0); + } + } + } + } + return Kg; +} +} \ No newline at end of file From 6348065e968c81539feb38666b06225ef3de223b Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 10:47:36 -0700 Subject: [PATCH 124/261] clean up TODOs --- SRC/coordTransformation/Frame/BasicFrameTransf.tpp | 13 ++++++------- SRC/coordTransformation/Frame/EuclidFrameTransf.h | 1 - SRC/coordTransformation/Frame/LinearFrameTransf.tpp | 12 ------------ 3 files changed, 6 insertions(+), 20 deletions(-) diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index 7cb9afa2f4..a7e5ade02a 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -255,8 +255,8 @@ BasicFrameTransf3d::getInitialGlobalStiffMatrix(const Matrix &KB) for (int j = 0; j < 6; j++) kb[i][j] = KB(i, j); - // Transform basic stiffness to local system - // First compute kb*T_{bl} + // + // for (int i = 0; i < 6; i++) { tmp[i][0] = -kb[i][0]; tmp[i][3] = -kb[i][5]; @@ -267,13 +267,12 @@ BasicFrameTransf3d::getInitialGlobalStiffMatrix(const Matrix &KB) tmp[i][10] = kb[i][4]; tmp[i][11] = kb[i][2]; } - // TODO: - // Now compute T'_{bl}*(kb*T_{bl}) + // for (int i = 0; i < 12; i++) { kl( 0, i) = -tmp[0][i]; kl( 3, i) = -tmp[5][i]; - kl( 4, i) = tmp[3][i]; - kl( 5, i) = tmp[1][i]; + kl( 4, i) = tmp[3][i]; + kl( 5, i) = tmp[1][i]; kl( 6, i) = tmp[0][i]; kl( 9, i) = tmp[5][i]; @@ -424,4 +423,4 @@ BasicFrameTransf3d::recvSelf(int cTag, Channel &, return -1; } -} +} // namespace OpenSees \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h index 3c5270f433..fbf25f30ec 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.h +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -107,7 +107,6 @@ class EuclidFrameTransf: public FrameTransform for (int b = 0; b(basis.getRotationGradient(b), 1.0); - // TODO(nn>2): Interpolate coordinate? A.assemble(ix*Gb, a*ndf , b*ndf, double(a)/double(nn-1)*L); A.assemble( Gb, a*ndf+3, b*ndf, -1.0); } diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index 35ffea2c7a..31a6dc7686 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -623,21 +623,9 @@ const Vector & LinearFrameTransf::getBasicDisplTotalGrad(int gradNumber) { - double dug[12]; - for (int i = 0; i < 6; i++) { - dug[i] = nodes[0]->getDispSensitivity((i + 1), gradNumber); - dug[i + 6] = nodes[1]->getDispSensitivity((i + 1), gradNumber); - } - static VectorND<6> dub; static Vector wrapper(dub); - // dub = T_{bl} T_{lg} * ug' - // TODO - // dub = getBasic(dug, R, offsets[0], offsets[nn-1], 1/L); - - wrapper += getBasicDisplFixedGrad(); - return wrapper; } From 914994bb7296566d04ba1db1fe800774501998a1 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 10:48:43 -0700 Subject: [PATCH 125/261] add frame element parsing --- .../commands/modeling/element/frames.cpp | 1419 +++++++++++++++++ 1 file changed, 1419 insertions(+) create mode 100644 SRC/runtime/commands/modeling/element/frames.cpp diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp new file mode 100644 index 0000000000..d99c42ea94 --- /dev/null +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -0,0 +1,1419 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Written: cmp, mhs, rms, fmk +// +// Created: Feb 2023 +// +// Standard library + #include + #include + #include + #include + #include + #include + #include + #include + #include + #ifdef _MSC_VER + # include + # define strcasecmp _stricmp + #else + # include + #endif + #define strcmp strcasecmp + + // Parsing + #include + #include + #include + #include + + // Model + #include + #include + #include + + // Sections + #include + #include + #include + + // Elements + #include "ElasticBeam2d.h" + #include "ElasticBeam2d.h" + #include "ElasticBeam3d.h" + #include "ElasticBeam3d.h" + #include "PrismFrame2d.h" + #include "PrismFrame2d.h" + #include "PrismFrame3d.h" + #include "PrismFrame3d.h" + + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + #include + + // Quadrature + #include + #include + #include + #include + #include + #include + #include + + #include + +using namespace OpenSees; + +struct Options { + int mass_flag; + int use_mass; + int shear_flag; + int geom_flag; +}; + + +extern BeamIntegration* GetBeamIntegration(TCL_Char* type, int); +extern BeamIntegrationRule* GetHingeStencil(int argc, TCL_Char ** const argv); + + +template +static Element* +CreateFrame(BasicModelBuilder& builder, + const char* name, + int tag, + std::vector& nodev, + int transfTag, + const std::vector& section_tags, + BeamIntegration& beamIntegr, + double mass, int max_iter, double tol, + Options& options) +{ + + std::vector sections; + + // Finalize sections + assert(section_tags.size() != 0); + for (int tag : section_tags) { + Section *section = builder.getTypedObject
(tag); + if (section == nullptr) + return nullptr; + sections.push_back(section); + } + int nIP = sections.size(); + + SectionForceDeformation** secptrs = (SectionForceDeformation**)(sections.data()); + + if (options.shear_flag == -1) { + options.shear_flag = 0; + const ID& resultants = sections[0]->getType(); + for (int i=0; i< sections[0]->getOrder(); i++) + if (resultants(i) == FrameStress::Vy) + options.shear_flag = 1; + } + + // Finalize the coordinate transform + Transform* theTransf = builder.getTypedObject(transfTag); + if (theTransf == nullptr) { + opserr << OpenSees::PromptValueError << "transformation not found with tag " << transfTag << "\n"; + return nullptr; + } + + // + // Create the element + // + Element *theElement = nullptr; + + int iNode = nodev[0], + jNode = nodev[1]; + bool use_mass = options.use_mass; + + if constexpr (ndm == 2) { + + if (strcmp(name, "elasticForceBeamColumn") == 0) + theElement = new ElasticForceBeamColumn2d(tag, iNode, jNode, nIP, secptrs, beamIntegr, *theTransf, mass); + else if (strcmp(name, "timoshenkoBeamColumn") == 0) + theElement = + new TimoshenkoBeamColumn2d(tag, iNode, jNode, nIP, secptrs, beamIntegr, *theTransf, mass); + else if (strcmp(name, "dispBeamColumn") == 0) + theElement = + new DispBeamColumn2d(tag, iNode, jNode, nIP, secptrs, beamIntegr, *theTransf, mass, options.mass_flag); + else if (strcmp(name, "dispBeamColumnNL") == 0) + theElement = + new DispBeamColumnNL2d(tag, iNode, jNode, nIP, secptrs, + beamIntegr, *theTransf, mass); + + else if (strcmp(name, "dispBeamColumnThermal") == 0) + theElement = new DispBeamColumn2dThermal(tag, iNode, jNode, nIP, secptrs, beamIntegr, *theTransf, mass); + + + else if (strcmp(name, "dispBeamColumnWithSensitivity") == 0) + theElement = new DispBeamColumn2d(tag, iNode, jNode, nIP, secptrs, beamIntegr, *theTransf, mass); + + + // Force formulations + else if (strcmp(name, "forceBeamColumnCBDI") == 0) + theElement = new ForceBeamColumnCBDI2d(tag, iNode, jNode, nIP, secptrs, + beamIntegr, *theTransf, mass, false); + + else if (strcmp(name, "forceBeamColumnCSBDI") == 0) + return new ForceBeamColumnCBDI2d(tag, iNode, jNode, nIP, secptrs, + beamIntegr, *theTransf, mass, true); + + else if (strcmp(name, "forceBeamColumnWarping") == 0) + return + new ForceBeamColumnWarping2d(tag, iNode, jNode, nIP, + secptrs, beamIntegr, *theTransf); + + else if (strcmp(name, "forceBeamColumnThermal") == 0) + return new ForceBeamColumn2dThermal(tag, iNode, jNode, nIP, secptrs, beamIntegr, *theTransf, mass); + + else if (strcmp(name, "elasticForceBeamColumnWarping") == 0) + return new ElasticForceBeamColumnWarping2d( + tag, iNode, jNode, nIP, secptrs, beamIntegr, *theTransf); + else + theElement = + new ForceBeamColumn2d(tag, iNode, jNode, nIP, secptrs, + beamIntegr, *theTransf, mass, max_iter, tol); + + + } else { + // + // ndm == 3 + // + if (strstr(name, "Frame") != nullptr) { + if (strstr(name, "Exact") == nullptr) { + std::array nodes {nodev[0], nodev[1]}; + + FrameTransformBuilder* tb = builder.getTypedObject(transfTag); + + if (!tb) { + opserr << OpenSees::PromptValueError << "invalid transform\n"; + return nullptr; + } + + + if (strcmp(name, "EulerFrame") == 0) { + theElement = new EulerFrame3d(tag, nodes, nIP, + sections.data(), + beamIntegr, + *tb, + mass, options.mass_flag); + } + + if (strcmp(name, "CubicFrame") == 0) { + if (options.shear_flag) + theElement = new CubicFrame3d(tag, nodes, + sections, + beamIntegr, + *theTransf, // TODO: Use FrameTransformBuilder + mass); + else + theElement = new CubicFrame3d(tag, nodes, + sections, + beamIntegr, + *theTransf, // TODO: Use FrameTransformBuilder + mass); + } + + else if (strcmp(name, "DisplFrame") == 0) { + theElement = new EulerDeltaFrame3d(tag, nodes, sections, + beamIntegr, *theTransf, + mass, + options.mass_flag, + use_mass); + } + + else if ((strstr(name, "Force") != 0) || + (strcmp(name, "MixedFrame") == 0)) { + if (strcmp(name, "ForceDeltaFrame") == 0 || options.geom_flag) { + if (!options.shear_flag) + static_loop<2,6>([&](auto nip) constexpr { + if (nip.value == sections.size()) + theElement = new ForceDeltaFrame3d(tag, nodes, sections, + beamIntegr, *tb, + mass, + options.mass_flag, + use_mass, + max_iter, tol, + options.shear_flag + ); + }); + else + static_loop<2,6>([&](auto nip) constexpr { + if (nip.value == sections.size()) + theElement = new ForceDeltaFrame3d(tag, nodes, sections, + beamIntegr, *tb, + mass, + options.mass_flag, + use_mass, + max_iter, tol, + options.shear_flag + ); + }); + } else { + int ndf = builder.getNDF(); + + static_loop<0, 3>([&](auto nwm) constexpr { + if (nwm.value + 6 == ndf) { + // Create the transform +#if 0 || defined(NEW_TRANSFORM) + FrameTransform<2,6+nwm.value> *tran = tb->template create<2,6+nwm.value>(); +#endif + if (!options.shear_flag) { + static_loop<2,30>([&](auto nip) constexpr { + if (nip.value == sections.size()) + theElement = new ForceFrame3d(tag, + nodes, sections, + beamIntegr, *tb, + mass, options.mass_flag, use_mass, + max_iter, tol + ); + }); + } + else + theElement = new ForceFrame3d<20, 6+nwm.value*2, nwm.value>(tag, + nodes, sections, + beamIntegr, *tb, + mass, options.mass_flag, use_mass, + max_iter, tol + ); + } + }); + } + } + } + + else if (strcmp(name, "ExactFrame") == 0) { + if (!options.shear_flag) { + opserr << OpenSees::PromptValueError << "ExactFrame3d requires shear formulation\n"; + return nullptr; + } + int ndf = builder.getNDF(); + if (sections.size() < nodev.size()-1) + for (unsigned i = 0; i < nodev.size()-1; ++i) + sections.push_back(sections[0]); + + unsigned nen = nodev.size(); + static_loop<2,6>([&](auto nn) constexpr { + if (nn.value == nen) { + std::array nodes; + std::copy_n(nodev.begin(), nn.value, nodes.begin()); + static_loop<0,4>([&](auto nwm) constexpr { + if (nwm.value+6 == ndf) + theElement = new ExactFrame3d(tag, nodes, sections.data(), *theTransf); + }); + } + }); + if (theElement == nullptr) { + opserr << OpenSees::PromptValueError << "invalid number of dofs for ExactFrame; got " << ndf + << "\n"; + return nullptr; + } + } + } + + else if (strcmp(name, "elasticForceBeamColumn") == 0) + theElement = new ElasticForceBeamColumn3d(tag, iNode, jNode, nIP, secptrs, + beamIntegr, *theTransf, mass); + + else if (strcasecmp(name, "dispBeamColumn") == 0) + theElement = new DispBeamColumn3d(tag, iNode, jNode, nIP, secptrs, + beamIntegr, *theTransf, + mass, options.mass_flag); + + else if (strcmp(name, "dispBeamColumnWithSensitivity") == 0) + theElement = new DispBeamColumn3d( + tag, iNode, jNode, nIP, secptrs, beamIntegr, *theTransf, mass); + + else if (strcmp(name, "dispBeamColumnThermal") == 0) + theElement = new DispBeamColumn3dThermal( + tag, iNode, jNode, nIP, secptrs, beamIntegr, *theTransf, mass); + + else if (strcmp(name, "forceBeamColumnCBDI") == 0) + theElement = new ForceBeamColumnCBDI3d(tag, iNode, jNode, nIP, secptrs, + beamIntegr, *theTransf, + mass, false, max_iter, tol); + else + theElement = new ForceBeamColumn3d(tag, iNode, jNode, nIP, secptrs, + beamIntegr, *theTransf, mass, max_iter, tol); + } + return theElement; +} + + +#if 0 +Element* +CreateInelasticFrame(std::string, std::vector& nodes, + std::vector&, + BeamIntegration&, + // FrameQuadrature&, + FrameTransform&, + Options&); +Element* +CreatePrismaticFrame(std::string); +#endif + +// 0 1 2 3 4 +// element beam 1 $i $j 0 1 2 +// +// a) +// 0 1 2 3 4 5 6 +// 0 1 +// element $type $tag $ndi $ndj $trn "Gauss arg1 arg2 ..." +// <-mass $mass> <-iter $iter $tol> +// +// b) +// 0 1 +// element(type, tag, ndi, ndj, trn, itag, +// iter=(10, 1e-12), mass=0.0) +// +// c) "Original/Obsolete" +// 0 1 2 +// element $type $tag $ndi $ndj $nip $sec $trn +// <-mass $mass> <-iter $iter $tol> <-integration $ityp> +// +// d) +// 0 1 ... (2 + nIP) +// element $type $tag $ndi $ndj $nip -sections ... $trn +// <-mass $massDens> <-cMass> <-integration $ityp> +// +// e) +// 0 +// element $type $tag $ndi $ndj $trn +// -sections {...} +// <-mass $massDens> <-cMass> <-integration $ityp> +// +// +// Integration may be specitied as either +// i ) a single name, +// ii ) a pattern spec, or +// iii) a tag for a pattern +// +// if a list of sections is given with -sections, or nIP is provided, then +// we must have an integration with the form (i) +// +// 1) Parse common keyword args: +// "-mass" $mass, +// "-cMass"/"-lMass" +// "-mass-form" $form +// +// "-iter" $iter $tol, +// +// "-integration" $Integration +// - first try parsing $Integration as integer ($itag, form (iii)) +// if successfull, populate section_tags and continue +// - next try parsing $Integration as basic quadrature ($ityp, form (i)) +// - finally, try parsing as full pattern spec +// +// "-section" $Tag +// +// "-transform" $Tag +// "-vertical" {} +// "-horizontal" {} +// +// "-sections" $SectionTags +// - if cannot split $SectionTags as list, then +// mark "-sections" as positional and continue +// with keyword loop +// - Check if "-integration" was provided already; if so, it must have been in form (i); +// otherwise throw an error. +// - Parse $SectionTags +// -sections {...} may occur anywhere +// -sections ... must occur after nIP is obtained +// +// +// 2) +// If pos[1] == "-sections" then command is Form (d): +// nIP = pos[0] +// trn = pos[2+nIP] +// +// else +// +// switch (pos.size()) +// case 1: // Form (e) +// trn = pos[0] +// if (section_tags.size() == 0) +// ERROR +// +// case 2: +// // Form (a) or (b) +// trn = pos[0] +// if GetInt(interp, pos[1]): +// itag = pos[1] +// else +// ParseHingeScheme(pos[1]) +// +// case 3: +// // Form (c) +// nip = int(pos[0]) +// sec = int(pos[1]) +// trn = int(pos[2]) +// +int +TclBasicBuilder_addForceBeamColumn(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char **const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + Domain *domain = builder->getDomain(); + assert(domain != nullptr); + + int status = TCL_OK; + +//enum class GaussMethod { +// None, +// Rule, // Quadrature name + section locations; Hinge methods +// Quad, // Quadrature name +//} gauss_method = GaussMethod::None; + + // collect positional arguments + std::vector positions; + + + // + // Preliminary checks + // + int ndm = builder->getNDM(); + int ndf = builder->getNDF(); + + { // Check dimension and DOFs of problem + int ok = 0; + if ((ndm == 2 && ndf == 3) || (ndm == 2 && ndf == 4)) + ok = 1; + if (ndm == 3 && ndf >= 6) + ok = 1; + + if (ok == 0) { + opserr << OpenSees::PromptValueError << "ndm = " << ndm << " and ndf = " << ndf + << " not compatible with Frame element" << "\n"; + return TCL_ERROR; + } + } + + if (argc < 6) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + return TCL_ERROR; + } + + // + // Required positional arguments + // + int tag; + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid " << " tag " << tag << "\n"; + return TCL_ERROR; + } + + int argi = 5; + // int iNode=0, jNode=0; + // bool multi_node = false; + std::vector multi_nodes; + { + int list_argc; + TCL_Char **list_argv; + if (Tcl_SplitList(interp, argv[3], &list_argc, &list_argv) == TCL_OK && list_argc >= 2) { + argi -= 1; + + for (int i = 0; i < list_argc; ++i) { + int node; + if (Tcl_GetInt(interp, list_argv[i], &node) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid node\n"; + return TCL_ERROR; + } + multi_nodes.push_back(node); + } + Tcl_Free((char *)list_argv); + } + else { + int iNode, jNode; + if (Tcl_GetInt(interp, argv[3], &iNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid iNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4], &jNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid jNode\n"; + return TCL_ERROR; + } + multi_nodes.push_back(iNode); + multi_nodes.push_back(jNode); + } + } + + int max_iter = 10; + double tol = 1.0e-12; + double mass = 0.0; + bool use_mass = false; + int transfTag; + std::vector section_tags; + const char* integration_type = nullptr; + BeamIntegration *beamIntegr = nullptr; + BeamIntegrationRule *theRule = nullptr; + int itg_tag; + + // If we get a BeamIntegration from a BeamIntegrationRule + // then we dont own it and can't delete it + bool deleteBeamIntegr = true; + bool removeHingeIntegr = false; + + // + // Defaults + // + struct Options options; + options.mass_flag = 0; + options.shear_flag = -1; + options.geom_flag = 0; + if (strcasecmp(argv[1], "elasticBeamColumn") == 0) { + options.shear_flag = 0; + } + if (strcasecmp(argv[1], "dispBeamColumn") == 0 || + strcasecmp(argv[1], "nonlinearBeamColumn") == 0) { + options.shear_flag = 0; + } + else if (strcasecmp(argv[1], "timoshenkoBeamColumn") == 0) { + options.shear_flag = 1; + } + + + // + // Parse positions + // + { + while (argi < argc) { + // Shear + if (strcmp(argv[argi], "-shear") == 0) { + if (argc < argi + 2) { + opserr << OpenSees::PromptValueError << "not enough arguments, expected -shear $flag\n"; + status = TCL_ERROR; + goto clean_up; + } + if (Tcl_GetInt(interp, argv[argi + 1], &options.shear_flag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid shear_flag, expected integer\n"; + status = TCL_ERROR; + goto clean_up; + } + argi += 2; + } + + // Geometry + else if (strcmp(argv[argi], "-order") == 0) { + if (argc < argi + 2) { + opserr << OpenSees::PromptValueError << "not enough arguments, expected -order $flag\n"; + status = TCL_ERROR; + goto clean_up; + } + if (Tcl_GetInt(interp, argv[argi + 1], &options.geom_flag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid geom_flag, expected integer\n"; + status = TCL_ERROR; + goto clean_up; + } + argi += 2; + } + + // -iter $max_iter $tol + else if (strcmp(argv[argi], "-iter") == 0) { + if (argc < argi + 3) { + opserr << OpenSees::PromptValueError << "not enough -iter args need -iter max_iter? tol?\n"; + status = TCL_ERROR; + goto clean_up; + } + if (Tcl_GetInt(interp, argv[argi + 1], &max_iter) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid max_iter\n"; + status = TCL_ERROR; + goto clean_up; + } + if (Tcl_GetDouble(interp, argv[argi + 2], &tol) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid tol\n"; + status = TCL_ERROR; + goto clean_up; + } + argi += 3; + } + // mass + else if (strcmp(argv[argi], "-mass") == 0) { + if (argc < argi + 2) { + opserr << OpenSees::PromptValueError << "not enough arguments, expected -mass $mass\n"; + status = TCL_ERROR; + goto clean_up; + } + if (Tcl_GetDouble(interp, argv[argi + 1], &mass) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid mass\n"; + status = TCL_ERROR; + goto clean_up; + } + argi += 2; + use_mass = true; + + // mass type + } else if ((strcmp(argv[argi], "-lMass") == 0) || + (strcmp(argv[argi], "lMass") == 0)) { + options.mass_flag = 0; + argi++; + } + else if ((strcmp(argv[argi], "-cMass") == 0) || + (strcmp(argv[argi], "cMass") == 0)) { + options.mass_flag = 1; + argi++; + } + + // Quadrature + else if (strcmp(argv[argi], "-integration") == 0) { + if (argc < argi + 2) { + opserr << OpenSees::PromptValueError << "not enough arguments, expected -integration $integration\n"; + status = TCL_ERROR; + goto clean_up; + } + + argi++; + integration_type = argv[argi]; + // beamIntegr = GetBeamIntegration(argv[argi]); + + // if (beamIntegr == nullptr) { + // opserr << OpenSees::PromptValueError << "invalid integration type\n"; + // status = TCL_ERROR; + // goto clean_up; + // } + argi++; + } + + // Transform + else if (strcmp(argv[argi], "-transform") == 0) { + if (argc < argi + 2) { + opserr << OpenSees::PromptValueError << "not enough arguments, expected -transform $transform\n"; + status = TCL_ERROR; + goto clean_up; + } + + argi++; + if (Tcl_GetInt(interp, argv[argi], &transfTag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid transform\n"; + status = TCL_ERROR; + goto clean_up; + } + argi++; + } + + // Section + else if (strcmp(argv[argi], "-section") == 0) { + if (argc < argi + 2) { + opserr << OpenSees::PromptValueError << "not enough arguments, expected -section $section\n"; + status = TCL_ERROR; + goto clean_up; + } + + argi++; + int sec_tag; + if (Tcl_GetInt(interp, argv[argi], &sec_tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid sec_tag\n"; + status = TCL_ERROR; + goto clean_up; + } + + section_tags.push_back(sec_tag); + + argi++; + } + + + //else if (strcmp(argv[argi], "-sections") == 0) { + // split possible lists present in argv + //char *List = Tcl_Merge(inArgc, inArgv); + //if (List == nullptr) { + // opserr << OpenSees::PromptValueError << "problem merging list\n"; + // return TCL_ERROR; + //} + // int secc; + // TCL_Char ** secv; + // if (Tcl_SplitList(interp, argv[positions[2]], &secc, &secv) != TCL_OK) { + // opserr << OpenSees::PromptValueError << "problem splitting list\n"; + // return TCL_ERROR; + // } + //Tcl_Free((char *)List); + + //} + else { + positions.push_back(argi); + argi++; + } + } + } + + // + // II Parse Positional Arguments + // + + // Version d) + // positional arguments are: + // 0: nIP + // 1: -sections + // 2: secTag1 + // 3: secTag2... + if (positions.size() > 1 && strcmp(argv[positions[1]], "-sections") == 0) { + + int nIP; + if (Tcl_GetInt(interp, argv[positions[0]], &nIP) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid nIP\n"; + status = TCL_ERROR; + goto clean_up; + } + // TODO: Make sure 2+nIP < positions.size() + + // Get section tags + for (int i = 0; i < nIP; i++) { + int secTag; + if (Tcl_GetInt(interp, argv[positions[2+i]], &secTag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid section\n"; + status = TCL_ERROR; + goto clean_up; + } + section_tags.push_back(secTag); + } + + if (Tcl_GetInt(interp, argv[positions[2+nIP]], &transfTag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid transform\n"; + status = TCL_ERROR; + goto clean_up; + } + + } + + // Version e) ? + else if (positions.size() == 1) { + if (section_tags.empty()) { + status = TCL_ERROR; + goto clean_up; + } + } + + // Version a or b + else if (positions.size() == 2 || positions.size() > 3) { + // Here we create a BeamIntegrationRule (theRule) which is a pair of + // section tags and a BeamIntegration. In this case we do not + // delete the BeamIntegration because it is owned by theRule. + + // Geometric transformation + if (Tcl_GetInt(interp, argv[positions[0]], &transfTag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid transform " << argv[positions[0]] + << OpenSees::SignalMessageEnd; + status = TCL_ERROR; + goto clean_up; + } + + // Version b) + if (Tcl_GetInt(interp, argv[positions[1]], &itg_tag) == TCL_OK) { + deleteBeamIntegr = false; + removeHingeIntegr = false; + } + + // Version a) + else { + // If we fail to parse an integer tag, treat it like an inline definition + builder->findFreeTag(itg_tag); + std::string integrCommand{argv[positions[1]]}; + integrCommand.insert(integrCommand.find(" "), " "+std::to_string(itg_tag)+" "); + integrCommand.insert(0, "beamIntegration "); + if (Tcl_Eval(interp, integrCommand.c_str()) != TCL_OK) { + opserr << OpenSees::PromptValueError << "failed to parse integration\n"; + status = TCL_ERROR; + goto clean_up; + } + + deleteBeamIntegr = false; + removeHingeIntegr = true; + } + + theRule = builder->getTypedObject(itg_tag); + if (theRule == nullptr) { + status = TCL_ERROR; + goto clean_up; + } + + beamIntegr = theRule->getBeamIntegration(); + const ID& secTags = theRule->getSectionTags(); + + for (int i=0; i < secTags.Size(); i++) + section_tags.push_back(secTags(i)); + } + + // Version c) + // + // .. nip section transf + else if (positions.size() == 3) { + + int nIP; + if (Tcl_GetInt(interp, argv[positions[0]], &nIP) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid nIP\n"; + status = TCL_ERROR; + goto clean_up; + } + if (nIP <= 0) { + opserr << OpenSees::PromptValueError << "invalid nIP, must be > 0\n"; + status = TCL_ERROR; + goto clean_up; + } + + // + int secTag; + if (Tcl_GetInt(interp, argv[positions[1]], &secTag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid secTag\n"; + status = TCL_ERROR; + goto clean_up; + } + + for (int i=0; i < nIP; i++) + section_tags.push_back(secTag); + + // Transform + if (Tcl_GetInt(interp, argv[positions[2]], &transfTag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid transform\n"; + status = TCL_ERROR; + goto clean_up; + } + } + + // + // Finalize the quadrature + // + // TODO + if (section_tags.size() == 1 && theRule == nullptr) { + if (strstr(argv[1], "isp") == 0) { + section_tags.resize(5, section_tags[0]); + } else { + section_tags.resize(5, section_tags[0]); + } + } + + if (beamIntegr == nullptr) { + if (integration_type == nullptr) { + if (strstr(argv[1], "ispBeam") == 0) { + integration_type = "Lobatto"; + } else { + integration_type = "Legendre"; + } + } + + if ((beamIntegr = GetBeamIntegration(integration_type, section_tags.size())) == nullptr) { + opserr << OpenSees::PromptValueError << "invalid integration type or size\n"; + status = TCL_ERROR; + goto clean_up; + } + deleteBeamIntegr = true; + } + + // + // + options.use_mass = use_mass; + { + Element *theElement = ndm == 2 + ? CreateFrame<2, CrdTransf, FrameSection>(*builder, argv[1], tag, multi_nodes, transfTag, + section_tags, *beamIntegr, mass, max_iter, tol, options) + : CreateFrame<3, CrdTransf, FrameSection>(*builder, argv[1], tag, multi_nodes, transfTag, + section_tags, *beamIntegr, mass, max_iter, tol, options); + + + if (theElement == nullptr) { + status = TCL_ERROR; + goto clean_up; + } + if (domain->addElement(theElement) == false) { + opserr << OpenSees::PromptValueError + << "could not add element to the domain" + << OpenSees::SignalMessageEnd; + delete theElement; + status = TCL_ERROR; + goto clean_up; + } + } + + +clean_up: + // + // Clean up + // + if (deleteBeamIntegr && beamIntegr != nullptr) + delete beamIntegr; + + if (removeHingeIntegr) { + builder->removeObject(itg_tag); + delete theRule; + } + + return status; +} + + +// +// BeamWithHinges +// +// element beamWithHinges tag? ndI? ndJ? secTagI? lenI? secTagJ? lenJ? +// E? A? I? transfTag? <-shear shearLength?> <-mass massDens?> +// <-iter maxIters tolerance> +// +int +TclBasicBuilder_addBeamWithHinges(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + + int NDM = builder->getNDM(); + int NDF = builder->getNDF(); + + // Plane frame element + if (NDM == 2 && NDF == 3) { + if (argc < 13) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element beamWithHinges tag? ndI? ndJ? secTagI? lenI? " + "secTagJ? lenJ? "; + opserr << "E? A? I? transfTag? <-shear shearLength?> <-mass massDens?> " + "<-iter maxIters tolerance>" + << "\n"; + return TCL_ERROR; + } + + double massDens = 0.0; + int max_iters = 10; + double tol = 1.0e-10; + int tag, ndI, ndJ, secTagI, secTagJ, transfTag; + double lenI, lenJ, E, A, I; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid beamWithHinges tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &ndI) != TCL_OK) { + opserr << "WARNING invalid ndI\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4], &ndJ) != TCL_OK) { + opserr << "WARNING invalid ndJ\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[5], &secTagI) != TCL_OK) { + opserr << "WARNING invalid secTagI\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &lenI) != TCL_OK) { + opserr << "WARNING invalid lenI\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[7], &secTagJ) != TCL_OK) { + opserr << "WARNING invalid ndJ\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[8], &lenJ) != TCL_OK) { + opserr << "WARNING invalid lenJ\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[9], &E) != TCL_OK) { + opserr << "WARNING invalid E\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10], &A) != TCL_OK) { + opserr << "WARNING invalid A\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[11], &I) != TCL_OK) { + opserr << "WARNING invalid I\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[12], &transfTag) != TCL_OK) { + opserr << "WARNING invalid transfTag\n"; + return TCL_ERROR; + } + + bool isShear = false; + int shearTag = 0; + + if (argc > 13) { + for (int i = 13; i < argc; ++i) { + if (strcmp(argv[i], "-mass") == 0 && ++i < argc) { + if (Tcl_GetDouble(interp, argv[i], &massDens) != TCL_OK) { + opserr << "WARNING invalid massDens\n"; + opserr << "BeamWithHinges: " << tag << "\n"; + return TCL_ERROR; + } + } + + if (strcmp(argv[i], "-constHinge") == 0 && ++i < argc) { + if (Tcl_GetInt(interp, argv[i], &shearTag) != TCL_OK) { + opserr << "WARNING invalid constHinge tag\n"; + opserr << "BeamWithHinges: " << tag << "\n"; + return TCL_ERROR; + } + isShear = true; + } + + if (strcmp(argv[i], "-iter") == 0 && i + 2 < argc) { + if (Tcl_GetInt(interp, argv[++i], &max_iters) != TCL_OK) { + opserr << "WARNING invalid maxIters\n"; + opserr << "BeamWithHinges: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[++i], &tol) != TCL_OK) { + opserr << "WARNING invalid tolerance\n"; + opserr << "BeamWithHinges: " << tag << "\n"; + return TCL_ERROR; + } + } + } + } + + // Retrieve section I from the model builder + FrameSection *sectionI = builder->getTypedObject(secTagI); + if (sectionI == nullptr) + return TCL_ERROR; + + // Retrieve section J from the model builder + FrameSection *sectionJ = builder->getTypedObject(secTagJ); + if (sectionJ == nullptr) + return TCL_ERROR; + + + CrdTransf *theTransf = builder->getTypedObject(transfTag); + if (theTransf == nullptr) + return TCL_ERROR; + + Element *theElement = nullptr; + int numSections = 0; + SectionForceDeformation *sections[10]; + BeamIntegration *theBeamIntegr = nullptr; + + ElasticSection2d elastic(8, E, A, I); + + if (strcmp(argv[1], "beamWithHinges1") == 0) { + theBeamIntegr = new HingeMidpointBeamIntegration(lenI, lenJ); + + numSections = 4; + + sections[0] = sectionI; + sections[1] = &elastic; + sections[2] = &elastic; + sections[3] = sectionJ; + + } else if (strcmp(argv[1], "beamWithHinges2") == 0) { + theBeamIntegr = new HingeRadauTwoBeamIntegration(lenI, lenJ); + + numSections = 6; + sections[0] = sectionI; + sections[1] = sectionI; + sections[2] = &elastic; + sections[3] = &elastic; + sections[4] = sectionJ; + sections[5] = sectionJ; + + } else if (strcmp(argv[1], "beamWithHinges3") == 0 || + strcmp(argv[1], "beamWithHinges") == 0) { + theBeamIntegr = new HingeRadauBeamIntegration(lenI, lenJ); + + numSections = 6; + sections[0] = sectionI; + sections[1] = &elastic; + sections[2] = &elastic; + sections[3] = &elastic; + sections[4] = &elastic; + sections[5] = sectionJ; + + } else if (strcmp(argv[1], "beamWithHinges4") == 0) { + theBeamIntegr = new HingeEndpointBeamIntegration(lenI, lenJ); + + numSections = 4; + sections[0] = sectionI; + sections[1] = &elastic; + sections[2] = &elastic; + sections[3] = sectionJ; + } + + if (theBeamIntegr == nullptr) { + opserr << "Unknown element type: " << argv[1] << "\n"; + return TCL_ERROR; + } + + if (isShear) { + FrameSection *sectionL = builder->getTypedObject(shearTag); + if (sectionL == nullptr) + return TCL_ERROR; + + sections[numSections++] = sectionL; + } + + theElement = new ForceBeamColumn2d(tag, ndI, ndJ, numSections, + sections, + *theBeamIntegr, *theTransf, massDens, + max_iters, tol); + + delete theBeamIntegr; + + if (builder->getDomain()->addElement(theElement) == false) { + opserr << "WARNING could not add element to domain.\n"; + return TCL_ERROR; + } + } + + else if (NDM == 3 && NDF == 6) { + if (argc < 16) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element beamWithHinges tag? ndI? ndJ? secTagI? lenI? " + "secTagJ? lenJ? "; + opserr << "E? A? Iz? Iy? G? J? transfTag? <-shear shearLength?> <-mass " + "massDens?> <-iter maxIters tolerance>" + << "\n"; + return TCL_ERROR; + } + + int tag, ndI, ndJ, secTagI, secTagJ, transfTag; + double lenI, lenJ, E, A, Iz, Iy, G, J; + double massDens = 0.0; + int max_iters = 10; + double tol = 1.0e-10; + double shearLength = 1.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid beamWithHinges tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &ndI) != TCL_OK) { + opserr << "WARNING invalid ndI\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4], &ndJ) != TCL_OK) { + opserr << "WARNING invalid ndJ\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[5], &secTagI) != TCL_OK) { + opserr << "WARNING invalid secTagI\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &lenI) != TCL_OK) { + opserr << "WARNING invalid lenI\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[7], &secTagJ) != TCL_OK) { + opserr << "WARNING invalid ndJ\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[8], &lenJ) != TCL_OK) { + opserr << "WARNING invalid lenJ\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[9], &E) != TCL_OK) { + opserr << "WARNING invalid E\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10], &A) != TCL_OK) { + opserr << "WARNING invalid A\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[11], &Iz) != TCL_OK) { + opserr << "WARNING invalid Iz\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[12], &Iy) != TCL_OK) { + opserr << "WARNING invalid Iy\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[13], &G) != TCL_OK) { + opserr << "WARNING invalid G\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[14], &J) != TCL_OK) { + opserr << "WARNING invalid J\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[15], &transfTag) != TCL_OK) { + opserr << "WARNING invalid transfTag\n"; + return TCL_ERROR; + } + + + if (argc > 16) { + for (int i = 16; i < argc; ++i) { + if (strcmp(argv[i], "-mass") == 0 && ++i < argc) { + if (Tcl_GetDouble(interp, argv[i], &massDens) != TCL_OK) { + opserr << "WARNING invalid massDens\n"; + opserr << "BeamWithHinges: " << tag << "\n"; + return TCL_ERROR; + } + } + + if (strcmp(argv[i], "-shear") == 0 && ++i < argc) { + if (Tcl_GetDouble(interp, argv[i], &shearLength) != TCL_OK) { + opserr << "WARNING invalid shear\n"; + return TCL_ERROR; + } + } + + if (strcmp(argv[i], "-iter") == 0 && i + 2 < argc) { + if (Tcl_GetInt(interp, argv[++i], &max_iters) != TCL_OK) { + opserr << "WARNING invalid maxIters\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[++i], &tol) != TCL_OK) { + opserr << "WARNING invalid tolerance\n"; + return TCL_ERROR; + } + } + } + } + + // Retrieve section I from the model builder + SectionForceDeformation *sectionI = builder->getTypedObject(secTagI); + if (sectionI == nullptr) + return TCL_ERROR; + + // Retrieve section J from the model builder + SectionForceDeformation *sectionJ = builder->getTypedObject(secTagJ); + if (sectionJ == nullptr) + return TCL_ERROR; + + + CrdTransf *theTransf = builder->getTypedObject(transfTag); + if (theTransf == nullptr) + return TCL_ERROR; + + + Element *theElement = nullptr; + int numSections = 0; + SectionForceDeformation *sections[10]; + BeamIntegration *theBeamIntegr = nullptr; + + ElasticSection3d elastic(0, E, A, Iz, Iy, G, J); + + if (strcmp(argv[1], "beamWithHinges1") == 0) { + theBeamIntegr = new HingeMidpointBeamIntegration(lenI, lenJ); + + numSections = 4; + sections[0] = sectionI; + sections[1] = &elastic; + sections[2] = &elastic; + sections[3] = sectionJ; + + } else if (strcmp(argv[1], "beamWithHinges2") == 0) { + theBeamIntegr = new HingeRadauTwoBeamIntegration(lenI, lenJ); + + numSections = 6; + sections[0] = sectionI; + sections[1] = sectionI; + sections[2] = &elastic; + sections[3] = &elastic; + sections[4] = sectionJ; + sections[5] = sectionJ; + + } else if (strcmp(argv[1], "beamWithHinges3") == 0 || + strcmp(argv[1], "beamWithHinges") == 0) { + theBeamIntegr = new HingeRadauBeamIntegration(lenI, lenJ); + + numSections = 6; + sections[0] = sectionI; + sections[1] = &elastic; + sections[2] = &elastic; + sections[3] = &elastic; + sections[4] = &elastic; + sections[5] = sectionJ; + + } else if (strcmp(argv[1], "beamWithHinges4") == 0) { + theBeamIntegr = new HingeEndpointBeamIntegration(lenI, lenJ); + + numSections = 4; + sections[0] = sectionI; + sections[1] = &elastic; + sections[2] = &elastic; + sections[3] = sectionJ; + } + + if (theBeamIntegr == nullptr) { + opserr << "Unknown element type: " << argv[1] << "\n"; + return TCL_ERROR; + } + + // TODO fix shear for beamWithHinges + /* + if (isShear) { + SectionForceDeformation *sectionL = builder->getTypedObject(shearTag); + + if (sectionL == 0) { + opserr << "WARNING section L does not exist\n"; + opserr << "section: " << shearTag; + opserr << "\nBeamWithHinges: " << tag << "\n"; + return TCL_ERROR; + } + sections[numSections++] = sectionL; + } + */ + + theElement = new ForceBeamColumn3d(tag, ndI, ndJ, numSections, sections, + *theBeamIntegr, *theTransf, massDens, + max_iters, tol); + + delete theBeamIntegr; + + // Add to the domain + if (builder->getDomain()->addElement(theElement) == false) { + opserr << "WARNING could not add " + "element to domain "; + opserr << tag << "\n"; + return TCL_ERROR; + } + } + + else { + opserr << "ERROR -- model dimension: " << NDM + << " and nodal degrees of freedom: " << NDF + << " are incompatible for BeamWithHinges element" << "\n"; + return TCL_ERROR; + } + + return TCL_OK; +} From 211b412c274c7629f95df5bf440eade0cbcbef6a Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 11:09:01 -0700 Subject: [PATCH 126/261] clean --- SRC/matrix/VectorND.h | 13 +- SRC/matrix/VectorND.tpp | 504 +++++++++++++++++++--------------------- SRC/matrix/Versor.h | 2 +- 3 files changed, 248 insertions(+), 271 deletions(-) diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index 5bc38a621d..0303909a84 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -33,6 +33,7 @@ #ifndef VectorND_H #define VectorND_H #include +#include #include #include @@ -73,15 +74,15 @@ struct VectorND { VectorND extract(int a) noexcept; - int - addVector(const T thisFact, const Vector &other, const T otherFact) noexcept; - int addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept; - template - inline int - addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact); + // int + // addVector(const T thisFact, const Vector &other, const T otherFact) noexcept; + + // template + // inline VectorND& + // addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact); template inline int diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index 99c16161a9..5c6a1bcaa0 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -63,66 +63,61 @@ VectorND::extract(int a) noexcept } -template -int -VectorND::addVector(const T thisFact, const Vector &other, const T otherFact) noexcept -{ - if (otherFact == 0.0 && thisFact == 1.0) - return 0; - - else if (thisFact == 1.0) { - // want: this += other * otherFact - double *dataPtr = values; - double *otherDataPtr = other.theData; - if (otherFact == 1.0) { - // no point doing a multiplication if otherFact == 1.0 - for (int i=0; i +// int +// VectorND::addVector(const T thisFact, const Vector &other, const T otherFact) noexcept +// { +// if (otherFact == 0.0 && thisFact == 1.0) +// return 0; + + +// const double * otherDataPtr = &other[0]; +// if (thisFact == 1.0) { +// // this += other * otherFact +// double *dataPtr = values; +// if (otherFact == 1.0) +// for (int i=0; i @@ -136,13 +131,13 @@ VectorND::addVector(const T thisFact, const VectorND &other, const T oth // want: this += other * otherFact double *dataPtr = values; const double * otherDataPtr = other.values; - if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0 + if (otherFact == 1.0) for (int i=0; i::addVector(const T thisFact, const VectorND &other, const T oth double *dataPtr = values; const double *otherDataPtr = other.values; if (otherFact == 1.0) { - // no point doing a multiplication if otherFact == 1.0 for (int i=0; i::addVector(const T thisFact, const VectorND &other, const T oth // want: this = this * thisFact + other * otherFact double *dataPtr = values; const double *otherDataPtr = other.values; - if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0 + if (otherFact == 1.0) { for (int i=0; i::addVector(const T thisFact, const VectorND &other, const T oth } -template -template -inline int -VectorND::addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact) -{ - // check the sizes are compatable - assert(NC == v.sz); - - // see if quick return - if (thisFact == 1.0 && otherFact == 0.0) - return 0; - - else { - int incr = 1, - i = N, - n = NC; - DGEMV("N", &i, &n, - &otherFact, - &m.values[0][0], &i, - v.theData, &incr, - &thisFact, - values, - &incr); - - return 0; - } -} - - -template -template -inline int -VectorND::addMatrixTransposeVector(double thisFact, const MatrixND &m, const Vector &v, double otherFact) -{ - // check the sizes are compatable - assert(NR == v.sz); - - - if (thisFact == 1.0 && otherFact == 0.0) - return 0; - - else { - int incr = 1, - i = NR, - n = N; - DGEMV("T", &i, &n, - &otherFact, - &m.values[0][0], &i, - v.theData, &incr, - &thisFact, - values, &incr); - return 0; - } -} - - -template -inline int -VectorND::addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact) -{ - // check the sizes are compatable - assert(N == m.noRows()); - assert(m.noCols() == v.sz); - - // see if quick return - if (thisFact == 1.0 && otherFact == 0.0) - return 0; - -#ifdef VECTOR_BLAS - else if (v.sz > 10) { - int incr = 1, - i = m.numRows, - n = m.numCols; - return - DGEMV("N", &i, &n, - &otherFact, - m.data, &i, - v.theData, &incr, - &thisFact, - values, &incr); - } -#endif - - else if (thisFact == 1.0) { - - // want: this += m * v * otherFact - if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0 - int otherSize = v.sz; - double *matrixDataPtr = m.data; - const double *otherDataPtr = v.theData; - for (int i=0; i +// template +// inline int +// VectorND::addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact) +// { +// // check the sizes are compatable +// assert(NC == v.Size()); + +// // see if quick return +// if (thisFact == 1.0 && otherFact == 0.0) +// return 0; + +// else { +// int incr = 1, +// i = N, +// n = NC; +// DGEMV("N", &i, &n, +// &otherFact, +// &m.values[0][0], &i, +// &v[0], &incr, +// &thisFact, +// values, +// &incr); + +// return 0; +// } +// } + + +// template +// template +// inline int +// VectorND::addMatrixTransposeVector(double thisFact, const MatrixND &m, const Vector &v, double otherFact) +// { +// // check the sizes are compatable +// assert(NR == v.Size()); + + +// if (thisFact == 1.0 && otherFact == 0.0) +// return 0; + +// else { +// int incr = 1, +// i = NR, +// n = N; +// DGEMV("T", &i, &n, +// &otherFact, +// &m.values[0][0], &i, +// &v[0], &incr, +// &thisFact, +// values, &incr); +// return 0; +// } +// } + + +// template +// inline VectorND& +// VectorND::addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact) +// { +// // check the sizes are compatable +// assert(N == m.noRows()); +// assert(m.noCols() == v.Size()); + +// // see if quick return +// if (thisFact == 1.0 && otherFact == 0.0) +// return 0; + +// else if (thisFact == 1.0) { + +// // want: this += m * v * otherFact +// if (otherFact == 1.0) { +// int otherSize = v.Size(); +// double *matrixDataPtr = m.data; +// const double *otherDataPtr = &v[0]; +// for (int i=0; i -#include +#include #if 0 namespace OpenSees { From c7525664f378f986587954ff34fa6bb4ccb7be57 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 11:18:46 -0700 Subject: [PATCH 127/261] clean up --- SRC/matrix/VectorND.h | 12 -- SRC/matrix/VectorND.tpp | 242 ---------------------------------------- 2 files changed, 254 deletions(-) diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index 0303909a84..5e882e00fc 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -77,18 +77,6 @@ struct VectorND { int addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept; - // int - // addVector(const T thisFact, const Vector &other, const T otherFact) noexcept; - - // template - // inline VectorND& - // addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact); - - template - inline int - addMatrixTransposeVector(double thisFact, const MatrixND &m, - const Vector &v, double otherFact); - inline int addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact); diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index 5c6a1bcaa0..8296383cef 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -8,8 +8,6 @@ // #include #include "VectorND.h" -#include "blasdecl.h" - namespace OpenSees { @@ -63,63 +61,6 @@ VectorND::extract(int a) noexcept } -// template -// int -// VectorND::addVector(const T thisFact, const Vector &other, const T otherFact) noexcept -// { -// if (otherFact == 0.0 && thisFact == 1.0) -// return 0; - - -// const double * otherDataPtr = &other[0]; -// if (thisFact == 1.0) { -// // this += other * otherFact -// double *dataPtr = values; -// if (otherFact == 1.0) -// for (int i=0; i int VectorND::addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept @@ -178,187 +119,4 @@ VectorND::addVector(const T thisFact, const VectorND &other, const T oth return 0; } - -// template -// template -// inline int -// VectorND::addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact) -// { -// // check the sizes are compatable -// assert(NC == v.Size()); - -// // see if quick return -// if (thisFact == 1.0 && otherFact == 0.0) -// return 0; - -// else { -// int incr = 1, -// i = N, -// n = NC; -// DGEMV("N", &i, &n, -// &otherFact, -// &m.values[0][0], &i, -// &v[0], &incr, -// &thisFact, -// values, -// &incr); - -// return 0; -// } -// } - - -// template -// template -// inline int -// VectorND::addMatrixTransposeVector(double thisFact, const MatrixND &m, const Vector &v, double otherFact) -// { -// // check the sizes are compatable -// assert(NR == v.Size()); - - -// if (thisFact == 1.0 && otherFact == 0.0) -// return 0; - -// else { -// int incr = 1, -// i = NR, -// n = N; -// DGEMV("T", &i, &n, -// &otherFact, -// &m.values[0][0], &i, -// &v[0], &incr, -// &thisFact, -// values, &incr); -// return 0; -// } -// } - - -// template -// inline VectorND& -// VectorND::addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact) -// { -// // check the sizes are compatable -// assert(N == m.noRows()); -// assert(m.noCols() == v.Size()); - -// // see if quick return -// if (thisFact == 1.0 && otherFact == 0.0) -// return 0; - -// else if (thisFact == 1.0) { - -// // want: this += m * v * otherFact -// if (otherFact == 1.0) { -// int otherSize = v.Size(); -// double *matrixDataPtr = m.data; -// const double *otherDataPtr = &v[0]; -// for (int i=0; i Date: Sun, 29 Jun 2025 11:20:51 -0700 Subject: [PATCH 128/261] clean up matrices --- SRC/matrix/{Rotations.hpp => GroupSO3.h} | 0 SRC/matrix/MatrixND.h | 11 +---------- SRC/matrix/MatrixND.tpp | 1 - 3 files changed, 1 insertion(+), 11 deletions(-) rename SRC/matrix/{Rotations.hpp => GroupSO3.h} (100%) diff --git a/SRC/matrix/Rotations.hpp b/SRC/matrix/GroupSO3.h similarity index 100% rename from SRC/matrix/Rotations.hpp rename to SRC/matrix/GroupSO3.h diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index b0fd8a6b33..7938625169 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -39,7 +39,6 @@ #include "VectorND.h" #include "Matrix.h" #include "Vector.h" -#include "routines/SY3.h" #if __cplusplus < 202000L # define consteval @@ -55,19 +54,11 @@ requires(NR > 0 && NC > 0) struct MatrixND { double values[NC][NR]; - // MatrixND(const MatrixND&) = default; - - // Convert to regular Matrix class + // Convert to dynamic Matrix class operator Matrix() { return Matrix(&values[0][0], NR, NC);} operator const Matrix() const { return Matrix(&values[0][0], NR, NC);} - int symeig(VectorND& vals) requires(NR == NC == 3) { - double work[3][3]; - cmx_eigSY3(values, work, vals.values); - return 0; - } - consteval void zero(); constexpr MatrixND transpose() const; diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index 78dd7ec459..97e63fc9d4 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -12,7 +12,6 @@ #include "MatrixND.h" #include "blasdecl.h" #include "routines/cmx.h" -#include "routines/SY3.h" namespace OpenSees { From ddc1da0a5dd7408e2708c1911b83cd7f9c1a2a4d Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 11:42:41 -0700 Subject: [PATCH 129/261] cleaning --- .../Frame/BasicFrameTransf.tpp | 1 - .../Frame/EuclidFrameTransf.tpp | 3 +- .../Frame/FrameTransform.h | 54 +- .../Frame/Isometry/CrisfieldIsometry.tpp | 18 + .../Frame/Isometry/CrisfieldTransform.h | 284 ++++++ .../Frame/Isometry/EuclidIsometry.h | 4 - .../Frame/LinearFrameTransf.h | 13 +- .../Frame/LinearFrameTransf.tpp | 64 +- .../Frame/SouzaFrameTransf.h | 156 +++ .../Frame/SouzaFrameTransf.tpp | 941 ++++++++++++++++++ SRC/matrix/GroupSO3.h | 30 - SRC/matrix/MatrixND.h | 38 +- SRC/matrix/MatrixND.tpp | 16 - SRC/matrix/VectorND.h | 22 - SRC/matrix/Versor.h | 2 + 15 files changed, 1426 insertions(+), 220 deletions(-) create mode 100644 SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp create mode 100644 SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h create mode 100644 SRC/coordTransformation/Frame/SouzaFrameTransf.h create mode 100644 SRC/coordTransformation/Frame/SouzaFrameTransf.tpp diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index a7e5ade02a..ae3a9d9886 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "FrameTransform.h" diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 8d384c3532..5503160dcd 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -27,8 +27,7 @@ #include #include #include -#include -#include +#include #include "EuclidFrameTransf.h" namespace OpenSees { diff --git a/SRC/coordTransformation/Frame/FrameTransform.h b/SRC/coordTransformation/Frame/FrameTransform.h index 3a3e54af78..53bf7713c6 100644 --- a/SRC/coordTransformation/Frame/FrameTransform.h +++ b/SRC/coordTransformation/Frame/FrameTransform.h @@ -24,25 +24,11 @@ #include #include #include -#include // TODO: remove this include -// class CrdTransf; -#define MAYBE_STATIC static - -using OpenSees::VectorND; -using OpenSees::MatrixND; -using OpenSees::Matrix3D; class Information; class Response; class Node; -enum { - CRDTR_TAG_CorotFrameTransfWarping3d, - CRDTR_TAG_CorotFrameTransf3d, - CRDTR_TAG_LinearFrameTransf3d, - CRDTR_TAG_PDeltaFrameTransf3d -}; - enum { OffsetGlobal = 0, // 1<<0, OffsetLocal = 1, // 1<<1, @@ -67,32 +53,24 @@ class FrameTransform : public TaggedObject virtual FrameTransform *getCopy() const =0; - virtual VectorND getStateVariation() =0; - - virtual Vector3D getNodePosition(int tag) =0; - virtual Vector3D getNodeRotationLogarithm(int tag) =0; -#if 0 - virtual Versor getNodeRotation(int tag); - virtual Vector3D getNodeRotationVariation(int tag); - virtual VectorND getNodeRotationIncrement(int tag); - - virtual VectorND getNodeLogarithm(int tag) =0; - virtual VectorND getNodeVariation(int tag) =0; - virtual VectorND getNodeVelocity(int tag); - virtual VectorND getNodeLocation(int tag); -#endif virtual int initialize(std::array& nodes)=0; virtual int update() =0; virtual int commit() =0; virtual int revertToLastCommit() =0; virtual int revertToStart() =0; + + virtual Vector3D getNodePosition(int tag) =0; + virtual Vector3D getNodeRotationLogarithm(int tag) =0; + virtual VectorND getStateVariation() =0; + virtual double getInitialLength() =0; virtual double getDeformedLength() =0; virtual const std::array *getRigidOffsets() const =0; virtual VectorND pushResponse(VectorND&pl) =0; - virtual MatrixND pushResponse(MatrixND& kl, const VectorND& pl) =0; + virtual MatrixND pushResponse(MatrixND& kl, + const VectorND& pl) =0; VectorND pushConstant(const VectorND&pl); MatrixND pushConstant(const MatrixND& kl); @@ -101,18 +79,13 @@ class FrameTransform : public TaggedObject virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const =0; // Recorders - virtual Response *setResponse(const char **argv, int argc, - OPS_Stream &theHandler) { + virtual Response *setResponse(const char **argv, int argc, OPS_Stream &) { return nullptr; } virtual int getResponse(int responseID, Information &) { return -1; } - // Sensitivity - // virtual const Vector &getBasicDisplTotalGrad(int grad)=0; - // virtual const Vector &getBasicDisplFixedGrad()=0; - // virtual const Vector &getGlobalResistingForceShapeSensitivity(const Vector &pb, const Vector &p0, int grad)=0; virtual bool isShapeSensitivity() {return false;} virtual double getLengthGrad() {return 0.0;} virtual double getd1overLdh() {return 0.0;} @@ -143,10 +116,17 @@ class FrameTransform : public TaggedObject } return 0; } -protected: +}; +enum { + CRDTR_TAG_CorotFrameTransfWarping3d, + CRDTR_TAG_CorotFrameTransf3d, + CRDTR_TAG_LinearFrameTransf3d, + CRDTR_TAG_PDeltaFrameTransf3d }; -} + +} // namespace OpenSees + #include "FrameTransform.tpp" #endif // include guard diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp new file mode 100644 index 0000000000..1017532ab9 --- /dev/null +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h new file mode 100644 index 0000000000..6709c96a71 --- /dev/null +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h @@ -0,0 +1,284 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +#pragma once +#include +#include +#include +#include +#include + +namespace OpenSees { + +class CrisfieldTransform { +public: + CrisfieldTransform() {} + + int + update(const Versor& qI, const Versor& qJ, const Vector3D& dx) + { + + Ln = dx.norm(); + + { + Vector3D gammaw = CayleyFromVersor(qJ.mult_conj(qI)); + + gammaw *= 0.5; + + // Qbar = VersorProduct(VersorFromMatrix(CaySO3(gammaw)), qI); + Qbar = VersorFromMatrix(CaySO3(gammaw)*MatrixFromVersor(qI)); + Triad r{CaySO3(gammaw)*MatrixFromVersor(qI)}; + r1 = r[1]; + r2 = r[2]; + r3 = r[3]; + } + + // + // Compute the base vectors e2, e3 + // + { + // 'rotate' the mean rotation matrix Rbar on to e1 to + // obtain e2 and e3 (using the 'mid-point' procedure) + // + // Vector3D e1, e2, e3; + e[0] = dx; + e[0] /= Ln; + Matrix3D Rbar = MatrixFromVersor(Qbar); + Triad r = Triad{Rbar}; + Vector3D r1 = r[1], + r2 = r[2], + r3 = r[3]; + + // e2 = r2 - (e1 + r1)*((r2^e1)*0.5); + + Vector3D tmp; + tmp = e[0]; + tmp += r1;//Qbar.rotate(E1); + + e[1] = tmp; + { + // const Vector3D r2 = Qbar.rotate(E2); + e[1] *= 0.5*r2.dot(e[0]); + e[1].addVector(-1.0, r2, 1.0); + } + + // e3 = r3 - (e1 + r1)*((r3^e1)*0.5); + e[2] = tmp; + { + // const Vector3D r3 = Qbar.rotate(E3); + e[2] *= r3.dot(e[0])*0.5; + e[2].addVector(-1.0, r3, 1.0); + } + } + return 0; + } + + inline Matrix3D + getRotation() const noexcept + { + Matrix3D E; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + E(i,j) = e[j][i]; + return E; + } + + constexpr const Vector3D& + getBasisE1() const noexcept + { + return e[0]; + } + constexpr const Vector3D& + getBasisE2() const noexcept + { + return e[1]; + } + constexpr const Vector3D& + getBasisE3() const noexcept + { + return e[2]; + } + + + const Versor& + getReference() + { + return Qbar; + } + + static inline void + getLMatrix(const Matrix3D& A, const Vector3D& e1, const Vector3D& r1, const Vector3D &ri, MatrixND<12,3>& L) + { + static Matrix3D L1, L2; + static Matrix3D rie1r1; + static Matrix3D e1e1r1; + + const double rie1 = ri.dot(e1); + + for (int k = 0; k < 3; k++) { + const double e1r1k = (e1[k] + r1[k]); + for (int j = 0; j < 3; j++) { + rie1r1(j,k) = ri[j]*e1r1k; + e1e1r1(j,k) = e1[j]*e1r1k; + } + } + + // L1 = ri'*e1 * A/2 + A*ri*(e1 + r1)'/2; + L1.zero(); + L1.addMatrix(A, rie1*0.5); + L1.addMatrixProduct(A, rie1r1, 0.5); + + // L2 = Sri/2 - ri'*e1*S(r1)/4 - Sri*e1*(e1 + r1)'/4; + L2.zero(); + L2.addSpin(ri, 0.5); + L2.addSpin(r1, -rie1/4.0); + L2.addSpinMatrixProduct(ri, e1e1r1, -0.25); + + // L = [L1 + // L2 + // -L1 + // L2]; + + L.zero(); + L.assemble(L1, 0, 0, 1.0); + L.assemble(L2, 3, 0, 1.0); + L.assemble(L1, 6, 0, -1.0); + L.assemble(L2, 9, 0, 1.0); + + } + + static inline const MatrixND<12,12> & + getKs2Matrix(Matrix3D& A, const Vector3D& e1, const Vector3D& r1, const double Ln, const Vector3D &ri, const Vector3D &z) + { + static MatrixND<12,12> ks2; + + // Ksigma2 = [ K11 K12 -K11 K12 + // K12' K22 -K12' K22 + // -K11 -K12 K11 -K12 + // K12' K22 -K12' K22]; + + // U = (-1/2)*A*z*ri'*A + ri'*e1*A*z*e1'/(2*Ln)+... + // z'*(e1+r1)*A*ri*e1'/(2*Ln); + + const double rite1 = ri.dot(e1); + const double zte1 = z.dot(e1); + const double ztr1 = z.dot(r1); + + static Matrix3D zrit, ze1t; + static Matrix rizt(3,3), rie1t(3,3); + static Matrix3D e1zt; + + // const Matrix3D e1zt = e1.bun(z); + + // Chrystal's looping order + for (int j = 0; j < 3; j++) { + for (int i = 0; i < 3; i++) { + zrit(i,j) = z[i]*ri[j]; + rizt(i,j) = ri[i]*z[j]; + ze1t(i,j) = z[i]*e1[j]; + e1zt(i,j) = e1[i]*z[j]; + rie1t(i,j) = ri[i]*e1[j]; + } + } + + static Matrix3D U; + + U.addMatrixTripleProduct(0.0, A, zrit, -0.5); + U.addMatrixProduct(A, ze1t, rite1/(2*Ln)); + U.addMatrixProduct(A, rie1t, (zte1 + ztr1)/(2*Ln)); + + static Matrix3D ks; + static Matrix3D m1; + + // K11 = U + U' + ri'*e1*(2*(e1'*z)+z'*r1)*A/(2*Ln); + ks.zero(); + ks.addMatrix(U, 1.0); + + // Add matrix U transpose + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + ks(i,j) += U(j,i); + + ks.addMatrix(A, rite1*(2*zte1 + ztr1)/(2*Ln)); + + ks2.zero(); + ks2.assemble(ks, 0, 0, 1.0); + ks2.assemble(ks, 0, 6, -1.0); + ks2.assemble(ks, 6, 0, -1.0); + ks2.assemble(ks, 6, 6, 1.0); + + // K12 = (1/4)*(-A*z*e1'*Sri - A*ri*z'*Sr1 - z'*(e1+r1)*A*Sri); + m1.zero(); + m1.addMatrixProduct(A, ze1t, -1.0); + ks.zero(); + ks.addMatrixSpinProduct(m1, ri, 0.25); + + m1.zero(); + m1.addMatrixProduct(A, rizt, -1.0); + ks.addMatrixSpinProduct(m1, r1, 0.25); + ks.addMatrixSpinProduct(A, ri, -0.25*(zte1+ztr1)); + + ks2.assemble(ks, 0, 3, 1.0); + ks2.assemble(ks, 0, 9, 1.0); + ks2.assemble(ks, 6, 3, -1.0); + ks2.assemble(ks, 6, 9, -1.0); + + ks2.assembleTranspose(ks, 3, 0, 1.0); + ks2.assembleTranspose(ks, 3, 6, -1.0); + ks2.assembleTranspose(ks, 9, 0, 1.0); + ks2.assembleTranspose(ks, 9, 6, -1.0); + + // K22 = (1/8)*((-ri'*e1)*Sz*Sr1 + Sr1*z*e1'*Sri + ... + // Sri*e1*z'*Sr1 - (e1+r1)'*z*S(e1)*Sri + 2*Sz*Sri); + + ks.zero(); + ks.addSpinProduct(z, r1, -0.125*(rite1)); + + m1.zero(); + m1.addSpinMatrixProduct( r1, ze1t, 1.0); + ks.addMatrixSpinProduct( m1, ri, 0.125); + + m1.zero(); + m1.addSpinMatrixProduct(ri, e1zt, 1.0); + ks.addMatrixSpinProduct(m1, r1, 0.125); + + ks.addSpinProduct(e1, ri, -0.125*(zte1 + ztr1)); + ks.addSpinProduct( z, ri, 0.25); + + // Ksigma2 = [ K11 K12 -K11 K12; + // K12t K22 -K12t K22; + // -K11 -K12 K11 -K12; + // K12t K22 -K12t K22]; + + ks2.assemble(ks, 3, 3, 1.0); + ks2.assemble(ks, 3, 9, 1.0); + ks2.assemble(ks, 9, 3, 1.0); + ks2.assemble(ks, 9, 9, 1.0); + + return ks2; + } + +private: + Versor Qbar; + Vector3D r1, r2, r3; + Vector3D e[3]; + double Ln; + +}; +} \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h index b90d40062b..87e8524c65 100644 --- a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h @@ -57,10 +57,8 @@ class AlignedIsometry : public Isometry virtual Vector3D getRotationVariation(int ndf, double* du) { - // psi_r = omega Vector3D w{}; for (int i=0; igetIncrDeltaDisp(); auto Wi = this->getRotationGradient(i); for (int j=0; j<3; j++) for (int k=0; k<6; k++) @@ -68,8 +66,6 @@ class AlignedIsometry : public Isometry } return w; } - -protected: }; } // namespace OpenSees diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.h b/SRC/coordTransformation/Frame/LinearFrameTransf.h index 6622b92b01..a8705b2b3b 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.h +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.h @@ -18,12 +18,10 @@ //===----------------------------------------------------------------------===// // -// Description: This file contains the class definition for -// LinearFrameTransf.h. LinearFrameTransf provides the -// abstraction of a linear transformation for a spatial frame -// between the global and basic coordinate systems +// Description: LinearFrameTransf implements a linear axis-aligning transformation +// for a spatial frame element. // -// Adapted: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) +// Claudio Perez // #ifndef LinearFrameTransf_hpp #define LinearFrameTransf_hpp @@ -70,11 +68,8 @@ class LinearFrameTransf: public FrameTransform VectorND pushResponse(VectorND&pl) final; MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - - // // method used to rotate consistent mass matrix - // const Matrix &getGlobalMatrixFromLocal(const Matrix &local); - + // // Sensitivity // const Vector & getBasicDisplFixedGrad(); diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index 31a6dc7686..309ea3f1cd 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -17,22 +17,12 @@ // //===----------------------------------------------------------------------===// -// -// Description: This file contains the implementation for the -// LinearFrameTransf class. LinearFrameTransf is a linear -// transformation for a space frame between the global -// and basic coordinate systems -// -// Adapted: Remo Magalhaes de Souza -// Created: 04/2000 -// #pragma once #include #include #include #include -#include -#include +#include #include "LinearFrameTransf.h" namespace OpenSees { @@ -48,8 +38,6 @@ FrameOrientationGradient(const Vector3D& xi, const Vector3D& xj, Vector3D v2 = vz.cross(e1); Vector3D e2 = v2 / v2.norm(); -// Vector3D v3 = e1.cross(e2); -// Vector3D e3 = v3 / v3.norm(); // Vector3D dvz{0.0}; @@ -477,7 +465,6 @@ LinearFrameTransf::isShapeSensitivity() int nodeParameterI = nodes[ 0]->getCrdsSensitivity(); int nodeParameterJ = nodes[nn-1]->getCrdsSensitivity(); // TODO(sensitivity): implement dvz - return (nodeParameterI != 0 || nodeParameterJ != 0); } @@ -565,56 +552,8 @@ LinearFrameTransf::getBasicDisplFixedGrad() static VectorND<6> dub; static Vector wrapper(dub); // - // Form ug - // // TODO(sensitivity) -#if 0 - VectorND ug; - for (int i = 0; i < nn; i++) { - const Vector& u = nodes[i]->getTrialDisp(); - for (int j = 0; j < ndf; j++) { - ug[i*ndf+j] = u(j); - } - } - - if (u_init[0] != 0) { - for (int j = 0; j < ndf; j++) - ug[j] -= (*u_init[0])[j]; - } - - if (u_init[nn-1] != 0) { - for (int j = 0; j < ndf; j++) - ug[j + 6] -= (*u_init[nn-1])[j]; - } - - // - // dub += (T_{bl}' T_{lg} + T_{bl} T_{lg}') * ug // - int dv = 0; // TODO(sensitivity) - - // TODO: Sensitivity - int di = nodes[0]->getCrdsSensitivity(); - int dj = nodes[1]->getCrdsSensitivity(); - - - // TODO(sensitivity) - // Matrix3D dR = FrameOrientationGradient(xi, xj, vz, di, dj, dv); - // dub = getBasic(ug, 1/L); - - // - // - VectorND ul = LinearFrameTransf::pullConstant(ug, R, offsets); - // - dub[0] += 0; - double dL = this->getLengthGrad(); - double doneOverL = -dL/(L*L); - double tmp = doneOverL * (ul[1] - ul[7]); - dub[1] += tmp; - dub[2] += tmp; - tmp = doneOverL * (ul[8] - ul[2]); - dub[3] += tmp; - dub[4] += tmp; -#endif return wrapper; } @@ -625,7 +564,6 @@ LinearFrameTransf::getBasicDisplTotalGrad(int gradNumber) static VectorND<6> dub; static Vector wrapper(dub); - return wrapper; } diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.h b/SRC/coordTransformation/Frame/SouzaFrameTransf.h new file mode 100644 index 0000000000..495d26bd23 --- /dev/null +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.h @@ -0,0 +1,156 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +// +// Description: This file contains the class definition for +// SouzaFrameTransf. SouzaFrameTransf implements the formulation +// of Crisfield (1990) with the objective of maintaining the +// original "Corotational" implementation by Remo Magalhaes de Souza, within +// the new framework proposed by Perez and Filippou (2024). +// +// Written by : cmp, March 2024 +// +// Adapted from work by: Remo Magalhaes de Souza +// +#ifndef SouzaFrameTransf_hpp +#define SouzaFrameTransf_hpp + +#include +#include "FrameTransform.h" +#include +#include +#include +#include +#include +#include "Isometry/CrisfieldTransform.h" + +struct Triad; + +namespace OpenSees { + +template +class SouzaFrameTransf: public FrameTransform +{ +public: + SouzaFrameTransf(int tag, const Vector3D &vecxz, + const std::array *offset=nullptr, + int offset_flags = 0); + + ~SouzaFrameTransf(); + + const char *getClassType() const { + return "SouzaFrameTransf"; + } + + // NOTE: maybe add arg for rotation parameterization + FrameTransform *getCopy() const final; + + int initialize(std::array& new_nodes) final; + int update() final; + int commit() final; + int revertToLastCommit() final; + int revertToStart() final; + int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const final; + const std::array *getRigidOffsets() const final { return offsets; } + + double getInitialLength(); + double getDeformedLength(); + + VectorND getStateVariation() final; + Vector3D getNodePosition(int tag) final; + Vector3D getNodeRotationLogarithm(int tag) final; + + VectorND pushResponse(VectorND&pl) final; + MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + + // Sensitivity + double getLengthGrad() final; + virtual const Vector &getBasicDisplTotalGrad(int grad); + virtual const Vector &getBasicDisplFixedGrad(); + virtual const Vector &getGlobalResistingForceShapeSensitivity(const Vector &pb, const Vector &p0, int gradNumber); + + // Tagged Object + void Print(OPS_Stream &s, int flag = 0) final; + +private: + constexpr static int n = nn*ndf; + + // compute the transformation matrix + void compTransfMatrixBasicGlobal(const Versor&, const Versor*); + + int addTangent(MatrixND<12,12>& M, const VectorND<12>& pl); + + VectorND<6> pushResponse(const VectorND<6>& pa, int a, int b); + + enum { + inx= 0, // axial + iny= 1, // Vy + inz= 2, // Vz + imx= 3, // torsion + imy= 4, // rot y I + imz= 5, // rot z I + + jnx= 6, // axial + jny= 7, + jnz= 8, + jmx= 9, // torsion + jmy=10, // rot y J + jmz=11, // rot z J + }; + + // + // Member data + // + std::array nodes; + + Vector3D xAxis; // local x axis + Vector3D vz; // Vector that lies in local plane xz + Vector3D dX; + + std::array *offsets; + + double *nodeIInitialDisp, *nodeJInitialDisp; + bool initialDispChecked; + + double L; // initial element length + double Ln; // current element length (at trial state) + + Versor Q_past[nn]; // commited rotations + Versor Q_pres[nn]; // trial rotations + + Vector3D alphaI; // last trial rotations end i + Vector3D alphaJ; // last trial rotatations end j + + VectorND ul; // local displacements (size=7) + Vector3D vr[nn]; // + VectorND ulcommit; // commited local displacements + VectorND ulpr; // previous local displacements + + OpenSees::MatrixND T; // transformation from local to global system + + OpenSees::Matrix3D R0; // rotation from local to global coordinates + CrisfieldTransform crs; + + // Static workspace variables + Matrix3D A; + MatrixND<12,3> Lr2, Lr3; // auxiliary matrices +}; +} // namespace OpenSees +#include "SouzaFrameTransf.tpp" +#endif diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp new file mode 100644 index 0000000000..eca419383f --- /dev/null +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp @@ -0,0 +1,941 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +// +// Description: This file contains the implementation for the +// SouzaFrameTransf class. SouzaFrameTransf is a Corotational +// transformation for a spatial frame element between the global +// and basic coordinate systems. +// +// Written: Claudio Perez +// Created: 05/2024 +// +// Adapted from: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) +// +#include +#include +#include "SouzaFrameTransf.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Isometry/CrisfieldTransform.h" + +namespace OpenSees { + +template +SouzaFrameTransf::SouzaFrameTransf(int tag, const Vector3D &vz, + const std::array *offset, + int offset_flags) + : FrameTransform(tag), + vz(vz), + offsets{nullptr}, + L(0), Ln(0), + nodeIInitialDisp(0), nodeJInitialDisp(0), + initialDispChecked(false) +{ + alphaI.zero(); + alphaJ.zero(); + + // Rigid joint offsets + if (offset != nullptr) { + offsets = new std::array{}; + *offsets = *offset; + } +} + + +template +SouzaFrameTransf::~SouzaFrameTransf() +{ + if (offsets != nullptr) + delete offsets; +} + + +template +double +SouzaFrameTransf::getInitialLength() +{ + return L; +} + + +template +double +SouzaFrameTransf::getDeformedLength() +{ + return Ln; +} + + +template +FrameTransform * +SouzaFrameTransf::getCopy() const +{ + + SouzaFrameTransf *theCopy = + new SouzaFrameTransf(this->getTag(), vz, offsets); + + theCopy->nodes[0] = nodes[0]; + theCopy->nodes[1] = nodes[1]; + theCopy->xAxis = xAxis; + theCopy->L = L; + theCopy->Ln = Ln; + theCopy->R0 = R0; + theCopy->Q_pres[0] = Q_pres[0]; + theCopy->Q_pres[1] = Q_pres[1]; + theCopy->Q_past[0] = Q_past[0]; + theCopy->Q_past[1] = Q_past[1]; + theCopy->ul = ul; + theCopy->ulcommit = ulcommit; + return theCopy; +} + + +template +int +SouzaFrameTransf::revertToStart() +{ + ul.zero(); + Q_pres[0] = VersorFromMatrix(R0); + for (int i=1; iupdate(); + return 0; +} + + +template +int +SouzaFrameTransf::commit() +{ + ulcommit = ul; + Q_past[0] = Q_pres[0]; + Q_past[1] = Q_pres[1]; + return 0; +} + + +template +int +SouzaFrameTransf::revertToLastCommit() +{ + // determine global displacement increments from last iteration + const Vector &dispI = nodes[0]->getTrialDisp(); + const Vector &dispJ = nodes[1]->getTrialDisp(); + + for (int k = 0; k < 3; k++) { + alphaI(k) = dispI(k+3); + alphaJ(k) = dispJ(k+3); + } + + ul = ulcommit; + Q_pres[0] = Q_past[0]; + Q_pres[1] = Q_past[1]; + + this->update(); + + return 0; +} + + +template +int +SouzaFrameTransf::initialize(std::array& new_nodes) +{ + for (int i=0; igetCrds() - nodes[0]->getCrds(); + + // Add initial displacements at nodes + if (initialDispChecked == false) { + const Vector &nodeIDisp = nodes[0]->getDisp(); + const Vector &nodeJDisp = nodes[1]->getDisp(); + for (int i = 0; i<6; i++) + if (nodeIDisp[i] != 0.0) { + nodeIInitialDisp = new double [6]; + for (int j = 0; j<6; j++) + nodeIInitialDisp[j] = nodeIDisp[j]; + i = 6; + } + + for (int j = 0; j<6; j++) + if (nodeJDisp[j] != 0.0) { + nodeJInitialDisp = new double [6]; + for (int i = 0; i<6; i++) + nodeJInitialDisp[i] = nodeJDisp[i]; + j = 6; + } + initialDispChecked = true; + } + + // + // Length and Orientation + // + Vector3D dx; + + dx = nodes[nn-1]->getCrds() - nodes[0]->getCrds(); + + L = dx.norm(); + + if (L == 0.0) { + opserr << "\nSouzaFrameTransf::computeElemtLengthAndOrien: 0 length\n"; + return -2; + } + + // + // Set rotation matrix + // + int error = FrameTransform::Orient(dx, vz, R0); + if (error) + return error; + + // Compute initial pseudo-vectors for nodal triads + Q_pres[0] = Q_pres[1] = VersorFromMatrix(R0); + + ul.zero(); + ulpr.zero(); + + for (int i=0; icommit(); + + return 0; +} + +template +VectorND +SouzaFrameTransf::getStateVariation() +{ + return ul - ulpr; +} + +template +Vector3D +SouzaFrameTransf::getNodePosition(int tag) +{ + Vector3D u; + for (int i=0; i<3; i++) + u[i] = ul[tag*ndf+i]; + return u; +} + +template +Vector3D +SouzaFrameTransf::getNodeRotationLogarithm(int tag) +{ + return vr[tag]; +} + +template +void inline +SouzaFrameTransf::compTransfMatrixBasicGlobal( + const Versor& Qbar, + const Versor* Q_pres) +{ + // extract columns of rotation matrices + const Triad r {MatrixFromVersor(Qbar)}, + rI{MatrixFromVersor(Q_pres[0])}, + rJ{MatrixFromVersor(Q_pres[1])}; + const Vector3D + &e1 = crs.getBasisE1(), // E[1], + &e2 = crs.getBasisE2(), // E[2], + &e3 = crs.getBasisE3(), // E[3], + &r1 = r[1], + &r2 = r[2], + &r3 = r[3], + &rI1 = rI[1], + &rI2 = rI[2], + &rI3 = rI[3], + &rJ1 = rJ[1], + &rJ2 = rJ[2], + &rJ3 = rJ[3]; + + // Compute the transformation matrix from the basic to the + // global system + // A = (1/Ln)*(I - e1*e1'); + // Matrix3D A; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; + + // This must be called up here + CrisfieldTransform::getLMatrix(A, e1, r1, r2, Lr2); + CrisfieldTransform::getLMatrix(A, e1, r1, r3, Lr3); + + // 3 | 3 | 3 | 3 | + // T1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', O', O']'; imx + // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; imz + // T3 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', -(A*rI3)', O']'; imy + // + // T4 = [ O', O', O', ( S(rJ2)*e3 - S(rJ3)*e2 )']'; jmx + // T5 = [(A*rJ2)', O', -(A*rJ2)', ( S(rJ1)*e2 - S(rJ2)*e1 )']'; jmz + // T6 = [(A*rJ3)', O', -(A*rJ3)', ( S(rJ1)*e3 - S(rJ3)*e1 )']'; jmy + + T.zero(); + + // T1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', O', O']'; + + // (-S(rI3)*e2 + S(rI2)*e3) + Vector3D Se = rI2.cross(e3); + Se -= rI3.cross(e2); + for (int i = 0; i < 3; i++) + // T(jmx,i+3) = -Se[i]; + T(imx,i+3) = Se[i]; + + // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; + + Vector3D At = A*rI2; + + // (-S(rI2)*e1 + S(rI1)*e2)' + Se = rI1.cross(e2); + Se -= rI2.cross(e1); + for (int i = 0; i < 3; i++) { + T(imz,i ) = At[i]; + T(imz,i+3) = Se[i]; + T(imz,i+6) = -At[i]; + } + + // T3 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', -(A*rI3)', O']'; + + At = A*rI3; + + // -S(rI3)*e1 + S(rI1)*e3 + Se = rI1.cross(e3); + Se -= rI3.cross(e1); + for (int i = 0; i < 3; i++) { + T(imy,i ) = At[i]*-1; + T(imy,i+3) = Se[i]*-1; + T(imy,i+6) = -At[i]*-1; + } + + // T4 = [ O', O', O', (-S(rJ3)*e2 + S(rJ2)*e3)']'; + Se = rJ2.cross(e3); + Se -= rJ3.cross(e2); + for (int i = 0; i < 3; i++) + T(jmx, i+9) = Se[i]; // S(rJ2)*e3 - S(rJ3)*e2 + + // T5 = [(A*rJ2)', O', -(A*rJ2)', (-S(rJ2)*e1 + S(rJ1)*e2)']'; + At = A*rJ2; + Se = rJ1.cross(e2); + Se -= rJ2.cross(e1); + for (int i = 0; i < 3; i++) { + T(jmz, i ) = At[i]; + T(jmz, i+6) = -At[i]; + T(jmz, i+9) = Se[i]; // (-S(rJ2)*e1 + S(rJ1)*e2) + } + + // T6 = [(A*rJ3)', O', -(A*rJ3)', (-S(rJ3)*e1 + S(rJ1)*e3)']' + At = A*rJ3; + Se = rJ1.cross(e3); // (-S(rJ3)*e1 + S(rJ1)*e3) + Se -= rJ3.cross(e1); + for (int i = 0; i < 3; i++) { + T(jmy,i ) = At[i]*-1; + T(jmy,i+6) = -At[i]*-1; + T(jmy,i+9) = Se[i]*-1; + } + + // + // Second part + // + + // T(:,1) += Lr3*rI2 - Lr2*rI3; + // T(:,2) += Lr2*rI1; z + // T(:,3) += Lr3*rI1 ; y + + // T(:,4) += Lr3*rJ2 - Lr2*rJ3; + // T(:,5) += Lr2*rJ1 ; z // ?????? check sign + // T(:,6) += Lr3*rJ1 ; y // ?????? check sign + + // Bending Z + for (int i = 0; i < 12; i++) { + double T1i = 0; + for (int k=0; k<3; k++) + T1i += Lr2(i,k)*rI1[k]; + T(imz,i) += T1i; + } + + for (int i = 0; i < 12; i++) { + double T4i = 0; + for (int k=0; k<3; k++) + T4i += Lr2(i,k)*rJ1[k]; // Lr[i]; + T(jmz,i) += T4i; + } + + // Torsion + for (int i = 0; i < 12; i++) { + double T0i = 0; + for (int k=0; k<3; k++) + T0i += Lr3(i,k)*rI2[k] - Lr2(i,k)*rI3[k]; + // T(jmx,i) += -T0i; + T(imx,i) += T0i; + } + for (int i = 0; i < 12; i++) { + double T3i = 0; + for (int k=0; k<3; k++) + T3i += Lr3(i,k)*rJ2[k] - Lr2(i,k)*rJ3[k]; + T(jmx,i) += T3i; + } + // Bending Y + for (int i = 0; i < 12; i++) { + double T2i = 0; + for (int k=0; k<3; k++) + T2i += Lr3(i,k)*rI1[k]; // Lr[i]; + T(imy,i) += T2i*-1; + } + for (int i = 0; i < 12; i++) { + double T5i = 0; + for (int k=0; k<3; k++) + T5i += Lr3(i,k)*rJ1[k]; // Lr[i]; + T(jmy,i) += T5i*-1; + } + + // + // + // + for (int node=0; node < 2; node++) + for (int j = 0; j < 3; j++) { + const double c = 0.5 / std::cos(ul[(node? jmx : imx) + j]); + for (int i = 0; i < 12; i++) + T((node? jmx : imx) + j, i) *= c; + } + + // Axial + // T(:,7) = [-e1' O' e1' O']'; + for (int i = 0; i < 3; i++) { + T(jnx,i ) = -e1[i]; + T(jnx,i+6) = e1[i]; + } + + // Combine torsion + for (int i=0; i<12; i++) { + T(jmx,i) -= T(imx,i); + T(imx,i) = 0; + } +} + +// +// Set RI,RJ,Rbar, Ln, e and ul +// +template +int +SouzaFrameTransf::update() +{ + // determine global displacement increments from last iteration + + const Vector& dispI = nodes[ 0]->getTrialDisp(); + const Vector& dispJ = nodes[nn-1]->getTrialDisp(); + + // + // Update state + // + // 1.1 Relative translation + Vector3D dx = dX;// dx = dX + dJI; + { + // Relative translation + for (int k = 0; k < 3; k++) + dx[k] += dispJ(k) - dispI(k); + + + // Calculate the deformed length + Ln = dx.norm(); + + if (Ln == 0.0) { + opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; + return -2; + } + } + + // 1.2 Rotational displacement increments + { + Vector3D dAlphaI, dAlphaJ; + + for (int k = 0; k < 3; k++) { + dAlphaI[k] = dispI(k+3) - alphaI[k]; + alphaI[k] = dispI(k+3); + dAlphaJ[k] = dispJ(k+3) - alphaJ[k]; + alphaJ[k] = dispJ(k+3); + } + + // Update the nodal rotations + Q_pres[0] = VersorProduct(Q_pres[0], Versor::from_vector(dAlphaI)); + Q_pres[1] = VersorProduct(Q_pres[1], Versor::from_vector(dAlphaJ)); + } + + // + // 2) Form transformation + // + + crs.update(Q_pres[0], Q_pres[1], dx); + // Form the transformation tangent + this->compTransfMatrixBasicGlobal(crs.getReference(), Q_pres); + + // + // 3) Local deformations + // + + // Save previous state + ulpr = ul; + + // Rotations + { + Matrix3D e = crs.getRotation(); + vr[0] = LogC90(e^MatrixFromVersor(Q_pres[0])); + for (int i=0; i<3; i++) + ul[imx+i] = vr[0][i]; + + vr[1] = LogC90(e^MatrixFromVersor(Q_pres[1])); + for (int i=0; i<3; i++) + ul[jmx+i] = vr[1][i]; + } + + // Axial + ul(inx) = 0; + ul(jnx) = Ln - L; + + return 0; +} + + +template +inline VectorND +SouzaFrameTransf::pushResponse(VectorND&pl) +{ + // return T^pl; + VectorND pg{}; + for (int a = 0; a pa {pl(a*ndf+0), pl(a*ndf+1), pl(a*ndf+2), + pl(a*ndf+3), pl(a*ndf+4), pl(a*ndf+5)}; + + for (int b = 0; b<2; b++) { + VectorND<6> pab = pushResponse(pa, a, b); + pg.assemble(b*6, pab, 1.0); + } + } + return pg; +} + +template +VectorND<6> +SouzaFrameTransf::pushResponse(const VectorND<6>&pa, int a, int b) +{ + VectorND<6> pg{}; + for (int i = 0; i < 6; i++) + for (int j = 0; j < 6; j++) + pg[j] += T(a*6 + i, b*6+j) * pa[i]; + + return pg; +} + +// do +// K = ag'*Km*ag + Kp +// +template +MatrixND +SouzaFrameTransf::pushResponse(MatrixND& kl, const VectorND& pl) +{ + MatrixND<12,12> K; + K.addMatrixTripleProduct(0.0, T, kl, 1.0); + + // Add geometric part kg + this->addTangent(K, pl); + + return K; +} + + +// +// Add geometric part of the transformation tangent +// +// kg += T'*kl*T + ks1 + T * diag(m.*tan(thetal))*T' + ... +// m(4)*(ks2r2t3_u3 + ks2r3u2_t2) + ... +// m(2)*ks2r2t1 + m(3)*ks2r3t1 + ... +// m(5)*ks2r2u1 + m(6)*ks2r3u1 + ... +// ks3 + ks3' + ks4 + ks5; +template +int +SouzaFrameTransf::addTangent(MatrixND<12,12>& kg, const VectorND<12>& pl) +{ + const Triad r {MatrixFromVersor(crs.getReference())}, + rI{MatrixFromVersor(Q_pres[0])}, + rJ{MatrixFromVersor(Q_pres[1])}; + const Vector3D + &e1 = crs.getBasisE1(), // E[1], + &e2 = crs.getBasisE2(), // E[2], + &e3 = crs.getBasisE3(), // E[3], + &r1 = r[1], // .rotate(E1), + &r2 = r[2], // .rotate(E2), + &r3 = r[3], // .rotate(E3), + &rI1 = rI[1], // .rotate(E1), + &rI2 = rI[2], // .rotate(E2), + &rI3 = rI[3], // .rotate(E3), + &rJ1 = rJ[1], // .rotate(E1), + &rJ2 = rJ[2], // .rotate(E2), + &rJ3 = rJ[3]; // .rotate(E3); + + // NOTE[cmp] + // SouzaFrameTransf::compTransfMatrixBasicGlobal must be + // called first to set Lr1, Lr2 and T + + // Matrix3D A; + // for (int i = 0; i < 3; i++) + // for (int j = 0; j < 3; j++) + // A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; + // getLMatrix(A, e1, r1, r2, Lr2); + // getLMatrix(A, e1, r1, r3, Lr3); + + // + // Ksigma1 + // + { + const double N = -pl[0]; // Axial force + // a=0 + kg.assemble(A, 0, 0, N); + kg.assemble(A, 0, 6, -N); + // a=1 + kg.assemble(A, 6, 0, -N); + kg.assemble(A, 6, 6, N); + } + + // + // Ksigma3 + // + // ks3 = [o kbar2 | o kbar4]; + // + // where + // + // kbar2 = -Lr2*(m(3)*S(rI3) + m(1)*S(rI1)) + Lr3*(m(3)*S(rI2) - m(2)*S(rI1)) ; + // + // kbar4 = Lr2*(m(3)*S(rJ3) - m(4)*S(rJ1)) - Lr3*(m(3)*S(rJ2) + m(5)*S(rJ1)); + // + // or + // + // ks3 = [o ka+kb | o kc+kd]; + // = [o ka | o kc] + [o kb | o kd]; + // + // where + // + // ka = -Lr2*S(rI3)*m(3) + // +Lr2*S(rI1)*m(1); + // kb = Lr3*S(rI2)*m(3) + // -Lr3*S(rI1)*m(2); + // + // kc = Lr2*S(rJ3)*m(3) + // -Lr2*S(rJ1)*m(4); + // kd = -Lr3*S(rJ2)*m(3) + // +Lr3*S(rJ1)*m(5); + + VectorND<6> m; + m[0] = 0.5*pl[imx]/std::cos(ul(imx)); + m[2] = -0.5*pl[imy]/std::cos(ul(imy)); + m[1] = 0.5*pl[imz]/std::cos(ul(imz)); + + m[3] = 0.5*pl[jmx]/std::cos(ul(jmx)); + m[5] = -0.5*pl[jmy]/std::cos(ul(jmy)); + m[4] = 0.5*pl[jmz]/std::cos(ul(jmz)); + + + static Matrix3D Sm; + Sm.zero(); + Sm.addSpin(rI3, m[3]); + Sm.addSpin(rI1, m[1]); + static MatrixND<12,3> kbar; + kbar.zero(); + kbar.addMatrixProduct(Lr2, Sm, -1.0); + + Sm.zero(); + Sm.addSpin(rI2, m[3]); + Sm.addSpin(rI1, -m[2]); + kbar.addMatrixProduct(Lr3, Sm, 1.0); + + kg.assemble(kbar, 0, 3, 1.0); + kg.assembleTranspose(kbar, 3, 0, 1.0); + + Sm.zero(); + Sm.addSpin(rJ3, m[3]); + Sm.addSpin(rJ1, -m[4]); + kbar.zero(); + kbar.addMatrixProduct(Lr2, Sm, 1.0); + + Sm.zero(); + Sm.addSpin(rJ2, m[3]); + Sm.addSpin(rJ1, m[5]); + kbar.addMatrixProduct(Lr3, Sm, -1.0); + + kg.assemble(kbar, 0, 9, 1.0); + kg.assembleTranspose(kbar, 9, 0, 1.0); + + + // + // Ksigma4 + // + { + Matrix3D ks33; + ks33.zero(); + ks33.addSpinProduct(e2, rI3, m[3]); + ks33.addSpinProduct(e3, rI2, -m[3]); + ks33.addSpinProduct(e2, rI1, m[1]); + ks33.addSpinProduct(e1, rI2, -m[1]); + ks33.addSpinProduct(e3, rI1, m[2]); + ks33.addSpinProduct(e1, rI3, -m[2]); + kg.assemble(ks33, 3, 3, 1.0); + } + + // + // Ksigma4 + // + { + Matrix3D ks33; + ks33.zero(); + ks33.addSpinProduct(e2, rJ3, -m[3]); + ks33.addSpinProduct(e3, rJ2, m[3]); + ks33.addSpinProduct(e2, rJ1, m[4]); + ks33.addSpinProduct(e1, rJ2, -m[4]); + ks33.addSpinProduct(e3, rJ1, m[5]); + ks33.addSpinProduct(e1, rJ3, -m[5]); + + kg.assemble(ks33, 9, 9, 1.0); + } + + + // + // Ksigma5 + // + // Ks5 = [ Ks5_11 Ks5_12 | -Ks5_11 Ks5_14; + // Ks5_12' O | -Ks5_12' O; + // -Ks5_11 -Ks5_12 | Ks5_11 -Ks5_14; + // Ks5_14t O | -Ks5_14' O]; + // + // + // v = (1/Ln)*(m(2)*rI2 + m(3)*rI3 + m(5)*rJ2 + m(6)*rJ3); + // = 1/Ln * (m[1]*rI2 + m[2]*rI3) + // + 1/Ln * (m[4]*rJ2 + m[5]*rJ3); + // = vi + vj + // + { + Vector3D v; + v.addVector(0.0, rI2, m[1]); + v.addVector(1.0, rI3, m[2]); + v.addVector(1.0, rJ2, m[4]); + v.addVector(1.0, rJ3, m[5]); + v /= Ln; + + // Ks5_11 = A*v*e1' + e1*v'*A + (e1'*v)*A; + // = A*vi*e1' + e1*vi'*A + (e1'*vi)*A + // + A*vj*e1' + e1*vj'*A + (e1'*vj)*A; + // + Matrix3D ks33; + ks33.zero(); + ks33.addMatrix(A, e1.dot(v)); + + static Matrix3D m33; + m33.zero(); + m33.addTensorProduct(v, e1, 1.0); + + ks33.addMatrixProduct(A, m33, 1.0); + + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + m33(i,j) = e1[i]*v[j]; + + ks33.addMatrixProduct(m33, A, 1.0); + + kg.assemble(ks33, 0, 0, 1.0); + kg.assemble(ks33, 0, 6, -1.0); + kg.assemble(ks33, 6, 0, -1.0); + kg.assemble(ks33, 6, 6, 1.0); + } + + // Ks5_12 = -(m(2)*A*S(rI2) + m(3)*A*S(rI3)); + + Matrix3D ks33; + ks33.zero(); + ks33.addMatrixSpinProduct(A, rI2, -m[1]); + ks33.addMatrixSpinProduct(A, rI3, -m[2]); + + kg.assemble(ks33, 0, 3, 1.0); + kg.assemble(ks33, 6, 3, -1.0); + kg.assembleTranspose(ks33, 3, 0, 1.0); + kg.assembleTranspose(ks33, 3, 6, -1.0); + + // Ks5_14 = -(m(5)*A*S(rJ2) + m(6)*A*S(rJ3)); + + ks33.zero(); + ks33.addMatrixSpinProduct(A, rJ2, -m[4]); + ks33.addMatrixSpinProduct(A, rJ3, -m[5]); + + kg.assemble(ks33, 0, 9, 1.0); + kg.assemble(ks33, 6, 9, -1.0); + + kg.assembleTranspose(ks33, 9, 0, 1.0); + kg.assembleTranspose(ks33, 9, 6, -1.0); + + // Ksigma ------------------------------- + Vector3D rm = rI3; + + rm.addVector(1.0, rJ3, -1.0); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rm), m[3]); + +// rm = rJ2; + rm.addVector(0.0, rJ2, -1.0); + rm.addVector(1.0, rI2, -1.0); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rm), m[3]); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rI1), m[1]); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rI1), m[2]); + // + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rJ1), m[4]); + kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rJ1), m[5]); + + // + // T' * diag (M .* tan(thetal))*T + // + + for (int node=0; node<2; node++) { + for (int k = 0; k < 3; k++) { + const double factor = pl[6*node+3+k] * std::tan(ul[(node ? jmx : imx) + k]); + for (int i = 0; i < 12; i++) { + const double Tki = T((node ? jmx : imx) + k,i); + for (int j = 0; j < 12; j++) + kg(i,j) += Tki * factor * T((node ? jmx : imx) + k, j); + } + } + } + + return 0; +} + + +template +int +SouzaFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector3D &e3) const +{ + for (int i = 0; i < 3; i++) { + e1[i] = R0(i,0); + e2[i] = R0(i,1); + e3[i] = R0(i,2); + } + return 0; +} + + +template +double +SouzaFrameTransf::getLengthGrad() +{ + const int di = nodes[0]->getCrdsSensitivity(); + const int dj = nodes[1]->getCrdsSensitivity(); + + Vector3D dxi{0.0}; + Vector3D dxj{0.0}; + + if (di != 0) + dxi(di-1) = 1.0; + if (dj != 0) + dxj(dj-1) = 1.0; + + return 1/L * dX.dot(dxj - dxi); +} + +template +const Vector & +SouzaFrameTransf::getBasicDisplTotalGrad(int gradNumber) +{ + opserr << "WARNING CrdTransf::getBasicDisplTotalGrad() - this method " + << " should not be called.\n"; + + static Vector dummy(1); + return dummy; +} + +template +const Vector & +SouzaFrameTransf::getBasicDisplFixedGrad() +{ + opserr << "ERROR CrdTransf::getBasicDisplFixedGrad() - has not been" + << " implemented yet for the chosen transformation\n."; + + static Vector dummy(1); + return dummy; +} + + +template +const Vector & +SouzaFrameTransf::getGlobalResistingForceShapeSensitivity(const Vector &pb, + const Vector &p0, + int gradNumber) +{ + opserr << "ERROR CrdTransf::getGlobalResistingForceSensitivity() - has not been" + << " implemented yet for the chosen transformation." << endln; + + static Vector dummy(1); + return dummy; +} + +template +void +SouzaFrameTransf::Print(OPS_Stream &s, int flag) +{ + + if (flag == OPS_PRINT_CURRENTSTATE) { + s << "\nFrameTransform: " << this->getTag() << " Type: SouzaFrameTransf"; + s << "\tvxz: " << Vector(vz); + } + + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << OPS_PRINT_JSON_MATE_INDENT << "{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"SouzaFrameTransf\"" << ", "; + s << "\"vecxz\": [" << vz(0) << ", " << vz(1) << ", " << vz(2) << "]"; + + if (offsets != nullptr) { + s << ", \"offsets\": ["; + for (int i=0; i -//void addSpinAtRow(const VecT& V, size_t row_index); -//template -//void addSpinAtRow(const VecT& V, size_t vector_index, size_t matrix_row_index); -//template -//MatrixND& addSpin(const VecT& V, double mult) requires(NR == 3); -//template -//void addSpinAtRow(const VecT& V, double mult, size_t row_index); -//template -//void addSpinAtRow(const VecT& V, double mult, size_t vector_index, size_t matrix_row_index); -#endif - // // Indexing // @@ -408,11 +379,6 @@ struct MatrixND { inline constexpr friend MatrixND operator*(const MatrixND &left, const MatrixND &right) { MatrixND prod; -#if 0 - if constexpr (NR*NC > 16) - prod.addMatrixProduct(0, left, right, 1); - else -#endif for (index_t i = 0; i < NR; ++i) { for (index_t j = 0; j < J; ++j) { prod(i, j) = 0.0; diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index 97e63fc9d4..b3083a96c7 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -201,22 +201,6 @@ MatrixND::addMatrixProduct(const MatrixND& A, const MatT& } } -#if 0 -template -template inline -void -MatrixND::addMatrixProduct(double scale_this, const MatrixND& A, const MatT& B, double scale) -{ - int m = nr, - n = nc, - k = nk; - DGEMM("N", "N", &m, &n, &k, &scale, - const_cast(&A(0,0)), &m, - const_cast(&B(0,0)), &k, - &scale_this, &(*this)(0,0), &m); -} -#endif - // B'*C template template inline diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index 5e882e00fc..3d01b764a7 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -6,28 +6,6 @@ // https://xara.so //===----------------------------------------------------------------------===// // -// Objectives: -// - little to no overhead above C-style arrays -// - value semantics; objects do not decay to pointers; -// -// This code is influenced by the following sources -// list initialization: -// - https://stackoverflow.com/questions/42068882/list-initialization-for-a-matrix-class -// -// style/practices -// - https://quuxplusone.github.io/blog/2021/04/03/static-constexpr-whittling-knife/ -// -// Operator overloading / semantics -// - https://stackoverflow.com/questions/9851188/does-it-make-sense-to-use-move-semantics-for-operator-and-or-operator/9851423#9851423 -// -// compile-time template restrictions/concepts: -// - https://codereview.stackexchange.com/questions/259038/compile-time-matrix-class -// (C++ 20) -// - https://github.com/calebzulawski/cotila/ -// (C++ 17) -// -//===----------------------------------------------------------------------===// -// // Claudio Perez // #ifndef VectorND_H diff --git a/SRC/matrix/Versor.h b/SRC/matrix/Versor.h index bac1d1c99f..de138a77d4 100644 --- a/SRC/matrix/Versor.h +++ b/SRC/matrix/Versor.h @@ -8,6 +8,8 @@ // // Description: Versor implements a unit-normalized quaternion. // +// Claudio Perez +// #pragma once #include #include From d615b8cf066707893fc48334f245293d04ecd665 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 11:47:06 -0700 Subject: [PATCH 130/261] more small touch ups --- .../Frame/BasicFrameTransf.h | 1 - .../Frame/BasicFrameTransf.tpp | 1 + .../Frame/EuclidFrameTransf.h | 8 +- SRC/matrix/MatrixND.tpp | 42 --------- SRC/matrix/blasdecl.h | 90 ------------------- 5 files changed, 3 insertions(+), 139 deletions(-) delete mode 100644 SRC/matrix/blasdecl.h diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.h b/SRC/coordTransformation/Frame/BasicFrameTransf.h index 64d1a0f9c0..203caf626d 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.h +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.h @@ -27,7 +27,6 @@ #ifndef BasicFrameTransf3d_h #define BasicFrameTransf3d_h -#include #include #include #include diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index ae3a9d9886..37cad89f0e 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -17,6 +17,7 @@ // //===----------------------------------------------------------------------===// // +#include #include #include #include diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h index fbf25f30ec..f0d664ea08 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.h +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -73,12 +73,8 @@ class EuclidFrameTransf: public FrameTransform VectorND pushResponse(VectorND&pl) final; MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - -#if 0 - // method used to rotate consistent mass matrix - const Matrix &getGlobalMatrixFromLocal(const Matrix &local); -#endif - + + // // Sensitivity // bool isShapeSensitivity() final; diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index b3083a96c7..33d17c9029 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -262,27 +262,6 @@ MatrixND::addMatrixTransposeProduct(double thisFact, } } } -#if 0 - if (thisFact == 1.0) { - for (int j=0; j::addMatrixTripleProduct( BT.zero(); BT.addMatrixProduct(B, T, otherFact); this->addMatrixTransposeProduct(thisFact, T, BT, 1.0); - -#if 0 - { - int m = B.numRows, - n = T.numCols, - k = B.numCols, - nrT = T.numRows; - //k = T.numRows; - double zero = 0.0, - one = 1.0; - - DGEMM ("N", "N", &m , &n , &k,&one , B.data, &m, // m - T.data, &nrT, // k - &zero, matrixWork, &m); - - DGEMM ("T", "N", &numRows, &numCols, &k,&otherFact, T.data, &nrT, - matrixWork, &m, // k - &thisFact, data, &numRows); - return 0; - } -#endif return 0; } diff --git a/SRC/matrix/blasdecl.h b/SRC/matrix/blasdecl.h deleted file mode 100644 index 6b57935b82..0000000000 --- a/SRC/matrix/blasdecl.h +++ /dev/null @@ -1,90 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// -//===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// -#ifndef blasdecl_H -#define blasdecl_H - -#ifndef _WIN32 -# define DAXPY daxpy_ -# define DSCAL dscal_ -# define DGEMV dgemv_ -// Level 3 -# define DGETRF dgetrf_ -# define DGETRI dgetri_ -# define DGEMM dgemm_ -// Lapack -# define DGESV dgesv_ -# define DGETRS dgetrs_ -# define DGBSV dgbsv_ -# define DGBTRS dgbtrs_ -# define DPBSV dpbsv_ -# define DPBTRS dpbtrs_ -#endif -extern "C" { - void DAXPY (int*, double*, double*, const int*, double*, const int*); - void DSCAL (int*, double*, double*, const int*); - void DGEMV (const char* trans, int* M, int* N, - double* alpha, - const double* A, int* lda, - double* X, int* incX, - double* beta, - double* Y, int* incY); -// Level 3 -//void DGESV(int *N, int *NRHS, double *A, int *LDA, -// int *iPiv, double *B, int *LDB, int *INFO); - - void DGETRF(int *M, int *N, double *A, int *LDA, - int *iPiv, int *INFO); - -//void DGETRS(char *TRANS, unsigned int sizeT, -// int *N, int *NRHS, double *A, int *LDA, -// int *iPiv, double *B, int *LDB, int *INFO); - - void DGETRI(int *N, double *A, int *LDA, - int *iPiv, double *Work, int *WORKL, int *INFO); - - void DGEMM(const char* transA, const char* transB, int* M, int* N, int* K, - double* alpha, - double* A, const int* lda, - double* B, const int* ldb, - double* beta, - double* C, const int* ldc); - -// -// Lapack -// -// FullGen -int DGESV(int *N, int *NRHS, double *A, int *LDA, - int *iPiv, double *B, int *LDB, int *INFO); - -int DGETRS(char *TRANS, - int *N, int *NRHS, double *A, int *LDA, - int *iPiv, double *B, int *LDB, int *INFO); - -// BandGen -int DGBSV(int *N, int *KL, int *KU, int *NRHS, double *A, - int *LDA, int *iPiv, double *B, int *LDB, - int *INFO); - -int DGBTRS(char *TRANS, - int *N, int *KL, int *KU, int *NRHS, - double *A, int *LDA, int *iPiv, - double *B, int *LDB, int *INFO); - -// BandSPD -int DPBSV(char *UPLO, - int *N, int *KD, int *NRHS, - double *A, int *LDA, double *B, int *LDB, - int *INFO); - -int DPBTRS(char *UPLO, - int *N, int *KD, int *NRHS, - double *A, int *LDA, double *B, int *LDB, - int *INFO); -} - -#endif // blasdecl_H From 29e6467f17a65421208f08ae01c9ea8725159542 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 11:53:09 -0700 Subject: [PATCH 131/261] more cleaning --- .../Frame/EuclidFrameTransf.h | 2 -- .../Frame/EuclidFrameTransf.tpp | 22 ++++--------------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h index f0d664ea08..e61c44a800 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.h +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -87,8 +87,6 @@ class EuclidFrameTransf: public FrameTransform private: - int computeElemtLengthAndOrient(); - inline MatrixND getProjection() { diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 5503160dcd..03200408d1 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -100,25 +100,10 @@ EuclidFrameTransf::initialize(std::array& new_nodes) opserr << "invalid pointers to the element nodes\n"; return -1; } - // ensure the node is initialized + // ensure the node rotation is initialized nodes[i]->getTrialRotation(); } - int error; - // set element length and orientation - if ((error = this->computeElemtLengthAndOrient())) - return error; - - R0 = basis.getRotation(); - return 0; -} - - -template -int -EuclidFrameTransf::computeElemtLengthAndOrient() -{ - const Vector &XI = nodes[ 0]->getCrds(); const Vector &XJ = nodes[nn-1]->getCrds(); @@ -136,13 +121,14 @@ EuclidFrameTransf::computeElemtLengthAndOrient() dx(i) += (*offsets)[nn-1][i]; } - // calculate the element length L = dx.norm(); if (L == 0.0) return -2; - return basis.initialize(); + int status = basis.initialize(); + R0 = basis.getRotation(); + return status; } From 22561c81c11d9380da0f376ffec0e6892461e9cf Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 11:55:39 -0700 Subject: [PATCH 132/261] remove `SouzaFrameTransf` --- .../Frame/SouzaFrameTransf.h | 156 --- .../Frame/SouzaFrameTransf.tpp | 941 ------------------ 2 files changed, 1097 deletions(-) delete mode 100644 SRC/coordTransformation/Frame/SouzaFrameTransf.h delete mode 100644 SRC/coordTransformation/Frame/SouzaFrameTransf.tpp diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.h b/SRC/coordTransformation/Frame/SouzaFrameTransf.h deleted file mode 100644 index 495d26bd23..0000000000 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.h +++ /dev/null @@ -1,156 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures -// -//----------------------------------------------------------------------------// -// -// Please cite the following resource in any derivative works: -// -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; -// https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// - -// -// Description: This file contains the class definition for -// SouzaFrameTransf. SouzaFrameTransf implements the formulation -// of Crisfield (1990) with the objective of maintaining the -// original "Corotational" implementation by Remo Magalhaes de Souza, within -// the new framework proposed by Perez and Filippou (2024). -// -// Written by : cmp, March 2024 -// -// Adapted from work by: Remo Magalhaes de Souza -// -#ifndef SouzaFrameTransf_hpp -#define SouzaFrameTransf_hpp - -#include -#include "FrameTransform.h" -#include -#include -#include -#include -#include -#include "Isometry/CrisfieldTransform.h" - -struct Triad; - -namespace OpenSees { - -template -class SouzaFrameTransf: public FrameTransform -{ -public: - SouzaFrameTransf(int tag, const Vector3D &vecxz, - const std::array *offset=nullptr, - int offset_flags = 0); - - ~SouzaFrameTransf(); - - const char *getClassType() const { - return "SouzaFrameTransf"; - } - - // NOTE: maybe add arg for rotation parameterization - FrameTransform *getCopy() const final; - - int initialize(std::array& new_nodes) final; - int update() final; - int commit() final; - int revertToLastCommit() final; - int revertToStart() final; - int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const final; - const std::array *getRigidOffsets() const final { return offsets; } - - double getInitialLength(); - double getDeformedLength(); - - VectorND getStateVariation() final; - Vector3D getNodePosition(int tag) final; - Vector3D getNodeRotationLogarithm(int tag) final; - - VectorND pushResponse(VectorND&pl) final; - MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - - // Sensitivity - double getLengthGrad() final; - virtual const Vector &getBasicDisplTotalGrad(int grad); - virtual const Vector &getBasicDisplFixedGrad(); - virtual const Vector &getGlobalResistingForceShapeSensitivity(const Vector &pb, const Vector &p0, int gradNumber); - - // Tagged Object - void Print(OPS_Stream &s, int flag = 0) final; - -private: - constexpr static int n = nn*ndf; - - // compute the transformation matrix - void compTransfMatrixBasicGlobal(const Versor&, const Versor*); - - int addTangent(MatrixND<12,12>& M, const VectorND<12>& pl); - - VectorND<6> pushResponse(const VectorND<6>& pa, int a, int b); - - enum { - inx= 0, // axial - iny= 1, // Vy - inz= 2, // Vz - imx= 3, // torsion - imy= 4, // rot y I - imz= 5, // rot z I - - jnx= 6, // axial - jny= 7, - jnz= 8, - jmx= 9, // torsion - jmy=10, // rot y J - jmz=11, // rot z J - }; - - // - // Member data - // - std::array nodes; - - Vector3D xAxis; // local x axis - Vector3D vz; // Vector that lies in local plane xz - Vector3D dX; - - std::array *offsets; - - double *nodeIInitialDisp, *nodeJInitialDisp; - bool initialDispChecked; - - double L; // initial element length - double Ln; // current element length (at trial state) - - Versor Q_past[nn]; // commited rotations - Versor Q_pres[nn]; // trial rotations - - Vector3D alphaI; // last trial rotations end i - Vector3D alphaJ; // last trial rotatations end j - - VectorND ul; // local displacements (size=7) - Vector3D vr[nn]; // - VectorND ulcommit; // commited local displacements - VectorND ulpr; // previous local displacements - - OpenSees::MatrixND T; // transformation from local to global system - - OpenSees::Matrix3D R0; // rotation from local to global coordinates - CrisfieldTransform crs; - - // Static workspace variables - Matrix3D A; - MatrixND<12,3> Lr2, Lr3; // auxiliary matrices -}; -} // namespace OpenSees -#include "SouzaFrameTransf.tpp" -#endif diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp deleted file mode 100644 index eca419383f..0000000000 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp +++ /dev/null @@ -1,941 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures -// -//----------------------------------------------------------------------------// -// -// Please cite the following resource in any derivative works: -// -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; -// https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// - -// -// Description: This file contains the implementation for the -// SouzaFrameTransf class. SouzaFrameTransf is a Corotational -// transformation for a spatial frame element between the global -// and basic coordinate systems. -// -// Written: Claudio Perez -// Created: 05/2024 -// -// Adapted from: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) -// -#include -#include -#include "SouzaFrameTransf.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include "Isometry/CrisfieldTransform.h" - -namespace OpenSees { - -template -SouzaFrameTransf::SouzaFrameTransf(int tag, const Vector3D &vz, - const std::array *offset, - int offset_flags) - : FrameTransform(tag), - vz(vz), - offsets{nullptr}, - L(0), Ln(0), - nodeIInitialDisp(0), nodeJInitialDisp(0), - initialDispChecked(false) -{ - alphaI.zero(); - alphaJ.zero(); - - // Rigid joint offsets - if (offset != nullptr) { - offsets = new std::array{}; - *offsets = *offset; - } -} - - -template -SouzaFrameTransf::~SouzaFrameTransf() -{ - if (offsets != nullptr) - delete offsets; -} - - -template -double -SouzaFrameTransf::getInitialLength() -{ - return L; -} - - -template -double -SouzaFrameTransf::getDeformedLength() -{ - return Ln; -} - - -template -FrameTransform * -SouzaFrameTransf::getCopy() const -{ - - SouzaFrameTransf *theCopy = - new SouzaFrameTransf(this->getTag(), vz, offsets); - - theCopy->nodes[0] = nodes[0]; - theCopy->nodes[1] = nodes[1]; - theCopy->xAxis = xAxis; - theCopy->L = L; - theCopy->Ln = Ln; - theCopy->R0 = R0; - theCopy->Q_pres[0] = Q_pres[0]; - theCopy->Q_pres[1] = Q_pres[1]; - theCopy->Q_past[0] = Q_past[0]; - theCopy->Q_past[1] = Q_past[1]; - theCopy->ul = ul; - theCopy->ulcommit = ulcommit; - return theCopy; -} - - -template -int -SouzaFrameTransf::revertToStart() -{ - ul.zero(); - Q_pres[0] = VersorFromMatrix(R0); - for (int i=1; iupdate(); - return 0; -} - - -template -int -SouzaFrameTransf::commit() -{ - ulcommit = ul; - Q_past[0] = Q_pres[0]; - Q_past[1] = Q_pres[1]; - return 0; -} - - -template -int -SouzaFrameTransf::revertToLastCommit() -{ - // determine global displacement increments from last iteration - const Vector &dispI = nodes[0]->getTrialDisp(); - const Vector &dispJ = nodes[1]->getTrialDisp(); - - for (int k = 0; k < 3; k++) { - alphaI(k) = dispI(k+3); - alphaJ(k) = dispJ(k+3); - } - - ul = ulcommit; - Q_pres[0] = Q_past[0]; - Q_pres[1] = Q_past[1]; - - this->update(); - - return 0; -} - - -template -int -SouzaFrameTransf::initialize(std::array& new_nodes) -{ - for (int i=0; igetCrds() - nodes[0]->getCrds(); - - // Add initial displacements at nodes - if (initialDispChecked == false) { - const Vector &nodeIDisp = nodes[0]->getDisp(); - const Vector &nodeJDisp = nodes[1]->getDisp(); - for (int i = 0; i<6; i++) - if (nodeIDisp[i] != 0.0) { - nodeIInitialDisp = new double [6]; - for (int j = 0; j<6; j++) - nodeIInitialDisp[j] = nodeIDisp[j]; - i = 6; - } - - for (int j = 0; j<6; j++) - if (nodeJDisp[j] != 0.0) { - nodeJInitialDisp = new double [6]; - for (int i = 0; i<6; i++) - nodeJInitialDisp[i] = nodeJDisp[i]; - j = 6; - } - initialDispChecked = true; - } - - // - // Length and Orientation - // - Vector3D dx; - - dx = nodes[nn-1]->getCrds() - nodes[0]->getCrds(); - - L = dx.norm(); - - if (L == 0.0) { - opserr << "\nSouzaFrameTransf::computeElemtLengthAndOrien: 0 length\n"; - return -2; - } - - // - // Set rotation matrix - // - int error = FrameTransform::Orient(dx, vz, R0); - if (error) - return error; - - // Compute initial pseudo-vectors for nodal triads - Q_pres[0] = Q_pres[1] = VersorFromMatrix(R0); - - ul.zero(); - ulpr.zero(); - - for (int i=0; icommit(); - - return 0; -} - -template -VectorND -SouzaFrameTransf::getStateVariation() -{ - return ul - ulpr; -} - -template -Vector3D -SouzaFrameTransf::getNodePosition(int tag) -{ - Vector3D u; - for (int i=0; i<3; i++) - u[i] = ul[tag*ndf+i]; - return u; -} - -template -Vector3D -SouzaFrameTransf::getNodeRotationLogarithm(int tag) -{ - return vr[tag]; -} - -template -void inline -SouzaFrameTransf::compTransfMatrixBasicGlobal( - const Versor& Qbar, - const Versor* Q_pres) -{ - // extract columns of rotation matrices - const Triad r {MatrixFromVersor(Qbar)}, - rI{MatrixFromVersor(Q_pres[0])}, - rJ{MatrixFromVersor(Q_pres[1])}; - const Vector3D - &e1 = crs.getBasisE1(), // E[1], - &e2 = crs.getBasisE2(), // E[2], - &e3 = crs.getBasisE3(), // E[3], - &r1 = r[1], - &r2 = r[2], - &r3 = r[3], - &rI1 = rI[1], - &rI2 = rI[2], - &rI3 = rI[3], - &rJ1 = rJ[1], - &rJ2 = rJ[2], - &rJ3 = rJ[3]; - - // Compute the transformation matrix from the basic to the - // global system - // A = (1/Ln)*(I - e1*e1'); - // Matrix3D A; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; - - // This must be called up here - CrisfieldTransform::getLMatrix(A, e1, r1, r2, Lr2); - CrisfieldTransform::getLMatrix(A, e1, r1, r3, Lr3); - - // 3 | 3 | 3 | 3 | - // T1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', O', O']'; imx - // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; imz - // T3 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', -(A*rI3)', O']'; imy - // - // T4 = [ O', O', O', ( S(rJ2)*e3 - S(rJ3)*e2 )']'; jmx - // T5 = [(A*rJ2)', O', -(A*rJ2)', ( S(rJ1)*e2 - S(rJ2)*e1 )']'; jmz - // T6 = [(A*rJ3)', O', -(A*rJ3)', ( S(rJ1)*e3 - S(rJ3)*e1 )']'; jmy - - T.zero(); - - // T1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', O', O']'; - - // (-S(rI3)*e2 + S(rI2)*e3) - Vector3D Se = rI2.cross(e3); - Se -= rI3.cross(e2); - for (int i = 0; i < 3; i++) - // T(jmx,i+3) = -Se[i]; - T(imx,i+3) = Se[i]; - - // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; - - Vector3D At = A*rI2; - - // (-S(rI2)*e1 + S(rI1)*e2)' - Se = rI1.cross(e2); - Se -= rI2.cross(e1); - for (int i = 0; i < 3; i++) { - T(imz,i ) = At[i]; - T(imz,i+3) = Se[i]; - T(imz,i+6) = -At[i]; - } - - // T3 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', -(A*rI3)', O']'; - - At = A*rI3; - - // -S(rI3)*e1 + S(rI1)*e3 - Se = rI1.cross(e3); - Se -= rI3.cross(e1); - for (int i = 0; i < 3; i++) { - T(imy,i ) = At[i]*-1; - T(imy,i+3) = Se[i]*-1; - T(imy,i+6) = -At[i]*-1; - } - - // T4 = [ O', O', O', (-S(rJ3)*e2 + S(rJ2)*e3)']'; - Se = rJ2.cross(e3); - Se -= rJ3.cross(e2); - for (int i = 0; i < 3; i++) - T(jmx, i+9) = Se[i]; // S(rJ2)*e3 - S(rJ3)*e2 - - // T5 = [(A*rJ2)', O', -(A*rJ2)', (-S(rJ2)*e1 + S(rJ1)*e2)']'; - At = A*rJ2; - Se = rJ1.cross(e2); - Se -= rJ2.cross(e1); - for (int i = 0; i < 3; i++) { - T(jmz, i ) = At[i]; - T(jmz, i+6) = -At[i]; - T(jmz, i+9) = Se[i]; // (-S(rJ2)*e1 + S(rJ1)*e2) - } - - // T6 = [(A*rJ3)', O', -(A*rJ3)', (-S(rJ3)*e1 + S(rJ1)*e3)']' - At = A*rJ3; - Se = rJ1.cross(e3); // (-S(rJ3)*e1 + S(rJ1)*e3) - Se -= rJ3.cross(e1); - for (int i = 0; i < 3; i++) { - T(jmy,i ) = At[i]*-1; - T(jmy,i+6) = -At[i]*-1; - T(jmy,i+9) = Se[i]*-1; - } - - // - // Second part - // - - // T(:,1) += Lr3*rI2 - Lr2*rI3; - // T(:,2) += Lr2*rI1; z - // T(:,3) += Lr3*rI1 ; y - - // T(:,4) += Lr3*rJ2 - Lr2*rJ3; - // T(:,5) += Lr2*rJ1 ; z // ?????? check sign - // T(:,6) += Lr3*rJ1 ; y // ?????? check sign - - // Bending Z - for (int i = 0; i < 12; i++) { - double T1i = 0; - for (int k=0; k<3; k++) - T1i += Lr2(i,k)*rI1[k]; - T(imz,i) += T1i; - } - - for (int i = 0; i < 12; i++) { - double T4i = 0; - for (int k=0; k<3; k++) - T4i += Lr2(i,k)*rJ1[k]; // Lr[i]; - T(jmz,i) += T4i; - } - - // Torsion - for (int i = 0; i < 12; i++) { - double T0i = 0; - for (int k=0; k<3; k++) - T0i += Lr3(i,k)*rI2[k] - Lr2(i,k)*rI3[k]; - // T(jmx,i) += -T0i; - T(imx,i) += T0i; - } - for (int i = 0; i < 12; i++) { - double T3i = 0; - for (int k=0; k<3; k++) - T3i += Lr3(i,k)*rJ2[k] - Lr2(i,k)*rJ3[k]; - T(jmx,i) += T3i; - } - // Bending Y - for (int i = 0; i < 12; i++) { - double T2i = 0; - for (int k=0; k<3; k++) - T2i += Lr3(i,k)*rI1[k]; // Lr[i]; - T(imy,i) += T2i*-1; - } - for (int i = 0; i < 12; i++) { - double T5i = 0; - for (int k=0; k<3; k++) - T5i += Lr3(i,k)*rJ1[k]; // Lr[i]; - T(jmy,i) += T5i*-1; - } - - // - // - // - for (int node=0; node < 2; node++) - for (int j = 0; j < 3; j++) { - const double c = 0.5 / std::cos(ul[(node? jmx : imx) + j]); - for (int i = 0; i < 12; i++) - T((node? jmx : imx) + j, i) *= c; - } - - // Axial - // T(:,7) = [-e1' O' e1' O']'; - for (int i = 0; i < 3; i++) { - T(jnx,i ) = -e1[i]; - T(jnx,i+6) = e1[i]; - } - - // Combine torsion - for (int i=0; i<12; i++) { - T(jmx,i) -= T(imx,i); - T(imx,i) = 0; - } -} - -// -// Set RI,RJ,Rbar, Ln, e and ul -// -template -int -SouzaFrameTransf::update() -{ - // determine global displacement increments from last iteration - - const Vector& dispI = nodes[ 0]->getTrialDisp(); - const Vector& dispJ = nodes[nn-1]->getTrialDisp(); - - // - // Update state - // - // 1.1 Relative translation - Vector3D dx = dX;// dx = dX + dJI; - { - // Relative translation - for (int k = 0; k < 3; k++) - dx[k] += dispJ(k) - dispI(k); - - - // Calculate the deformed length - Ln = dx.norm(); - - if (Ln == 0.0) { - opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; - return -2; - } - } - - // 1.2 Rotational displacement increments - { - Vector3D dAlphaI, dAlphaJ; - - for (int k = 0; k < 3; k++) { - dAlphaI[k] = dispI(k+3) - alphaI[k]; - alphaI[k] = dispI(k+3); - dAlphaJ[k] = dispJ(k+3) - alphaJ[k]; - alphaJ[k] = dispJ(k+3); - } - - // Update the nodal rotations - Q_pres[0] = VersorProduct(Q_pres[0], Versor::from_vector(dAlphaI)); - Q_pres[1] = VersorProduct(Q_pres[1], Versor::from_vector(dAlphaJ)); - } - - // - // 2) Form transformation - // - - crs.update(Q_pres[0], Q_pres[1], dx); - // Form the transformation tangent - this->compTransfMatrixBasicGlobal(crs.getReference(), Q_pres); - - // - // 3) Local deformations - // - - // Save previous state - ulpr = ul; - - // Rotations - { - Matrix3D e = crs.getRotation(); - vr[0] = LogC90(e^MatrixFromVersor(Q_pres[0])); - for (int i=0; i<3; i++) - ul[imx+i] = vr[0][i]; - - vr[1] = LogC90(e^MatrixFromVersor(Q_pres[1])); - for (int i=0; i<3; i++) - ul[jmx+i] = vr[1][i]; - } - - // Axial - ul(inx) = 0; - ul(jnx) = Ln - L; - - return 0; -} - - -template -inline VectorND -SouzaFrameTransf::pushResponse(VectorND&pl) -{ - // return T^pl; - VectorND pg{}; - for (int a = 0; a pa {pl(a*ndf+0), pl(a*ndf+1), pl(a*ndf+2), - pl(a*ndf+3), pl(a*ndf+4), pl(a*ndf+5)}; - - for (int b = 0; b<2; b++) { - VectorND<6> pab = pushResponse(pa, a, b); - pg.assemble(b*6, pab, 1.0); - } - } - return pg; -} - -template -VectorND<6> -SouzaFrameTransf::pushResponse(const VectorND<6>&pa, int a, int b) -{ - VectorND<6> pg{}; - for (int i = 0; i < 6; i++) - for (int j = 0; j < 6; j++) - pg[j] += T(a*6 + i, b*6+j) * pa[i]; - - return pg; -} - -// do -// K = ag'*Km*ag + Kp -// -template -MatrixND -SouzaFrameTransf::pushResponse(MatrixND& kl, const VectorND& pl) -{ - MatrixND<12,12> K; - K.addMatrixTripleProduct(0.0, T, kl, 1.0); - - // Add geometric part kg - this->addTangent(K, pl); - - return K; -} - - -// -// Add geometric part of the transformation tangent -// -// kg += T'*kl*T + ks1 + T * diag(m.*tan(thetal))*T' + ... -// m(4)*(ks2r2t3_u3 + ks2r3u2_t2) + ... -// m(2)*ks2r2t1 + m(3)*ks2r3t1 + ... -// m(5)*ks2r2u1 + m(6)*ks2r3u1 + ... -// ks3 + ks3' + ks4 + ks5; -template -int -SouzaFrameTransf::addTangent(MatrixND<12,12>& kg, const VectorND<12>& pl) -{ - const Triad r {MatrixFromVersor(crs.getReference())}, - rI{MatrixFromVersor(Q_pres[0])}, - rJ{MatrixFromVersor(Q_pres[1])}; - const Vector3D - &e1 = crs.getBasisE1(), // E[1], - &e2 = crs.getBasisE2(), // E[2], - &e3 = crs.getBasisE3(), // E[3], - &r1 = r[1], // .rotate(E1), - &r2 = r[2], // .rotate(E2), - &r3 = r[3], // .rotate(E3), - &rI1 = rI[1], // .rotate(E1), - &rI2 = rI[2], // .rotate(E2), - &rI3 = rI[3], // .rotate(E3), - &rJ1 = rJ[1], // .rotate(E1), - &rJ2 = rJ[2], // .rotate(E2), - &rJ3 = rJ[3]; // .rotate(E3); - - // NOTE[cmp] - // SouzaFrameTransf::compTransfMatrixBasicGlobal must be - // called first to set Lr1, Lr2 and T - - // Matrix3D A; - // for (int i = 0; i < 3; i++) - // for (int j = 0; j < 3; j++) - // A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; - // getLMatrix(A, e1, r1, r2, Lr2); - // getLMatrix(A, e1, r1, r3, Lr3); - - // - // Ksigma1 - // - { - const double N = -pl[0]; // Axial force - // a=0 - kg.assemble(A, 0, 0, N); - kg.assemble(A, 0, 6, -N); - // a=1 - kg.assemble(A, 6, 0, -N); - kg.assemble(A, 6, 6, N); - } - - // - // Ksigma3 - // - // ks3 = [o kbar2 | o kbar4]; - // - // where - // - // kbar2 = -Lr2*(m(3)*S(rI3) + m(1)*S(rI1)) + Lr3*(m(3)*S(rI2) - m(2)*S(rI1)) ; - // - // kbar4 = Lr2*(m(3)*S(rJ3) - m(4)*S(rJ1)) - Lr3*(m(3)*S(rJ2) + m(5)*S(rJ1)); - // - // or - // - // ks3 = [o ka+kb | o kc+kd]; - // = [o ka | o kc] + [o kb | o kd]; - // - // where - // - // ka = -Lr2*S(rI3)*m(3) - // +Lr2*S(rI1)*m(1); - // kb = Lr3*S(rI2)*m(3) - // -Lr3*S(rI1)*m(2); - // - // kc = Lr2*S(rJ3)*m(3) - // -Lr2*S(rJ1)*m(4); - // kd = -Lr3*S(rJ2)*m(3) - // +Lr3*S(rJ1)*m(5); - - VectorND<6> m; - m[0] = 0.5*pl[imx]/std::cos(ul(imx)); - m[2] = -0.5*pl[imy]/std::cos(ul(imy)); - m[1] = 0.5*pl[imz]/std::cos(ul(imz)); - - m[3] = 0.5*pl[jmx]/std::cos(ul(jmx)); - m[5] = -0.5*pl[jmy]/std::cos(ul(jmy)); - m[4] = 0.5*pl[jmz]/std::cos(ul(jmz)); - - - static Matrix3D Sm; - Sm.zero(); - Sm.addSpin(rI3, m[3]); - Sm.addSpin(rI1, m[1]); - static MatrixND<12,3> kbar; - kbar.zero(); - kbar.addMatrixProduct(Lr2, Sm, -1.0); - - Sm.zero(); - Sm.addSpin(rI2, m[3]); - Sm.addSpin(rI1, -m[2]); - kbar.addMatrixProduct(Lr3, Sm, 1.0); - - kg.assemble(kbar, 0, 3, 1.0); - kg.assembleTranspose(kbar, 3, 0, 1.0); - - Sm.zero(); - Sm.addSpin(rJ3, m[3]); - Sm.addSpin(rJ1, -m[4]); - kbar.zero(); - kbar.addMatrixProduct(Lr2, Sm, 1.0); - - Sm.zero(); - Sm.addSpin(rJ2, m[3]); - Sm.addSpin(rJ1, m[5]); - kbar.addMatrixProduct(Lr3, Sm, -1.0); - - kg.assemble(kbar, 0, 9, 1.0); - kg.assembleTranspose(kbar, 9, 0, 1.0); - - - // - // Ksigma4 - // - { - Matrix3D ks33; - ks33.zero(); - ks33.addSpinProduct(e2, rI3, m[3]); - ks33.addSpinProduct(e3, rI2, -m[3]); - ks33.addSpinProduct(e2, rI1, m[1]); - ks33.addSpinProduct(e1, rI2, -m[1]); - ks33.addSpinProduct(e3, rI1, m[2]); - ks33.addSpinProduct(e1, rI3, -m[2]); - kg.assemble(ks33, 3, 3, 1.0); - } - - // - // Ksigma4 - // - { - Matrix3D ks33; - ks33.zero(); - ks33.addSpinProduct(e2, rJ3, -m[3]); - ks33.addSpinProduct(e3, rJ2, m[3]); - ks33.addSpinProduct(e2, rJ1, m[4]); - ks33.addSpinProduct(e1, rJ2, -m[4]); - ks33.addSpinProduct(e3, rJ1, m[5]); - ks33.addSpinProduct(e1, rJ3, -m[5]); - - kg.assemble(ks33, 9, 9, 1.0); - } - - - // - // Ksigma5 - // - // Ks5 = [ Ks5_11 Ks5_12 | -Ks5_11 Ks5_14; - // Ks5_12' O | -Ks5_12' O; - // -Ks5_11 -Ks5_12 | Ks5_11 -Ks5_14; - // Ks5_14t O | -Ks5_14' O]; - // - // - // v = (1/Ln)*(m(2)*rI2 + m(3)*rI3 + m(5)*rJ2 + m(6)*rJ3); - // = 1/Ln * (m[1]*rI2 + m[2]*rI3) - // + 1/Ln * (m[4]*rJ2 + m[5]*rJ3); - // = vi + vj - // - { - Vector3D v; - v.addVector(0.0, rI2, m[1]); - v.addVector(1.0, rI3, m[2]); - v.addVector(1.0, rJ2, m[4]); - v.addVector(1.0, rJ3, m[5]); - v /= Ln; - - // Ks5_11 = A*v*e1' + e1*v'*A + (e1'*v)*A; - // = A*vi*e1' + e1*vi'*A + (e1'*vi)*A - // + A*vj*e1' + e1*vj'*A + (e1'*vj)*A; - // - Matrix3D ks33; - ks33.zero(); - ks33.addMatrix(A, e1.dot(v)); - - static Matrix3D m33; - m33.zero(); - m33.addTensorProduct(v, e1, 1.0); - - ks33.addMatrixProduct(A, m33, 1.0); - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - m33(i,j) = e1[i]*v[j]; - - ks33.addMatrixProduct(m33, A, 1.0); - - kg.assemble(ks33, 0, 0, 1.0); - kg.assemble(ks33, 0, 6, -1.0); - kg.assemble(ks33, 6, 0, -1.0); - kg.assemble(ks33, 6, 6, 1.0); - } - - // Ks5_12 = -(m(2)*A*S(rI2) + m(3)*A*S(rI3)); - - Matrix3D ks33; - ks33.zero(); - ks33.addMatrixSpinProduct(A, rI2, -m[1]); - ks33.addMatrixSpinProduct(A, rI3, -m[2]); - - kg.assemble(ks33, 0, 3, 1.0); - kg.assemble(ks33, 6, 3, -1.0); - kg.assembleTranspose(ks33, 3, 0, 1.0); - kg.assembleTranspose(ks33, 3, 6, -1.0); - - // Ks5_14 = -(m(5)*A*S(rJ2) + m(6)*A*S(rJ3)); - - ks33.zero(); - ks33.addMatrixSpinProduct(A, rJ2, -m[4]); - ks33.addMatrixSpinProduct(A, rJ3, -m[5]); - - kg.assemble(ks33, 0, 9, 1.0); - kg.assemble(ks33, 6, 9, -1.0); - - kg.assembleTranspose(ks33, 9, 0, 1.0); - kg.assembleTranspose(ks33, 9, 6, -1.0); - - // Ksigma ------------------------------- - Vector3D rm = rI3; - - rm.addVector(1.0, rJ3, -1.0); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rm), m[3]); - -// rm = rJ2; - rm.addVector(0.0, rJ2, -1.0); - rm.addVector(1.0, rI2, -1.0); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rm), m[3]); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rI1), m[1]); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rI1), m[2]); - // - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r2, rJ1), m[4]); - kg.addMatrix(CrisfieldTransform::getKs2Matrix(A, e1, r1, Ln, r3, rJ1), m[5]); - - // - // T' * diag (M .* tan(thetal))*T - // - - for (int node=0; node<2; node++) { - for (int k = 0; k < 3; k++) { - const double factor = pl[6*node+3+k] * std::tan(ul[(node ? jmx : imx) + k]); - for (int i = 0; i < 12; i++) { - const double Tki = T((node ? jmx : imx) + k,i); - for (int j = 0; j < 12; j++) - kg(i,j) += Tki * factor * T((node ? jmx : imx) + k, j); - } - } - } - - return 0; -} - - -template -int -SouzaFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector3D &e3) const -{ - for (int i = 0; i < 3; i++) { - e1[i] = R0(i,0); - e2[i] = R0(i,1); - e3[i] = R0(i,2); - } - return 0; -} - - -template -double -SouzaFrameTransf::getLengthGrad() -{ - const int di = nodes[0]->getCrdsSensitivity(); - const int dj = nodes[1]->getCrdsSensitivity(); - - Vector3D dxi{0.0}; - Vector3D dxj{0.0}; - - if (di != 0) - dxi(di-1) = 1.0; - if (dj != 0) - dxj(dj-1) = 1.0; - - return 1/L * dX.dot(dxj - dxi); -} - -template -const Vector & -SouzaFrameTransf::getBasicDisplTotalGrad(int gradNumber) -{ - opserr << "WARNING CrdTransf::getBasicDisplTotalGrad() - this method " - << " should not be called.\n"; - - static Vector dummy(1); - return dummy; -} - -template -const Vector & -SouzaFrameTransf::getBasicDisplFixedGrad() -{ - opserr << "ERROR CrdTransf::getBasicDisplFixedGrad() - has not been" - << " implemented yet for the chosen transformation\n."; - - static Vector dummy(1); - return dummy; -} - - -template -const Vector & -SouzaFrameTransf::getGlobalResistingForceShapeSensitivity(const Vector &pb, - const Vector &p0, - int gradNumber) -{ - opserr << "ERROR CrdTransf::getGlobalResistingForceSensitivity() - has not been" - << " implemented yet for the chosen transformation." << endln; - - static Vector dummy(1); - return dummy; -} - -template -void -SouzaFrameTransf::Print(OPS_Stream &s, int flag) -{ - - if (flag == OPS_PRINT_CURRENTSTATE) { - s << "\nFrameTransform: " << this->getTag() << " Type: SouzaFrameTransf"; - s << "\tvxz: " << Vector(vz); - } - - if (flag == OPS_PRINT_PRINTMODEL_JSON) { - s << OPS_PRINT_JSON_MATE_INDENT << "{"; - s << "\"name\": " << this->getTag() << ", "; - s << "\"type\": \"SouzaFrameTransf\"" << ", "; - s << "\"vecxz\": [" << vz(0) << ", " << vz(1) << ", " << vz(2) << "]"; - - if (offsets != nullptr) { - s << ", \"offsets\": ["; - for (int i=0; i Date: Sun, 29 Jun 2025 12:10:11 -0700 Subject: [PATCH 133/261] remove some files --- .../Frame/Isometry/CrisfieldIsometry.tpp | 18 -- .../Frame/Isometry/CrisfieldTransform.h | 284 ------------------ 2 files changed, 302 deletions(-) delete mode 100644 SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp delete mode 100644 SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp deleted file mode 100644 index 1017532ab9..0000000000 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.tpp +++ /dev/null @@ -1,18 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures -// -//----------------------------------------------------------------------------// -// -// Please cite the following resource in any derivative works: -// -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; -// https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h deleted file mode 100644 index 6709c96a71..0000000000 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldTransform.h +++ /dev/null @@ -1,284 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures -// -//----------------------------------------------------------------------------// -// -// Please cite the following resource in any derivative works: -// -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; -// https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// - -#pragma once -#include -#include -#include -#include -#include - -namespace OpenSees { - -class CrisfieldTransform { -public: - CrisfieldTransform() {} - - int - update(const Versor& qI, const Versor& qJ, const Vector3D& dx) - { - - Ln = dx.norm(); - - { - Vector3D gammaw = CayleyFromVersor(qJ.mult_conj(qI)); - - gammaw *= 0.5; - - // Qbar = VersorProduct(VersorFromMatrix(CaySO3(gammaw)), qI); - Qbar = VersorFromMatrix(CaySO3(gammaw)*MatrixFromVersor(qI)); - Triad r{CaySO3(gammaw)*MatrixFromVersor(qI)}; - r1 = r[1]; - r2 = r[2]; - r3 = r[3]; - } - - // - // Compute the base vectors e2, e3 - // - { - // 'rotate' the mean rotation matrix Rbar on to e1 to - // obtain e2 and e3 (using the 'mid-point' procedure) - // - // Vector3D e1, e2, e3; - e[0] = dx; - e[0] /= Ln; - Matrix3D Rbar = MatrixFromVersor(Qbar); - Triad r = Triad{Rbar}; - Vector3D r1 = r[1], - r2 = r[2], - r3 = r[3]; - - // e2 = r2 - (e1 + r1)*((r2^e1)*0.5); - - Vector3D tmp; - tmp = e[0]; - tmp += r1;//Qbar.rotate(E1); - - e[1] = tmp; - { - // const Vector3D r2 = Qbar.rotate(E2); - e[1] *= 0.5*r2.dot(e[0]); - e[1].addVector(-1.0, r2, 1.0); - } - - // e3 = r3 - (e1 + r1)*((r3^e1)*0.5); - e[2] = tmp; - { - // const Vector3D r3 = Qbar.rotate(E3); - e[2] *= r3.dot(e[0])*0.5; - e[2].addVector(-1.0, r3, 1.0); - } - } - return 0; - } - - inline Matrix3D - getRotation() const noexcept - { - Matrix3D E; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - E(i,j) = e[j][i]; - return E; - } - - constexpr const Vector3D& - getBasisE1() const noexcept - { - return e[0]; - } - constexpr const Vector3D& - getBasisE2() const noexcept - { - return e[1]; - } - constexpr const Vector3D& - getBasisE3() const noexcept - { - return e[2]; - } - - - const Versor& - getReference() - { - return Qbar; - } - - static inline void - getLMatrix(const Matrix3D& A, const Vector3D& e1, const Vector3D& r1, const Vector3D &ri, MatrixND<12,3>& L) - { - static Matrix3D L1, L2; - static Matrix3D rie1r1; - static Matrix3D e1e1r1; - - const double rie1 = ri.dot(e1); - - for (int k = 0; k < 3; k++) { - const double e1r1k = (e1[k] + r1[k]); - for (int j = 0; j < 3; j++) { - rie1r1(j,k) = ri[j]*e1r1k; - e1e1r1(j,k) = e1[j]*e1r1k; - } - } - - // L1 = ri'*e1 * A/2 + A*ri*(e1 + r1)'/2; - L1.zero(); - L1.addMatrix(A, rie1*0.5); - L1.addMatrixProduct(A, rie1r1, 0.5); - - // L2 = Sri/2 - ri'*e1*S(r1)/4 - Sri*e1*(e1 + r1)'/4; - L2.zero(); - L2.addSpin(ri, 0.5); - L2.addSpin(r1, -rie1/4.0); - L2.addSpinMatrixProduct(ri, e1e1r1, -0.25); - - // L = [L1 - // L2 - // -L1 - // L2]; - - L.zero(); - L.assemble(L1, 0, 0, 1.0); - L.assemble(L2, 3, 0, 1.0); - L.assemble(L1, 6, 0, -1.0); - L.assemble(L2, 9, 0, 1.0); - - } - - static inline const MatrixND<12,12> & - getKs2Matrix(Matrix3D& A, const Vector3D& e1, const Vector3D& r1, const double Ln, const Vector3D &ri, const Vector3D &z) - { - static MatrixND<12,12> ks2; - - // Ksigma2 = [ K11 K12 -K11 K12 - // K12' K22 -K12' K22 - // -K11 -K12 K11 -K12 - // K12' K22 -K12' K22]; - - // U = (-1/2)*A*z*ri'*A + ri'*e1*A*z*e1'/(2*Ln)+... - // z'*(e1+r1)*A*ri*e1'/(2*Ln); - - const double rite1 = ri.dot(e1); - const double zte1 = z.dot(e1); - const double ztr1 = z.dot(r1); - - static Matrix3D zrit, ze1t; - static Matrix rizt(3,3), rie1t(3,3); - static Matrix3D e1zt; - - // const Matrix3D e1zt = e1.bun(z); - - // Chrystal's looping order - for (int j = 0; j < 3; j++) { - for (int i = 0; i < 3; i++) { - zrit(i,j) = z[i]*ri[j]; - rizt(i,j) = ri[i]*z[j]; - ze1t(i,j) = z[i]*e1[j]; - e1zt(i,j) = e1[i]*z[j]; - rie1t(i,j) = ri[i]*e1[j]; - } - } - - static Matrix3D U; - - U.addMatrixTripleProduct(0.0, A, zrit, -0.5); - U.addMatrixProduct(A, ze1t, rite1/(2*Ln)); - U.addMatrixProduct(A, rie1t, (zte1 + ztr1)/(2*Ln)); - - static Matrix3D ks; - static Matrix3D m1; - - // K11 = U + U' + ri'*e1*(2*(e1'*z)+z'*r1)*A/(2*Ln); - ks.zero(); - ks.addMatrix(U, 1.0); - - // Add matrix U transpose - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - ks(i,j) += U(j,i); - - ks.addMatrix(A, rite1*(2*zte1 + ztr1)/(2*Ln)); - - ks2.zero(); - ks2.assemble(ks, 0, 0, 1.0); - ks2.assemble(ks, 0, 6, -1.0); - ks2.assemble(ks, 6, 0, -1.0); - ks2.assemble(ks, 6, 6, 1.0); - - // K12 = (1/4)*(-A*z*e1'*Sri - A*ri*z'*Sr1 - z'*(e1+r1)*A*Sri); - m1.zero(); - m1.addMatrixProduct(A, ze1t, -1.0); - ks.zero(); - ks.addMatrixSpinProduct(m1, ri, 0.25); - - m1.zero(); - m1.addMatrixProduct(A, rizt, -1.0); - ks.addMatrixSpinProduct(m1, r1, 0.25); - ks.addMatrixSpinProduct(A, ri, -0.25*(zte1+ztr1)); - - ks2.assemble(ks, 0, 3, 1.0); - ks2.assemble(ks, 0, 9, 1.0); - ks2.assemble(ks, 6, 3, -1.0); - ks2.assemble(ks, 6, 9, -1.0); - - ks2.assembleTranspose(ks, 3, 0, 1.0); - ks2.assembleTranspose(ks, 3, 6, -1.0); - ks2.assembleTranspose(ks, 9, 0, 1.0); - ks2.assembleTranspose(ks, 9, 6, -1.0); - - // K22 = (1/8)*((-ri'*e1)*Sz*Sr1 + Sr1*z*e1'*Sri + ... - // Sri*e1*z'*Sr1 - (e1+r1)'*z*S(e1)*Sri + 2*Sz*Sri); - - ks.zero(); - ks.addSpinProduct(z, r1, -0.125*(rite1)); - - m1.zero(); - m1.addSpinMatrixProduct( r1, ze1t, 1.0); - ks.addMatrixSpinProduct( m1, ri, 0.125); - - m1.zero(); - m1.addSpinMatrixProduct(ri, e1zt, 1.0); - ks.addMatrixSpinProduct(m1, r1, 0.125); - - ks.addSpinProduct(e1, ri, -0.125*(zte1 + ztr1)); - ks.addSpinProduct( z, ri, 0.25); - - // Ksigma2 = [ K11 K12 -K11 K12; - // K12t K22 -K12t K22; - // -K11 -K12 K11 -K12; - // K12t K22 -K12t K22]; - - ks2.assemble(ks, 3, 3, 1.0); - ks2.assemble(ks, 3, 9, 1.0); - ks2.assemble(ks, 9, 3, 1.0); - ks2.assemble(ks, 9, 9, 1.0); - - return ks2; - } - -private: - Versor Qbar; - Vector3D r1, r2, r3; - Vector3D e[3]; - double Ln; - -}; -} \ No newline at end of file From 7d26a8ccdee8f4fc61dab466527fb2924d5db8f7 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 12:54:38 -0700 Subject: [PATCH 134/261] clean up --- .../Frame/BasicFrameTransf.h | 4 +- .../Frame/BasicFrameTransf.tpp | 3 +- .../Frame/EuclidFrameTransf.h | 1 + .../Frame/EuclidFrameTransf.tpp | 29 +++----------- .../Frame/Isometry/RankineIsometry.h | 40 ++----------------- 5 files changed, 13 insertions(+), 64 deletions(-) diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.h b/SRC/coordTransformation/Frame/BasicFrameTransf.h index 203caf626d..7aa68e6692 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.h +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.h @@ -29,8 +29,8 @@ #include #include -#include -#include +class Matrix; +class Vector; namespace OpenSees { diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index 37cad89f0e..2221065ab9 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -216,7 +216,6 @@ BasicFrameTransf3d::getGlobalStiffMatrix(const Matrix &kb, const Vector &q_ for (int i=0; i= NBV) continue; @@ -225,7 +224,7 @@ BasicFrameTransf3d::getGlobalStiffMatrix(const Matrix &kb, const Vector &q_ if (jj >= NBV) continue; - kl(i,j) = kb(ii, jj)*c; + kl(i,j) = kb(ii, jj); } } diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h index e61c44a800..a84e95e606 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.h +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -141,6 +141,7 @@ class EuclidFrameTransf: public FrameTransform Matrix3D R0; Vector3D xi, xj, vz; double L; // undeformed element length + double Ln; // deformed element length IsoT basis; }; diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 03200408d1..83c8180b0d 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -122,6 +122,7 @@ EuclidFrameTransf::initialize(std::array& new_nodes) } L = dx.norm(); + Ln = L; if (L == 0.0) return -2; @@ -156,7 +157,7 @@ template double EuclidFrameTransf::getDeformedLength() { - return L; + return Ln; } @@ -170,6 +171,8 @@ EuclidFrameTransf::update() if (basis.update() < 0) return -1; + Ln = basis.getLength(); + Matrix3D R = basis.getRotation(); for (int i=0; igetTrialRotation(); @@ -191,25 +194,9 @@ template Vector3D EuclidFrameTransf::getNodePosition(int node) { -#if 0 - const Vector& ug = nodes[node]->getTrialDisp(); - - Vector3D u; - for (int i=0; i<3; i++) - u[i] = ug[i]; - - if (offsets != nullptr) [[unlikely]] { - u.addVector(1.0, (*offsets)[node], -1.0); - u.addVector(1.0, nodes[node]->getTrialRotation().rotate((*offsets)[node]), 1.0); - } - - u.addVector(1.0, basis.getPosition(), -1.0); -#else - Vector3D u = this->pullPosition<&Node::getTrialDisp>(node) - - basis.getPosition(); -#endif + Vector3D u = this->pullPosition<&Node::getTrialDisp>(node); + u -= basis.getPosition(); u += basis.getRotationDelta()^(nodes[node]->getCrds()); - return u; } @@ -236,10 +223,6 @@ EuclidFrameTransf::getStateVariation() } Matrix3D R = basis.getRotation(); - // return EuclidFrameTransf::pullVariation(ug, R, offsets, offset_flags); - - - // VectorND ul = ug; // (1) Global Offsets // Do ui -= ri x wi diff --git a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h b/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h index 80ce23c7dc..72132530f1 100644 --- a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h @@ -6,6 +6,7 @@ // // FEDEASLab // Finite Elements for Design Evaluation and Analysis of Structures +// https://fedeas.net // //----------------------------------------------------------------------------// // @@ -17,13 +18,12 @@ // //===----------------------------------------------------------------------===// #include +#include #include #include #include #include "EuclidIsometry.h" -class Node; -#define TRIAD C2 namespace OpenSees { @@ -77,12 +77,10 @@ class RankineIsometry : public AlignedIsometry R[init](i,2) = e3[i]; } -#if 1 Xc = nodes[ic]->getCrds(); c[init] = R[init]^(Xc); -#endif - update(); + this->update(); return 0; } @@ -120,7 +118,6 @@ class RankineIsometry : public AlignedIsometry } { -#if 1 // TRIAD==R2 constexpr static Vector3D D2 {0,1,0}; const Vector3D E2 = R[init]*D2; Vector3D e2 = MatrixFromVersor(nodes[0]->getTrialRotation())*E2; //*R[init]; @@ -136,37 +133,6 @@ class RankineIsometry : public AlignedIsometry R[pres](i,1) = e2[i]; R[pres](i,2) = e3[i]; } - -#elif 1 // TRIAD==C2 - Versor q0 = VersorFromMatrix(R[init]); - Versor qI = nodes[0]->getTrialRotation()*q0; - Versor qJ = nodes[nn-1]->getTrialRotation()*q0; - Vector3D gammaw = CayleyFromVersor(qJ.mult_conj(qI)); - - gammaw *= 0.5; - - // Qbar = VersorProduct(VersorFromMatrix(CaySO3(gammaw)), qI); - Matrix3D Rbar = CaySO3(gammaw)*MatrixFromVersor(qI); // *q0); - Vector3D v { Rbar(0,0), Rbar(1,0), Rbar(2,0) }; - double dot = v.dot(e1); - if (std::fabs(std::fabs(dot)-1.0) < 1.0e-10) { - R[pres] = Rbar; - } else { - v = v.cross(e1); - double scale = std::acos(dot)/v.norm(); - v *= scale; // ::acos(r1.dot(e1)); - - R[pres] = ExpSO3(v)*Rbar; - - Vector3D r1 { R[pres](0,0), R[pres](1,0), R[pres](2,0) }; - Vector3D r2 { R[pres](0,1), R[pres](1,1), R[pres](2,1) }; - Vector3D r3 { R[pres](0,2), R[pres](1,2), R[pres](2,2) }; - // opserr << Vector(r1-e1); - // R[pres] = Rbar^ExpSO3(v); - } -#else - Vector3D e2 = vz.cross(e1); -#endif } Vector3D uc = nodes[ic]->getTrialDisp(); From cfbc92a1c2ebf37e56bd094b8563930eea183817 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 13:00:09 -0700 Subject: [PATCH 135/261] move comments up to header --- .../commands/modeling/element/frames.cpp | 377 +++++++++--------- 1 file changed, 185 insertions(+), 192 deletions(-) diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index d99c42ea94..d95dced1bb 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -6,90 +6,194 @@ // https://xara.so //===----------------------------------------------------------------------===// // +// Description: This file implements the parsing of inelastic beam elements. +// We need to support *all* forms of the command that have been used in the past, +// which considerable complicates the logic. +// +// The various forms are +// +// +// 0 1 2 3 4 +// element 1 $i $j 0 1 2 +// +// a) +// 0 1 2 3 4 5 6 +// 0 1 +// element $type $tag $ndi $ndj $trn "Gauss arg1 arg2 ..." +// <-mass $mass> <-iter $iter $tol> +// +// b) OpenSeesPy +// 0 1 +// element(type, tag, ndi, ndj, trn, itag, +// iter=(10, 1e-12), mass=0.0) +// +// c) Original/Obsolete +// 0 1 2 +// element $type $tag $ndi $ndj $nip $sec $trn +// <-mass $mass> <-iter $iter $tol> <-integration $ityp> +// +// d) +// 0 1 ... (2 + nIP) +// element $type $tag $ndi $ndj $nip -sections ... $trn +// <-mass $massDens> <-cMass> <-integration $ityp> +// +// e) +// 0 +// element $type $tag $ndi $ndj $trn +// -sections {...} +// <-mass $massDens> <-cMass> <-integration $ityp> +// +// +// Integration may be specitied as either +// i ) a single name, +// ii ) a pattern spec, or +// iii) a tag for a pattern +// +// If a list of sections is given with -sections, or nIP is provided, then +// we must have an integration with the form (i) +// +// 1) Parse common keyword args: +// "-mass" $mass, +// "-cMass"/"-lMass" +// "-mass-form" $form +// +// "-iter" $iter $tol, +// +// "-integration" $Integration +// - first try parsing $Integration as integer ($itag, form (iii)) +// if successfull, populate section_tags and continue +// - next try parsing $Integration as basic quadrature ($ityp, form (i)) +// - finally, try parsing as full pattern spec +// +// "-section" $Tag +// +// "-transform" $Tag +// "-vertical" {} +// "-horizontal" {} +// +// "-sections" $SectionTags +// - if cannot split $SectionTags as list, then +// mark "-sections" as positional and continue +// with keyword loop +// - Check if "-integration" was provided already; if so, it must have been in form (i); +// otherwise throw an error. +// - Parse $SectionTags +// -sections {...} may occur anywhere +// -sections ... must occur after nIP is obtained +// +// +// 2) +// If pos[1] == "-sections" then command is Form (d): +// nIP = pos[0] +// trn = pos[2+nIP] +// +// else +// +// switch (pos.size()) +// case 1: // Form (e) +// trn = pos[0] +// if (section_tags.size() == 0) +// ERROR +// +// case 2: +// // Form (a) or (b) +// trn = pos[0] +// if GetInt(interp, pos[1]): +// itag = pos[1] +// else +// ParseHingeScheme(pos[1]) +// +// case 3: +// // Form (c) +// nip = int(pos[0]) +// sec = int(pos[1]) +// trn = int(pos[2]) +// +// // Written: cmp, mhs, rms, fmk // // Created: Feb 2023 // // Standard library - #include - #include - #include - #include - #include - #include - #include - #include - #include - #ifdef _MSC_VER - # include - # define strcasecmp _stricmp - #else - # include - #endif - #define strcmp strcasecmp - - // Parsing - #include - #include - #include - #include - - // Model - #include - #include - #include - - // Sections - #include - #include - #include - - // Elements - #include "ElasticBeam2d.h" - #include "ElasticBeam2d.h" - #include "ElasticBeam3d.h" - #include "ElasticBeam3d.h" - #include "PrismFrame2d.h" - #include "PrismFrame2d.h" - #include "PrismFrame3d.h" - #include "PrismFrame3d.h" - - #include - #include - #include - #include - #include - #include - - #include - #include - #include - #include - #include - - #include - #include - #include - - #include - #include - #include - #include - #include - #include - #include - #include - - // Quadrature - #include - #include - #include - #include - #include - #include - #include - - #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _MSC_VER +# include +# define strcasecmp _stricmp +#else +# include +#endif +#define strcmp strcasecmp + +// Parsing +#include +#include +#include +#include + +// Model +#include +#include +#include + +// Sections +#include +#include +#include + +// Elements +#include "ElasticBeam2d.h" +#include "ElasticBeam2d.h" +#include "ElasticBeam3d.h" +#include "ElasticBeam3d.h" +#include "PrismFrame2d.h" +#include "PrismFrame2d.h" +#include "PrismFrame3d.h" +#include "PrismFrame3d.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// Quadrature +#include +#include +#include +#include +#include +#include +#include + +#include using namespace OpenSees; @@ -143,7 +247,8 @@ CreateFrame(BasicModelBuilder& builder, // Finalize the coordinate transform Transform* theTransf = builder.getTypedObject(transfTag); if (theTransf == nullptr) { - opserr << OpenSees::PromptValueError << "transformation not found with tag " << transfTag << "\n"; + opserr << OpenSees::PromptValueError + << "transformation not found with tag " << transfTag << "\n"; return nullptr; } @@ -284,10 +389,6 @@ CreateFrame(BasicModelBuilder& builder, static_loop<0, 3>([&](auto nwm) constexpr { if (nwm.value + 6 == ndf) { - // Create the transform -#if 0 || defined(NEW_TRANSFORM) - FrameTransform<2,6+nwm.value> *tran = tb->template create<2,6+nwm.value>(); -#endif if (!options.shear_flag) { static_loop<2,30>([&](auto nip) constexpr { if (nip.value == sections.size()) @@ -370,114 +471,6 @@ CreateFrame(BasicModelBuilder& builder, } -#if 0 -Element* -CreateInelasticFrame(std::string, std::vector& nodes, - std::vector&, - BeamIntegration&, - // FrameQuadrature&, - FrameTransform&, - Options&); -Element* -CreatePrismaticFrame(std::string); -#endif - -// 0 1 2 3 4 -// element beam 1 $i $j 0 1 2 -// -// a) -// 0 1 2 3 4 5 6 -// 0 1 -// element $type $tag $ndi $ndj $trn "Gauss arg1 arg2 ..." -// <-mass $mass> <-iter $iter $tol> -// -// b) -// 0 1 -// element(type, tag, ndi, ndj, trn, itag, -// iter=(10, 1e-12), mass=0.0) -// -// c) "Original/Obsolete" -// 0 1 2 -// element $type $tag $ndi $ndj $nip $sec $trn -// <-mass $mass> <-iter $iter $tol> <-integration $ityp> -// -// d) -// 0 1 ... (2 + nIP) -// element $type $tag $ndi $ndj $nip -sections ... $trn -// <-mass $massDens> <-cMass> <-integration $ityp> -// -// e) -// 0 -// element $type $tag $ndi $ndj $trn -// -sections {...} -// <-mass $massDens> <-cMass> <-integration $ityp> -// -// -// Integration may be specitied as either -// i ) a single name, -// ii ) a pattern spec, or -// iii) a tag for a pattern -// -// if a list of sections is given with -sections, or nIP is provided, then -// we must have an integration with the form (i) -// -// 1) Parse common keyword args: -// "-mass" $mass, -// "-cMass"/"-lMass" -// "-mass-form" $form -// -// "-iter" $iter $tol, -// -// "-integration" $Integration -// - first try parsing $Integration as integer ($itag, form (iii)) -// if successfull, populate section_tags and continue -// - next try parsing $Integration as basic quadrature ($ityp, form (i)) -// - finally, try parsing as full pattern spec -// -// "-section" $Tag -// -// "-transform" $Tag -// "-vertical" {} -// "-horizontal" {} -// -// "-sections" $SectionTags -// - if cannot split $SectionTags as list, then -// mark "-sections" as positional and continue -// with keyword loop -// - Check if "-integration" was provided already; if so, it must have been in form (i); -// otherwise throw an error. -// - Parse $SectionTags -// -sections {...} may occur anywhere -// -sections ... must occur after nIP is obtained -// -// -// 2) -// If pos[1] == "-sections" then command is Form (d): -// nIP = pos[0] -// trn = pos[2+nIP] -// -// else -// -// switch (pos.size()) -// case 1: // Form (e) -// trn = pos[0] -// if (section_tags.size() == 0) -// ERROR -// -// case 2: -// // Form (a) or (b) -// trn = pos[0] -// if GetInt(interp, pos[1]): -// itag = pos[1] -// else -// ParseHingeScheme(pos[1]) -// -// case 3: -// // Form (c) -// nip = int(pos[0]) -// sec = int(pos[1]) -// trn = int(pos[2]) -// int TclBasicBuilder_addForceBeamColumn(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **const argv) From 9fc375c47fced82a906a73e92573c3a6721a3f52 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 13:01:42 -0700 Subject: [PATCH 136/261] clean --- SRC/runtime/commands/modeling/element/frames.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index d95dced1bb..cd4e2c3652 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -6,9 +6,9 @@ // https://xara.so //===----------------------------------------------------------------------===// // -// Description: This file implements the parsing of inelastic beam elements. -// We need to support *all* forms of the command that have been used in the past, -// which considerable complicates the logic. +// Description: This file implements parsing for inelastic beam elements. +// We support *all* forms of the command that have been used in the past, +// which considerably complicates things. // // The various forms are // @@ -114,6 +114,7 @@ // // Created: Feb 2023 // + // Standard library #include #include From e7f70a22f371048d85885c873b1b8adc8b1ecd44 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 13:02:28 -0700 Subject: [PATCH 137/261] clean --- .../commands/modeling/element/frames.cpp | 447 ------------------ 1 file changed, 447 deletions(-) diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index cd4e2c3652..7183252248 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -964,450 +964,3 @@ TclBasicBuilder_addForceBeamColumn(ClientData clientData, Tcl_Interp *interp, return status; } - - -// -// BeamWithHinges -// -// element beamWithHinges tag? ndI? ndJ? secTagI? lenI? secTagJ? lenJ? -// E? A? I? transfTag? <-shear shearLength?> <-mass massDens?> -// <-iter maxIters tolerance> -// -int -TclBasicBuilder_addBeamWithHinges(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) -{ - BasicModelBuilder *builder = (BasicModelBuilder*)clientData; - - int NDM = builder->getNDM(); - int NDF = builder->getNDF(); - - // Plane frame element - if (NDM == 2 && NDF == 3) { - if (argc < 13) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: element beamWithHinges tag? ndI? ndJ? secTagI? lenI? " - "secTagJ? lenJ? "; - opserr << "E? A? I? transfTag? <-shear shearLength?> <-mass massDens?> " - "<-iter maxIters tolerance>" - << "\n"; - return TCL_ERROR; - } - - double massDens = 0.0; - int max_iters = 10; - double tol = 1.0e-10; - int tag, ndI, ndJ, secTagI, secTagJ, transfTag; - double lenI, lenJ, E, A, I; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid beamWithHinges tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &ndI) != TCL_OK) { - opserr << "WARNING invalid ndI\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[4], &ndJ) != TCL_OK) { - opserr << "WARNING invalid ndJ\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[5], &secTagI) != TCL_OK) { - opserr << "WARNING invalid secTagI\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &lenI) != TCL_OK) { - opserr << "WARNING invalid lenI\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[7], &secTagJ) != TCL_OK) { - opserr << "WARNING invalid ndJ\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[8], &lenJ) != TCL_OK) { - opserr << "WARNING invalid lenJ\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[9], &E) != TCL_OK) { - opserr << "WARNING invalid E\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[10], &A) != TCL_OK) { - opserr << "WARNING invalid A\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[11], &I) != TCL_OK) { - opserr << "WARNING invalid I\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[12], &transfTag) != TCL_OK) { - opserr << "WARNING invalid transfTag\n"; - return TCL_ERROR; - } - - bool isShear = false; - int shearTag = 0; - - if (argc > 13) { - for (int i = 13; i < argc; ++i) { - if (strcmp(argv[i], "-mass") == 0 && ++i < argc) { - if (Tcl_GetDouble(interp, argv[i], &massDens) != TCL_OK) { - opserr << "WARNING invalid massDens\n"; - opserr << "BeamWithHinges: " << tag << "\n"; - return TCL_ERROR; - } - } - - if (strcmp(argv[i], "-constHinge") == 0 && ++i < argc) { - if (Tcl_GetInt(interp, argv[i], &shearTag) != TCL_OK) { - opserr << "WARNING invalid constHinge tag\n"; - opserr << "BeamWithHinges: " << tag << "\n"; - return TCL_ERROR; - } - isShear = true; - } - - if (strcmp(argv[i], "-iter") == 0 && i + 2 < argc) { - if (Tcl_GetInt(interp, argv[++i], &max_iters) != TCL_OK) { - opserr << "WARNING invalid maxIters\n"; - opserr << "BeamWithHinges: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[++i], &tol) != TCL_OK) { - opserr << "WARNING invalid tolerance\n"; - opserr << "BeamWithHinges: " << tag << "\n"; - return TCL_ERROR; - } - } - } - } - - // Retrieve section I from the model builder - FrameSection *sectionI = builder->getTypedObject(secTagI); - if (sectionI == nullptr) - return TCL_ERROR; - - // Retrieve section J from the model builder - FrameSection *sectionJ = builder->getTypedObject(secTagJ); - if (sectionJ == nullptr) - return TCL_ERROR; - - - CrdTransf *theTransf = builder->getTypedObject(transfTag); - if (theTransf == nullptr) - return TCL_ERROR; - - Element *theElement = nullptr; - int numSections = 0; - SectionForceDeformation *sections[10]; - BeamIntegration *theBeamIntegr = nullptr; - - ElasticSection2d elastic(8, E, A, I); - - if (strcmp(argv[1], "beamWithHinges1") == 0) { - theBeamIntegr = new HingeMidpointBeamIntegration(lenI, lenJ); - - numSections = 4; - - sections[0] = sectionI; - sections[1] = &elastic; - sections[2] = &elastic; - sections[3] = sectionJ; - - } else if (strcmp(argv[1], "beamWithHinges2") == 0) { - theBeamIntegr = new HingeRadauTwoBeamIntegration(lenI, lenJ); - - numSections = 6; - sections[0] = sectionI; - sections[1] = sectionI; - sections[2] = &elastic; - sections[3] = &elastic; - sections[4] = sectionJ; - sections[5] = sectionJ; - - } else if (strcmp(argv[1], "beamWithHinges3") == 0 || - strcmp(argv[1], "beamWithHinges") == 0) { - theBeamIntegr = new HingeRadauBeamIntegration(lenI, lenJ); - - numSections = 6; - sections[0] = sectionI; - sections[1] = &elastic; - sections[2] = &elastic; - sections[3] = &elastic; - sections[4] = &elastic; - sections[5] = sectionJ; - - } else if (strcmp(argv[1], "beamWithHinges4") == 0) { - theBeamIntegr = new HingeEndpointBeamIntegration(lenI, lenJ); - - numSections = 4; - sections[0] = sectionI; - sections[1] = &elastic; - sections[2] = &elastic; - sections[3] = sectionJ; - } - - if (theBeamIntegr == nullptr) { - opserr << "Unknown element type: " << argv[1] << "\n"; - return TCL_ERROR; - } - - if (isShear) { - FrameSection *sectionL = builder->getTypedObject(shearTag); - if (sectionL == nullptr) - return TCL_ERROR; - - sections[numSections++] = sectionL; - } - - theElement = new ForceBeamColumn2d(tag, ndI, ndJ, numSections, - sections, - *theBeamIntegr, *theTransf, massDens, - max_iters, tol); - - delete theBeamIntegr; - - if (builder->getDomain()->addElement(theElement) == false) { - opserr << "WARNING could not add element to domain.\n"; - return TCL_ERROR; - } - } - - else if (NDM == 3 && NDF == 6) { - if (argc < 16) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: element beamWithHinges tag? ndI? ndJ? secTagI? lenI? " - "secTagJ? lenJ? "; - opserr << "E? A? Iz? Iy? G? J? transfTag? <-shear shearLength?> <-mass " - "massDens?> <-iter maxIters tolerance>" - << "\n"; - return TCL_ERROR; - } - - int tag, ndI, ndJ, secTagI, secTagJ, transfTag; - double lenI, lenJ, E, A, Iz, Iy, G, J; - double massDens = 0.0; - int max_iters = 10; - double tol = 1.0e-10; - double shearLength = 1.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid beamWithHinges tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &ndI) != TCL_OK) { - opserr << "WARNING invalid ndI\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[4], &ndJ) != TCL_OK) { - opserr << "WARNING invalid ndJ\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[5], &secTagI) != TCL_OK) { - opserr << "WARNING invalid secTagI\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &lenI) != TCL_OK) { - opserr << "WARNING invalid lenI\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[7], &secTagJ) != TCL_OK) { - opserr << "WARNING invalid ndJ\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[8], &lenJ) != TCL_OK) { - opserr << "WARNING invalid lenJ\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[9], &E) != TCL_OK) { - opserr << "WARNING invalid E\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[10], &A) != TCL_OK) { - opserr << "WARNING invalid A\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[11], &Iz) != TCL_OK) { - opserr << "WARNING invalid Iz\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[12], &Iy) != TCL_OK) { - opserr << "WARNING invalid Iy\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[13], &G) != TCL_OK) { - opserr << "WARNING invalid G\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[14], &J) != TCL_OK) { - opserr << "WARNING invalid J\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[15], &transfTag) != TCL_OK) { - opserr << "WARNING invalid transfTag\n"; - return TCL_ERROR; - } - - - if (argc > 16) { - for (int i = 16; i < argc; ++i) { - if (strcmp(argv[i], "-mass") == 0 && ++i < argc) { - if (Tcl_GetDouble(interp, argv[i], &massDens) != TCL_OK) { - opserr << "WARNING invalid massDens\n"; - opserr << "BeamWithHinges: " << tag << "\n"; - return TCL_ERROR; - } - } - - if (strcmp(argv[i], "-shear") == 0 && ++i < argc) { - if (Tcl_GetDouble(interp, argv[i], &shearLength) != TCL_OK) { - opserr << "WARNING invalid shear\n"; - return TCL_ERROR; - } - } - - if (strcmp(argv[i], "-iter") == 0 && i + 2 < argc) { - if (Tcl_GetInt(interp, argv[++i], &max_iters) != TCL_OK) { - opserr << "WARNING invalid maxIters\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[++i], &tol) != TCL_OK) { - opserr << "WARNING invalid tolerance\n"; - return TCL_ERROR; - } - } - } - } - - // Retrieve section I from the model builder - SectionForceDeformation *sectionI = builder->getTypedObject(secTagI); - if (sectionI == nullptr) - return TCL_ERROR; - - // Retrieve section J from the model builder - SectionForceDeformation *sectionJ = builder->getTypedObject(secTagJ); - if (sectionJ == nullptr) - return TCL_ERROR; - - - CrdTransf *theTransf = builder->getTypedObject(transfTag); - if (theTransf == nullptr) - return TCL_ERROR; - - - Element *theElement = nullptr; - int numSections = 0; - SectionForceDeformation *sections[10]; - BeamIntegration *theBeamIntegr = nullptr; - - ElasticSection3d elastic(0, E, A, Iz, Iy, G, J); - - if (strcmp(argv[1], "beamWithHinges1") == 0) { - theBeamIntegr = new HingeMidpointBeamIntegration(lenI, lenJ); - - numSections = 4; - sections[0] = sectionI; - sections[1] = &elastic; - sections[2] = &elastic; - sections[3] = sectionJ; - - } else if (strcmp(argv[1], "beamWithHinges2") == 0) { - theBeamIntegr = new HingeRadauTwoBeamIntegration(lenI, lenJ); - - numSections = 6; - sections[0] = sectionI; - sections[1] = sectionI; - sections[2] = &elastic; - sections[3] = &elastic; - sections[4] = sectionJ; - sections[5] = sectionJ; - - } else if (strcmp(argv[1], "beamWithHinges3") == 0 || - strcmp(argv[1], "beamWithHinges") == 0) { - theBeamIntegr = new HingeRadauBeamIntegration(lenI, lenJ); - - numSections = 6; - sections[0] = sectionI; - sections[1] = &elastic; - sections[2] = &elastic; - sections[3] = &elastic; - sections[4] = &elastic; - sections[5] = sectionJ; - - } else if (strcmp(argv[1], "beamWithHinges4") == 0) { - theBeamIntegr = new HingeEndpointBeamIntegration(lenI, lenJ); - - numSections = 4; - sections[0] = sectionI; - sections[1] = &elastic; - sections[2] = &elastic; - sections[3] = sectionJ; - } - - if (theBeamIntegr == nullptr) { - opserr << "Unknown element type: " << argv[1] << "\n"; - return TCL_ERROR; - } - - // TODO fix shear for beamWithHinges - /* - if (isShear) { - SectionForceDeformation *sectionL = builder->getTypedObject(shearTag); - - if (sectionL == 0) { - opserr << "WARNING section L does not exist\n"; - opserr << "section: " << shearTag; - opserr << "\nBeamWithHinges: " << tag << "\n"; - return TCL_ERROR; - } - sections[numSections++] = sectionL; - } - */ - - theElement = new ForceBeamColumn3d(tag, ndI, ndJ, numSections, sections, - *theBeamIntegr, *theTransf, massDens, - max_iters, tol); - - delete theBeamIntegr; - - // Add to the domain - if (builder->getDomain()->addElement(theElement) == false) { - opserr << "WARNING could not add " - "element to domain "; - opserr << tag << "\n"; - return TCL_ERROR; - } - } - - else { - opserr << "ERROR -- model dimension: " << NDM - << " and nodal degrees of freedom: " << NDF - << " are incompatible for BeamWithHinges element" << "\n"; - return TCL_ERROR; - } - - return TCL_OK; -} From e76dc1cce693fe81942abacaf525c2ea2ff461a2 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 29 Jun 2025 13:39:35 -0700 Subject: [PATCH 138/261] clean up --- SRC/coordTransformation/Frame/FrameTransform.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/SRC/coordTransformation/Frame/FrameTransform.h b/SRC/coordTransformation/Frame/FrameTransform.h index 53bf7713c6..7ca2611212 100644 --- a/SRC/coordTransformation/Frame/FrameTransform.h +++ b/SRC/coordTransformation/Frame/FrameTransform.h @@ -118,13 +118,6 @@ class FrameTransform : public TaggedObject } }; -enum { - CRDTR_TAG_CorotFrameTransfWarping3d, - CRDTR_TAG_CorotFrameTransf3d, - CRDTR_TAG_LinearFrameTransf3d, - CRDTR_TAG_PDeltaFrameTransf3d -}; - } // namespace OpenSees #include "FrameTransform.tpp" From 7d0289fad8a37e549615fa0d7374358f6db7f057 Mon Sep 17 00:00:00 2001 From: gaaraujo Date: Sun, 29 Jun 2025 14:51:12 -0700 Subject: [PATCH 139/261] Allow quad mesh generator to work with 2-node lines --- SRC/element/PFEMElement/QuadMeshGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/element/PFEMElement/QuadMeshGenerator.cpp b/SRC/element/PFEMElement/QuadMeshGenerator.cpp index 969aa6d8e7..43a1a5b5a1 100644 --- a/SRC/element/PFEMElement/QuadMeshGenerator.cpp +++ b/SRC/element/PFEMElement/QuadMeshGenerator.cpp @@ -127,7 +127,7 @@ QuadMeshGenerator::mesh(double size) } // create points - if (m<=1 || n<=1) return 0; + if (m<1 || n<1) return 0; Matrix grid(m+1, n+1); for (int i=0; i Date: Thu, 3 Jul 2025 11:35:28 -0700 Subject: [PATCH 140/261] clean up transformations --- .../Frame/BasicFrameTransf.h | 16 +- .../Frame/BasicFrameTransf.tpp | 24 +- .../Frame/EuclidFrameTransf.h | 25 +- .../Frame/EuclidFrameTransf.tpp | 112 ++- .../Frame/Isometry/BattiniIsometry.h | 128 +++ .../Frame/Isometry/CrisfieldIsometry.h | 852 ++++++++++++++++++ .../Frame/Isometry/EuclidIsometry.h | 240 ++++- .../Frame/Isometry/RankinIsometry.h | 171 ++++ .../Frame/Isometry/RankinIsometry.tpp | 18 + .../Frame/Isometry/SphericalIsometry.h | 132 +++ .../Frame/LinearFrameTransf.h | 15 +- .../Frame/LinearFrameTransf.tpp | 83 +- .../Frame/PDeltaFrameTransf3d.h | 6 +- .../Frame/SouzaFrameTransf.h | 162 ++++ .../Frame/SouzaFrameTransf.tpp | 551 +++++++++++ SRC/matrix/GroupSO3.h | 248 +++-- 16 files changed, 2631 insertions(+), 152 deletions(-) create mode 100644 SRC/coordTransformation/Frame/Isometry/BattiniIsometry.h create mode 100644 SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h create mode 100644 SRC/coordTransformation/Frame/Isometry/RankinIsometry.h create mode 100644 SRC/coordTransformation/Frame/Isometry/RankinIsometry.tpp create mode 100644 SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h create mode 100644 SRC/coordTransformation/Frame/SouzaFrameTransf.h create mode 100644 SRC/coordTransformation/Frame/SouzaFrameTransf.tpp diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.h b/SRC/coordTransformation/Frame/BasicFrameTransf.h index 7aa68e6692..3743485b3b 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.h +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.h @@ -2,10 +2,6 @@ // // xara // https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures // //----------------------------------------------------------------------------// // @@ -22,15 +18,17 @@ // templates to reproduce the legacy CrdTransf classes that were derived // for elements in a "basic" coordinate system. // -// cmp +// +// Written: Claudio M. Perez // #ifndef BasicFrameTransf3d_h #define BasicFrameTransf3d_h +#include #include #include -class Matrix; -class Vector; +#include +#include namespace OpenSees { @@ -115,8 +113,8 @@ class BasicFrameTransf3d: public CrdTransf }; constexpr static int iq[] = { - inx, iny, inz, imx, imy, imz, - jnx, jny, jnz, jmx, jmy, jmz + inx, iny, inz, imx, imy, imz, + jnx, jny, jnz, jmx, jmy, jmz }; }; diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index 2221065ab9..50f9baca63 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -2,10 +2,6 @@ // // xara // https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures // //----------------------------------------------------------------------------// // @@ -16,13 +12,13 @@ // https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// -// -#include + #include #include #include #include #include +#include #include #include "FrameTransform.h" @@ -254,8 +250,8 @@ BasicFrameTransf3d::getInitialGlobalStiffMatrix(const Matrix &KB) for (int j = 0; j < 6; j++) kb[i][j] = KB(i, j); - // - // + // Transform basic stiffness to local system + // First compute kb*T_{bl} for (int i = 0; i < 6; i++) { tmp[i][0] = -kb[i][0]; tmp[i][3] = -kb[i][5]; @@ -266,12 +262,13 @@ BasicFrameTransf3d::getInitialGlobalStiffMatrix(const Matrix &KB) tmp[i][10] = kb[i][4]; tmp[i][11] = kb[i][2]; } - // + // TODO: + // Now compute T'_{bl}*(kb*T_{bl}) for (int i = 0; i < 12; i++) { kl( 0, i) = -tmp[0][i]; kl( 3, i) = -tmp[5][i]; - kl( 4, i) = tmp[3][i]; - kl( 5, i) = tmp[1][i]; + kl( 4, i) = tmp[3][i]; + kl( 5, i) = tmp[1][i]; kl( 6, i) = tmp[0][i]; kl( 9, i) = tmp[5][i]; @@ -292,8 +289,7 @@ template CrdTransf * BasicFrameTransf3d::getCopy3d() { - BasicFrameTransf3d *theCopy = new BasicFrameTransf3d(t.getCopy()); - return theCopy; + return new BasicFrameTransf3d(t.getCopy()); } @@ -422,4 +418,4 @@ BasicFrameTransf3d::recvSelf(int cTag, Channel &, return -1; } -} // namespace OpenSees \ No newline at end of file +} diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h index a84e95e606..0ac9b6b451 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.h +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -2,10 +2,6 @@ // // xara // https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures // //----------------------------------------------------------------------------// // @@ -21,10 +17,11 @@ // Description: This file contains the implementation for the // EuclidFrameTransf class. EuclidFrameTransf is a euclidean transformation // of 3D space. -// When used with the RankineIsometry, it furnishes an improved corotational +// When used with the RankinIsometry, it furnishes an improved corotational // transformation for 3D frames. // -// Written: cmp +// +// Written: Claudio M. Perez // Created: 04/2025 // #ifndef EuclidFrameTransf_hpp @@ -73,8 +70,12 @@ class EuclidFrameTransf: public FrameTransform VectorND pushResponse(VectorND&pl) final; MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - - // + +#if 0 + // method used to rotate consistent mass matrix + const Matrix &getGlobalMatrixFromLocal(const Matrix &local); +#endif + // Sensitivity // bool isShapeSensitivity() final; @@ -87,21 +88,21 @@ class EuclidFrameTransf: public FrameTransform private: + Vector3D getNodeLocation(int tag); + inline MatrixND getProjection() { MatrixND A{}; A.addDiagonal(1.0); - // double L = basis.getLength(); - constexpr Vector3D axis{1, 0, 0}; - constexpr Matrix3D ix = Hat(axis); MatrixND<3,ndf> Gb{}; for (int a = 0; a(basis.getRotationGradient(b), 1.0); - A.assemble(ix*Gb, a*ndf , b*ndf, double(a)/double(nn-1)*L); + Matrix3D Xa = Hat(this->getNodeLocation(a)); + A.assemble(Xa*Gb, a*ndf , b*ndf, 1.0); A.assemble( Gb, a*ndf+3, b*ndf, -1.0); } } diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 83c8180b0d..aecd84fe53 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -2,10 +2,6 @@ // // xara // https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures // //----------------------------------------------------------------------------// // @@ -27,7 +23,8 @@ #include #include #include -#include +#include +#include #include "EuclidFrameTransf.h" namespace OpenSees { @@ -43,7 +40,7 @@ EuclidFrameTransf::EuclidFrameTransf(int tag, ur{}, offsets{nullptr}, offset_flags(offset_flags), - basis{nodes, vecxz} + basis{vecxz} { R0.zero(); R0.addDiagonal(1.0); @@ -100,10 +97,10 @@ EuclidFrameTransf::initialize(std::array& new_nodes) opserr << "invalid pointers to the element nodes\n"; return -1; } - // ensure the node rotation is initialized + // ensure the node is initialized nodes[i]->getTrialRotation(); } - + const Vector &XI = nodes[ 0]->getCrds(); const Vector &XJ = nodes[nn-1]->getCrds(); @@ -121,18 +118,21 @@ EuclidFrameTransf::initialize(std::array& new_nodes) dx(i) += (*offsets)[nn-1][i]; } + // calculate the element length L = dx.norm(); Ln = L; if (L == 0.0) return -2; - int status = basis.initialize(); - R0 = basis.getRotation(); - return status; + int error = basis.initialize(nodes); + + R0 = basis.getRotation(); + return error; } + template int EuclidFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector3D &e3) const @@ -168,12 +168,13 @@ template int EuclidFrameTransf::update() { - if (basis.update() < 0) + if (basis.update(nodes) < 0) return -1; + Matrix3D R = basis.getRotation(); + Ln = basis.getLength(); - Matrix3D R = basis.getRotation(); for (int i=0; igetTrialRotation(); ur[i] = LogSO3(R^(MatrixFromVersor(q)*R0)); @@ -189,14 +190,41 @@ EuclidFrameTransf::getNodeRotation(int tag) return nodes[tag]->getTrialRotation(); } +template +Vector3D +EuclidFrameTransf::getNodeLocation(int node) +{ + Vector3D xn = basis.getRotation()^nodes[node]->getCrds(); + + xn += this->pullPosition<&Node::getTrialDisp>(node); + + return xn - basis.getLocation(); +} + template Vector3D EuclidFrameTransf::getNodePosition(int node) { - Vector3D u = this->pullPosition<&Node::getTrialDisp>(node); - u -= basis.getPosition(); +#if 0 + const Vector& ug = nodes[node]->getTrialDisp(); + + Vector3D u; + for (int i=0; i<3; i++) + u[i] = ug[i]; + + if (offsets != nullptr) [[unlikely]] { + u.addVector(1.0, (*offsets)[node], -1.0); + u.addVector(1.0, nodes[node]->getTrialRotation().rotate((*offsets)[node]), 1.0); + } + + u.addVector(1.0, basis.getPosition(), -1.0); +#else + Vector3D u = this->pullPosition<&Node::getTrialDisp>(node) + - basis.getPosition(); +#endif u += basis.getRotationDelta()^(nodes[node]->getCrds()); + return u; } @@ -296,14 +324,29 @@ EuclidFrameTransf::pushResponse(VectorND&p) // 1) Logarithm if (1) { // !(offset_flags & LogIter)) { for (int i=0; i A = getProjection(); pa = A^pa; +#else + // 2.1) Sum of moments: m = sum_i mi + sum_i (xi x ni) + Vector3D m{}; + for (int i=0; igetNodeLocation(i).cross(Vector3D{pa[i*ndf+0], pa[i*ndf+1], pa[i*ndf+2]}); + } + // 2.2) Adjust + for (int i=0; i(i*ndf, basis.getRotationGradient(i)^m, -1.0); +#endif + // 3,4) Rotate and joint offsets auto pg = this->FrameTransform::pushConstant(pa); @@ -341,9 +384,9 @@ EuclidFrameTransf::pushResponse(MatrixND&kb, const V {Kb(i*ndf+3*k+0, j*ndf+3*l+2), Kb(i*ndf+3*k+1, j*ndf+3*l+2), Kb(i*ndf+3*k+2, j*ndf+3*l+2)} }}; if (k == 1) - Kab = Kab*Aj; + Kab = Ai^Kab; // row rotation block if (l == 1) - Kab = Ai^Kab; + Kab = Kab*Aj; // column rotation block Kb.insert(Kab, i*ndf+3*k, j*ndf+3*l, 1.0); if (i == j && k == 1 && l == 1) @@ -360,20 +403,39 @@ EuclidFrameTransf::pushResponse(MatrixND&kb, const V MatrixND A = getProjection(); Kl.addMatrixTripleProduct(0, A, Kb, 1); + + VectorND Ap = A^p; +#if 0 + p = A^p; + +#else + Kb.zero(); + VectorND<12> qwx{}; + for (int i=0; i Kw = basis.getRotationJacobian(qwx); + Kb.assemble(Kw.template extract<0, 6, 0, 6>(), 0, 0, 1.0); + Kb.assemble(Kw.template extract<0, 6, 6,12>(), 0, ndf, 1.0); + Kb.assemble(Kw.template extract<6,12, 0, 6>(), ndf, 0, 1.0); + Kb.assemble(Kw.template extract<6,12, 6,12>(), ndf, ndf, 1.0); + Kl.addMatrixProduct(Kb, A, 1.0); + // p = A^p; +#endif + // // Kl += -W'*Pn'*A // - p = A^p; Kb.zero(); for (int j=0; j Gj = basis.getRotationGradient(j); for (int i=0; i +#include +#include +#include +#include "EuclidIsometry.h" + +class Node; + +namespace OpenSees { + +template +class BattiniIsometry : public AlignedIsometry +{ +public: + BattiniIsometry(const Vector3D& vecxz) + : AlignedIsometry(vecxz), + n(0) + { + } + + using AlignedIsometry::init; + using AlignedIsometry::pres; + + Matrix3D + update_basis(const Matrix3D& RI, const Matrix3D& RJ, const Vector3D& dx) final + { + Matrix3D R; + { + Vector3D e1 = dx; + e1 /= e1.norm(); + + constexpr static Vector3D D2 {0,1,0}; + const Vector3D E2 = this->AlignedIsometry::R[init]*D2; + q = RI*E2; //*R[init]; + q.addVector(0.5, RJ*E2, 0.5); + + + Vector3D e3 = e1.cross(q); + e3 /= e3.norm(); + + Vector3D e2 = e3.cross(e1); + + for (int i = 0; i < 3; i++) { + R(i,0) = e1[i]; + R(i,1) = e2[i]; + R(i,2) = e3[i]; + } + + Vector3D Q = R^q; + n = Q[0]/Q[1]; + + Vector3D QI = R^(RI*E2); + Vector3D QJ = R^(RJ*E2); + n11 = QI[0]/Q[1]; + n12 = QI[1]/Q[1]; + n21 = QJ[0]/Q[1]; + n22 = QJ[1]/Q[1]; + } + return R; + } + + + MatrixND<3,6> + getRotationGradient(int node) final { + MatrixND<3,6> Gb{}; + + constexpr Vector3D axis{1, 0, 0}; + constexpr Matrix3D ix = Hat(axis); + + double Ln = this->getLength(); + + if (node == 0) { + Gb.template insert<0,0>( ix, -1.0/Ln); + Gb(0,2) = n/Ln; + Gb(0,3) = n12/2.0; // - n; + Gb(0,4) = -n11/2.0; + } + else if (node == nn-1) { + Gb.template insert<0,0>( ix, 1.0/Ln); + Gb(0,2) = - n/Ln; + Gb(0,3) = n22/2.0; + Gb(0,4) = -n12/2.0; + } + + return Gb; + } + +private: + Vector3D q {0,1,0}; + double n = 0, + n11 = 0, + n12 = 1, + n21 = 0, + n22 = 1; +}; +} // namespace OpenSees \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h new file mode 100644 index 0000000000..75041eda13 --- /dev/null +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h @@ -0,0 +1,852 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//----------------------------------------------------------------------------// +// +// The following resource should be cited in derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. (2024) +// "On Nonlinear Geometric Transformations of Finite Elements" +// Int. J. Numer. Meth. Engrg.; +// Available at: https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +// +// Written: Claudio M. Perez, +// Filip C. Filippou +// University of California, Berkeley +// +// Developed with FEDEASLab [2]. +// +// References: +// +// [2] Filippou, F.C. (1998) +// "FEDEASLab: Finite Elements for Design Evaluation and Analysis of Structures" +// +// [3] Crisfield, M.A. (1990) "A consistent co-rotational formulation for +// non-linear, three-dimensional, beam-elements", Computer Methods in Applied +// Mechanics and Engineering, 81(2), pp. 131–150. Available at: +// https://doi.org/10.1016/0045-7825(90)90106-V. +// +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include "EuclidIsometry.h" + +class Node; + +namespace OpenSees { + +template +class CrisfieldIsometry : public AlignedIsometry { +public: + CrisfieldIsometry(const Vector3D& vecxz) + : AlignedIsometry{vecxz}, Lr2{}, Lr3{}, v{} + { + + } + + MatrixND<3,6> + getRotationGradient(int node) final { + constexpr Vector3D e1{1, 0, 0}; + + double Ln = this->getLength(); + +#if 1 + static constexpr + MatrixND<1,3> E3 {{{0.0}, {0.0}, {1.0}}}, + E2 {{{0.0}, {1.0}, {0.0}}}; + + + const Matrix3D& Tr = this->getRotation(); + Triad r{Tr^Rbar}; + Vector3D r1 = r[1], r3 = r[3]; + + + Matrix3D A{}; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; + + + #if 0 + constexpr Matrix3D ix = Hat(e1); + auto de2 = this->getLMatrix(r2, r1, e1, A).transpose(); + auto de3 = this->getLMatrix(r3, r1, e1, A).transpose(); + #else + auto de3 = this->getBasisVariation(r3, r1, e1, v, A); + #endif + + MatrixND<3,12> de1{}; + de1.template insert<0,0>(A, -1.0); + de1.template insert<0,6>(A, 1.0); + + MatrixND<3,12> G{}; + G.template insert<0,0, 1,12>(E2*de3, -1.0); + G.template insert<1,0, 1,12>(E3*de1, -1.0); + G.template insert<2,0, 1,12>(E2*de1, 1.0); + + if (node == 0) { + MatrixND<3,6> Gb = G.template extract<0,3, 0, 6>(); + return Gb; + } + else { + MatrixND<3,6> Gb = G.template extract<0,3, 6,12>(); + return Gb; + } +#else + MatrixND<3,6> Gb{}; + + if (node == 0) { + Gb.template insert<0,0>( ix, -1.0/Ln); + Gb(0,3) = 0.5; + } + else if (node == nn-1) { + Gb.template insert<0,0>( ix, 1.0/Ln); + Gb(0,3) = 0.5; + } + return Gb; +#endif + } + + Matrix3D + update_basis(const Matrix3D& RI, const Matrix3D& RJ, const Vector3D& dx) + { + Ln = dx.norm(); + { + Triad TrI{RI}, TrJ{RJ}; + rI[0] = TrI[1]; + rI[1] = TrI[2]; + rI[2] = TrI[3]; + rJ[0] = TrJ[1]; + rJ[1] = TrJ[2]; + rJ[2] = TrJ[3]; + } + + { + Versor qI = VersorFromMatrix(RI); + Versor qJ = VersorFromMatrix(RJ); + Vector3D gammaw = CayleyFromVersor(qJ.mult_conj(qI)); + + gammaw *= 0.5; + + Rbar = CaySO3(gammaw)*RI; + + Triad r{Rbar}; + r1 = r[1]; + r2 = r[2]; + r3 = r[3]; + } + + e[0] = dx; + e[0] /= Ln; + + // + // Compute the base vectors e2, e3 + // + + Matrix3D E; +#if 1 + { + constexpr double ktol = 50.0*std::numeric_limits::epsilon(); + Vector3D r1 { Rbar(0,0), Rbar(1,0), Rbar(2,0) }; + + // Clamp to avoid NaNs from acos + double dot = std::clamp(r1.dot(e[0]), -1.0, 1.0); + + if (std::fabs(dot - 1.0) < ktol) { // Rbar already aligned + v.zero(); + E = Rbar; + } + else if (std::fabs(dot + 1.0) < ktol) { // opposite direction + // choose any axis with numerical separation from r1 + v = r1.cross(Vector3D{1.0, 0.0, 0.0}); + if (v.dot(v) < ktol) + v = r1.cross(Vector3D{0.0, 1.0, 0.0}); + v *= M_PI / v.norm(); + } + else { // general case + v = r1.cross(e[0]); + double angle = std::atan2(v.norm(), dot); + v *= angle / v.norm(); + } + E = ExpSO3(v)*Rbar; + + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + e[j][i] = E(i,j); + } +#else + { + // Not working with frame-1007? + // + // 'rotate' the mean rotation matrix Rbar on to e1 to + // obtain e2 and e3 (using the 'mid-point' procedure) + + // e2 = r2 - (e1 + r1)*((r2^e1)*0.5); + + Vector3D tmp; + tmp = e[0]; + tmp += r1; + + e[1] = tmp; + { + e[1] *= 0.5*r2.dot(e[0]); + e[1].addVector(-1.0, r2, 1.0); + } + + // e3 = r3 - (e1 + r1)*((r3^e1)*0.5); + e[2] = tmp; + { + e[2] *= r3.dot(e[0])*0.5; + e[2].addVector(-1.0, r3, 1.0); + } + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + E(i,j) = e[j][i]; + } +#endif + + // + // + // + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + A(i,j) = (double(i==j) - e[0][i]*e[0][j])/Ln; + + Lr2 = this->getLMatrix(r2, r1, e[0], A); + Lr3 = this->getLMatrix(r3, r1, e[0], A); + + return E; + } + + // + // + // + inline MatrixND<12,12> + compute_tangent(const VectorND<12> &ul) + { + // extract columns of rotation matrices + const Vector3D + &e1 = e[0], + &e2 = e[1], + &e3 = e[2], + + &rI1 = rI[0], + &rI2 = rI[1], + &rI3 = rI[2], + &rJ1 = rJ[0], + &rJ2 = rJ[1], + &rJ3 = rJ[2]; + + // + // + // + MatrixND<12,12> T{}; + + // T1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', O', O']'; + + // (-S(rI3)*e2 + S(rI2)*e3) + Vector3D Se = rI2.cross(e3); + Se -= rI3.cross(e2); + for (int i = 0; i < 3; i++) + // T(jmx,i+3) = -Se[i]; + T(imx,i+3) = Se[i]; + + // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; + + Vector3D At = A*rI2; + + // (-S(rI2)*e1 + S(rI1)*e2)' + Se = rI1.cross(e2); + Se -= rI2.cross(e1); + for (int i = 0; i < 3; i++) { + T(imz,i ) = At[i]; + T(imz,i+3) = Se[i]; + T(imz,i+6) = -At[i]; + } + + // T3 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', -(A*rI3)', O']'; + + At = A*rI3; + + // -S(rI3)*e1 + S(rI1)*e3 + Se = rI1.cross(e3); + Se -= rI3.cross(e1); + for (int i = 0; i < 3; i++) { + T(imy,i ) = At[i]*-1; + T(imy,i+3) = Se[i]*-1; + T(imy,i+6) = -At[i]*-1; + } + + // T4 = [ O', O', O', (-S(rJ3)*e2 + S(rJ2)*e3)']'; + Se = rJ2.cross(e3); + Se -= rJ3.cross(e2); + for (int i = 0; i < 3; i++) + T(jmx, i+9) = Se[i]; // S(rJ2)*e3 - S(rJ3)*e2 + + // T5 = [(A*rJ2)', O', -(A*rJ2)', (-S(rJ2)*e1 + S(rJ1)*e2)']'; + At = A*rJ2; + Se = rJ1.cross(e2); + Se -= rJ2.cross(e1); + for (int i = 0; i < 3; i++) { + T(jmz, i ) = At[i]; + T(jmz, i+6) = -At[i]; + T(jmz, i+9) = Se[i]; // (-S(rJ2)*e1 + S(rJ1)*e2) + } + + // T6 = [(A*rJ3)', O', -(A*rJ3)', (-S(rJ3)*e1 + S(rJ1)*e3)']' + At = A*rJ3; + Se = rJ1.cross(e3); // (-S(rJ3)*e1 + S(rJ1)*e3) + Se -= rJ3.cross(e1); + for (int i = 0; i < 3; i++) { + T(jmy,i ) = At[i]*-1; + T(jmy,i+6) = -At[i]*-1; + T(jmy,i+9) = Se[i]*-1; + } + + // + // Second part + // + + // T(:,1) += Lr3*rI2 - Lr2*rI3; + // T(:,2) += Lr2*rI1; z + // T(:,3) += Lr3*rI1 ; y + + // T(:,4) += Lr3*rJ2 - Lr2*rJ3; + // T(:,5) += Lr2*rJ1 ; z // ?????? check sign + // T(:,6) += Lr3*rJ1 ; y // ?????? check sign + + // Bending Z + for (int i = 0; i < 12; i++) { + double T1i = 0; + for (int k=0; k<3; k++) + T1i += Lr2(i,k)*rI1[k]; + T(imz,i) += T1i; + } + + for (int i = 0; i < 12; i++) { + double T4i = 0; + for (int k=0; k<3; k++) + T4i += Lr2(i,k)*rJ1[k]; // Lr[i]; + T(jmz,i) += T4i; + } + + // Torsion + for (int i = 0; i < 12; i++) { + double T0i = 0; + for (int k=0; k<3; k++) + T0i += Lr3(i,k)*rI2[k] - Lr2(i,k)*rI3[k]; + // T(jmx,i) += -T0i; + T(imx,i) += T0i; + } + for (int i = 0; i < 12; i++) { + double T3i = 0; + for (int k=0; k<3; k++) + T3i += Lr3(i,k)*rJ2[k] - Lr2(i,k)*rJ3[k]; + T(jmx,i) += T3i; + } + // Bending Y + for (int i = 0; i < 12; i++) { + double T2i = 0; + for (int k=0; k<3; k++) + T2i += Lr3(i,k)*rI1[k]; // Lr[i]; + T(imy,i) += T2i*-1; + } + for (int i = 0; i < 12; i++) { + double T5i = 0; + for (int k=0; k<3; k++) + T5i += Lr3(i,k)*rJ1[k]; // Lr[i]; + T(jmy,i) += T5i*-1; + } + + // + // + // + for (int node=0; node < 2; node++) + for (int j = 0; j < 3; j++) { + const double c = 0.5 / std::cos(ul[(node? jmx : imx) + j]); + for (int i = 0; i < 12; i++) + T((node? jmx : imx) + j, i) *= c; + } + + // Axial + // T(:,7) = [-e1' O' e1' O']'; + for (int i = 0; i < 3; i++) { + T(jnx,i ) = -e1[i]; + T(jnx,i+6) = e1[i]; + } + + // Combine torsion + for (int i=0; i<12; i++) { + T(jmx,i) -= T(imx,i); + T(imx,i) = 0; + } + + return T; + } + + + // + // Add geometric part of the transformation tangent + // + // kg += T'*kl*T + ks1 + T * diag(m.*tan(thetal))*T' + // + m(4)*(ks2r2t3_u3 + ks2r3u2_t2) + // + m(2)*ks2r2t1 + m(3)*ks2r3t1 + // + m(5)*ks2r2u1 + m(6)*ks2r3u1 + // + ks3 + ks3' + ks4 + ks5; + // + int addTangent(MatrixND<12,12>& kg, + const VectorND<12>& pl, + const VectorND<12>& ul) + { + const Vector3D + &e1 = e[0], + &e2 = e[1], + &e3 = e[2], + + &rI1 = rI[0], + &rI2 = rI[1], + &rI3 = rI[2], + &rJ1 = rJ[0], + &rJ2 = rJ[1], + &rJ3 = rJ[2]; + + double Ln = this->getLength(); + + // + // Ksigma1 + // + { + const double N = -pl[0]; // Axial force + this->getKs1Matrix(kg, N); + } + + // + // Ksigma3 + // + // ks3 = [o kbar2 | o kbar4]; + // + // where + // + // kbar2 = -Lr2*(m(3)*S(rI3) + m(1)*S(rI1)) + Lr3*(m(3)*S(rI2) - m(2)*S(rI1)) ; + // + // kbar4 = Lr2*(m(3)*S(rJ3) - m(4)*S(rJ1)) - Lr3*(m(3)*S(rJ2) + m(5)*S(rJ1)); + // + // or + // + // ks3 = [o ka+kb | o kc+kd]; + // = [o ka | o kc] + [o kb | o kd]; + // + // where + // + // ka = -Lr2*S(rI3)*m(3) + // +Lr2*S(rI1)*m(1); + // kb = Lr3*S(rI2)*m(3) + // -Lr3*S(rI1)*m(2); + // + // kc = Lr2*S(rJ3)*m(3) + // -Lr2*S(rJ1)*m(4); + // kd = -Lr3*S(rJ2)*m(3) + // +Lr3*S(rJ1)*m(5); + + VectorND<6> m; + m[0] = 0.5*pl[imx]/std::cos(ul(imx)); + m[2] = -0.5*pl[imy]/std::cos(ul(imy)); + m[1] = 0.5*pl[imz]/std::cos(ul(imz)); + + m[3] = 0.5*pl[jmx]/std::cos(ul(jmx)); + m[5] = -0.5*pl[jmy]/std::cos(ul(jmy)); + m[4] = 0.5*pl[jmz]/std::cos(ul(jmz)); + + this->getKs3Matrix(kg, m); + + // + // Ksigma4 + // + { + Matrix3D ks33; + ks33.zero(); + ks33.addSpinProduct(e2, rI3, m[3]); + ks33.addSpinProduct(e3, rI2, -m[3]); + ks33.addSpinProduct(e2, rI1, m[1]); + ks33.addSpinProduct(e1, rI2, -m[1]); + ks33.addSpinProduct(e3, rI1, m[2]); + ks33.addSpinProduct(e1, rI3, -m[2]); + kg.assemble(ks33, 3, 3, 1.0); + } + + // + // Ksigma4 + // + { + Matrix3D ks33; + ks33.zero(); + ks33.addSpinProduct(e2, rJ3, -m[3]); + ks33.addSpinProduct(e3, rJ2, m[3]); + ks33.addSpinProduct(e2, rJ1, m[4]); + ks33.addSpinProduct(e1, rJ2, -m[4]); + ks33.addSpinProduct(e3, rJ1, m[5]); + ks33.addSpinProduct(e1, rJ3, -m[5]); + + kg.assemble(ks33, 9, 9, 1.0); + } + + // + // Ksigma5 + // + // Ks5 = [ Ks5_11 Ks5_12 | -Ks5_11 Ks5_14; + // Ks5_12' O | -Ks5_12' O; + // -Ks5_11 -Ks5_12 | Ks5_11 -Ks5_14; + // Ks5_14t O | -Ks5_14' O]; + // + // + // v = (1/Ln)*(m(2)*rI2 + m(3)*rI3 + m(5)*rJ2 + m(6)*rJ3); + // = 1/Ln * (m[1]*rI2 + m[2]*rI3) + // + 1/Ln * (m[4]*rJ2 + m[5]*rJ3); + // = vi + vj + // + { + Vector3D v; + v.addVector(0.0, rI2, m[1]); + v.addVector(1.0, rI3, m[2]); + v.addVector(1.0, rJ2, m[4]); + v.addVector(1.0, rJ3, m[5]); + v /= Ln; + + // Ks5_11 = A*v*e1' + e1*v'*A + (e1'*v)*A; + // = A*vi*e1' + e1*vi'*A + (e1'*vi)*A + // + A*vj*e1' + e1*vj'*A + (e1'*vj)*A; + // + Matrix3D ks33{}; + ks33.addMatrix(A, e1.dot(v)); + + Matrix3D m33{}; + m33.addTensorProduct(v, e1, 1.0); + + ks33.addMatrixProduct(A, m33, 1.0); + + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + m33(i,j) = e1[i]*v[j]; + + ks33.addMatrixProduct(m33, A, 1.0); + + kg.assemble(ks33, 0, 0, 1.0); + kg.assemble(ks33, 0, 6, -1.0); + kg.assemble(ks33, 6, 0, -1.0); + kg.assemble(ks33, 6, 6, 1.0); + } + + // Ks5_12 = -(m(2)*A*S(rI2) + m(3)*A*S(rI3)); + { + Matrix3D ks33; + ks33.zero(); + ks33.addMatrixSpinProduct(A, rI2, -m[1]); + ks33.addMatrixSpinProduct(A, rI3, -m[2]); + + kg.assemble(ks33, 0, 3, 1.0); + kg.assemble(ks33, 6, 3, -1.0); + kg.assembleTranspose(ks33, 3, 0, 1.0); + kg.assembleTranspose(ks33, 3, 6, -1.0); + + // Ks5_14 = -(m(5)*A*S(rJ2) + m(6)*A*S(rJ3)); + + ks33.zero(); + ks33.addMatrixSpinProduct(A, rJ2, -m[4]); + ks33.addMatrixSpinProduct(A, rJ3, -m[5]); + + kg.assemble(ks33, 0, 9, 1.0); + kg.assemble(ks33, 6, 9, -1.0); + + kg.assembleTranspose(ks33, 9, 0, 1.0); + kg.assembleTranspose(ks33, 9, 6, -1.0); + } + + // Ksigma ------------------------------- + Vector3D rm = rI3; + + rm.addVector(1.0, rJ3, -1.0); + this->getKs2Matrix(kg, r2, rm, m[3]); + + // rm = rJ2; + rm.addVector(0.0, rJ2, 1.0); + rm.addVector(1.0, rI2, -1.0); + this->getKs2Matrix(kg, r3, rm, m[3]); + this->getKs2Matrix(kg, r2, rI1, m[1]); + this->getKs2Matrix(kg, r3, rI1, m[2]); + // + this->getKs2Matrix(kg, r2, rJ1, m[4]); + this->getKs2Matrix(kg, r3, rJ1, m[5]); + + return 0; + } + + +private: + + inline MatrixND<3,12> + getBasisVariation(const Vector3D &ri, + const Vector3D& r1, + const Vector3D& e1, + const Vector3D& v, + const Matrix3D& A) const noexcept + { + double nu = v.norm(); + Matrix3D L1 = ExpSO3(v)^dExpSO3(v, ri)*Hat(r1)*A; // nu + Matrix3D L2 = ExpSO3(v)^dExpSO3(v, ri)*Hat(e1)*Hat(r1); // nu/2.0 + Matrix3D L3 = Hat(ri); + + MatrixND<3,12> L{}; + // i + L.assemble(L1, 0, 0, -nu); + L.assemble(L2, 0, 3, nu/2.0); + L.assemble(L3, 0, 3, -0.5); + // j + L.assemble(L1, 0, 6, nu); + L.assemble(L2, 0, 9, nu/2.0); + L.assemble(L3, 0, 9, -0.5); + + return L; + } + + inline MatrixND<12,3> + getLMatrix(const Vector3D &ri, + const Vector3D& r1, const Vector3D& e1, const Matrix3D& A) const noexcept + { + + static Matrix3D rie1r1; + static Matrix3D e1e1r1; + + const double rie1 = ri.dot(e1); + + for (int k = 0; k < 3; k++) { + const double e1r1k = (e1[k] + r1[k]); + for (int j = 0; j < 3; j++) { + rie1r1(j,k) = ri[j]*e1r1k; + e1e1r1(j,k) = e1[j]*e1r1k; + } + } + + static Matrix3D L1, L2; + // L1 = ri'*e1 * A/2 + A*ri*(e1 + r1)'/2; + L1.zero(); + L1.addMatrix(A, rie1*0.5); + L1.addMatrixProduct(A, rie1r1, 0.5); + + // L2 = Sri/2 - ri'*e1*S(r1)/4 - Sri*e1*(e1 + r1)'/4; + L2.zero(); + L2.addSpin(ri, 0.5); + L2.addSpin(r1, -rie1/4.0); + L2.addSpinMatrixProduct(ri, e1e1r1, -0.25); + + // L = [L1 + // L2 + // -L1 + // L2]; + + MatrixND<12,3> L{}; + L.assemble(L1, 0, 0, 1.0); + L.assemble(L2, 3, 0, 1.0); + L.assemble(L1, 6, 0, -1.0); + L.assemble(L2, 9, 0, 1.0); + + return L; + } + + inline void + getKs1Matrix(MatrixND<12,12> &Kg, double N) const noexcept + { + // a=0 + Kg.assemble(A, 0, 0, N); + Kg.assemble(A, 0, 6, -N); + // a=1 + Kg.assemble(A, 6, 0, -N); + Kg.assemble(A, 6, 6, N); + } + + inline void + getKs3Matrix(MatrixND<12,12> &Kg, const VectorND<6>& m) const noexcept + { + const Vector3D &rI1 = rI[0], + &rI2 = rI[1], + &rI3 = rI[2], + &rJ1 = rJ[0], + &rJ2 = rJ[1], + &rJ3 = rJ[2]; + Matrix3D Sm{}; + Sm.addSpin(rI3, m[3]); + Sm.addSpin(rI1, m[1]); + MatrixND<12,3> kbar{}; + kbar.addMatrixProduct(Lr2, Sm, -1.0); + + Sm.zero(); + Sm.addSpin(rI2, m[3]); + Sm.addSpin(rI1, -m[2]); + kbar.addMatrixProduct(Lr3, Sm, 1.0); + + Kg.assemble(kbar, 0, 3, 1.0); + Kg.assembleTranspose(kbar, 3, 0, 1.0); + + Sm.zero(); + Sm.addSpin(rJ3, m[3]); + Sm.addSpin(rJ1, -m[4]); + kbar.zero(); + kbar.addMatrixProduct(Lr2, Sm, 1.0); + + Sm.zero(); + Sm.addSpin(rJ2, m[3]); + Sm.addSpin(rJ1, m[5]); + kbar.addMatrixProduct(Lr3, Sm, -1.0); + + Kg.assemble(kbar, 0, 9, 1.0); + Kg.assembleTranspose(kbar, 9, 0, 1.0); + } + + inline void + getKs2Matrix(MatrixND<12,12> &Kg, + const Vector3D &ri, + const Vector3D &z, + double scale) const noexcept + { + const Vector3D &e1 = e[0]; + + // const double Ln = this->getLength(); + // Ksigma2 = [ K11 K12 -K11 K12 + // K12' K22 -K12' K22 + // -K11 -K12 K11 -K12 + // K12' K22 -K12' K22]; + + // U = (-1/2)*A*z*ri'*A + ri'*e1*A*z*e1'/(2*Ln)+... + // z'*(e1+r1)*A*ri*e1'/(2*Ln); + + const double rite1 = ri.dot(e1); + const double zte1 = z.dot(e1); + const double ztr1 = z.dot(r1); + + static Matrix3D zrit, ze1t; + static Matrix rizt(3,3), rie1t(3,3); + static Matrix3D e1zt; + + // const Matrix3D e1zt = e1.bun(z); + + // Chrystal's looping order + for (int j = 0; j < 3; j++) { + for (int i = 0; i < 3; i++) { + zrit(i,j) = z[i]*ri[j]; + rizt(i,j) = ri[i]*z[j]; + ze1t(i,j) = z[i]*e1[j]; + e1zt(i,j) = e1[i]*z[j]; + rie1t(i,j) = ri[i]*e1[j]; + } + } + + Matrix3D U; + U.addMatrixTripleProduct(0.0, A, zrit, -0.5); + U.addMatrixProduct(A, ze1t, rite1/(2*Ln)); + U.addMatrixProduct(A, rie1t, (zte1 + ztr1)/(2*Ln)); + + + // K11 = U + U' + ri'*e1*(2*(e1'*z)+z'*r1)*A/(2*Ln); + + Matrix3D ks{}; + ks.addMatrix(U, 1.0); + + // Add matrix U transpose + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + ks(i,j) += U(j,i); + + ks.addMatrix(A, rite1*(2*zte1 + ztr1)/(2*Ln)); + + Kg.assemble(ks, 0, 0, scale); + Kg.assemble(ks, 0, 6, -scale); + Kg.assemble(ks, 6, 0, -scale); + Kg.assemble(ks, 6, 6, scale); + + // K12 = (1/4)*(-A*z*e1'*Sri - A*ri*z'*Sr1 - z'*(e1+r1)*A*Sri); + Matrix3D m1{}; + m1.addMatrixProduct(A, ze1t, -1.0); + ks.zero(); + ks.addMatrixSpinProduct(m1, ri, 0.25); + + m1.zero(); + m1.addMatrixProduct(A, rizt, -1.0); + ks.addMatrixSpinProduct(m1, r1, 0.25); + ks.addMatrixSpinProduct(A, ri, -0.25*(zte1+ztr1)); + + Kg.assemble(ks, 0, 3, scale); + Kg.assemble(ks, 0, 9, scale); + Kg.assemble(ks, 6, 3, -scale); + Kg.assemble(ks, 6, 9, -scale); + + Kg.assembleTranspose(ks, 3, 0, scale); + Kg.assembleTranspose(ks, 3, 6, -scale); + Kg.assembleTranspose(ks, 9, 0, scale); + Kg.assembleTranspose(ks, 9, 6, -scale); + + // K22 = (1/8)*((-ri'*e1)*Sz*Sr1 + Sr1*z*e1'*Sri + ... + // Sri*e1*z'*Sr1 - (e1+r1)'*z*S(e1)*Sri + 2*Sz*Sri); + + ks.zero(); + ks.addSpinProduct(z, r1, -0.125*(rite1)); + + m1.zero(); + m1.addSpinMatrixProduct( r1, ze1t, 1.0); + ks.addMatrixSpinProduct( m1, ri, 0.125); + + m1.zero(); + m1.addSpinMatrixProduct(ri, e1zt, 1.0); + ks.addMatrixSpinProduct(m1, r1, 0.125); + + ks.addSpinProduct(e1, ri, -0.125*(zte1 + ztr1)); + ks.addSpinProduct( z, ri, 0.25); + + // Ksigma2 = [ K11 K12 -K11 K12; + // K12t K22 -K12t K22; + // -K11 -K12 K11 -K12; + // K12t K22 -K12t K22]; + + Kg.assemble(ks, 3, 3, scale); + Kg.assemble(ks, 3, 9, scale); + Kg.assemble(ks, 9, 3, scale); + Kg.assemble(ks, 9, 9, scale); + } + + +private: + + enum { + inx= 0, // axial + iny= 1, // Vy + inz= 2, // Vz + imx= 3, // torsion + imy= 4, // rot y I + imz= 5, // rot z I + + jnx= 6, // axial + jny= 7, + jnz= 8, + jmx= 9, // torsion + jmy=10, // rot y J + jmz=11, // rot z J + }; + + Matrix3D A; + Matrix3D Rbar; + Vector3D v; + Vector3D r1, r2, r3; + Vector3D e[3], rI[3], rJ[3]; + MatrixND<12,3> Lr2, Lr3; + double Ln; +}; +} \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h index 87e8524c65..bad39f560c 100644 --- a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h @@ -2,10 +2,6 @@ // // xara // https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures // //----------------------------------------------------------------------------// // @@ -17,6 +13,9 @@ // //===----------------------------------------------------------------------===// +// +// Written: Claudio M. Perez +// #pragma once #include #include @@ -27,36 +26,203 @@ #include #include - namespace OpenSees { +template class Isometry { public: - virtual int initialize() =0; - virtual int update() =0; + virtual int initialize(std::array& nodes) =0; + virtual int update(std::array& nodes) =0; + + virtual int update(const Matrix3D& RI, const Matrix3D& RJ, const Vector3D& dx, + std::array& nodes) =0; virtual double getLength() const =0; - // x, \Lambda + virtual Matrix3D getRotation() const =0; virtual Vector3D getPosition() =0; - // \psi + virtual Vector3D getPositionVariation(int ndf, double* du) =0; virtual Vector3D getRotationVariation(int ndf, double* du) =0; + virtual MatrixND<12,12> getRotationJacobian(const VectorND<12>&pl) { + MatrixND<12,12> K; + K.zero(); + return K; + } virtual Matrix3D getRotationDelta() =0; // virtual MatrixND<3,6> getRotationGradient(int node) =0; - }; template -class AlignedIsometry : public Isometry +class AlignedIsometry : public Isometry { public: + AlignedIsometry(const Vector3D& vecxz) + : vz(vecxz), Xc{}, c{}, R{} + { + } + + void + setOffsets(std::array* offsets) { + this->offsets = offsets; + } + + + virtual int + initialize(std::array& nodes) final + { + for (int i=0; igetTrialRotation(); + + const Vector &XI = nodes[ 0]->getCrds(); + const Vector &XJ = nodes[nn-1]->getCrds(); + + for (int i=0; i<3; i++) + dX[i] = XJ[i] - XI[i]; + + L = dX.norm(); + Ln = L; + Vector3D e1 = dX/L; + + // + Vector3D e2 = vz.cross(e1); + + const double ynorm = e2.norm(); + + if (ynorm == 0.0) + return -1; + + e2 /= ynorm; + + Vector3D e3 = e1.cross(e2); + + e2 = e3.cross(e1); + + for (int i = 0; i < 3; i++) { + R[init](i,0) = e1[i]; + R[init](i,1) = e2[i]; + R[init](i,2) = e3[i]; + } + + Xc = nodes[ic]->getCrds(); + c[init] = R[init]^Xc; + + return this->update(nodes); + } + + virtual + int update(std::array& nodes) final { + Matrix3D RI = MatrixFromVersor(nodes[0]->getTrialRotation()); + Matrix3D RJ = MatrixFromVersor(nodes[nn-1]->getTrialRotation()); + + Vector3D dx = dX; + // + // Update position + // + { + const Vector& uI = nodes[ 0]->getTrialDisp(); + const Vector& uJ = nodes[nn-1]->getTrialDisp(); + for (int k = 0; k < 3; k++) + dx[k] += uJ(k) - uI(k); + + if (offsets != nullptr) [[unlikely]] { + dx.addVector(1.0, (*offsets)[ 0], 1.0); + dx.addVector(1.0, RI*((*offsets)[0]), -1.0); + dx.addVector(1.0, (*offsets)[nn-1], -1.0); + dx.addVector(1.0, RJ*((*offsets)[nn-1]), 1.0); + } + } + + return this->update(RI, RJ, dx, nodes); + } + + + int + update(const Matrix3D& RI, const Matrix3D& RJ, const Vector3D& dx, std::array& nodes) final + { + // Calculate the deformed length + Ln = dx.norm(); + + if (Ln == 0.0) [[unlikely]] { + opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; + return -2; + } + + // + // + // + R[pres] = this->update_basis(RI, RJ, dx); + + // + // + // + Vector3D uc = nodes[ic]->getTrialDisp(); + if (offsets != nullptr) { + uc.addVector(1.0, (*offsets)[ic], -1.0); + uc.addVector(1.0, nodes[ic]->getTrialRotation().rotate((*offsets)[ic]), 1.0); + } + + c[pres] = R[pres]^(Xc + uc); + return 0; + } + + + // int + // update(std::array& nodes) final + // { + // Matrix3D RI = MatrixFromVersor(nodes[0]->getTrialRotation()); + // Matrix3D RJ = MatrixFromVersor(nodes[nn-1]->getTrialRotation()); + + // Vector3D dx = dX; + // // + // // Update position + // // + // { + // const Vector& uI = nodes[ 0]->getTrialDisp(); + // const Vector& uJ = nodes[nn-1]->getTrialDisp(); + // for (int k = 0; k < 3; k++) + // dx[k] += uJ(k) - uI(k); + + // if (offsets != nullptr) [[unlikely]] { + // dx.addVector(1.0, (*offsets)[ 0], 1.0); + // dx.addVector(1.0, RI*((*offsets)[0]), -1.0); + // dx.addVector(1.0, (*offsets)[nn-1], -1.0); + // dx.addVector(1.0, RJ*((*offsets)[nn-1]), 1.0); + // } + // } + + // // Calculate the deformed length + // Ln = dx.norm(); + + // if (Ln == 0.0) [[unlikely]] { + // opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; + // return -2; + // } + + // // + // // + // // + // R[pres] = this->update_basis(RI, RJ, dx); + + // // + // // + // // + // Vector3D uc = nodes[ic]->getTrialDisp(); + // if (offsets != nullptr) { + // uc.addVector(1.0, (*offsets)[ic], -1.0); + // uc.addVector(1.0, nodes[ic]->getTrialRotation().rotate((*offsets)[ic]), 1.0); + // } + // c[pres] = R[pres]^(Xc + uc); + // return 0; + // } + virtual Vector3D getRotationVariation(int ndf, double* du) { + // psi_r = omega Vector3D w{}; for (int i=0; igetRotationGradient(i); @@ -66,6 +232,58 @@ class AlignedIsometry : public Isometry } return w; } + + double + getLength() const override { + return Ln; + } + + Matrix3D + getRotation() const final { + return R[pres]; + } + + Matrix3D + getInitialRotation() const { + return R[init]; + } + + virtual Matrix3D + getRotationDelta() { + return R[pres] - R[init]; + } + + Vector3D + getLocation() { + return c[pres]; + } + + virtual Vector3D + getPosition() { + // Return Delta c + Vector3D Dc = c[pres] - (R[init]^Xc) ; // (R[pres]^c[init]); + return Dc; + } + + virtual Vector3D + getPositionVariation(int ndf, double* du) { + return Vector3D {du[ndf*ic+0], du[ndf*ic+1], du[ndf*ic+2]}; + } + + virtual + Matrix3D + update_basis(const Matrix3D& RI, const Matrix3D& RJ, const Vector3D& dx) = 0; + +protected: + constexpr static int ic = 0; // std::floor(0.5*(nn+1)); + enum { pres, prev, init}; + double L, Ln; + Vector3D vz, dX, Xc; + Matrix3D R[3]; + Vector3D c[3]; + Matrix3D dR; + // std::array& nodes; + std::array* offsets = nullptr; // offsets }; } // namespace OpenSees diff --git a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h new file mode 100644 index 0000000000..507f75105e --- /dev/null +++ b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h @@ -0,0 +1,171 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. (2024) +// "On Nonlinear Geometric Transformations of Finite Elements" +// Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +// +// Written: Claudio M. Perez, +// Filip C. Filippou +// University of California, Berkeley +// +// Developed with FEDEASLab [2]. +// +// References: +// +// [2] Filippou, F.C. (1998) +// "FEDEASLab: Finite Elements for Design Evaluation and Analysis of Structures" +// +// [3] Nour-Omid, B. and Rankin, C.C. (1991) "Finite rotation analysis and +// consistent linearization using projectors", +// Computer Methods in Applied Mechanics and Engineering, 93(3), pp. 353–384. +// Available at: https://doi.org/10.1016/0045-7825(91)90248-5. +// +#pragma once +#include +#include +#include +#include +#include "EuclidIsometry.h" + +class Node; +#define TRIAD C2 + +namespace OpenSees { + +template +class RankinIsometry : public AlignedIsometry +{ +public: + RankinIsometry(const Vector3D& vecxz) + : AlignedIsometry(vecxz), + n(0) + { + } + + using AlignedIsometry::init; + using AlignedIsometry::pres; + + Matrix3D + update_basis(const Matrix3D& RI, const Matrix3D& RJ, const Vector3D& dx) final + { + Matrix3D R; + { + Vector3D e1 = dx; + e1 /= e1.norm(); + + constexpr static Vector3D D2 {0,1,0}; + const Vector3D E2 = this->AlignedIsometry::R[init]*D2; + q = RI*E2; + Vector3D e3 = e1.cross(q); + e3 /= e3.norm(); + + Vector3D e2 = e3.cross(e1); + + for (int i = 0; i < 3; i++) { + R(i,0) = e1[i]; + R(i,1) = e2[i]; + R(i,2) = e3[i]; + } + + Vector3D Q = R^q; + n = Q[0]/Q[1]; + } + return R; + } + + virtual + MatrixND<12,12> + getRotationJacobian(const VectorND<12>&pwx) final + { + MatrixND<3,12> NWL{}; + double Ln = this->getLength(); + + constexpr static Vector3D e1 {1,0,0}; + constexpr static Matrix3D ex = Hat(e1); + + for (int i=0; i Gamma{}; + Gamma.template insert<0,0>(ex, 1.0); + Gamma(3,0) = -1.0; + Gamma.template insert<6,0>(ex, -1.0); + + MatrixND<12,3> Psi{}; + Psi.template insert<3,0>(Eye3, 1.0); + Psi.template insert<6,0>(ex, Ln); + Psi.template insert<9,0>(Eye3, 1.0); + + Matrix3D B = Gamma^Psi; + B.invert(); + return Gamma*B.transpose()*NWL; + } + + MatrixND<3,6> + getBasisVariation(int ie, int node) + { + MatrixND<3,6> dei{}; + if (ie == 1) { + Matrix3D A{}; + A(1,1) = A(2,2) = 1.0/this->getLength(); + if (node == 0) { + dei.template insert<0,0>(A, -1.0); + } + else if (node == nn-1) { + dei.template insert<0,0>(A, 1.0); + } + } + + else if (ie == 3) { + Matrix3D A{}; + Vector3D q = this->getRotation()^this->q; + Vector3D v = q.cross(Vector3D{1,0,0}); + + A(0,0) = A(1,1) = 1.0/v.norm(); + Matrix3D Q = Hat(q); + dei = A*( + Hat(Vector3D{1,0,0})*Q + +Q*this->getBasisVariation(1, node) + ); + } + return dei; + } + + MatrixND<3,6> + getRotationGradient(int node) final { + MatrixND<3,6> Gb{}; + + constexpr Vector3D axis{1, 0, 0}; + constexpr Matrix3D ix = Hat(axis); + + double Ln = this->getLength(); + + if (node == 0) { + Gb.template insert<0,0>( ix, -1.0/Ln); + Gb(0,2) = n/Ln; + Gb(0,3) = 1.0; + Gb(0,4) = -n; + } + else if (node == nn-1) { + Gb.template insert<0,0>( ix, 1.0/Ln); + Gb(0,2) = -n/Ln; + Gb(0,3) = 0.0; + } + return Gb; + } + +private: + Vector3D q; + double n = 0; +}; +} // namespace OpenSees \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.tpp b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.tpp new file mode 100644 index 0000000000..1017532ab9 --- /dev/null +++ b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.tpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// FEDEASLab +// Finite Elements for Design Evaluation and Analysis of Structures +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// diff --git a/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h b/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h new file mode 100644 index 0000000000..93b5fa2c16 --- /dev/null +++ b/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h @@ -0,0 +1,132 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. (2024) +// "On Nonlinear Geometric Transformations of Finite Elements" +// Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +// +// Written: Claudio M. Perez, +// Filip C. Filippou +// University of California, Berkeley +// +// Developed with FEDEASLab [2]. +// +// References: +// +// [2] Filippou, F.C. (1998) +// "FEDEASLab: Finite Elements for Design Evaluation and Analysis of Structures" +// +#pragma once +#include +#include +#include +#include +#include "EuclidIsometry.h" + +template +class SphericalIsometry : public Isometry { +public: + SphericalIsometry(std::array& nodes, const Vector3D& vecxz); + + int initialize() final; + int update() final; + + double getLength() const final; + Matrix3D getRotation() const final; + Vector3D getPosition() final; + Vector3D getPositionVariation(int ndf, double* du) final; + Vector3D getRotationVariation(int ndf, double* du) final; + Matrix3D getRotationDelta() final; + MatrixND<3,6> getRotationGradient(int node) final; +private: + double L; + double Ln; + std::array nodes; + Vector3D vz; // vector in the x-z plane + Vector3D dX; // deformed length vector + Vector3D c[2]; // current position of the center + Matrix3D R[2]; // rotation matrices at the current and previous time step + Vector3D Xc; // center of the isometry +}; + + +template +SphericalIsometry::SphericalIsometry(std::array& nodes, const Vector3D& vecxz) +: nodes(nodes), vz(vecxz), Xc{}, + c{}, R{}, dX{}, Ln(0.0), L(0.0), + offsets(nullptr), offset_flags(0), ic(0) +{ + +} + + +template +int +SphericalIsometry::update() { + + Vector3D e1 = dX; + { + // + // Update state + // + const Vector& uI = nodes[ 0]->getTrialDisp(); + const Vector& uJ = nodes[nn-1]->getTrialDisp(); + for (int k = 0; k < 3; k++) + e1[k] += uJ(k) - uI(k); + + if (offsets != nullptr) [[unlikely]] { + e1.addVector(1.0, (*offsets)[ 0], 1.0); + e1.addVector(1.0, nodes[0]->getTrialRotation().rotate((*offsets)[0]), -1.0); + e1.addVector(1.0, (*offsets)[nn-1], -1.0); + e1.addVector(1.0, nodes[nn-1]->getTrialRotation().rotate((*offsets)[nn-1]), 1.0); + } + + // Calculate the deformed length + Ln = e1.norm(); + + if (Ln == 0.0) [[unlikely]] { + opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; + return -2; + } + + e1 /= Ln; + } + + { +#if 1 // TRIAD==R2 + constexpr static Vector3D D2 {0,1,0}; + const Vector3D E2 = R[init]*D2; + Vector3D e2 = MatrixFromVersor(nodes[0]->getTrialRotation())*E2; //*R[init]; + e2.addVector(0.5, MatrixFromVersor(nodes[1]->getTrialRotation())*E2, 0.5); + n = e2[0]/e2[1]; + Vector3D e3 = e1.cross(e2); + e3 /= e3.norm(); + + e2 = e3.cross(e1); + + for (int i = 0; i < 3; i++) { + R[pres](i,0) = e1[i]; + R[pres](i,1) = e2[i]; + R[pres](i,2) = e3[i]; + } + Vector3D e2 = vz.cross(e1); +#endif + } + + Vector3D uc = nodes[ic]->getTrialDisp(); + if (offsets != nullptr) { + uc.addVector(1.0, (*offsets)[ic], -1.0); + uc.addVector(1.0, nodes[ic]->getTrialRotation().rotate((*offsets)[ic]), 1.0); + } + Vector3D X = nodes[ic]->getCrds(); + c[pres] = R[pres]^(X + uc); + return 0; +} \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.h b/SRC/coordTransformation/Frame/LinearFrameTransf.h index a8705b2b3b..1988fea727 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.h +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.h @@ -2,10 +2,6 @@ // // xara // https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures // //----------------------------------------------------------------------------// // @@ -18,10 +14,10 @@ //===----------------------------------------------------------------------===// // -// Description: LinearFrameTransf implements a linear axis-aligning transformation -// for a spatial frame element. +// Description: LinearFrameTransf implements a linearized euclidean transformation +// for a spatial frame // -// Claudio Perez +// Written: Claudio Perez // #ifndef LinearFrameTransf_hpp #define LinearFrameTransf_hpp @@ -68,8 +64,11 @@ class LinearFrameTransf: public FrameTransform VectorND pushResponse(VectorND&pl) final; MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + + // // method used to rotate consistent mass matrix + // const Matrix &getGlobalMatrixFromLocal(const Matrix &local); - // + // Sensitivity // const Vector & getBasicDisplFixedGrad(); diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index 309ea3f1cd..bd68dd4540 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -17,12 +17,22 @@ // //===----------------------------------------------------------------------===// +// +// Description: This file contains the implementation for the +// LinearFrameTransf class. LinearFrameTransf is a linear +// transformation for a space frame between the global +// and basic coordinate systems +// +// Adapted: Remo Magalhaes de Souza +// Created: 04/2000 +// #pragma once #include #include #include #include -#include +#include +#include #include "LinearFrameTransf.h" namespace OpenSees { @@ -38,6 +48,8 @@ FrameOrientationGradient(const Vector3D& xi, const Vector3D& xj, Vector3D v2 = vz.cross(e1); Vector3D e2 = v2 / v2.norm(); +// Vector3D v3 = e1.cross(e2); +// Vector3D e3 = v3 / v3.norm(); // Vector3D dvz{0.0}; @@ -261,7 +273,6 @@ LinearFrameTransf::pullConstant(const VectorND& ug, constexpr static int N = nn * ndf; - // Initialize ul = ug VectorND ul = ug; // (1) @@ -392,7 +403,7 @@ LinearFrameTransf::pushResponse(VectorND&p) // 1.2) Adjust force part for (int i=0; i::pushResponse(MatrixND&kb, const Vector MatrixND A{}; A.addDiagonal(1.0); constexpr Vector3D axis{1, 0, 0}; - constexpr Matrix3D ix = Hat(axis); - constexpr Matrix3D ioi = axis.bun(axis); + constexpr Matrix3D ix = Hat(Vector3D{1, 0, 0}); + constexpr Matrix3D ioi = axis.bun(Vector3D{1, 0, 0}); MatrixND<3,ndf> Gb{}; Gb.template insert<0, 3>(ioi, 0.5); @@ -465,6 +476,7 @@ LinearFrameTransf::isShapeSensitivity() int nodeParameterI = nodes[ 0]->getCrdsSensitivity(); int nodeParameterJ = nodes[nn-1]->getCrdsSensitivity(); // TODO(sensitivity): implement dvz + return (nodeParameterI != 0 || nodeParameterJ != 0); } @@ -552,8 +564,56 @@ LinearFrameTransf::getBasicDisplFixedGrad() static VectorND<6> dub; static Vector wrapper(dub); // + // Form ug + // // TODO(sensitivity) +#if 0 + VectorND ug; + for (int i = 0; i < nn; i++) { + const Vector& u = nodes[i]->getTrialDisp(); + for (int j = 0; j < ndf; j++) { + ug[i*ndf+j] = u(j); + } + } + + if (u_init[0] != 0) { + for (int j = 0; j < ndf; j++) + ug[j] -= (*u_init[0])[j]; + } + + if (u_init[nn-1] != 0) { + for (int j = 0; j < ndf; j++) + ug[j + 6] -= (*u_init[nn-1])[j]; + } + + // + // dub += (T_{bl}' T_{lg} + T_{bl} T_{lg}') * ug // + int dv = 0; // TODO(sensitivity) + + // TODO: Sensitivity + int di = nodes[0]->getCrdsSensitivity(); + int dj = nodes[1]->getCrdsSensitivity(); + + + // TODO(sensitivity) + // Matrix3D dR = FrameOrientationGradient(xi, xj, vz, di, dj, dv); + // dub = getBasic(ug, 1/L); + + // + // + VectorND ul = LinearFrameTransf::pullConstant(ug, R, offsets); + // + dub[0] += 0; + double dL = this->getLengthGrad(); + double doneOverL = -dL/(L*L); + double tmp = doneOverL * (ul[1] - ul[7]); + dub[1] += tmp; + dub[2] += tmp; + tmp = doneOverL * (ul[8] - ul[2]); + dub[3] += tmp; + dub[4] += tmp; +#endif return wrapper; } @@ -562,8 +622,21 @@ const Vector & LinearFrameTransf::getBasicDisplTotalGrad(int gradNumber) { + double dug[12]; + for (int i = 0; i < 6; i++) { + dug[i] = nodes[0]->getDispSensitivity((i + 1), gradNumber); + dug[i + 6] = nodes[1]->getDispSensitivity((i + 1), gradNumber); + } + static VectorND<6> dub; static Vector wrapper(dub); + + // dub = T_{bl} T_{lg} * ug' + // TODO + // dub = getBasic(dug, R, offsets[0], offsets[nn-1], 1/L); + + wrapper += getBasicDisplFixedGrad(); + return wrapper; } diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h index 9b92fc79f8..a774caf258 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h @@ -20,11 +20,13 @@ #include #include -#include -#include +#include "LinearFrameTransf.h" #include #include +class Vector; +class Matrix; + namespace OpenSees { template diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.h b/SRC/coordTransformation/Frame/SouzaFrameTransf.h new file mode 100644 index 0000000000..018c8859cb --- /dev/null +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.h @@ -0,0 +1,162 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +// +// Description: SouzaFrameTransf implements the formulation +// of Crisfield (1990) with the objective of maintaining the +// original "Corotational" implementation by Remo Magalhaes de Souza, within +// the new framework proposed by Perez and Filippou (2024). +// +// Written: cmp +// Created: March 2024 +// +// Adapted from work by: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) +// +// [2] Crisfield, M.A. (1990) "A consistent co-rotational formulation for +// non-linear, three-dimensional, beam-elements", Computer Methods in Applied +// Mechanics and Engineering, 81(2), pp. 131–150. Available at: +// https://doi.org/10.1016/0045-7825(90)90106-V. +// +#ifndef SouzaFrameTransf_hpp +#define SouzaFrameTransf_hpp + +#include +#include "FrameTransform.h" +#include +#include +#include +#include +#include +#include "Isometry/CrisfieldIsometry.h" + +struct Triad; + +namespace OpenSees { + +template +class SouzaFrameTransf: public FrameTransform +{ +public: + SouzaFrameTransf(int tag, + const Vector3D &vecxz, + const std::array *offset=nullptr, + int offset_flags = 0); + + ~SouzaFrameTransf(); + + const char *getClassType() const { + return "SouzaFrameTransf"; + } + + // NOTE: maybe add arg for rotation parameterization + FrameTransform *getCopy() const final; + + int initialize(std::array& new_nodes) final; + int update() final; + int commit() final; + int revertToLastCommit() final; + int revertToStart() final; + int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const final; + const std::array *getRigidOffsets() const final { return offsets; } + + double getInitialLength() final; + double getDeformedLength() final; + + VectorND getStateVariation() final; + Vector3D getNodePosition(int tag) final; + Vector3D getNodeRotationLogarithm(int tag) final; + + VectorND pushResponse(VectorND&pl) final; + MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + + // Sensitivity + double getLengthGrad() final; + const Vector &getBasicDisplTotalGrad(int grad); // final; + const Vector &getBasicDisplFixedGrad(); + const Vector &getGlobalResistingForceShapeSensitivity(const Vector &pb, const Vector &p0, int gradNumber); + + // Tagged Object + void Print(OPS_Stream &s, int flag = 0) final; + +protected: + + VectorND<6> pushResponse(const VectorND<6>& pa, int a, int b); + +private: + constexpr static int n = nn*ndf; + + // compute the transformation matrix + // void compute_tangent(const Matrix3D&, const Versor*); + int addTangent(MatrixND<12,12>& M, const VectorND<12>& pl, const VectorND<12>&ul); + + enum { + inx= 0, // axial + iny= 1, // Vy + inz= 2, // Vz + imx= 3, // torsion + imy= 4, // rot y I + imz= 5, // rot z I + + jnx= 6, // axial + jny= 7, + jnz= 8, + jmx= 9, // torsion + jmy=10, // rot y J + jmz=11, // rot z J + }; + + // + // Member data + // + std::array nodes; + + Vector3D xAxis; // local x axis + Vector3D vz; // Vector that lies in local plane xz + Vector3D dX; + + std::array *offsets; + + double *nodeIInitialDisp, *nodeJInitialDisp; + bool initialDispChecked; + + double L; // initial element length + double Ln; // current element length (at trial state) + + Versor Q_past[nn]; // commited rotations + Versor Q_pres[nn]; // trial rotations + + Vector3D alphaI; // last trial rotations end i + Vector3D alphaJ; // last trial rotatations end j + + VectorND ul; // local displacements + Vector3D vr[nn]; // + VectorND ulcommit; // commited local displacements + VectorND ulpr; // previous local displacements + + OpenSees::MatrixND T; // transformation from local to global system + + OpenSees::Matrix3D R0; // rotation from local to global coordinates + CrisfieldIsometry<2> crs; + +}; + +} // namespace OpenSees + +#include "SouzaFrameTransf.tpp" +#endif diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp new file mode 100644 index 0000000000..d5007c2779 --- /dev/null +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp @@ -0,0 +1,551 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +// +// Description: SouzaFrameTransf implements a Corotational +// transformation for a spatial frame element following the formulation +// by Crisfield (1990). +// +// Written: Claudio Perez +// Created: 05/2024 +// +// Adapted from: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) +// +// [2] Crisfield, M.A. (1990) "A consistent co-rotational formulation for +// non-linear, three-dimensional, beam-elements", Computer Methods in Applied +// Mechanics and Engineering, 81(2), pp. 131–150. Available at: +// https://doi.org/10.1016/0045-7825(90)90106-V. +// +#include +#include +#include +#include "SouzaFrameTransf.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Isometry/CrisfieldIsometry.h" + +namespace OpenSees { + +template +SouzaFrameTransf::SouzaFrameTransf(int tag, const Vector3D &vz, + const std::array *offset, + int offset_flags) + : FrameTransform(tag), + vz(vz), + offsets{nullptr}, + L(0), Ln(0), + nodeIInitialDisp(0), nodeJInitialDisp(0), + initialDispChecked(false), + crs{vz} +{ + alphaI.zero(); + alphaJ.zero(); + + // Rigid joint offsets + if (offset != nullptr) { + offsets = new std::array{}; + *offsets = *offset; + } +} + + +template +SouzaFrameTransf::~SouzaFrameTransf() +{ + if (offsets != nullptr) + delete offsets; +} + + +template +double +SouzaFrameTransf::getInitialLength() +{ + return L; +} + + +template +double +SouzaFrameTransf::getDeformedLength() +{ + return Ln; +} + + +template +FrameTransform * +SouzaFrameTransf::getCopy() const +{ + + SouzaFrameTransf *theCopy = + new SouzaFrameTransf(this->getTag(), vz, offsets); + + theCopy->nodes[0] = nodes[0]; + theCopy->nodes[1] = nodes[1]; + theCopy->xAxis = xAxis; + theCopy->L = L; + theCopy->Ln = Ln; + theCopy->R0 = R0; + theCopy->Q_pres[0] = Q_pres[0]; + theCopy->Q_pres[1] = Q_pres[1]; + theCopy->Q_past[0] = Q_past[0]; + theCopy->Q_past[1] = Q_past[1]; + theCopy->ul = ul; + theCopy->ulcommit = ulcommit; + return theCopy; +} + + +template +int +SouzaFrameTransf::revertToStart() +{ + ul.zero(); + Q_pres[0] = VersorFromMatrix(R0); + for (int i=1; iupdate(); + return 0; +} + + +template +int +SouzaFrameTransf::commit() +{ + ulcommit = ul; + Q_past[0] = Q_pres[0]; + Q_past[1] = Q_pres[1]; + return 0; +} + + +template +int +SouzaFrameTransf::revertToLastCommit() +{ + // determine global displacement increments from last iteration + const Vector &dispI = nodes[0]->getTrialDisp(); + const Vector &dispJ = nodes[1]->getTrialDisp(); + + for (int k = 0; k < 3; k++) { + alphaI(k) = dispI(k+3); + alphaJ(k) = dispJ(k+3); + } + + ul = ulcommit; + Q_pres[0] = Q_past[0]; + Q_pres[1] = Q_past[1]; + + this->update(); + + return 0; +} + + +template +int +SouzaFrameTransf::initialize(std::array& new_nodes) +{ + for (int i=0; igetCrds(); + dX -= nodes[ 0]->getCrds(); + + // Add initial displacements at nodes + if (initialDispChecked == false) { + const Vector &nodeIDisp = nodes[0]->getDisp(); + const Vector &nodeJDisp = nodes[1]->getDisp(); + for (int i = 0; i<6; i++) + if (nodeIDisp[i] != 0.0) { + nodeIInitialDisp = new double [6]; + for (int j = 0; j<6; j++) + nodeIInitialDisp[j] = nodeIDisp[j]; + i = 6; + } + + for (int j = 0; j<6; j++) + if (nodeJDisp[j] != 0.0) { + nodeJInitialDisp = new double [6]; + for (int i = 0; i<6; i++) + nodeJInitialDisp[i] = nodeJDisp[i]; + j = 6; + } + initialDispChecked = true; + } + + // + // Length and Orientation + // + Vector3D dx; + + dx = nodes[nn-1]->getCrds() - nodes[0]->getCrds(); + + L = dx.norm(); + + if (L == 0.0) { + opserr << "\nSouzaFrameTransf::computeElemtLengthAndOrien: 0 length\n"; + return -2; + } + + // + // Set rotation matrix + // + int error = FrameTransform::Orient(dx, vz, R0); + if (error) + return error; + + // Compute initial pseudo-vectors for nodal triads + Q_pres[0] = Q_pres[1] = VersorFromMatrix(R0); + + ul.zero(); + ulpr.zero(); + + for (int i=0; icommit(); + + return 0; +} + +template +VectorND +SouzaFrameTransf::getStateVariation() +{ + return ul - ulpr; +} + + +template +Vector3D +SouzaFrameTransf::getNodePosition(int tag) +{ + Vector3D u; + for (int i=0; i<3; i++) + u[i] = ul[tag*ndf+i]; + return u; +} + + +template +Vector3D +SouzaFrameTransf::getNodeRotationLogarithm(int tag) +{ + return vr[tag]; +} + + +// +// Set RI,RJ,Rbar, Ln, e and ul +// +template +int +SouzaFrameTransf::update() +{ + // determine global displacement increments from last iteration + + const Vector& dispI = nodes[ 0]->getTrialDisp(); + const Vector& dispJ = nodes[nn-1]->getTrialDisp(); + + // + // Update state + // + + // 1.1 Relative translation + Vector3D dx = dX;// dx = dX + dJI; + { + // Relative translation + for (int k = 0; k < 3; k++) + dx[k] += dispJ(k) - dispI(k); + + + // Calculate the deformed length + Ln = dx.norm(); + + if (Ln == 0.0) { + opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; + return -2; + } + } + + // 1.2 Rotational displacement increments + { + Vector3D dAlphaI, dAlphaJ; + + for (int k = 0; k < 3; k++) { + dAlphaI[k] = dispI(k+3) - alphaI[k]; + alphaI[k] = dispI(k+3); + dAlphaJ[k] = dispJ(k+3) - alphaJ[k]; + alphaJ[k] = dispJ(k+3); + } + + // Update the nodal rotations + Q_pres[0] = VersorProduct(Q_pres[0], Versor::from_vector(dAlphaI)); + Q_pres[1] = VersorProduct(Q_pres[1], Versor::from_vector(dAlphaJ)); + // Q_pres[0] = VersorFromMatrix(MatrixFromVersor(Q_pres[0]) * + // MatrixFromVersor(Versor::from_vector(dAlphaI))); + // Q_pres[1] = VersorFromMatrix(MatrixFromVersor(Q_pres[1]) * + // MatrixFromVersor(Versor::from_vector(dAlphaJ))); + } + + // + // 2) Form transformation + // + + crs.update(MatrixFromVersor(Q_pres[0]), + MatrixFromVersor(Q_pres[1]), + dx, nodes); + + // + // 3) Local deformations + // + + // Save previous state + ulpr = ul; + + // Rotations + { + Matrix3D e = crs.getRotation(); + vr[0] = LogC90(e^MatrixFromVersor(Q_pres[0])); + for (int i=0; i<3; i++) + ul[imx+i] = vr[0][i]; + + vr[1] = LogC90(e^MatrixFromVersor(Q_pres[1])); + for (int i=0; i<3; i++) + ul[jmx+i] = vr[1][i]; + } + + // Axial + ul(inx) = 0; + // ul(jnx) = Ln - L; + ul(jnx) = (dX + (dx-dX)*0.5).dot(dx-dX)*2.0/(Ln+L); + + // Form the transformation tangent + T = crs.compute_tangent(ul); + return 0; +} + + +template +inline VectorND +SouzaFrameTransf::pushResponse(VectorND&pl) +{ + // return T^pl; + VectorND pg{}; + for (int a = 0; a pa {pl(a*ndf+0), pl(a*ndf+1), pl(a*ndf+2), + pl(a*ndf+3), pl(a*ndf+4), pl(a*ndf+5)}; + + for (int b = 0; b<2; b++) { + VectorND<6> pab = pushResponse(pa, a, b); + pg.assemble(b*6, pab, 1.0); + } + } + return pg; +} + +template +VectorND<6> +SouzaFrameTransf::pushResponse(const VectorND<6>&pa, int a, int b) +{ + VectorND<6> pg{}; + for (int i = 0; i < 6; i++) + for (int j = 0; j < 6; j++) + pg[j] += T(a*6 + i, b*6+j) * pa[i]; + + return pg; +} + +// do +// K = ag'*Km*ag + Kp +// +template +MatrixND +SouzaFrameTransf::pushResponse(MatrixND& kl, const VectorND& pl) +{ + MatrixND<12,12> K; + K.addMatrixTripleProduct(0.0, T, kl, 1.0); + + // Add geometric part kg + this->addTangent(K, pl, ul); + + return K; +} + + +// +// Add geometric part of the transformation tangent +// +// kg += T'*kl*T + ks1 + T * diag(m.*tan(thetal))*T' + ... +// m(4)*(ks2r2t3_u3 + ks2r3u2_t2) + ... +// m(2)*ks2r2t1 + m(3)*ks2r3t1 + ... +// m(5)*ks2r2u1 + m(6)*ks2r3u1 + ... +// ks3 + ks3' + ks4 + ks5; +template +int +SouzaFrameTransf::addTangent(MatrixND<12,12>& kg, + const VectorND<12>& pl, + const VectorND<12>& ul) +{ + + crs.addTangent(kg, pl, ul); + + // + // T' * diag (M .* tan(thetal))*T + // + + for (int node=0; node<2; node++) { + for (int k = 0; k < 3; k++) { + const double factor = pl[(node ? jmx : imx) + k] // pl[6*node+3+k] + * std::tan(ul[(node ? jmx : imx) + k]); + + + for (int i = 0; i < 12; i++) { + const double Tki = T((node ? jmx : imx) + k,i); + for (int j = 0; j < 12; j++) + kg(i,j) += Tki * factor * T((node ? jmx : imx) + k, j); + } + } + } + + return 0; +} + + +template +int +SouzaFrameTransf::getLocalAxes(Vector3D &e1, Vector3D &e2, Vector3D &e3) const +{ + for (int i = 0; i < 3; i++) { + e1[i] = R0(i,0); + e2[i] = R0(i,1); + e3[i] = R0(i,2); + } + return 0; +} + + +template +double +SouzaFrameTransf::getLengthGrad() +{ + const int di = nodes[0]->getCrdsSensitivity(); + const int dj = nodes[1]->getCrdsSensitivity(); + + Vector3D dxi{0.0}; + Vector3D dxj{0.0}; + + if (di != 0) + dxi(di-1) = 1.0; + if (dj != 0) + dxj(dj-1) = 1.0; + + return 1.0/L * dX.dot(dxj - dxi); +} + +template +const Vector & +SouzaFrameTransf::getBasicDisplTotalGrad(int gradNumber) +{ + opserr << "WARNING CrdTransf::getBasicDisplTotalGrad() - this method " + << " should not be called.\n"; + + static Vector dummy(1); + return dummy; +} + +template +const Vector & +SouzaFrameTransf::getBasicDisplFixedGrad() +{ + opserr << "ERROR CrdTransf::getBasicDisplFixedGrad() - has not been" + << " implemented yet for the chosen transformation\n."; + + static Vector dummy(1); + return dummy; +} + + +template +const Vector & +SouzaFrameTransf::getGlobalResistingForceShapeSensitivity(const Vector &pb, + const Vector &p0, + int gradNumber) +{ + opserr << "ERROR CrdTransf::getGlobalResistingForceSensitivity() - has not been" + << " implemented yet for the chosen transformation." << endln; + + static Vector dummy(1); + return dummy; +} + +template +void +SouzaFrameTransf::Print(OPS_Stream &s, int flag) +{ + + if (flag == OPS_PRINT_CURRENTSTATE) { + s << "\nFrameTransform: " << this->getTag() << " Type: SouzaFrameTransf"; + s << "\tvxz: " << Vector(vz); + } + + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << OPS_PRINT_JSON_MATE_INDENT << "{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"SouzaFrameTransf\"" << ", "; + s << "\"vecxz\": [" << vz(0) << ", " << vz(1) << ", " << vz(2) << "]"; + + if (offsets != nullptr) { + s << ", \"offsets\": ["; + for (int i=0; i using OpenSees::Matrix3D; -#define cot(x) std::cos(x)/std::sin(x) - static constexpr Matrix3D Eye3 {{ {1, 0, 0}, {0, 1, 0}, @@ -61,7 +78,7 @@ Hat(const Vec3Type &u) { u[1], -u[0], 0 }}}; } -static inline void +static inline double GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) { // @@ -108,11 +125,13 @@ GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) a[3] = 1.0/6.0 - angle2/(1.0/120.0 - angle2/(1.0/5040.0 - angle2/362880.0)); } if (b != nullptr) { + b[0] = - a[1]; b[1] = - 1.0/3.0 + angle2*(1.0/30.0 - angle2*(1.0/840.0 - angle2/45360.0)); b[2] = - 1.0/12.0 + angle2*(1.0/180.0 - angle2*(1.0/6720.0 - angle2/453600.0)); b[3] = - 1.0/60.0 + angle2*(1.0/1260.0 - angle2*(1.0/60480 - angle2/4989600.0)); } if (c != nullptr) { + c[0] = - b[1]; c[1] = b[3] - b[2]; c[2] = 1.0/90.0 - angle2*(1.0/1680.0 - angle2*(1.0/75600.0 - angle2/5987520.0)); c[3] = 1.0/630.0 - angle2*(1.0/15120.0 - angle2*(1.0/831600.0 - angle2/77837760.0)); @@ -124,13 +143,11 @@ GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) // double angle = vec.norm(); -// double angle = sqrt(angle2); double sn = std::sin(angle); double cs = std::cos(angle); double angle3 = angle*angle2; double angle4 = angle*angle3; double angle5 = angle*angle4; -// double angle6 = angle*angle5; if (a != nullptr) { a[0] = cs; @@ -141,16 +158,20 @@ GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) } if (b != nullptr) { + b[0] = -a[1]; b[1] = ( angle*cs - sn)/angle3; - b[2] = ( angle*sn - 2 + 2*cs)/angle4; - b[3] = ( 3*sn - 2*angle - angle*cs )/angle5; + b[2] = ( angle*sn - 2.0 + 2.0*cs)/angle4; + b[3] = ( 3.0*sn - 2.0*angle - angle*cs )/angle5; } + if (c != nullptr) { + c[0] = -b[1]; c[1] = (3.*sn - angle2*sn - 3.*angle*cs)/(angle5); c[2] = (8. - 8.*cs - 5.*angle*sn + angle2*cs)/(angle5*angle); c[3] = (8.*angle + 7.*angle*cs + angle2*sn - 15.*sn)/(angle5*angle2); } } + return std::sqrt(angle2); } // @@ -308,11 +329,12 @@ ExpSO3(const Vector3D &theta) { // Form the first Gib coefficients double a[4]; - GibSO3(theta, a); Matrix3D R = Eye3; - R.addSpin(theta, a[1]); - R.addSpinSquare(theta, a[2]); + if (GibSO3(theta, a) > 1e-12) { + R.addSpin(theta, a[1]); + R.addSpinSquare(theta, a[2]); + } return R; } @@ -390,7 +412,7 @@ TanSO3(const Vector3D &vec, char repr='L') inline Matrix3D -dExpSO3(const Vector3D &v) +TExpSO3(const Vector3D &v) { // Compute the right differential of the exponential on SO(3) using the formula in // Equation (A11) in [1]: @@ -478,8 +500,31 @@ dTanSO3(const Vector3D &v, const Vector3D &p, char repr='L') .addDiagonal(a[3]*v.dot(p)) .addTensorProduct(v, p, a[3]) .addTensorProduct(p, v, b[1]) - .addTensorProduct(v.cross(p), v, b[1]*(repr == 'R' ? 1.0 : -1.0)) + .addTensorProduct(v.cross(p), v, b[2]*(repr == 'R' ? 1.0 : -1.0)) + .addTensorProduct(v, v, v.dot(p)*b[3]); + return Xi; +} + + +inline Matrix3D +dExpSO3(const Vector3D &v, const Vector3D &p) +{ + // + // ========================================================================================= + // function by Claudio Perez 2023 + // ----------------------------------------------------------------------------------------- + // + double a[4], b[4]; + GibSO3(v, a, b); + + Matrix3D Xi{}; + Xi.addSpin(p, -a[1]) + .addDiagonal(a[2]*v.dot(p)) + .addTensorProduct(v, p, a[2]) + .addTensorProduct(p, v, b[0]) + .addTensorProduct(v.cross(p), v, b[1]) .addTensorProduct(v, v, v.dot(p)*b[2]); + return Xi; } @@ -546,6 +591,7 @@ LogC90_Skew(const Matrix3D &R) // //===--------------------------------------------------------------------===// // Crisfield's approximation to the logarithm on SO(3) + return Vector3D { std::asin(0.5*(R(1,2) - R(2,1))), std::asin(0.5*(R(0,1) - R(1,0))), @@ -553,6 +599,87 @@ LogC90_Skew(const Matrix3D &R) }; } +namespace Utility { + +static inline double +dLogConst(double angle, double& a3, double& b3) +{ + // + // a3 == eta + // + static constexpr double tol = 1.0/20.0; + + double ahalf = angle/2.0; + double angle2 = angle*angle; + double angle3 = angle*angle2; + double angle4 = angle*angle3; + double angle5 = angle*angle4; + double angle6 = angle*angle5; + + double a1; + if (std::fabs(angle) > tol) [[unlikely]] { + // a0 = 1.0 + angle2/2.0; + a1 = ahalf/std::tan(ahalf); + + a3 = (1.0 - a1)/angle2; + // a3 = (2.0*sn - angle*(1.0+cs))/(2.0*angle2*sn); + // a3 = (1.0 - 0.5*angle*cot(0.5*angle))/angle2; + + // b3 = (angle*(angle + 2.0*hsn*hcs) - 8.0*hsn*hsn)/(4.0*angle4*hsn*hsn); // wrong? + // b3 = (angle*(angle + std::sin(angle)) - 8.0*hsn*hsn)/(4.0*angle4*hsn*hsn); + // b3 = std::fma(angle, angle + sn, 4.0*(cs - 1.0))/(2.0*angle4*(1.0 - cs)); + // b3 = std::fma(angle, angle + 2.0*hsn*hcs, -8.0*hsn*hsn)/(4.0*angle4*hsn*hsn); + b3 = std::fma(a1, a1 + 1.0, 0.25 * angle2 - 2.0)/angle4; + } + else { + // Maclaurin series + a1 = 1.0 - angle2/12.0 + angle4/720.0 - angle6/30240.0; + a3 = 1.0/12. + angle2/720. + angle4/30240. + angle6/1209600.; + b3 = 1.0/360. + angle2/7560. + angle4/201600. + angle6/5987520.; + } + return 0.0; +} + +static inline Vector3D +RescaleVector(const Vector3D &v, double &angle) +{ + static constexpr double pi = 3.14159265358979323846; + static constexpr double two_pi = 2.0 * pi; + static constexpr double eps = 1e-8; // pole-avoidance band + + Vector3D u = v; // copy; v is const + + return u; + + // Fast exit when |angle| already <= pi (no poles inside) + if (std::fabs(angle) <= pi) + return u; + + // Wrap once modulo 2pi + double wrapped = std::remainder(angle, two_pi); // (-pi, pi] + + // Nudge away from the sole pole at 0 + if (std::fabs(wrapped) < eps) + wrapped = (wrapped < 0.0 ? -eps : eps); + +// #define PRINCIPAL_WRAP +#ifndef PRINCIPAL_WRAP + // Keep original magnitude unless it was near a pole + if (std::fabs(angle) > pi && std::fabs(wrapped) >= eps) + wrapped = angle; +#endif + + // Rescale u + if (std::fabs(angle) > eps) { // safe denominator + double scale = wrapped / angle; + for (int i = 0; i < 3; ++i) + u[i] *= scale; + } + + angle = wrapped; + return u; +} +} inline Matrix3D dLogSO3(const Vector3D &v, double* a=nullptr) @@ -564,26 +691,12 @@ dLogSO3(const Vector3D &v, double* a=nullptr) // function by Claudio Perez 2023 // ----------------------------------------------------------------------------------------- // - constexpr double tol = 1./20.; double angle = v.norm(); - Vector3D u = v; - if (abs(angle) > M_PI/1.01) [[unlikely]] { - u -= 2.0*v/angle*double(floor(angle + M_PI))/2.0; - angle = u.norm(); - } - - double angle2 = angle*angle; - double angle3 = angle*angle2; - double angle4 = angle*angle3; - double angle5 = angle*angle4; - double angle6 = angle*angle5; + const Vector3D u = Utility::RescaleVector(v, angle); - double eta; - if (angle > tol) [[unlikely]] - eta = (1.0 - 0.5*angle*cot(0.5*angle))/angle2; - else - eta = 1./12. + angle2/720. + angle4/30240. + angle6/1209600.; + double eta, mu; + Utility::dLogConst(angle, eta, mu); Matrix3D dH = Eye3; dH.addSpin(u, -0.5); @@ -592,50 +705,53 @@ dLogSO3(const Vector3D &v, double* a=nullptr) } inline Matrix3D -ddLogSO3(const Vector3D& u, const Vector3D& v) +ddLogSO3(const Vector3D& u, const Vector3D& p) { -// ========================================================================================= -// function by Claudio Perez 2023 -// ----------------------------------------------------------------------------------------- - - constexpr double tol = 1./20.; + double angle = u.norm(); - - Vector3D th = u; - if (abs(angle) > M_PI/1.01) [[unlikely]] { - th -= 2.0*u/angle*double(floor(angle + M_PI))/2.0; - angle = th.norm(); - } - - double angle2 = angle*angle; - double angle3 = angle*angle2; - double angle4 = angle*angle3; - double angle5 = angle*angle4; - double angle6 = angle*angle5; + const Vector3D th = Utility::RescaleVector(u, angle); double eta, mu; - if (angle < tol) { - eta = 1./12. + angle2/720. + angle4/30240. + angle6/1209600.; - mu = 1./360. + angle2/7560. + angle4/201600. + angle6/5987520.; - } - else { - double an2 = angle/2.; - double sn = std::sin(an2); - double cs = std::cos(an2); - - eta = (sn - angle2*cs)/(angle2*sn); - mu = (angle*(angle + 2.*sn*cs) - 8.*sn*sn)/(4.*angle4*sn*sn); - } + Utility::dLogConst(angle, eta, mu); Matrix3D St2 = Hat(th); St2 = St2*St2; Matrix3D dH{}; // -0.5*Hat(v) + eta*(Eye3*th.dot(v) + th.bun(v) - 2.*v.bun(th)) + mu*St2*v.bun(th); - dH.addSpin(v, -0.5); - dH.addDiagonal( eta*th.dot(v)); - dH.addTensorProduct(th, v, eta); - dH.addTensorProduct(v, th, -2.0*eta); - dH.addMatrixProduct(St2, v.bun(th), mu);; - // dH += mu*St2*v.bun(th); + dH.addSpin(p, -0.5); + dH.addDiagonal( eta*th.dot(p)); + dH.addTensorProduct(th, p, eta); + dH.addTensorProduct(p, th, -2.0*eta); + dH.addMatrixProduct(St2, p.bun(th), mu); return dH*dLogSO3(th); } + +#if 0 + +class Align { +public: + Align(Vector3D& original, Vector3D& target) + : original(original), target(target) + { + } + + // Align a vector to another vector using the exponential map + static Vector3D + rot(const Vector3D &v, const Vector3D &target) + { + // e3 = r3 - (e1 + r1)*((r3^e1)*0.5); + // e2 = r2 - (e1 + r1)*((r2^e1)*0.5); + Vector3D axis = v.cross(target); + double angle = std::acos(v.dot(target)/(v.norm()*target.norm())); + + if (angle < 1e-10) return v; + + return ExpSO3(axis*angle)*v; + } + + private: + Vector3D original; + Vector3D target; +}; + +#endif From 93788eebbd0d10210dd92949fe9341fad68b550e Mon Sep 17 00:00:00 2001 From: alec0498 Date: Fri, 4 Jul 2025 12:11:16 +0200 Subject: [PATCH 141/261] bond_slip fixes --- .../uniaxial/ASDConcrete1DMaterial.cpp | 12 +- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 116 +++++++++++++++--- SRC/material/uniaxial/ASDSteel1DMaterial.h | 3 +- 3 files changed, 112 insertions(+), 19 deletions(-) diff --git a/SRC/material/uniaxial/ASDConcrete1DMaterial.cpp b/SRC/material/uniaxial/ASDConcrete1DMaterial.cpp index 393aa68c50..ee5d9e29d4 100644 --- a/SRC/material/uniaxial/ASDConcrete1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDConcrete1DMaterial.cpp @@ -1324,11 +1324,16 @@ int ASDConcrete1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_Obje int ASDConcrete1DMaterial::setParameter(const char** argv, int argc, Parameter& param) { - // 1000 - elasticity & mass + + // 1000 - elasticity & mass & length if (strcmp(argv[0], "E") == 0) { param.setValue(E); return param.addObject(1000, this); } + if (strcmp(argv[0], "lch_ref") == 0) { + param.setValue(lch_ref); + return param.addObject(1001, this); + } // 2000 - time if (strcmp(argv[0], "dTime") == 0) { @@ -1365,6 +1370,11 @@ int ASDConcrete1DMaterial::updateParameter(int parameterID, Information& info) case 1000: E = info.theDouble; return 0; + case 1001: + lch_ref = info.theDouble; + auto_regularize = true; + regularization_done = false; + return 0; // 2000 - time case 2000: diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index 64a052bd1d..bbc91aad9f 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -1,4 +1,4 @@ -/* ****************************************************************** ** +/* ****************************************************************** ** ** OpenSees - Open System for Earthquake Engineering Simulation ** ** Pacific Earthquake Engineering Research Center ** ** ** @@ -22,7 +22,7 @@ // $Date: 2025-01-03 11:29:01 $ // $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/ASDSteel1DMaterial.cpp,v $ -// Alessia Casalucci,Massimo Petracca, Guido Camata - ASDEA Software, Italy +// Alessia Casalucci, Massimo Petracca, Guido Camata - ASDEA Software, Italy // // A unified and efficient plastic-damage material model for steel bars including fracture, bond-slip, and buckling via multiscale homogenization // @@ -500,6 +500,7 @@ namespace { class SeriesComponent { public: + double lch_anchor = 0.0; SteelComponent steel_material; UniaxialMaterial* slip_material = nullptr; int serializationDataSize() const; @@ -507,8 +508,22 @@ namespace { void deserialize(Vector& data, int& pos, int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker); void serialize_slip(int commitTag, Channel& theChannel); void deserialize_slip(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker); + public: using param_t = ASDSteel1DMaterial::InputParameters; + inline void initialize_lch_anchor(const param_t& params) { + if (lch_anchor == 0.0) { + lch_anchor = lch_anchor_compute(params); + if (slip_material) { + // if the slip material supports the lch_ref parameter, let's set it to the anchorage length + Parameter lch_param(0, 0, 0, 0); + const char* the_args[] = { "lch_ref" }; + if (slip_material->setParameter(the_args, 1, lch_param) != -1) { + lch_param.update(lch_anchor); + } + } + } + } SeriesComponent() = default; SeriesComponent(const SeriesComponent& c) : steel_material(c.steel_material) @@ -552,9 +567,79 @@ namespace { slip_material->revertToStart(); } + inline double lch_anchor_compute(const param_t& params) { + //lch_anchor estimation + + // compute the gradient + double max_slip = params.radius * 100.0; + double tol = params.sy * 1.0e-6; + auto compute_gradient = [&](double slip) { + double epsilon = max_slip * 1.0e-8; + slip_material->setTrialStrain(slip); + slip_material->commitState(); + double stress_0 = slip_material->getStress(); + slip_material->revertToStart(); + slip_material->setTrialStrain(slip + epsilon); + slip_material->commitState(); + double stress_1 = slip_material->getStress(); + slip_material->revertToStart(); + double K = (stress_1 - stress_0) / epsilon; + if (std::abs(K) < tol) + K = 0.0; + return K; + }; + + double X0 = 0.0; + double Y0 = compute_gradient(X0); + double S0 = sign(Y0); + double X1 = max_slip; + double Y1 = compute_gradient(X1); + double S1 = sign(Y1); + double XM = (X1 + X0)/2.0; + bool found_peak = false; + for (int i = 0; i < 20; i++) { + double YM = compute_gradient(XM); + double SM = sign(YM); + if (S0 != SM) { + X1 = XM; + Y1 = YM; + S1 = SM; + found_peak = true; + } + else if (SM != S1) { + X0 = XM; + Y0 = YM; + S0 = SM; + found_peak = true; + } + else { + opserr << "Failed " << S0 << ", " << SM << ", " << S1 << "\n"; + break; + } + XM = (X1 + X0) / 2.0; + } + + double tau_max = 0.0; + double lch_anchor = 0.0; + if (found_peak) { + slip_material->setTrialStrain(XM); + slip_material->commitState(); + tau_max = slip_material->getStress(); + slip_material->revertToStart(); + + lch_anchor = (params.sy * params.radius) / (2.0 * tau_max); + } + else { + opserr << "No peak found — using default lch_anchor\n"; + lch_anchor = 80.0 * params.radius; + } + return lch_anchor; + } inline int compute(const param_t& params, bool do_implex, double time_factor, double _strain, double& sigma, double& tangent) { if (slip_material) { + initialize_lch_anchor(params); + // compute series response constexpr int MAX_ITER = 100; constexpr double TOL = 1e-6; @@ -573,7 +658,7 @@ namespace { // initial guess for the slip strain double lch_ele = 2.0 * params.lch_element; // it was divided in constructor for RVE symmetry - double strain_slip = slip_material->getStrain() / lch_ele; + double strain_slip = slip_material->getStrain() / lch_anchor; double strain_steel = _strain - strain_slip; // iterative procedure to impose the iso-stress condition @@ -584,13 +669,13 @@ namespace { double Stol = TOL; for (int iter = 0; iter < MAX_ITER; ++iter) { int Tsteel = steel_material.compute(params, do_implex, time_factor, strain_steel, sigma_steel, tangent_steel); - int Tslip = slip_material->setTrialStrain(strain_slip * lch_ele); - double sigma_slip = slip_material->getStress() * 2.0 * params.lch_anchor/ params.radius; - double tangent_slip = slip_material->getTangent() * 2.0 * lch_ele * params.lch_anchor / params.radius; + int Tslip = slip_material->setTrialStrain(strain_slip * lch_anchor); + double sigma_slip = slip_material->getStress() * 2.0 * lch_anchor/ params.radius; + double tangent_slip = slip_material->getTangent() * 2.0 * lch_anchor *lch_anchor / params.radius; double residual = sigma_slip - sigma_steel; double residual_derivative = tangent_steel + tangent_slip; if (std::abs(residual_derivative) < Ktol) { - residual_derivative = params.E + slip_material->getInitialTangent() * 2.0 * lch_ele * params.lch_anchor / params.radius; + residual_derivative = params.E + slip_material->getInitialTangent() * 2.0 * lch_anchor * lch_anchor / params.radius; } double strain_increment = - residual / residual_derivative; strain_slip += strain_increment; @@ -627,7 +712,7 @@ namespace { }; int SeriesComponent::serializationDataSize() const { - return 2 + steel_material.serializationDataSize(); + return 3 + steel_material.serializationDataSize(); } void SeriesComponent::serialize(Vector& data, int& pos, int commitTag, Channel& theChannel) @@ -642,10 +727,12 @@ namespace { slip_material->setDbTag(mat_db_tag); } data(pos++) = static_cast(mat_db_tag); + data(pos++) = lch_anchor; } else { data(pos++) = -1.0; // classTag data(pos++) = -1.0; // dbTag + data(pos++) = -1.0; //lch_anchor } } @@ -666,6 +753,7 @@ namespace { new_slip_material->setDbTag(mat_db_tag); slip_material = new_slip_material; } + lch_anchor = data(pos++); } @@ -1675,7 +1763,7 @@ void* OPS_ASDSteel1DMaterial() opserr << "Using ASDSteel1D - Developed by: Alessia Casalucci, Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; first_done = true; } - static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu <-implex> <-auto_regularization> <-buckling $lch < $r>> <-fracture <$r>> <-slip $matTag $lch_anc <$r>> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; + static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu <-implex> <-auto_regularization> <-buckling $lch < $r>> <-fracture <$r>> <-slip $matTag <$r>> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; // check arguments int numArgs = OPS_GetNumRemainingInputArgs(); @@ -1701,7 +1789,6 @@ void* OPS_ASDSteel1DMaterial() bool buckling = false; bool fracture = false; bool slip = false; - double lch_anc = 0.0; double K_alpha = 0.5; double max_iter= 100; double tolU = 1.0e-6; @@ -1818,8 +1905,8 @@ void* OPS_ASDSteel1DMaterial() } if (strcmp(value, "-slip") == 0) { slip = true; - if (OPS_GetNumRemainingInputArgs() < 2) { - opserr << "UniaxialMaterial ASDSteel1D: '-slip' requires '$matTag'and '$lch_anc'.\n"; + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "UniaxialMaterial ASDSteel1D: '-slip' requires '$matTag'.\n"; return nullptr; } // get slip material @@ -1834,7 +1921,7 @@ void* OPS_ASDSteel1DMaterial() opserr << "ASDSteel1D Error: No existing UniaxialMaterial with tag " << matTag << " for -slip option.\n"; return nullptr; } - if (!lam_optional_double( "lch_anc", lch_anc )) return nullptr; + // radius is optional (can be defined either here or in -buckling) if (OPS_GetNumRemainingInputArgs() > 0) { double trial_radius; @@ -1928,7 +2015,6 @@ void* OPS_ASDSteel1DMaterial() params.buckling = buckling; params.fracture = fracture; params.slip = slip; - params.lch_anchor = lch_anc; params.length = buckling ? lch / 2.0 : 1.0; // consider half distance, the RVE uses symmetry params.radius = r; params.K_alpha = K_alpha; @@ -2218,7 +2304,6 @@ int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) ddata(counter++) = static_cast(params.buckling); ddata(counter++) = static_cast(params.fracture); ddata(counter++) = static_cast(params.slip); - ddata(counter++) = params.lch_anchor; ddata(counter++) = params.radius; ddata(counter++) = params.length; ddata(counter++) = params.lch_element; @@ -2300,7 +2385,6 @@ int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectB params.buckling = static_cast(ddata(counter++)); params.fracture = static_cast(ddata(counter++)); params.slip = static_cast(ddata(counter++)); - params.lch_anchor = ddata(counter++); params.radius = ddata(counter++); params.length = ddata(counter++); params.lch_element = ddata(counter++); diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index e6204fb3e4..449d390671 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -69,7 +69,6 @@ class ASDSteel1DMaterial : public UniaxialMaterial bool buckling = false; bool fracture = false; bool slip = false; - double lch_anchor = 0.0; // buckling double radius = 0.0; double length = 0.0; @@ -81,7 +80,7 @@ class ASDSteel1DMaterial : public UniaxialMaterial double tolU = 0.0; double tolR = 0.0; // counter - static constexpr int NDATA = 20; + static constexpr int NDATA = 19; }; public: From 24b12b531cbcfee28944e75da2b4dc97d46cc33d Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 4 Jul 2025 16:44:07 -0700 Subject: [PATCH 142/261] more cleaning --- .../Frame/BasicFrameTransf.h | 11 +- .../Frame/BasicFrameTransf.tpp | 4 +- .../Frame/EuclidFrameTransf.tpp | 10 +- .../Frame/Isometry/CrisfieldIsometry.h | 151 +++++++++--------- .../Frame/Isometry/EuclidIsometry.h | 5 +- .../Frame/Isometry/RankinIsometry.h | 7 +- .../Frame/Isometry/RankinIsometry.tpp | 2 +- .../Frame/LinearFrameTransf.tpp | 5 +- 8 files changed, 93 insertions(+), 102 deletions(-) diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.h b/SRC/coordTransformation/Frame/BasicFrameTransf.h index 3743485b3b..7d66a14be2 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.h +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.h @@ -24,11 +24,10 @@ #ifndef BasicFrameTransf3d_h #define BasicFrameTransf3d_h -#include #include #include -#include -#include +class Vector; +class Matrix; namespace OpenSees { @@ -36,9 +35,9 @@ template class BasicFrameTransf3d: public CrdTransf { public: - BasicFrameTransf3d(FrameTransform<2,ndf> *t); + explicit BasicFrameTransf3d(FrameTransform<2,ndf> *t); - ~BasicFrameTransf3d(); + ~BasicFrameTransf3d() override; int getLocalAxes(Vector &x, Vector &y, Vector &z) final; @@ -89,7 +88,7 @@ class BasicFrameTransf3d: public CrdTransf } // TaggedObject - void Print(OPS_Stream &s, int flag = 0) final; + void Print(OPS_Stream &s, int flag) final; FrameTransform<2,ndf> &t; diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index 50f9baca63..1a5c1cba9c 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -7,7 +7,7 @@ // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// [1] Perez, C.M., and Filippou F.C. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // @@ -15,9 +15,7 @@ #include #include -#include #include -#include #include #include #include "FrameTransform.h" diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index aecd84fe53..75d08aa71e 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -94,7 +94,7 @@ EuclidFrameTransf::initialize(std::array& new_nodes) for (int i=0; i::pushResponse(VectorND&p) template MatrixND -EuclidFrameTransf::pushResponse(MatrixND&kb, const VectorND&pb) +EuclidFrameTransf::pushResponse(MatrixND&kb, + const VectorND&pb) { MatrixND Kb = kb; VectorND p = pb; @@ -415,7 +416,7 @@ EuclidFrameTransf::pushResponse(MatrixND&kb, const V for (int j=0; j<6; j++) qwx[i*6+j] = p[i*ndf+j] - Ap[i*ndf+j]; - MatrixND<12,12> Kw = basis.getRotationJacobian(qwx); + const MatrixND<12,12> Kw = basis.getRotationJacobian(qwx); Kb.assemble(Kw.template extract<0, 6, 0, 6>(), 0, 0, 1.0); Kb.assemble(Kw.template extract<0, 6, 6,12>(), 0, ndf, 1.0); Kb.assemble(Kw.template extract<6,12, 0, 6>(), ndf, 0, 1.0); @@ -441,7 +442,8 @@ EuclidFrameTransf::pushResponse(MatrixND&kb, const V Kl.addMatrixTransposeProduct(1.0, Kb, A, -1.0); // Kl = diag(R) * Kl * diag(R)^T - return this->FrameTransform::pushConstant(Kl); + FrameTransform::pushRotation(Kl, basis.getRotation()); + return Kl; } diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h index 75041eda13..615c0b3ae2 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h @@ -7,7 +7,7 @@ // // The following resource should be cited in derivative works: // -// [1] Perez, C.M., and Filippou F.C.. (2024) +// [1] Perez, C.M., and Filippou F.C. (2024) // "On Nonlinear Geometric Transformations of Finite Elements" // Int. J. Numer. Meth. Engrg.; // Available at: https://doi.org/10.1002/nme.7506 @@ -32,13 +32,11 @@ // https://doi.org/10.1016/0045-7825(90)90106-V. // #pragma once -#include #include #include #include #include #include -#include #include #include "EuclidIsometry.h" @@ -57,7 +55,7 @@ class CrisfieldIsometry : public AlignedIsometry { MatrixND<3,6> getRotationGradient(int node) final { - constexpr Vector3D e1{1, 0, 0}; + constexpr static Vector3D e1{1, 0, 0}; double Ln = this->getLength(); @@ -79,8 +77,6 @@ class CrisfieldIsometry : public AlignedIsometry { #if 0 - constexpr Matrix3D ix = Hat(e1); - auto de2 = this->getLMatrix(r2, r1, e1, A).transpose(); auto de3 = this->getLMatrix(r3, r1, e1, A).transpose(); #else auto de3 = this->getBasisVariation(r3, r1, e1, v, A); @@ -95,16 +91,16 @@ class CrisfieldIsometry : public AlignedIsometry { G.template insert<1,0, 1,12>(E3*de1, -1.0); G.template insert<2,0, 1,12>(E2*de1, 1.0); - if (node == 0) { - MatrixND<3,6> Gb = G.template extract<0,3, 0, 6>(); - return Gb; - } - else { - MatrixND<3,6> Gb = G.template extract<0,3, 6,12>(); - return Gb; - } + if (node == 0) + return G.template extract<0,3, 0, 6>(); + else if (node == nn-1) + return G.template extract<0,3, 6,12>(); + else + return MatrixND<3,6>{}; + #else MatrixND<3,6> Gb{}; + constexpr Matrix3D ix = Hat(e1); if (node == 0) { Gb.template insert<0,0>( ix, -1.0/Ln); @@ -123,7 +119,7 @@ class CrisfieldIsometry : public AlignedIsometry { { Ln = dx.norm(); { - Triad TrI{RI}, TrJ{RJ}; + const Triad TrI{RI}, TrJ{RJ}; rI[0] = TrI[1]; rI[1] = TrI[2]; rI[2] = TrI[3]; @@ -133,15 +129,15 @@ class CrisfieldIsometry : public AlignedIsometry { } { - Versor qI = VersorFromMatrix(RI); - Versor qJ = VersorFromMatrix(RJ); - Vector3D gammaw = CayleyFromVersor(qJ.mult_conj(qI)); + const Versor qI = VersorFromMatrix(RI); + const Versor qJ = VersorFromMatrix(RJ); + Vector3D gw = CayleyFromVersor(qJ.mult_conj(qI)); - gammaw *= 0.5; + gw *= 0.5; - Rbar = CaySO3(gammaw)*RI; + Rbar = CaySO3(gw)*RI; - Triad r{Rbar}; + const Triad r{Rbar}; r1 = r[1]; r2 = r[2]; r3 = r[3]; @@ -323,8 +319,8 @@ class CrisfieldIsometry : public AlignedIsometry { // T(:,3) += Lr3*rI1 ; y // T(:,4) += Lr3*rJ2 - Lr2*rJ3; - // T(:,5) += Lr2*rJ1 ; z // ?????? check sign - // T(:,6) += Lr3*rJ1 ; y // ?????? check sign + // T(:,5) += Lr2*rJ1 ; z // TODO ?????? check sign + // T(:,6) += Lr3*rJ1 ; y // TODO ?????? check sign // Bending Z for (int i = 0; i < 12; i++) { @@ -434,31 +430,6 @@ class CrisfieldIsometry : public AlignedIsometry { // // Ksigma3 // - // ks3 = [o kbar2 | o kbar4]; - // - // where - // - // kbar2 = -Lr2*(m(3)*S(rI3) + m(1)*S(rI1)) + Lr3*(m(3)*S(rI2) - m(2)*S(rI1)) ; - // - // kbar4 = Lr2*(m(3)*S(rJ3) - m(4)*S(rJ1)) - Lr3*(m(3)*S(rJ2) + m(5)*S(rJ1)); - // - // or - // - // ks3 = [o ka+kb | o kc+kd]; - // = [o ka | o kc] + [o kb | o kd]; - // - // where - // - // ka = -Lr2*S(rI3)*m(3) - // +Lr2*S(rI1)*m(1); - // kb = Lr3*S(rI2)*m(3) - // -Lr3*S(rI1)*m(2); - // - // kc = Lr2*S(rJ3)*m(3) - // -Lr2*S(rJ1)*m(4); - // kd = -Lr3*S(rJ2)*m(3) - // +Lr3*S(rJ1)*m(5); - VectorND<6> m; m[0] = 0.5*pl[imx]/std::cos(ul(imx)); m[2] = -0.5*pl[imy]/std::cos(ul(imy)); @@ -489,16 +460,16 @@ class CrisfieldIsometry : public AlignedIsometry { // Ksigma4 // { - Matrix3D ks33; - ks33.zero(); - ks33.addSpinProduct(e2, rJ3, -m[3]); - ks33.addSpinProduct(e3, rJ2, m[3]); - ks33.addSpinProduct(e2, rJ1, m[4]); - ks33.addSpinProduct(e1, rJ2, -m[4]); - ks33.addSpinProduct(e3, rJ1, m[5]); - ks33.addSpinProduct(e1, rJ3, -m[5]); - - kg.assemble(ks33, 9, 9, 1.0); + Matrix3D ks99; + ks99.zero(); + ks99.addSpinProduct(e2, rJ3, -m[3]); + ks99.addSpinProduct(e3, rJ2, m[3]); + ks99.addSpinProduct(e2, rJ1, m[4]); + ks99.addSpinProduct(e1, rJ2, -m[4]); + ks99.addSpinProduct(e3, rJ1, m[5]); + ks99.addSpinProduct(e1, rJ3, -m[5]); + + kg.assemble(ks99, 9, 9, 1.0); } // @@ -572,21 +543,14 @@ class CrisfieldIsometry : public AlignedIsometry { kg.assembleTranspose(ks33, 9, 6, -1.0); } - // Ksigma ------------------------------- - Vector3D rm = rI3; + // Ksigma - rm.addVector(1.0, rJ3, -1.0); - this->getKs2Matrix(kg, r2, rm, m[3]); - - // rm = rJ2; - rm.addVector(0.0, rJ2, 1.0); - rm.addVector(1.0, rI2, -1.0); - this->getKs2Matrix(kg, r3, rm, m[3]); - this->getKs2Matrix(kg, r2, rI1, m[1]); - this->getKs2Matrix(kg, r3, rI1, m[2]); - // - this->getKs2Matrix(kg, r2, rJ1, m[4]); - this->getKs2Matrix(kg, r3, rJ1, m[5]); + this->getKs2Matrix(kg, r2, rI3-rJ3, m[3]); + this->getKs2Matrix(kg, r3, rJ2-rI2, m[3]); + this->getKs2Matrix(kg, r2, rI1, m[1]); + this->getKs2Matrix(kg, r3, rI1, m[2]); + this->getKs2Matrix(kg, r2, rJ1, m[4]); + this->getKs2Matrix(kg, r3, rJ1, m[5]); return 0; } @@ -596,10 +560,10 @@ class CrisfieldIsometry : public AlignedIsometry { inline MatrixND<3,12> getBasisVariation(const Vector3D &ri, - const Vector3D& r1, - const Vector3D& e1, - const Vector3D& v, - const Matrix3D& A) const noexcept + const Vector3D& r1, + const Vector3D& e1, + const Vector3D& v, + const Matrix3D& A) const noexcept { double nu = v.norm(); Matrix3D L1 = ExpSO3(v)^dExpSO3(v, ri)*Hat(r1)*A; // nu @@ -619,9 +583,11 @@ class CrisfieldIsometry : public AlignedIsometry { return L; } - inline MatrixND<12,3> + [[nodiscard]] inline MatrixND<12,3> getLMatrix(const Vector3D &ri, - const Vector3D& r1, const Vector3D& e1, const Matrix3D& A) const noexcept + const Vector3D& r1, + const Vector3D& e1, + const Matrix3D& A) const noexcept { static Matrix3D rie1r1; @@ -677,6 +643,34 @@ class CrisfieldIsometry : public AlignedIsometry { inline void getKs3Matrix(MatrixND<12,12> &Kg, const VectorND<6>& m) const noexcept { + // + // Ksigma3 + // + // ks3 = [o kbar2 | o kbar4]; + // + // where + // + // kbar2 = -Lr2*(m(3)*S(rI3) + m(1)*S(rI1)) + Lr3*(m(3)*S(rI2) - m(2)*S(rI1)) ; + // + // kbar4 = Lr2*(m(3)*S(rJ3) - m(4)*S(rJ1)) - Lr3*(m(3)*S(rJ2) + m(5)*S(rJ1)); + // + // or + // + // ks3 = [o ka+kb | o kc+kd]; + // = [o ka | o kc] + [o kb | o kd]; + // + // where + // + // ka = -Lr2*S(rI3)*m(3) + // +Lr2*S(rI1)*m(1); + // kb = Lr3*S(rI2)*m(3) + // -Lr3*S(rI1)*m(2); + // + // kc = Lr2*S(rJ3)*m(3) + // -Lr2*S(rJ1)*m(4); + // kd = -Lr3*S(rJ2)*m(3) + // +Lr3*S(rJ1)*m(5); + const Vector3D &rI1 = rI[0], &rI2 = rI[1], &rI3 = rI[2], @@ -721,6 +715,7 @@ class CrisfieldIsometry : public AlignedIsometry { const Vector3D &e1 = e[0]; // const double Ln = this->getLength(); + // Ksigma2 = [ K11 K12 -K11 K12 // K12' K22 -K12' K22 // -K11 -K12 K11 -K12 diff --git a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h index bad39f560c..1ed032a3bb 100644 --- a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h @@ -46,12 +46,9 @@ class Isometry virtual Vector3D getPositionVariation(int ndf, double* du) =0; virtual Vector3D getRotationVariation(int ndf, double* du) =0; virtual MatrixND<12,12> getRotationJacobian(const VectorND<12>&pl) { - MatrixND<12,12> K; - K.zero(); - return K; + return MatrixND<12,12> {}; } virtual Matrix3D getRotationDelta() =0; - // virtual MatrixND<3,6> getRotationGradient(int node) =0; }; diff --git a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h index 507f75105e..95b2895dc1 100644 --- a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h @@ -7,7 +7,7 @@ // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. (2024) +// [1] Perez, C.M., and Filippou F.C. (2024) // "On Nonlinear Geometric Transformations of Finite Elements" // Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 // @@ -31,7 +31,6 @@ // Available at: https://doi.org/10.1016/0045-7825(91)90248-5. // #pragma once -#include #include #include #include @@ -88,7 +87,7 @@ class RankinIsometry : public AlignedIsometry getRotationJacobian(const VectorND<12>&pwx) final { MatrixND<3,12> NWL{}; - double Ln = this->getLength(); + const double Ln = this->getLength(); constexpr static Vector3D e1 {1,0,0}; constexpr static Matrix3D ex = Hat(e1); @@ -148,7 +147,7 @@ class RankinIsometry : public AlignedIsometry constexpr Vector3D axis{1, 0, 0}; constexpr Matrix3D ix = Hat(axis); - double Ln = this->getLength(); + const double Ln = this->getLength(); if (node == 0) { Gb.template insert<0,0>( ix, -1.0/Ln); diff --git a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.tpp b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.tpp index 1017532ab9..73880ccfaa 100644 --- a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.tpp +++ b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.tpp @@ -11,7 +11,7 @@ // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// [1] Perez, C.M., and Filippou F.C. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index bd68dd4540..2b5ba19e9a 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -39,10 +39,11 @@ namespace OpenSees { static inline MatrixND<3,3> FrameOrientationGradient(const Vector3D& xi, const Vector3D& xj, - const Vector3D& vz, int di, int dj, int dv) + const Vector3D& vz, + int di, int dj, int dv) { Vector3D v1 = xj - xi; - double L = v1.norm(); + const double L = v1.norm(); Vector3D e1 = v1/L; Vector3D v2 = vz.cross(e1); From 5d1c3da6a508b4e3df3ce64a4c5aeda0e5a7d15f Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 4 Jul 2025 17:43:40 -0700 Subject: [PATCH 143/261] more updating --- SRC/matrix/GroupSO3.h | 97 +- SRC/matrix/Matrix3D.h | 1 - SRC/matrix/MatrixND.h | 133 ++- SRC/matrix/MatrixND.tpp | 59 ++ SRC/matrix/Vector3D.h | 1 + SRC/matrix/VectorND.h | 35 +- SRC/matrix/VectorND.tpp | 276 +++++- SRC/matrix/Versor.h | 4 +- SRC/matrix/Versor.tpp | 9 + .../commands/modeling/element/frames.cpp | 825 ++++++++++++++---- .../transform/FrameTransformBuilder.hpp | 27 +- 11 files changed, 1190 insertions(+), 277 deletions(-) create mode 100644 SRC/matrix/Versor.tpp diff --git a/SRC/matrix/GroupSO3.h b/SRC/matrix/GroupSO3.h index 0d9167b882..5047237a6f 100755 --- a/SRC/matrix/GroupSO3.h +++ b/SRC/matrix/GroupSO3.h @@ -2,10 +2,6 @@ // // xara // https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures // //----------------------------------------------------------------------------// // @@ -33,6 +29,7 @@ // // [5] Nurlanov Z (2021) Exploring SO(3) logarithmic map: degeneracies and // derivatives. +// //===----------------------------------------------------------------------===// // @@ -40,7 +37,7 @@ // follows value semantics with the expectation that RVO will make this // performant. // -// Written: Claudio M. Perez, Filip C. Filippou +// Written: Claudio M. Perez // #pragma once @@ -116,10 +113,10 @@ GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) if (angle2 <= 1e-07) { // - // Use series formula of Equation (A9) from [1] + // Maclaurin series in Horner form // if (a != nullptr) { - a[0] = 0.0; + a[0] = 1.0 - angle2*(1.0/2.0 - angle2*(1.0/6.0 - angle2/24.0)); a[1] = 1.0 - angle2*(1.0/6.0 - angle2*(1.0/120.0 - angle2/5040.0)); a[2] = 0.5 - angle2*(1.0/24.0 - angle2*(1.0/720.0 - angle2/40320.0)); a[3] = 1.0/6.0 - angle2/(1.0/120.0 - angle2/(1.0/5040.0 - angle2/362880.0)); @@ -133,7 +130,7 @@ GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) if (c != nullptr) { c[0] = - b[1]; c[1] = b[3] - b[2]; - c[2] = 1.0/90.0 - angle2*(1.0/1680.0 - angle2*(1.0/75600.0 - angle2/5987520.0)); + c[2] = 1.0/90.0 - angle2*(1.0/1680.0 - angle2*(1.0/75600.0 - angle2/5987520.0)); c[3] = 1.0/630.0 - angle2*(1.0/15120.0 - angle2*(1.0/831600.0 - angle2/77837760.0)); } @@ -141,7 +138,6 @@ GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) // // Use formulas of Equation (A8) from [1] // - double angle = vec.norm(); double sn = std::sin(angle); double cs = std::cos(angle); @@ -171,6 +167,7 @@ GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) c[3] = (8.*angle + 7.*angle*cs + angle2*sn - 15.*sn)/(angle5*angle2); } } + return std::sqrt(angle2); } @@ -227,17 +224,17 @@ VersorProduct(const Versor &qa, const Versor &qb) static inline Matrix3D MatrixFromVersor(const Versor &q) { - Matrix3D R{}; + Matrix3D R{}; - const double factor = q.scalar*q.scalar - q.vector.dot(q.vector); + const double factor = q.scalar*q.scalar - q.vector.dot(q.vector); - for (int i = 0; i < 3; i++) - R(i,i) = factor; + for (int i = 0; i < 3; i++) + R(i,i) = factor; - R.addTensorProduct(q.vector, q.vector, 2.0); - R.addSpin(q.vector, 2.0*q.scalar); + R.addTensorProduct(q.vector, q.vector, 2.0); + R.addSpin(q.vector, 2.0*q.scalar); - return R; + return R; } @@ -557,7 +554,6 @@ LogSO3(const Matrix3D &R) //===--------------------------------------------------------------------===// return VectorFromVersor(VersorFromMatrix(R)); - } @@ -601,6 +597,16 @@ LogC90_Skew(const Matrix3D &R) namespace Utility { +template +constexpr T horner(T x2, const std::array& c) noexcept +{ + // Evaluate c0 + c1*x2 + c2*x2² + ... with Horner's rule (and FMA if available). + T y = c.back(); + for (std::size_t i = N-1; i-- > 0; ) + y = std::fma(x2, y, c[i]); + return y; +} + static inline double dLogConst(double angle, double& a3, double& b3) { @@ -643,41 +649,44 @@ dLogConst(double angle, double& a3, double& b3) static inline Vector3D RescaleVector(const Vector3D &v, double &angle) { - static constexpr double pi = 3.14159265358979323846; - static constexpr double two_pi = 2.0 * pi; - static constexpr double eps = 1e-8; // pole-avoidance band + static constexpr double pi = 3.14159265358979323846; + static constexpr double two_pi = 2.0 * pi; + static constexpr double eps = 1e-8; // pole-avoidance band - Vector3D u = v; // copy; v is const + Vector3D u = v; - return u; + // NOTE: Currently we are skipping the rescaling as it is not generally + // needed by the formulations that have been ported to OpenSees from + // FEDEASLab. + return u; - // Fast exit when |angle| already <= pi (no poles inside) - if (std::fabs(angle) <= pi) - return u; + // Fast exit when |angle| already <= pi (no poles inside) + if (std::fabs(angle) <= pi) + return u; - // Wrap once modulo 2pi - double wrapped = std::remainder(angle, two_pi); // (-pi, pi] + // Wrap once modulo 2pi + double wrapped = std::remainder(angle, two_pi); // (-pi, pi] - // Nudge away from the sole pole at 0 - if (std::fabs(wrapped) < eps) - wrapped = (wrapped < 0.0 ? -eps : eps); + // Nudge away from the sole pole at 0 + if (std::fabs(wrapped) < eps) + wrapped = (wrapped < 0.0 ? -eps : eps); // #define PRINCIPAL_WRAP #ifndef PRINCIPAL_WRAP - // Keep original magnitude unless it was near a pole - if (std::fabs(angle) > pi && std::fabs(wrapped) >= eps) - wrapped = angle; + // Keep original magnitude unless it was near a pole + if (std::fabs(angle) > pi && std::fabs(wrapped) >= eps) + wrapped = angle; #endif - // Rescale u - if (std::fabs(angle) > eps) { // safe denominator - double scale = wrapped / angle; - for (int i = 0; i < 3; ++i) - u[i] *= scale; - } + // Rescale u + if (std::fabs(angle) > eps) { // safe denominator + double scale = wrapped / angle; + for (int i = 0; i < 3; ++i) + u[i] *= scale; + } - angle = wrapped; - return u; + angle = wrapped; + return u; } } @@ -707,7 +716,9 @@ dLogSO3(const Vector3D &v, double* a=nullptr) inline Matrix3D ddLogSO3(const Vector3D& u, const Vector3D& p) { - + // + // -0.5*Hat(v) + eta*(Eye3*th.dot(v) + th.bun(v) - 2.*v.bun(th)) + mu*St2*v.bun(th); + // double angle = u.norm(); const Vector3D th = Utility::RescaleVector(u, angle); @@ -716,7 +727,7 @@ ddLogSO3(const Vector3D& u, const Vector3D& p) Matrix3D St2 = Hat(th); St2 = St2*St2; - Matrix3D dH{}; // -0.5*Hat(v) + eta*(Eye3*th.dot(v) + th.bun(v) - 2.*v.bun(th)) + mu*St2*v.bun(th); + Matrix3D dH{}; dH.addSpin(p, -0.5); dH.addDiagonal( eta*th.dot(p)); dH.addTensorProduct(th, p, eta); diff --git a/SRC/matrix/Matrix3D.h b/SRC/matrix/Matrix3D.h index 4a5d8afb73..cb5c55b98f 100644 --- a/SRC/matrix/Matrix3D.h +++ b/SRC/matrix/Matrix3D.h @@ -24,5 +24,4 @@ namespace OpenSees { static_assert(std::is_aggregate::value, "Matrix3D is not an aggregate type."); } - #endif // Matrix3D_H diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index aa7d25c123..1dfd7e5567 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -5,12 +5,28 @@ //===----------------------------------------------------------------------===// // https://xara.so //===----------------------------------------------------------------------===// - // // Desctiption: MatrixND is a fixed-size matrix class that is suitable for // stack-allocation. // -//----------------------------------------------------------------------------// +// +// This code is influenced by the following sources +// List initialization: +// - https://stackoverflow.com/questions/42068882/list-initialization-for-a-matrix-class +// +// Style/practices +// - https://quuxplusone.github.io/blog/2021/04/03/static-constexpr-whittling-knife/ +// +// Operator overloading / semantics +// - https://stackoverflow.com/questions/9851188/does-it-make-sense-to-use-move-semantics-for-operator-and-or-operator/9851423#9851423 +// +// Compile-time template restrictions/concepts: +// - https://codereview.stackexchange.com/questions/259038/compile-time-matrix-class +// (C++ 20) +// - https://github.com/calebzulawski/cotila/ +// (C++ 17) +// +//===----------------------------------------------------------------------===// // // Claudio Perez // @@ -23,6 +39,7 @@ #include "VectorND.h" #include "Matrix.h" #include "Vector.h" +#include "routines/SY3.h" #if __cplusplus < 202000L # define consteval @@ -38,11 +55,19 @@ requires(NR > 0 && NC > 0) struct MatrixND { double values[NC][NR]; - // Convert to dynamic Matrix class + // MatrixND(const MatrixND&) = default; + + // Convert to regular Matrix class operator Matrix() { return Matrix(&values[0][0], NR, NC);} operator const Matrix() const { return Matrix(&values[0][0], NR, NC);} + int symeig(VectorND& vals) requires(NR == NC == 3) { + double work[3][3]; + cmx_eigSY3(values, work, vals.values); + return 0; + } + consteval void zero(); constexpr MatrixND transpose() const; @@ -94,6 +119,19 @@ struct MatrixND { return Matrix(*this).Invert(); } +#if 0 +//template +//void addSpinAtRow(const VecT& V, size_t row_index); +//template +//void addSpinAtRow(const VecT& V, size_t vector_index, size_t matrix_row_index); +//template +//MatrixND& addSpin(const VecT& V, double mult) requires(NR == 3); +//template +//void addSpinAtRow(const VecT& V, double mult, size_t row_index); +//template +//void addSpinAtRow(const VecT& V, double mult, size_t vector_index, size_t matrix_row_index); +#endif + // // Indexing // @@ -232,38 +270,63 @@ struct MatrixND { } - int solve(const Vector &V, Vector &res) const - requires(NR == NC) + template + // requires (NR == NC) && (n == NR) && (n > 0) + int solve(const MatrixND& M, MatrixND& X) const { + static_assert(n == NR, "RHS row-count must match A."); - MatrixND work = *this; - int pivot_ind[NR]; - int nrhs = 1; - int nr = NR; - int nc = NC; - int info = 0; - res = V; // X will be overwritten with the solution - DGESV(&nr, &nrhs, &work.values[0][0], &nr, &pivot_ind[0], res.theData, &nc, &info); - return -abs(info); - } + MatrixND work = *this; // copy of A to be factorised + int ipiv[NR]{}; + int n_eq = NR; // order of the system + int nrhs = n; // number of RHS columns + int lda = NR; // leading dim of A + int ldb = NR; // leading dim of X + int info = 0; - int - solve(const Matrix &M, Matrix &res) - { - Matrix slver(*this); - return slver.Solve(M, res); + X = M; // copy RHS, DGESV overwrites + DGESV(&n_eq, &nrhs, + work.values[0], &lda, + &ipiv[0], + X.values[0], &ldb, + &info); - MatrixND work = *this; - int pivot_ind[NR]; - int nrhs = M.noCols(); - int nr = NR; - int nc = NC; - int info = 0; - res = M; // M will be overwritten with the solution - DGESV(&nr, &nrhs, &work(0,0), &nr, &pivot_ind[0], &res(0,0), &nc, &info); - return -abs(info); + return -std::abs(info); } + + // int solve(const Vector &V, Vector &res) const + // requires(NR == NC) + // { + + // MatrixND work = *this; + // int pivot_ind[NR]; + // int nrhs = 1; + // int nr = NR; + // int nc = NC; + // int info = 0; + // res = V; // X will be overwritten with the solution + // DGESV(&nr, &nrhs, &work.values[0][0], &nr, &pivot_ind[0], res.theData, &nc, &info); + // return -abs(info); + // } + + + // int + // solve(const Matrix &M, Matrix &res) + // { + // Matrix slver(*this); + // return slver.Solve(M, res); + + // MatrixND work = *this; + // int pivot_ind[NR]; + // int nrhs = M.noCols(); + // int nr = NR; + // int nc = NC; + // int info = 0; + // res = M; // M will be overwritten with the solution + // DGESV(&nr, &nrhs, &work(0,0), &nr, &pivot_ind[0], &res(0,0), &nc, &info); + // return -abs(info); + // } template @@ -292,9 +355,10 @@ struct MatrixND { insert(const MatrixND &M, double fact) { - [[maybe_unused]] int final_row = init_row + nr - 1; - [[maybe_unused]] int final_col = init_col + nc - 1; - assert((init_row >= 0) && (final_row < NR) && (init_col >= 0) && (final_col < NC)); + constexpr int final_row = init_row + nr - 1; + constexpr int final_col = init_col + nc - 1; + static_assert((init_row >= 0) && (final_row < NR) && (init_col >= 0) && (final_col < NC), + "MatrixND::insert: init_row, init_col, nr, nc out of bounds"); for (int i=0; i operator*(const MatrixND &left, const MatrixND &right) { MatrixND prod; +#if 0 + if constexpr (NR*NC > 16) + prod.addMatrixProduct(0, left, right, 1); + else +#endif for (index_t i = 0; i < NR; ++i) { for (index_t j = 0; j < J; ++j) { prod(i, j) = 0.0; diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index 33d17c9029..78dd7ec459 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -12,6 +12,7 @@ #include "MatrixND.h" #include "blasdecl.h" #include "routines/cmx.h" +#include "routines/SY3.h" namespace OpenSees { @@ -201,6 +202,22 @@ MatrixND::addMatrixProduct(const MatrixND& A, const MatT& } } +#if 0 +template +template inline +void +MatrixND::addMatrixProduct(double scale_this, const MatrixND& A, const MatT& B, double scale) +{ + int m = nr, + n = nc, + k = nk; + DGEMM("N", "N", &m, &n, &k, &scale, + const_cast(&A(0,0)), &m, + const_cast(&B(0,0)), &k, + &scale_this, &(*this)(0,0), &m); +} +#endif + // B'*C template template inline @@ -262,6 +279,27 @@ MatrixND::addMatrixTransposeProduct(double thisFact, } } } +#if 0 + if (thisFact == 1.0) { + for (int j=0; j::addMatrixTripleProduct( BT.zero(); BT.addMatrixProduct(B, T, otherFact); this->addMatrixTransposeProduct(thisFact, T, BT, 1.0); + +#if 0 + { + int m = B.numRows, + n = T.numCols, + k = B.numCols, + nrT = T.numRows; + //k = T.numRows; + double zero = 0.0, + one = 1.0; + + DGEMM ("N", "N", &m , &n , &k,&one , B.data, &m, // m + T.data, &nrT, // k + &zero, matrixWork, &m); + + DGEMM ("T", "N", &numRows, &numCols, &k,&otherFact, T.data, &nrT, + matrixWork, &m, // k + &thisFact, data, &numRows); + return 0; + } +#endif return 0; } diff --git a/SRC/matrix/Vector3D.h b/SRC/matrix/Vector3D.h index eef7ecf5cc..876c04929a 100644 --- a/SRC/matrix/Vector3D.h +++ b/SRC/matrix/Vector3D.h @@ -32,4 +32,5 @@ static_assert(std::is_trivial::value, "Vector3D is not trivial."); static_assert(std::is_nothrow_constructible::value, "Vector3D is not nothrow constructible."); static_assert(std::is_nothrow_move_assignable::value, "Vector3D is not nothrow move assignable."); + #endif // Vector3D_h diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index 3d01b764a7..5bc38a621d 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -6,12 +6,33 @@ // https://xara.so //===----------------------------------------------------------------------===// // +// Objectives: +// - little to no overhead above C-style arrays +// - value semantics; objects do not decay to pointers; +// +// This code is influenced by the following sources +// list initialization: +// - https://stackoverflow.com/questions/42068882/list-initialization-for-a-matrix-class +// +// style/practices +// - https://quuxplusone.github.io/blog/2021/04/03/static-constexpr-whittling-knife/ +// +// Operator overloading / semantics +// - https://stackoverflow.com/questions/9851188/does-it-make-sense-to-use-move-semantics-for-operator-and-or-operator/9851423#9851423 +// +// compile-time template restrictions/concepts: +// - https://codereview.stackexchange.com/questions/259038/compile-time-matrix-class +// (C++ 20) +// - https://github.com/calebzulawski/cotila/ +// (C++ 17) +// +//===----------------------------------------------------------------------===// +// // Claudio Perez // #ifndef VectorND_H #define VectorND_H #include -#include #include #include @@ -52,9 +73,21 @@ struct VectorND { VectorND extract(int a) noexcept; + int + addVector(const T thisFact, const Vector &other, const T otherFact) noexcept; + int addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept; + template + inline int + addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact); + + template + inline int + addMatrixTransposeVector(double thisFact, const MatrixND &m, + const Vector &v, double otherFact); + inline int addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact); diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index 8296383cef..99c16161a9 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -8,6 +8,8 @@ // #include #include "VectorND.h" +#include "blasdecl.h" + namespace OpenSees { @@ -61,6 +63,68 @@ VectorND::extract(int a) noexcept } +template +int +VectorND::addVector(const T thisFact, const Vector &other, const T otherFact) noexcept +{ + if (otherFact == 0.0 && thisFact == 1.0) + return 0; + + else if (thisFact == 1.0) { + // want: this += other * otherFact + double *dataPtr = values; + double *otherDataPtr = other.theData; + if (otherFact == 1.0) { + // no point doing a multiplication if otherFact == 1.0 + for (int i=0; i int VectorND::addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept @@ -72,13 +136,13 @@ VectorND::addVector(const T thisFact, const VectorND &other, const T oth // want: this += other * otherFact double *dataPtr = values; const double * otherDataPtr = other.values; - if (otherFact == 1.0) + if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0 for (int i=0; i::addVector(const T thisFact, const VectorND &other, const T oth double *dataPtr = values; const double *otherDataPtr = other.values; if (otherFact == 1.0) { + // no point doing a multiplication if otherFact == 1.0 for (int i=0; i::addVector(const T thisFact, const VectorND &other, const T oth // want: this = this * thisFact + other * otherFact double *dataPtr = values; const double *otherDataPtr = other.values; - if (otherFact == 1.0) { + if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0 for (int i=0; i::addVector(const T thisFact, const VectorND &other, const T oth return 0; } + +template +template +inline int +VectorND::addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact) +{ + // check the sizes are compatable + assert(NC == v.sz); + + // see if quick return + if (thisFact == 1.0 && otherFact == 0.0) + return 0; + + else { + int incr = 1, + i = N, + n = NC; + DGEMV("N", &i, &n, + &otherFact, + &m.values[0][0], &i, + v.theData, &incr, + &thisFact, + values, + &incr); + + return 0; + } +} + + +template +template +inline int +VectorND::addMatrixTransposeVector(double thisFact, const MatrixND &m, const Vector &v, double otherFact) +{ + // check the sizes are compatable + assert(NR == v.sz); + + + if (thisFact == 1.0 && otherFact == 0.0) + return 0; + + else { + int incr = 1, + i = NR, + n = N; + DGEMV("T", &i, &n, + &otherFact, + &m.values[0][0], &i, + v.theData, &incr, + &thisFact, + values, &incr); + return 0; + } +} + + +template +inline int +VectorND::addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact) +{ + // check the sizes are compatable + assert(N == m.noRows()); + assert(m.noCols() == v.sz); + + // see if quick return + if (thisFact == 1.0 && otherFact == 0.0) + return 0; + +#ifdef VECTOR_BLAS + else if (v.sz > 10) { + int incr = 1, + i = m.numRows, + n = m.numCols; + return + DGEMV("N", &i, &n, + &otherFact, + m.data, &i, + v.theData, &incr, + &thisFact, + values, &incr); + } +#endif + + else if (thisFact == 1.0) { + + // want: this += m * v * otherFact + if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0 + int otherSize = v.sz; + double *matrixDataPtr = m.data; + const double *otherDataPtr = v.theData; + for (int i=0; i -#include +#include #if 0 namespace OpenSees { diff --git a/SRC/matrix/Versor.tpp b/SRC/matrix/Versor.tpp new file mode 100644 index 0000000000..4e7244123f --- /dev/null +++ b/SRC/matrix/Versor.tpp @@ -0,0 +1,9 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// + diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index 7183252248..d99c42ea94 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -6,195 +6,90 @@ // https://xara.so //===----------------------------------------------------------------------===// // -// Description: This file implements parsing for inelastic beam elements. -// We support *all* forms of the command that have been used in the past, -// which considerably complicates things. -// -// The various forms are -// -// -// 0 1 2 3 4 -// element 1 $i $j 0 1 2 -// -// a) -// 0 1 2 3 4 5 6 -// 0 1 -// element $type $tag $ndi $ndj $trn "Gauss arg1 arg2 ..." -// <-mass $mass> <-iter $iter $tol> -// -// b) OpenSeesPy -// 0 1 -// element(type, tag, ndi, ndj, trn, itag, -// iter=(10, 1e-12), mass=0.0) -// -// c) Original/Obsolete -// 0 1 2 -// element $type $tag $ndi $ndj $nip $sec $trn -// <-mass $mass> <-iter $iter $tol> <-integration $ityp> -// -// d) -// 0 1 ... (2 + nIP) -// element $type $tag $ndi $ndj $nip -sections ... $trn -// <-mass $massDens> <-cMass> <-integration $ityp> -// -// e) -// 0 -// element $type $tag $ndi $ndj $trn -// -sections {...} -// <-mass $massDens> <-cMass> <-integration $ityp> -// -// -// Integration may be specitied as either -// i ) a single name, -// ii ) a pattern spec, or -// iii) a tag for a pattern -// -// If a list of sections is given with -sections, or nIP is provided, then -// we must have an integration with the form (i) -// -// 1) Parse common keyword args: -// "-mass" $mass, -// "-cMass"/"-lMass" -// "-mass-form" $form -// -// "-iter" $iter $tol, -// -// "-integration" $Integration -// - first try parsing $Integration as integer ($itag, form (iii)) -// if successfull, populate section_tags and continue -// - next try parsing $Integration as basic quadrature ($ityp, form (i)) -// - finally, try parsing as full pattern spec -// -// "-section" $Tag -// -// "-transform" $Tag -// "-vertical" {} -// "-horizontal" {} -// -// "-sections" $SectionTags -// - if cannot split $SectionTags as list, then -// mark "-sections" as positional and continue -// with keyword loop -// - Check if "-integration" was provided already; if so, it must have been in form (i); -// otherwise throw an error. -// - Parse $SectionTags -// -sections {...} may occur anywhere -// -sections ... must occur after nIP is obtained -// -// -// 2) -// If pos[1] == "-sections" then command is Form (d): -// nIP = pos[0] -// trn = pos[2+nIP] -// -// else -// -// switch (pos.size()) -// case 1: // Form (e) -// trn = pos[0] -// if (section_tags.size() == 0) -// ERROR -// -// case 2: -// // Form (a) or (b) -// trn = pos[0] -// if GetInt(interp, pos[1]): -// itag = pos[1] -// else -// ParseHingeScheme(pos[1]) -// -// case 3: -// // Form (c) -// nip = int(pos[0]) -// sec = int(pos[1]) -// trn = int(pos[2]) -// -// // Written: cmp, mhs, rms, fmk // // Created: Feb 2023 // - // Standard library -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _MSC_VER -# include -# define strcasecmp _stricmp -#else -# include -#endif -#define strcmp strcasecmp - -// Parsing -#include -#include -#include -#include - -// Model -#include -#include -#include - -// Sections -#include -#include -#include - -// Elements -#include "ElasticBeam2d.h" -#include "ElasticBeam2d.h" -#include "ElasticBeam3d.h" -#include "ElasticBeam3d.h" -#include "PrismFrame2d.h" -#include "PrismFrame2d.h" -#include "PrismFrame3d.h" -#include "PrismFrame3d.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -// Quadrature -#include -#include -#include -#include -#include -#include -#include - -#include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #ifdef _MSC_VER + # include + # define strcasecmp _stricmp + #else + # include + #endif + #define strcmp strcasecmp + + // Parsing + #include + #include + #include + #include + + // Model + #include + #include + #include + + // Sections + #include + #include + #include + + // Elements + #include "ElasticBeam2d.h" + #include "ElasticBeam2d.h" + #include "ElasticBeam3d.h" + #include "ElasticBeam3d.h" + #include "PrismFrame2d.h" + #include "PrismFrame2d.h" + #include "PrismFrame3d.h" + #include "PrismFrame3d.h" + + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + #include + + // Quadrature + #include + #include + #include + #include + #include + #include + #include + + #include using namespace OpenSees; @@ -248,8 +143,7 @@ CreateFrame(BasicModelBuilder& builder, // Finalize the coordinate transform Transform* theTransf = builder.getTypedObject(transfTag); if (theTransf == nullptr) { - opserr << OpenSees::PromptValueError - << "transformation not found with tag " << transfTag << "\n"; + opserr << OpenSees::PromptValueError << "transformation not found with tag " << transfTag << "\n"; return nullptr; } @@ -390,6 +284,10 @@ CreateFrame(BasicModelBuilder& builder, static_loop<0, 3>([&](auto nwm) constexpr { if (nwm.value + 6 == ndf) { + // Create the transform +#if 0 || defined(NEW_TRANSFORM) + FrameTransform<2,6+nwm.value> *tran = tb->template create<2,6+nwm.value>(); +#endif if (!options.shear_flag) { static_loop<2,30>([&](auto nip) constexpr { if (nip.value == sections.size()) @@ -472,6 +370,114 @@ CreateFrame(BasicModelBuilder& builder, } +#if 0 +Element* +CreateInelasticFrame(std::string, std::vector& nodes, + std::vector&, + BeamIntegration&, + // FrameQuadrature&, + FrameTransform&, + Options&); +Element* +CreatePrismaticFrame(std::string); +#endif + +// 0 1 2 3 4 +// element beam 1 $i $j 0 1 2 +// +// a) +// 0 1 2 3 4 5 6 +// 0 1 +// element $type $tag $ndi $ndj $trn "Gauss arg1 arg2 ..." +// <-mass $mass> <-iter $iter $tol> +// +// b) +// 0 1 +// element(type, tag, ndi, ndj, trn, itag, +// iter=(10, 1e-12), mass=0.0) +// +// c) "Original/Obsolete" +// 0 1 2 +// element $type $tag $ndi $ndj $nip $sec $trn +// <-mass $mass> <-iter $iter $tol> <-integration $ityp> +// +// d) +// 0 1 ... (2 + nIP) +// element $type $tag $ndi $ndj $nip -sections ... $trn +// <-mass $massDens> <-cMass> <-integration $ityp> +// +// e) +// 0 +// element $type $tag $ndi $ndj $trn +// -sections {...} +// <-mass $massDens> <-cMass> <-integration $ityp> +// +// +// Integration may be specitied as either +// i ) a single name, +// ii ) a pattern spec, or +// iii) a tag for a pattern +// +// if a list of sections is given with -sections, or nIP is provided, then +// we must have an integration with the form (i) +// +// 1) Parse common keyword args: +// "-mass" $mass, +// "-cMass"/"-lMass" +// "-mass-form" $form +// +// "-iter" $iter $tol, +// +// "-integration" $Integration +// - first try parsing $Integration as integer ($itag, form (iii)) +// if successfull, populate section_tags and continue +// - next try parsing $Integration as basic quadrature ($ityp, form (i)) +// - finally, try parsing as full pattern spec +// +// "-section" $Tag +// +// "-transform" $Tag +// "-vertical" {} +// "-horizontal" {} +// +// "-sections" $SectionTags +// - if cannot split $SectionTags as list, then +// mark "-sections" as positional and continue +// with keyword loop +// - Check if "-integration" was provided already; if so, it must have been in form (i); +// otherwise throw an error. +// - Parse $SectionTags +// -sections {...} may occur anywhere +// -sections ... must occur after nIP is obtained +// +// +// 2) +// If pos[1] == "-sections" then command is Form (d): +// nIP = pos[0] +// trn = pos[2+nIP] +// +// else +// +// switch (pos.size()) +// case 1: // Form (e) +// trn = pos[0] +// if (section_tags.size() == 0) +// ERROR +// +// case 2: +// // Form (a) or (b) +// trn = pos[0] +// if GetInt(interp, pos[1]): +// itag = pos[1] +// else +// ParseHingeScheme(pos[1]) +// +// case 3: +// // Form (c) +// nip = int(pos[0]) +// sec = int(pos[1]) +// trn = int(pos[2]) +// int TclBasicBuilder_addForceBeamColumn(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **const argv) @@ -964,3 +970,450 @@ TclBasicBuilder_addForceBeamColumn(ClientData clientData, Tcl_Interp *interp, return status; } + + +// +// BeamWithHinges +// +// element beamWithHinges tag? ndI? ndJ? secTagI? lenI? secTagJ? lenJ? +// E? A? I? transfTag? <-shear shearLength?> <-mass massDens?> +// <-iter maxIters tolerance> +// +int +TclBasicBuilder_addBeamWithHinges(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + + int NDM = builder->getNDM(); + int NDF = builder->getNDF(); + + // Plane frame element + if (NDM == 2 && NDF == 3) { + if (argc < 13) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element beamWithHinges tag? ndI? ndJ? secTagI? lenI? " + "secTagJ? lenJ? "; + opserr << "E? A? I? transfTag? <-shear shearLength?> <-mass massDens?> " + "<-iter maxIters tolerance>" + << "\n"; + return TCL_ERROR; + } + + double massDens = 0.0; + int max_iters = 10; + double tol = 1.0e-10; + int tag, ndI, ndJ, secTagI, secTagJ, transfTag; + double lenI, lenJ, E, A, I; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid beamWithHinges tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &ndI) != TCL_OK) { + opserr << "WARNING invalid ndI\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4], &ndJ) != TCL_OK) { + opserr << "WARNING invalid ndJ\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[5], &secTagI) != TCL_OK) { + opserr << "WARNING invalid secTagI\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &lenI) != TCL_OK) { + opserr << "WARNING invalid lenI\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[7], &secTagJ) != TCL_OK) { + opserr << "WARNING invalid ndJ\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[8], &lenJ) != TCL_OK) { + opserr << "WARNING invalid lenJ\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[9], &E) != TCL_OK) { + opserr << "WARNING invalid E\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10], &A) != TCL_OK) { + opserr << "WARNING invalid A\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[11], &I) != TCL_OK) { + opserr << "WARNING invalid I\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[12], &transfTag) != TCL_OK) { + opserr << "WARNING invalid transfTag\n"; + return TCL_ERROR; + } + + bool isShear = false; + int shearTag = 0; + + if (argc > 13) { + for (int i = 13; i < argc; ++i) { + if (strcmp(argv[i], "-mass") == 0 && ++i < argc) { + if (Tcl_GetDouble(interp, argv[i], &massDens) != TCL_OK) { + opserr << "WARNING invalid massDens\n"; + opserr << "BeamWithHinges: " << tag << "\n"; + return TCL_ERROR; + } + } + + if (strcmp(argv[i], "-constHinge") == 0 && ++i < argc) { + if (Tcl_GetInt(interp, argv[i], &shearTag) != TCL_OK) { + opserr << "WARNING invalid constHinge tag\n"; + opserr << "BeamWithHinges: " << tag << "\n"; + return TCL_ERROR; + } + isShear = true; + } + + if (strcmp(argv[i], "-iter") == 0 && i + 2 < argc) { + if (Tcl_GetInt(interp, argv[++i], &max_iters) != TCL_OK) { + opserr << "WARNING invalid maxIters\n"; + opserr << "BeamWithHinges: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[++i], &tol) != TCL_OK) { + opserr << "WARNING invalid tolerance\n"; + opserr << "BeamWithHinges: " << tag << "\n"; + return TCL_ERROR; + } + } + } + } + + // Retrieve section I from the model builder + FrameSection *sectionI = builder->getTypedObject(secTagI); + if (sectionI == nullptr) + return TCL_ERROR; + + // Retrieve section J from the model builder + FrameSection *sectionJ = builder->getTypedObject(secTagJ); + if (sectionJ == nullptr) + return TCL_ERROR; + + + CrdTransf *theTransf = builder->getTypedObject(transfTag); + if (theTransf == nullptr) + return TCL_ERROR; + + Element *theElement = nullptr; + int numSections = 0; + SectionForceDeformation *sections[10]; + BeamIntegration *theBeamIntegr = nullptr; + + ElasticSection2d elastic(8, E, A, I); + + if (strcmp(argv[1], "beamWithHinges1") == 0) { + theBeamIntegr = new HingeMidpointBeamIntegration(lenI, lenJ); + + numSections = 4; + + sections[0] = sectionI; + sections[1] = &elastic; + sections[2] = &elastic; + sections[3] = sectionJ; + + } else if (strcmp(argv[1], "beamWithHinges2") == 0) { + theBeamIntegr = new HingeRadauTwoBeamIntegration(lenI, lenJ); + + numSections = 6; + sections[0] = sectionI; + sections[1] = sectionI; + sections[2] = &elastic; + sections[3] = &elastic; + sections[4] = sectionJ; + sections[5] = sectionJ; + + } else if (strcmp(argv[1], "beamWithHinges3") == 0 || + strcmp(argv[1], "beamWithHinges") == 0) { + theBeamIntegr = new HingeRadauBeamIntegration(lenI, lenJ); + + numSections = 6; + sections[0] = sectionI; + sections[1] = &elastic; + sections[2] = &elastic; + sections[3] = &elastic; + sections[4] = &elastic; + sections[5] = sectionJ; + + } else if (strcmp(argv[1], "beamWithHinges4") == 0) { + theBeamIntegr = new HingeEndpointBeamIntegration(lenI, lenJ); + + numSections = 4; + sections[0] = sectionI; + sections[1] = &elastic; + sections[2] = &elastic; + sections[3] = sectionJ; + } + + if (theBeamIntegr == nullptr) { + opserr << "Unknown element type: " << argv[1] << "\n"; + return TCL_ERROR; + } + + if (isShear) { + FrameSection *sectionL = builder->getTypedObject(shearTag); + if (sectionL == nullptr) + return TCL_ERROR; + + sections[numSections++] = sectionL; + } + + theElement = new ForceBeamColumn2d(tag, ndI, ndJ, numSections, + sections, + *theBeamIntegr, *theTransf, massDens, + max_iters, tol); + + delete theBeamIntegr; + + if (builder->getDomain()->addElement(theElement) == false) { + opserr << "WARNING could not add element to domain.\n"; + return TCL_ERROR; + } + } + + else if (NDM == 3 && NDF == 6) { + if (argc < 16) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element beamWithHinges tag? ndI? ndJ? secTagI? lenI? " + "secTagJ? lenJ? "; + opserr << "E? A? Iz? Iy? G? J? transfTag? <-shear shearLength?> <-mass " + "massDens?> <-iter maxIters tolerance>" + << "\n"; + return TCL_ERROR; + } + + int tag, ndI, ndJ, secTagI, secTagJ, transfTag; + double lenI, lenJ, E, A, Iz, Iy, G, J; + double massDens = 0.0; + int max_iters = 10; + double tol = 1.0e-10; + double shearLength = 1.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid beamWithHinges tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &ndI) != TCL_OK) { + opserr << "WARNING invalid ndI\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4], &ndJ) != TCL_OK) { + opserr << "WARNING invalid ndJ\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[5], &secTagI) != TCL_OK) { + opserr << "WARNING invalid secTagI\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &lenI) != TCL_OK) { + opserr << "WARNING invalid lenI\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[7], &secTagJ) != TCL_OK) { + opserr << "WARNING invalid ndJ\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[8], &lenJ) != TCL_OK) { + opserr << "WARNING invalid lenJ\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[9], &E) != TCL_OK) { + opserr << "WARNING invalid E\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10], &A) != TCL_OK) { + opserr << "WARNING invalid A\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[11], &Iz) != TCL_OK) { + opserr << "WARNING invalid Iz\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[12], &Iy) != TCL_OK) { + opserr << "WARNING invalid Iy\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[13], &G) != TCL_OK) { + opserr << "WARNING invalid G\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[14], &J) != TCL_OK) { + opserr << "WARNING invalid J\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[15], &transfTag) != TCL_OK) { + opserr << "WARNING invalid transfTag\n"; + return TCL_ERROR; + } + + + if (argc > 16) { + for (int i = 16; i < argc; ++i) { + if (strcmp(argv[i], "-mass") == 0 && ++i < argc) { + if (Tcl_GetDouble(interp, argv[i], &massDens) != TCL_OK) { + opserr << "WARNING invalid massDens\n"; + opserr << "BeamWithHinges: " << tag << "\n"; + return TCL_ERROR; + } + } + + if (strcmp(argv[i], "-shear") == 0 && ++i < argc) { + if (Tcl_GetDouble(interp, argv[i], &shearLength) != TCL_OK) { + opserr << "WARNING invalid shear\n"; + return TCL_ERROR; + } + } + + if (strcmp(argv[i], "-iter") == 0 && i + 2 < argc) { + if (Tcl_GetInt(interp, argv[++i], &max_iters) != TCL_OK) { + opserr << "WARNING invalid maxIters\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[++i], &tol) != TCL_OK) { + opserr << "WARNING invalid tolerance\n"; + return TCL_ERROR; + } + } + } + } + + // Retrieve section I from the model builder + SectionForceDeformation *sectionI = builder->getTypedObject(secTagI); + if (sectionI == nullptr) + return TCL_ERROR; + + // Retrieve section J from the model builder + SectionForceDeformation *sectionJ = builder->getTypedObject(secTagJ); + if (sectionJ == nullptr) + return TCL_ERROR; + + + CrdTransf *theTransf = builder->getTypedObject(transfTag); + if (theTransf == nullptr) + return TCL_ERROR; + + + Element *theElement = nullptr; + int numSections = 0; + SectionForceDeformation *sections[10]; + BeamIntegration *theBeamIntegr = nullptr; + + ElasticSection3d elastic(0, E, A, Iz, Iy, G, J); + + if (strcmp(argv[1], "beamWithHinges1") == 0) { + theBeamIntegr = new HingeMidpointBeamIntegration(lenI, lenJ); + + numSections = 4; + sections[0] = sectionI; + sections[1] = &elastic; + sections[2] = &elastic; + sections[3] = sectionJ; + + } else if (strcmp(argv[1], "beamWithHinges2") == 0) { + theBeamIntegr = new HingeRadauTwoBeamIntegration(lenI, lenJ); + + numSections = 6; + sections[0] = sectionI; + sections[1] = sectionI; + sections[2] = &elastic; + sections[3] = &elastic; + sections[4] = sectionJ; + sections[5] = sectionJ; + + } else if (strcmp(argv[1], "beamWithHinges3") == 0 || + strcmp(argv[1], "beamWithHinges") == 0) { + theBeamIntegr = new HingeRadauBeamIntegration(lenI, lenJ); + + numSections = 6; + sections[0] = sectionI; + sections[1] = &elastic; + sections[2] = &elastic; + sections[3] = &elastic; + sections[4] = &elastic; + sections[5] = sectionJ; + + } else if (strcmp(argv[1], "beamWithHinges4") == 0) { + theBeamIntegr = new HingeEndpointBeamIntegration(lenI, lenJ); + + numSections = 4; + sections[0] = sectionI; + sections[1] = &elastic; + sections[2] = &elastic; + sections[3] = sectionJ; + } + + if (theBeamIntegr == nullptr) { + opserr << "Unknown element type: " << argv[1] << "\n"; + return TCL_ERROR; + } + + // TODO fix shear for beamWithHinges + /* + if (isShear) { + SectionForceDeformation *sectionL = builder->getTypedObject(shearTag); + + if (sectionL == 0) { + opserr << "WARNING section L does not exist\n"; + opserr << "section: " << shearTag; + opserr << "\nBeamWithHinges: " << tag << "\n"; + return TCL_ERROR; + } + sections[numSections++] = sectionL; + } + */ + + theElement = new ForceBeamColumn3d(tag, ndI, ndJ, numSections, sections, + *theBeamIntegr, *theTransf, massDens, + max_iters, tol); + + delete theBeamIntegr; + + // Add to the domain + if (builder->getDomain()->addElement(theElement) == false) { + opserr << "WARNING could not add " + "element to domain "; + opserr << tag << "\n"; + return TCL_ERROR; + } + } + + else { + opserr << "ERROR -- model dimension: " << NDM + << " and nodal degrees of freedom: " << NDF + << " are incompatible for BeamWithHinges element" << "\n"; + return TCL_ERROR; + } + + return TCL_OK; +} diff --git a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp index 7f1706f893..839ae4d216 100644 --- a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp +++ b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp @@ -6,6 +6,8 @@ // https://xara.so //===----------------------------------------------------------------------===// // +// Written: Claudio M. Perez +// #pragma once #include #include @@ -17,7 +19,9 @@ #include #include #include -#include +#include +#include +#include namespace OpenSees { @@ -52,16 +56,26 @@ class FrameTransformBuilder : public TaggedObject { int tag = this->getTag(); if (strstr(name, "Linear") != nullptr) return new LinearFrameTransf (tag, vz, offset_array, offset_flags); - - else if (strstr(name, "Corot") != nullptr) { + + else if (strcmp(name, "Corotational") == 0) { if constexpr (ndf == 6) return new SouzaFrameTransf (tag, vz, offset_array, offset_flags); + else + return nullptr; } + else if (strstr(name, "PDelta") != nullptr) return new PDeltaFrameTransf (tag, vz, offset_array, offset_flags); - else if (strcmp(name, "Isometric") == 0 || strstr(name, "Rigid") != nullptr) - return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); + else if (strcmp(name, "Corotational02") == 0 || strcmp(name, "Isometric") == 0 || strstr(name, "Rigid") != nullptr) + { + if (getenv("Battini")) + return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); + else if (getenv("Crisfield")) + return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); + else + return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); + } return nullptr; } @@ -93,4 +107,5 @@ class FrameTransformBuilder : public TaggedObject { std::map offsets; int offset_flags; }; -} \ No newline at end of file + +} // namespace OpenSees \ No newline at end of file From c19d2e888e3554a4246fc8dd808d5c8932388190 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 4 Jul 2025 18:26:07 -0700 Subject: [PATCH 144/261] add check for bad transform --- .../Frame/Isometry/CrisfieldIsometry.h | 3 +- .../commands/modeling/element/frames.cpp | 29 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h index 615c0b3ae2..428d47ea53 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h @@ -157,7 +157,8 @@ class CrisfieldIsometry : public AlignedIsometry { Vector3D r1 { Rbar(0,0), Rbar(1,0), Rbar(2,0) }; // Clamp to avoid NaNs from acos - double dot = std::clamp(r1.dot(e[0]), -1.0, 1.0); + // double dot = std::clamp(r1.dot(e[0]), -1.0, 1.0); + double dot = std::max(-1.0, std::min(1.0, r1.dot(e[0]))); if (std::fabs(dot - 1.0) < ktol) { // Rbar already aligned v.zero(); diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index d99c42ea94..d2c597c736 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -104,6 +104,29 @@ struct Options { extern BeamIntegration* GetBeamIntegration(TCL_Char* type, int); extern BeamIntegrationRule* GetHingeStencil(int argc, TCL_Char ** const argv); +static inline int +CheckTransformation(Domain& domain, int iNode, int jNode, CrdTransf& transform) +{ + Node* ni = domain.getNode(iNode); + Node* nj = domain.getNode(jNode); + if (ni == nullptr || nj == nullptr) { + opserr << OpenSees::PromptValueError << "nodes not found with tags " + << iNode << " and " << jNode + << OpenSees::SignalMessageEnd; + } + + if (transform.initialize(ni, nj) != 0) { + opserr << OpenSees::PromptValueError + << "transformation with tag " << transform.getTag() + << " could not be initialized with nodes " + << iNode << " and " << jNode + << "; check orientation" + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } + return TCL_OK; +} + template static Element* @@ -141,7 +164,7 @@ CreateFrame(BasicModelBuilder& builder, } // Finalize the coordinate transform - Transform* theTransf = builder.getTypedObject(transfTag); + CrdTransf* theTransf = builder.getTypedObject(transfTag); if (theTransf == nullptr) { opserr << OpenSees::PromptValueError << "transformation not found with tag " << transfTag << "\n"; return nullptr; @@ -209,6 +232,10 @@ CreateFrame(BasicModelBuilder& builder, // // ndm == 3 // + + if (CheckTransformation(*builder.getDomain(), nodev[0], nodev[1], *theTransf) != TCL_OK) + return nullptr; + if (strstr(name, "Frame") != nullptr) { if (strstr(name, "Exact") == nullptr) { std::array nodes {nodev[0], nodev[1]}; From fbb0183ed6572b6e967f2e0804c3bed1ac783cd0 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 4 Jul 2025 18:53:05 -0700 Subject: [PATCH 145/261] clean blas --- SRC/matrix/MatrixND.h | 7 ------- SRC/matrix/VectorND.h | 5 +---- SRC/matrix/VectorND.tpp | 13 ++++++------- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index 1dfd7e5567..4fabb2cd74 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -39,7 +39,6 @@ #include "VectorND.h" #include "Matrix.h" #include "Vector.h" -#include "routines/SY3.h" #if __cplusplus < 202000L # define consteval @@ -62,12 +61,6 @@ struct MatrixND { operator const Matrix() const { return Matrix(&values[0][0], NR, NC);} - int symeig(VectorND& vals) requires(NR == NC == 3) { - double work[3][3]; - cmx_eigSY3(values, work, vals.values); - return 0; - } - consteval void zero(); constexpr MatrixND transpose() const; diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index 5bc38a621d..2a20e3dd24 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -6,10 +6,6 @@ // https://xara.so //===----------------------------------------------------------------------===// // -// Objectives: -// - little to no overhead above C-style arrays -// - value semantics; objects do not decay to pointers; -// // This code is influenced by the following sources // list initialization: // - https://stackoverflow.com/questions/42068882/list-initialization-for-a-matrix-class @@ -33,6 +29,7 @@ #ifndef VectorND_H #define VectorND_H #include +#include #include #include diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index 99c16161a9..ac9a2182b0 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -19,8 +19,8 @@ VectorND::assemble(const VectorND &v, double fact) { static_assert((ir >= 0) && ((ir + nr - 1) < N)); - for (int j=0; j @@ -37,8 +37,8 @@ VectorND::insert(const VectorND &v, double fact) { static_assert((ir >= 0) && ((ir + nr - 1) < N)); - for (int j=0; j::addVector(const T thisFact, const Vector &other, const T otherFac } } - // successfull return 0; } @@ -185,7 +184,7 @@ VectorND::addVector(const T thisFact, const VectorND &other, const T oth return 0; } - +#ifdef VECTOR_BLAS template template inline int @@ -240,7 +239,7 @@ VectorND::addMatrixTransposeVector(double thisFact, const MatrixND inline int From 7eefd293e2c0b2be6984c83907004b2d0cda4413 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 4 Jul 2025 19:03:57 -0700 Subject: [PATCH 146/261] clean --- SRC/matrix/VectorND.tpp | 1 - 1 file changed, 1 deletion(-) diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index ac9a2182b0..4559844f46 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -8,7 +8,6 @@ // #include #include "VectorND.h" -#include "blasdecl.h" namespace OpenSees { From cfb768d944f65f0ac9a5aa65c174fe2c65c3022f Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 4 Jul 2025 19:11:35 -0700 Subject: [PATCH 147/261] clean --- SRC/matrix/VectorND.tpp | 322 ---------------------------------------- 1 file changed, 322 deletions(-) diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index 4559844f46..6bfe26e162 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -61,326 +61,4 @@ VectorND::extract(int a) noexcept return v; } - -template -int -VectorND::addVector(const T thisFact, const Vector &other, const T otherFact) noexcept -{ - if (otherFact == 0.0 && thisFact == 1.0) - return 0; - - else if (thisFact == 1.0) { - // want: this += other * otherFact - double *dataPtr = values; - double *otherDataPtr = other.theData; - if (otherFact == 1.0) { - // no point doing a multiplication if otherFact == 1.0 - for (int i=0; i -int -VectorND::addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept -{ - if (otherFact == 0.0 && thisFact == 1.0) - return 0; - - else if (thisFact == 1.0) { - // want: this += other * otherFact - double *dataPtr = values; - const double * otherDataPtr = other.values; - if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0 - for (int i=0; i -template -inline int -VectorND::addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact) -{ - // check the sizes are compatable - assert(NC == v.sz); - - // see if quick return - if (thisFact == 1.0 && otherFact == 0.0) - return 0; - - else { - int incr = 1, - i = N, - n = NC; - DGEMV("N", &i, &n, - &otherFact, - &m.values[0][0], &i, - v.theData, &incr, - &thisFact, - values, - &incr); - - return 0; - } -} - - -template -template -inline int -VectorND::addMatrixTransposeVector(double thisFact, const MatrixND &m, const Vector &v, double otherFact) -{ - // check the sizes are compatable - assert(NR == v.sz); - - - if (thisFact == 1.0 && otherFact == 0.0) - return 0; - - else { - int incr = 1, - i = NR, - n = N; - DGEMV("T", &i, &n, - &otherFact, - &m.values[0][0], &i, - v.theData, &incr, - &thisFact, - values, &incr); - return 0; - } -} -#endif // VECTOR_BLAS - -template -inline int -VectorND::addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact) -{ - // check the sizes are compatable - assert(N == m.noRows()); - assert(m.noCols() == v.sz); - - // see if quick return - if (thisFact == 1.0 && otherFact == 0.0) - return 0; - -#ifdef VECTOR_BLAS - else if (v.sz > 10) { - int incr = 1, - i = m.numRows, - n = m.numCols; - return - DGEMV("N", &i, &n, - &otherFact, - m.data, &i, - v.theData, &incr, - &thisFact, - values, &incr); - } -#endif - - else if (thisFact == 1.0) { - - // want: this += m * v * otherFact - if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0 - int otherSize = v.sz; - double *matrixDataPtr = m.data; - const double *otherDataPtr = v.theData; - for (int i=0; i Date: Fri, 4 Jul 2025 19:12:15 -0700 Subject: [PATCH 148/261] fix compile --- SRC/matrix/VectorND.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index 2a20e3dd24..90b4a19adf 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -70,24 +70,6 @@ struct VectorND { VectorND extract(int a) noexcept; - int - addVector(const T thisFact, const Vector &other, const T otherFact) noexcept; - - int - addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept; - - template - inline int - addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact); - - template - inline int - addMatrixTransposeVector(double thisFact, const MatrixND &m, - const Vector &v, double otherFact); - - inline int - addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact); - consteval int size() const { return N; From 4b588aa98e0072f4b59b2ebee25f3bf27c6c6992 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 4 Jul 2025 19:19:58 -0700 Subject: [PATCH 149/261] fix compile --- SRC/matrix/Versor.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SRC/matrix/Versor.h b/SRC/matrix/Versor.h index e4cd495181..241a792463 100644 --- a/SRC/matrix/Versor.h +++ b/SRC/matrix/Versor.h @@ -10,14 +10,14 @@ // #pragma once #include -#include +#include #if 0 namespace OpenSees { #endif struct Versor { - Vector3D vector; + OpenSees::Vector3D vector; double scalar; template From bf0559b8d7f7ca20d06fa909f03138a3243958e3 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 4 Jul 2025 19:20:46 -0700 Subject: [PATCH 150/261] fix compile --- SRC/matrix/Versor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/matrix/Versor.h b/SRC/matrix/Versor.h index 241a792463..bac1d1c99f 100644 --- a/SRC/matrix/Versor.h +++ b/SRC/matrix/Versor.h @@ -17,7 +17,7 @@ namespace OpenSees { #endif struct Versor { - OpenSees::Vector3D vector; + Vector3D vector; double scalar; template From 4709e4e5b77b5342981f95fb869197f8a8b8625e Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 4 Jul 2025 19:51:53 -0700 Subject: [PATCH 151/261] remove dead code --- .../Frame/EuclidFrameTransf.h | 5 -- .../Frame/EuclidFrameTransf.tpp | 27 ++--------- .../Frame/Isometry/CrisfieldIsometry.h | 4 -- .../Frame/LinearFrameTransf.tpp | 47 ------------------- 4 files changed, 3 insertions(+), 80 deletions(-) diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h index 0ac9b6b451..b70fcf7587 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.h +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -71,11 +71,6 @@ class EuclidFrameTransf: public FrameTransform VectorND pushResponse(VectorND&pl) final; MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; -#if 0 - // method used to rotate consistent mass matrix - const Matrix &getGlobalMatrixFromLocal(const Matrix &local); -#endif - // Sensitivity // bool isShapeSensitivity() final; diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 75d08aa71e..87ea11c0ac 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -206,23 +206,9 @@ template Vector3D EuclidFrameTransf::getNodePosition(int node) { -#if 0 - const Vector& ug = nodes[node]->getTrialDisp(); - - Vector3D u; - for (int i=0; i<3; i++) - u[i] = ug[i]; - - if (offsets != nullptr) [[unlikely]] { - u.addVector(1.0, (*offsets)[node], -1.0); - u.addVector(1.0, nodes[node]->getTrialRotation().rotate((*offsets)[node]), 1.0); - } - - u.addVector(1.0, basis.getPosition(), -1.0); -#else Vector3D u = this->pullPosition<&Node::getTrialDisp>(node) - basis.getPosition(); -#endif + u += basis.getRotationDelta()^(nodes[node]->getCrds()); return u; @@ -329,10 +315,6 @@ EuclidFrameTransf::pushResponse(VectorND&p) } } -#if 0 - MatrixND A = getProjection(); - pa = A^pa; -#else // 2.1) Sum of moments: m = sum_i mi + sum_i (xi x ni) Vector3D m{}; for (int i=0; i::pushResponse(VectorND&p) // 2.2) Adjust for (int i=0; i(i*ndf, basis.getRotationGradient(i)^m, -1.0); -#endif + // 3,4) Rotate and joint offsets @@ -406,10 +388,7 @@ EuclidFrameTransf::pushResponse(MatrixND&kb, VectorND Ap = A^p; -#if 0 - p = A^p; -#else Kb.zero(); VectorND<12> qwx{}; for (int i=0; i::pushResponse(MatrixND&kb, Kb.assemble(Kw.template extract<6,12, 6,12>(), ndf, ndf, 1.0); Kl.addMatrixProduct(Kb, A, 1.0); // p = A^p; -#endif + // // Kl += -W'*Pn'*A diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h index 428d47ea53..c122da8460 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h @@ -76,11 +76,7 @@ class CrisfieldIsometry : public AlignedIsometry { A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; - #if 0 - auto de3 = this->getLMatrix(r3, r1, e1, A).transpose(); - #else auto de3 = this->getBasisVariation(r3, r1, e1, v, A); - #endif MatrixND<3,12> de1{}; de1.template insert<0,0>(A, -1.0); diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index 2b5ba19e9a..baf2828e3d 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -568,53 +568,6 @@ LinearFrameTransf::getBasicDisplFixedGrad() // Form ug // // TODO(sensitivity) -#if 0 - VectorND ug; - for (int i = 0; i < nn; i++) { - const Vector& u = nodes[i]->getTrialDisp(); - for (int j = 0; j < ndf; j++) { - ug[i*ndf+j] = u(j); - } - } - - if (u_init[0] != 0) { - for (int j = 0; j < ndf; j++) - ug[j] -= (*u_init[0])[j]; - } - - if (u_init[nn-1] != 0) { - for (int j = 0; j < ndf; j++) - ug[j + 6] -= (*u_init[nn-1])[j]; - } - - // - // dub += (T_{bl}' T_{lg} + T_{bl} T_{lg}') * ug - // - int dv = 0; // TODO(sensitivity) - - // TODO: Sensitivity - int di = nodes[0]->getCrdsSensitivity(); - int dj = nodes[1]->getCrdsSensitivity(); - - - // TODO(sensitivity) - // Matrix3D dR = FrameOrientationGradient(xi, xj, vz, di, dj, dv); - // dub = getBasic(ug, 1/L); - - // - // - VectorND ul = LinearFrameTransf::pullConstant(ug, R, offsets); - // - dub[0] += 0; - double dL = this->getLengthGrad(); - double doneOverL = -dL/(L*L); - double tmp = doneOverL * (ul[1] - ul[7]); - dub[1] += tmp; - dub[2] += tmp; - tmp = doneOverL * (ul[8] - ul[2]); - dub[3] += tmp; - dub[4] += tmp; -#endif return wrapper; } From 042cd50732866a304cd582116daa3d5c179c9970 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 4 Jul 2025 19:56:38 -0700 Subject: [PATCH 152/261] implement revertToLastCommit for finite rotations --- SRC/domain/node/Node.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/SRC/domain/node/Node.cpp b/SRC/domain/node/Node.cpp index 2062b8c0e6..2d5854cf2c 100644 --- a/SRC/domain/node/Node.cpp +++ b/SRC/domain/node/Node.cpp @@ -490,7 +490,7 @@ Node::~Node() delete trialAccel; if (rotation != nullptr) - delete rotation; + delete[] rotation; if (incrDisp != 0) @@ -708,13 +708,12 @@ Versor Node::getTrialRotation() { if (rotation == nullptr) [[unlikely]] { - if (this->getNumberDOF() < 6) - return Versor(); - else - rotation = new Versor{{0.0, 0.0, 0.0}, 1.0}; + rotation = new Versor[2]; + rotation[0] = Versor{{0.0, 0.0, 0.0}, 1.0}; + rotation[1] = Versor{{0.0, 0.0, 0.0}, 1.0}; } - return *rotation; + return rotation[1]; } int @@ -839,7 +838,7 @@ Node::incrTrialDisp(const Vector &incrDispl) } if (rotation != nullptr && this->getNumberDOF() >= 6) - (*rotation) = (*rotation)*Versor::from_vector(&disp[3*numberDOF+3]); + rotation[1] = rotation[1]*Versor::from_vector(&disp[3*numberDOF+3]); // create a copy if no trial exists and add committed @@ -1114,6 +1113,8 @@ Node::commitState() accel[i+numberDOF] = accel[i]; } + if (rotation != nullptr) + rotation[0] = rotation[1]; // if we get here we are done return 0; } @@ -1144,6 +1145,8 @@ Node::revertToLastCommit() accel[i] = accel[numberDOF+i]; } + if (rotation != nullptr) + rotation[1] = rotation[0]; // if we get here we are done return 0; } @@ -1174,8 +1177,10 @@ Node::revertToStart() (*unbalLoad) *= 0; - if (rotation != nullptr) - *rotation = Versor{{0.0, 0.0, 0.0}, 1.0}; + if (rotation != nullptr) { + rotation[0] = Versor{{0.0, 0.0, 0.0}, 1.0}; + rotation[1] = rotation[0]; + } // AddingSensitivity: BEGIN ///////////////////////////////// From 7bfa8118e0d9d49f1f67dc6615d9a673fccef61c Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 4 Jul 2025 20:06:26 -0700 Subject: [PATCH 153/261] remove some files --- .../Frame/Isometry/SphericalIsometry.h | 132 ------------------ SRC/matrix/Versor.h | 6 - SRC/runtime/commands/modeling/geomTransf.cpp | 27 +++- 3 files changed, 20 insertions(+), 145 deletions(-) delete mode 100644 SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h diff --git a/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h b/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h deleted file mode 100644 index 93b5fa2c16..0000000000 --- a/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h +++ /dev/null @@ -1,132 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//----------------------------------------------------------------------------// -// -// Please cite the following resource in any derivative works: -// -// [1] Perez, C.M., and Filippou F.C.. (2024) -// "On Nonlinear Geometric Transformations of Finite Elements" -// Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// - -// -// Written: Claudio M. Perez, -// Filip C. Filippou -// University of California, Berkeley -// -// Developed with FEDEASLab [2]. -// -// References: -// -// [2] Filippou, F.C. (1998) -// "FEDEASLab: Finite Elements for Design Evaluation and Analysis of Structures" -// -#pragma once -#include -#include -#include -#include -#include "EuclidIsometry.h" - -template -class SphericalIsometry : public Isometry { -public: - SphericalIsometry(std::array& nodes, const Vector3D& vecxz); - - int initialize() final; - int update() final; - - double getLength() const final; - Matrix3D getRotation() const final; - Vector3D getPosition() final; - Vector3D getPositionVariation(int ndf, double* du) final; - Vector3D getRotationVariation(int ndf, double* du) final; - Matrix3D getRotationDelta() final; - MatrixND<3,6> getRotationGradient(int node) final; -private: - double L; - double Ln; - std::array nodes; - Vector3D vz; // vector in the x-z plane - Vector3D dX; // deformed length vector - Vector3D c[2]; // current position of the center - Matrix3D R[2]; // rotation matrices at the current and previous time step - Vector3D Xc; // center of the isometry -}; - - -template -SphericalIsometry::SphericalIsometry(std::array& nodes, const Vector3D& vecxz) -: nodes(nodes), vz(vecxz), Xc{}, - c{}, R{}, dX{}, Ln(0.0), L(0.0), - offsets(nullptr), offset_flags(0), ic(0) -{ - -} - - -template -int -SphericalIsometry::update() { - - Vector3D e1 = dX; - { - // - // Update state - // - const Vector& uI = nodes[ 0]->getTrialDisp(); - const Vector& uJ = nodes[nn-1]->getTrialDisp(); - for (int k = 0; k < 3; k++) - e1[k] += uJ(k) - uI(k); - - if (offsets != nullptr) [[unlikely]] { - e1.addVector(1.0, (*offsets)[ 0], 1.0); - e1.addVector(1.0, nodes[0]->getTrialRotation().rotate((*offsets)[0]), -1.0); - e1.addVector(1.0, (*offsets)[nn-1], -1.0); - e1.addVector(1.0, nodes[nn-1]->getTrialRotation().rotate((*offsets)[nn-1]), 1.0); - } - - // Calculate the deformed length - Ln = e1.norm(); - - if (Ln == 0.0) [[unlikely]] { - opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; - return -2; - } - - e1 /= Ln; - } - - { -#if 1 // TRIAD==R2 - constexpr static Vector3D D2 {0,1,0}; - const Vector3D E2 = R[init]*D2; - Vector3D e2 = MatrixFromVersor(nodes[0]->getTrialRotation())*E2; //*R[init]; - e2.addVector(0.5, MatrixFromVersor(nodes[1]->getTrialRotation())*E2, 0.5); - n = e2[0]/e2[1]; - Vector3D e3 = e1.cross(e2); - e3 /= e3.norm(); - - e2 = e3.cross(e1); - - for (int i = 0; i < 3; i++) { - R[pres](i,0) = e1[i]; - R[pres](i,1) = e2[i]; - R[pres](i,2) = e3[i]; - } - Vector3D e2 = vz.cross(e1); -#endif - } - - Vector3D uc = nodes[ic]->getTrialDisp(); - if (offsets != nullptr) { - uc.addVector(1.0, (*offsets)[ic], -1.0); - uc.addVector(1.0, nodes[ic]->getTrialRotation().rotate((*offsets)[ic]), 1.0); - } - Vector3D X = nodes[ic]->getCrds(); - c[pres] = R[pres]^(X + uc); - return 0; -} \ No newline at end of file diff --git a/SRC/matrix/Versor.h b/SRC/matrix/Versor.h index bac1d1c99f..d70b18fbd4 100644 --- a/SRC/matrix/Versor.h +++ b/SRC/matrix/Versor.h @@ -20,12 +20,6 @@ struct Versor { Vector3D vector; double scalar; - template - inline Vec3T - rotate(const Vec3T& u) const { - return u + 2.0 * vector.cross( scalar*u + vector.cross(u) ); - } - inline Versor conjugate() const { Versor c; diff --git a/SRC/runtime/commands/modeling/geomTransf.cpp b/SRC/runtime/commands/modeling/geomTransf.cpp index 9cf79d8292..12c2726360 100644 --- a/SRC/runtime/commands/modeling/geomTransf.cpp +++ b/SRC/runtime/commands/modeling/geomTransf.cpp @@ -1,5 +1,9 @@ //===----------------------------------------------------------------------===// // +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// // xara // //===----------------------------------------------------------------------===// @@ -8,13 +12,14 @@ // // Description: Geometric transformation command // -// cmp +// Written: cmp // #include #include #include #include #include +#include #include #include @@ -33,15 +38,18 @@ using namespace OpenSees; int -TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, int argc, - const char ** const argv) +TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, + Tcl_Size argc, + const char ** const argv) { assert(clientData != nullptr); BasicModelBuilder *builder = static_cast(clientData); // Make sure there is a minimum number of arguments if (argc < 3) { - opserr << OpenSees::PromptValueError << "insufficient number of arguments\n"; + opserr << OpenSees::PromptValueError + << "insufficient number of arguments" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -54,7 +62,8 @@ TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, int ar const char *name = argv[1]; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { opserr << OpenSees::PromptValueError - << "invalid tag\n"; + << "invalid tag" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -71,7 +80,9 @@ TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, int ar for (int i = 0; i < ndm; ++i) { if (argi == argc || Tcl_GetDouble(interp, argv[argi++], &transform.offsets[1][i]) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid offset at end I\n"; + opserr << OpenSees::PromptValueError + << "invalid offset at end I" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } } @@ -80,7 +91,9 @@ TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, int ar for (int i = 0; i < ndm; ++i) { if (argi == argc || Tcl_GetDouble(interp, argv[argi++], &transform.offsets[2][i]) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid offset at end J\n"; + opserr << OpenSees::PromptValueError + << "invalid offset at end J" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } } From e3f2ed10f523e9687b001d9dd3ec04ebdc5399e2 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 4 Jul 2025 20:09:09 -0700 Subject: [PATCH 154/261] remove more files --- .../Frame/Isometry/RankineIsometry.h | 216 ------------------ .../Frame/Isometry/RankineIsometry.tpp | 18 -- 2 files changed, 234 deletions(-) delete mode 100644 SRC/coordTransformation/Frame/Isometry/RankineIsometry.h delete mode 100644 SRC/coordTransformation/Frame/Isometry/RankineIsometry.tpp diff --git a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h b/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h deleted file mode 100644 index 72132530f1..0000000000 --- a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.h +++ /dev/null @@ -1,216 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures -// https://fedeas.net -// -//----------------------------------------------------------------------------// -// -// Please cite the following resource in any derivative works: -// -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; -// https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// -#include -#include -#include -#include -#include -#include "EuclidIsometry.h" - - -namespace OpenSees { - -template -class RankineIsometry : public AlignedIsometry -{ -public: - RankineIsometry(std::array& nodes, const Vector3D& vecxz) - : nodes{nodes}, vz(vecxz), Xc{}, c{}, R{} - { - } - - void - setOffsets(std::array* offsets) { - this->offsets = offsets; - } - - virtual int - initialize() { - - for (int i=0; igetTrialRotation(); - - const Vector &XI = nodes[ 0]->getCrds(); - const Vector &XJ = nodes[nn-1]->getCrds(); - - for (int i=0; i<3; i++) - dX[i] = XJ[i] - XI[i]; - - L = dX.norm(); - Ln = L; - Vector3D e1 = dX/L; - - // - Vector3D e2 = vz.cross(e1); - - const double ynorm = e2.norm(); - - if (ynorm == 0.0) - return -1; - - e2 /= ynorm; - - Vector3D e3 = e1.cross(e2); - - e2 = e3.cross(e1); - - for (int i = 0; i < 3; i++) { - R[init](i,0) = e1[i]; - R[init](i,1) = e2[i]; - R[init](i,2) = e3[i]; - } - - Xc = nodes[ic]->getCrds(); - c[init] = R[init]^(Xc); - - this->update(); - return 0; - } - - int - update() final { - - Vector3D e1 = dX; - { - // - // Update state - // - { - const Vector& uI = nodes[ 0]->getTrialDisp(); - const Vector& uJ = nodes[nn-1]->getTrialDisp(); - for (int k = 0; k < 3; k++) - e1[k] += uJ(k) - uI(k); - - if (offsets != nullptr) [[unlikely]] { - e1.addVector(1.0, (*offsets)[ 0], 1.0); - e1.addVector(1.0, nodes[0]->getTrialRotation().rotate((*offsets)[0]), -1.0); - e1.addVector(1.0, (*offsets)[nn-1], -1.0); - e1.addVector(1.0, nodes[nn-1]->getTrialRotation().rotate((*offsets)[nn-1]), 1.0); - } - - // Calculate the deformed length - Ln = e1.norm(); - - if (Ln == 0.0) [[unlikely]] { - opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; - return -2; - } - - e1 /= Ln; - } - } - - { - constexpr static Vector3D D2 {0,1,0}; - const Vector3D E2 = R[init]*D2; - Vector3D e2 = MatrixFromVersor(nodes[0]->getTrialRotation())*E2; //*R[init]; - e2.addVector(0.5, MatrixFromVersor(nodes[1]->getTrialRotation())*E2, 0.5); - n = e2[0]/e2[1]; - Vector3D e3 = e1.cross(e2); - e3 /= e3.norm(); - - e2 = e3.cross(e1); - - for (int i = 0; i < 3; i++) { - R[pres](i,0) = e1[i]; - R[pres](i,1) = e2[i]; - R[pres](i,2) = e3[i]; - } - } - - Vector3D uc = nodes[ic]->getTrialDisp(); - if (offsets != nullptr) { - uc.addVector(1.0, (*offsets)[ic], -1.0); - uc.addVector(1.0, nodes[ic]->getTrialRotation().rotate((*offsets)[ic]), 1.0); - } - Vector3D X = nodes[ic]->getCrds(); - c[pres] = R[pres]^(X + uc); - return 0; - }; - - virtual MatrixND<3,6> - getRotationGradient(int node) { - MatrixND<3,6> Gb{}; - - constexpr Vector3D axis{1, 0, 0}; - constexpr Matrix3D ix = Hat(axis); - constexpr Matrix3D ioi = axis.bun(axis); - - Gb.template insert<0, 3>(ioi, 0.5); - if (node == 0) - Gb.template insert<0,0>(ix, -1/Ln); - else if (node == nn-1) - Gb.template insert<0,0>(ix, 1/Ln); - - Gb(0,2) = (node == 0? 1.0 : -1.0)*n; - return Gb; - } - - virtual double - getLength() const override { - return Ln; - } - - virtual Matrix3D - getRotation() const override { - return R[pres]; - } - - virtual Matrix3D - getRotationDelta() { - return R[pres] - R[init]; - } - - Vector3D - getLocation() { - return c[pres]; - } - - virtual Vector3D - getPosition() { - // Return Delta c - Vector3D X = nodes[ic]->getCrds(); - Vector3D Dc = c[pres] - (R[init]^X) ; // (R[pres]^c[init]); - return Dc; - } - - virtual Vector3D - getPositionVariation(int ndf, double* du) { - return Vector3D {du[ndf*ic+0], du[ndf*ic+1], du[ndf*ic+2]}; - } - -private: - constexpr static int ic = 0; // std::floor(0.5*(nn+1)); - enum { pres, prev, init}; - double L, Ln; - Vector3D vz, dX, Xc; - Matrix3D R[3]; - Vector3D c[3]; - Matrix3D dR; - std::array& nodes; - std::array* offsets = nullptr; // offsets - - double n = 0, - n11 = 1, - n12 = 0, - n21 = 0, - n22 = 1; -}; -} // namespace OpenSees \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.tpp b/SRC/coordTransformation/Frame/Isometry/RankineIsometry.tpp deleted file mode 100644 index 1017532ab9..0000000000 --- a/SRC/coordTransformation/Frame/Isometry/RankineIsometry.tpp +++ /dev/null @@ -1,18 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures -// -//----------------------------------------------------------------------------// -// -// Please cite the following resource in any derivative works: -// -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; -// https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// From cbf9fcfe2e6dab51e5a6bbd6e61ac663818a71b5 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:36:23 -0700 Subject: [PATCH 155/261] cleaning up --- .../Frame/BasicFrameTransf.h | 24 ++- .../Frame/BasicFrameTransf.tpp | 39 ++-- .../Frame/EuclidFrameTransf.h | 11 +- .../Frame/EuclidFrameTransf.tpp | 80 ++++--- .../Frame/Isometry/CrisfieldIsometry.h | 201 ++++++++++-------- .../Frame/Isometry/EuclidIsometry.h | 50 ----- .../Frame/Isometry/RankinIsometry.h | 45 +++- .../Frame/Isometry/SphericalIsometry.h | 132 ++++++++++++ .../Frame/LinearFrameTransf.h | 11 +- .../Frame/LinearFrameTransf.tpp | 80 ++++++- .../Frame/PDeltaFrameTransf3d.h | 9 +- .../Frame/PDeltaFrameTransf3d.tpp | 14 +- .../Frame/SouzaFrameTransf.h | 15 +- .../Frame/SouzaFrameTransf.tpp | 62 +++--- SRC/matrix/AxisAngle.h | 82 +++++++ SRC/matrix/GroupSO3.h | 136 ++---------- SRC/matrix/Versor.h | 176 ++++++++++----- .../commands/modeling/element/frames.cpp | 15 +- SRC/runtime/commands/modeling/geomTransf.cpp | 27 +-- .../transform/FrameTransformBuilder.hpp | 4 +- 20 files changed, 762 insertions(+), 451 deletions(-) create mode 100644 SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h create mode 100644 SRC/matrix/AxisAngle.h diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.h b/SRC/coordTransformation/Frame/BasicFrameTransf.h index 7d66a14be2..140a2e0e3f 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.h +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.h @@ -26,6 +26,7 @@ #include #include +#include class Vector; class Matrix; @@ -92,8 +93,10 @@ class BasicFrameTransf3d: public CrdTransf FrameTransform<2,ndf> &t; + LinearFrameTransf<2,ndf> linear; private: + using Operation = typename FrameTransform<2,ndf>::Operation; constexpr static int NBV = 6; constexpr static int NDF = ndf; enum : int { @@ -103,18 +106,31 @@ class BasicFrameTransf3d: public CrdTransf imx = -12, // 3 imy = 3, // 4 imz = 1, // 5 + iwx = 6, // 6 jnx = 0, // 6 jny = -12, // 7 jnz = -12, // 8 jmx = 5, // 9 jmy = 4, // 10 jmz = 2, // 11 + jwx = 7, }; - constexpr static int iq[] = { - inx, iny, inz, imx, imy, imz, - jnx, jny, jnz, jmx, jmy, jmz - }; + + static constexpr std::array set_indices() { + if constexpr (ndf-6 > 0) { + return { + inx, iny, inz, imx, imy, imz, iwx, + jnx, jny, jnz, jmx, jmy, jmz, jwx + }; + } else { + return { + inx, iny, inz, imx, imy, imz, + jnx, jny, jnz, jmx, jmy, jmz + }; + } + } + static constexpr auto iq = set_indices(); }; } // namespace OpenSees diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index 1a5c1cba9c..8a7e662e2f 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -25,7 +25,8 @@ namespace OpenSees { template BasicFrameTransf3d::BasicFrameTransf3d(FrameTransform<2,ndf> *t) : CrdTransf(t->getTag(), 0), - t(*t) + t(*t), + linear(t->getTag(), t->getNormalVector(), t->getRigidOffsets()) { } @@ -70,6 +71,7 @@ int BasicFrameTransf3d::initialize(Node *i, Node *j) { std::array nodes = {i, j}; + linear.initialize(nodes); return t.initialize(nodes); } @@ -110,7 +112,7 @@ BasicFrameTransf3d::getBasicTrialDisp() static Vector wrapper(ub); Vector3D wi = t.getNodeRotationLogarithm(0), wj = t.getNodeRotationLogarithm(1); - ub[0] = t.getNodePosition(1)[0]; + ub[0] = t.getDeformedLength() - t.getInitialLength(); // t.getNodePosition(1)[0]; ub[1] = wi[2]; ub[2] = wj[2]; ub[3] = wi[1]; @@ -184,7 +186,7 @@ BasicFrameTransf3d::getGlobalResistingForce(const Vector &q_pres, const Vec static Vector wrapper(pg); pg = t.pushResponse(pl); - pg += t.pushConstant(pf); + pg += linear.pushResponse(pf); return wrapper; } @@ -193,26 +195,31 @@ template const Matrix & BasicFrameTransf3d::getGlobalStiffMatrix(const Matrix &kb, const Vector &q_pres) { + static constexpr int nwm = ndf - 6; // Number of warping DOFs VectorND pl{}; - pl[0*NDF+0] = -q_pres[jnx]; // Ni - pl[0*NDF+3] = -q_pres[jmx]; // Ti pl[0*NDF+4] = q_pres[imy]; pl[0*NDF+5] = q_pres[imz]; pl[1*NDF+0] = q_pres[jnx]; // Nj pl[1*NDF+3] = q_pres[jmx]; // Tj pl[1*NDF+4] = q_pres[jmy]; pl[1*NDF+5] = q_pres[jmz]; - + for (int i=0; i kl; + static MatrixND<2*NDF,2*NDF> kl; kl.zero(); for (int i=0; i= NBV) continue; - for (int j=0; j= NBV) @@ -223,14 +230,20 @@ BasicFrameTransf3d::getGlobalStiffMatrix(const Matrix &kb, const Vector &q_ } for (int i = 0; i < 2*NDF; i++) { - kl(0*NDF+0, i) = kl(i, 0*NDF+0) = i==0? kl(NDF+0, NDF+0): (i==3? kl(NDF+0, NDF+3) : -kl( NDF+0, i)); - kl(0*NDF+3, i) = kl(i, 0*NDF+3) = i==0? kl(NDF+3, NDF+0): (i==3? kl(NDF+3, NDF+3) : -kl( NDF+3, i)); + kl(0*NDF+0, i) = kl(i, 0*NDF+0) = i==0? kl(NDF+0, NDF+0): (i==3? kl(NDF+0, NDF+3) : -kl( NDF+0, i)); + kl(0*NDF+3, i) = kl(i, 0*NDF+3) = i==0? kl(NDF+3, NDF+0): (i==3? kl(NDF+3, NDF+3) : -kl( NDF+3, i)); } +#if 0 static MatrixND<2*NDF,2*NDF> Kg; static Matrix Wrapper(Kg); Kg = t.pushResponse(kl, pl); +#else + static Matrix Wrapper(kl); + t.push(kl, pl, Operation::Total); +#endif + return Wrapper; } @@ -276,8 +289,9 @@ BasicFrameTransf3d::getInitialGlobalStiffMatrix(const Matrix &KB) static MatrixND kg; static Matrix M(kg); + static constexpr VectorND p0{}; - kg = t.pushConstant(kl); + kg = linear.pushResponse(kl, p0); return M; } @@ -300,8 +314,9 @@ BasicFrameTransf3d::getGlobalMatrixFromLocal(const Matrix &M) // static MatrixND Kout; static Matrix wrapper(Kout); + static constexpr VectorND p0{}; wrapper = M; - MatrixND Kg = t.pushConstant(Kout); + MatrixND Kg = linear.pushResponse(Kout, p0); Kout = Kg; return wrapper; } diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h index b70fcf7587..e0e8f8f4ba 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.h +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -28,6 +28,7 @@ #define EuclidFrameTransf_hpp #include +#include #include #include #include @@ -47,6 +48,8 @@ class EuclidFrameTransf: public FrameTransform ~EuclidFrameTransf(); + using Operation = typename FrameTransform::Operation; + const char *getClassType() const {return "EuclidFrameTransf";} virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const; @@ -68,8 +71,8 @@ class EuclidFrameTransf: public FrameTransform Versor getNodeRotation(int tag) /* final */; Vector3D getNodeRotationLogarithm(int tag) final; - VectorND pushResponse(VectorND&pl) final; - MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; + int push(VectorND&pl, Operation) final; + int push(MatrixND& kl, const VectorND& pl, Operation) final; // Sensitivity // @@ -78,7 +81,7 @@ class EuclidFrameTransf: public FrameTransform double getd1overLdh() final; // TaggedObject - void Print(OPS_Stream &s, int flag = 0) final; + void Print(OPS_Stream &s, int flag) final; private: @@ -129,7 +132,7 @@ class EuclidFrameTransf: public FrameTransform } std::array nodes; - std::array ur; // rotation vector + std::array ur; // rotation vector std::array ux; // displacement vector std::array *offsets; diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 87ea11c0ac..5a699005dc 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -24,7 +24,8 @@ #include #include #include -#include +#include +#include #include "EuclidFrameTransf.h" namespace OpenSees { @@ -177,7 +178,7 @@ EuclidFrameTransf::update() for (int i=0; igetTrialRotation(); - ur[i] = LogSO3(R^(MatrixFromVersor(q)*R0)); + ur[i] = AxisAngle(R^(MatrixFromVersor(q)*R0)); } return 0; @@ -206,9 +207,23 @@ template Vector3D EuclidFrameTransf::getNodePosition(int node) { - Vector3D u = this->pullPosition<&Node::getTrialDisp>(node) - - basis.getPosition(); +#if 0 + const Vector& ug = nodes[node]->getTrialDisp(); + Vector3D u; + for (int i=0; i<3; i++) + u[i] = ug[i]; + + if (offsets != nullptr) [[unlikely]] { + u.addVector(1.0, (*offsets)[node], -1.0); + u.addVector(1.0, nodes[node]->getTrialRotation().rotate((*offsets)[node]), 1.0); + } + + u.addVector(1.0, basis.getPosition(), -1.0); +#else + Vector3D u = this->pullPosition<&Node::getTrialDisp>(node); + u -= basis.getPosition(); +#endif u += basis.getRotationDelta()^(nodes[node]->getCrds()); return u; @@ -219,7 +234,7 @@ template Vector3D EuclidFrameTransf::getNodeRotationLogarithm(int node) { - return ur[node]; + return ur[node].vector; } @@ -260,7 +275,7 @@ EuclidFrameTransf::getStateVariation() ul.insert(j+3, R^Vector3D{ul[j+3], ul[j+4], ul[j+5]}, 1.0); } - // Isometry + // Projection { Vector3D wr = basis.getRotationVariation(ndf, &ul[0]); Vector3D dc = basis.getPositionVariation(ndf, &ul[0]); @@ -291,7 +306,7 @@ EuclidFrameTransf::getStateVariation() for (int i=0; i::getStateVariation() // Push // template -VectorND -EuclidFrameTransf::pushResponse(VectorND&p) +// VectorND +int +EuclidFrameTransf::push(VectorND&p, Operation op) { - VectorND pa = p; + VectorND& pa = p; // 1) Logarithm if (1) { // !(offset_flags & LogIter)) { for (int i=0; i::pushResponse(VectorND&p) pa.template assemble<6>(i*ndf, basis.getRotationGradient(i)^m, -1.0); - // 3,4) Rotate and joint offsets - auto pg = this->FrameTransform::pushConstant(pa); - - return pg; + pa = this->FrameTransform::pushConstant(pa); + return 0; } template -MatrixND -EuclidFrameTransf::pushResponse(MatrixND&kb, - const VectorND&pb) +// MatrixND +int +EuclidFrameTransf::push(MatrixND&kb, + const VectorND& pb, + Operation op) { MatrixND Kb = kb; VectorND p = pb; @@ -348,13 +365,13 @@ EuclidFrameTransf::pushResponse(MatrixND&kb, if (1) {//!(offset_flags & LogIter)) { for (int i=0; i::pushResponse(MatrixND&kb, continue; Matrix3D Kab {{ - {Kb(i*ndf+3*k+0, j*ndf+3*l ), Kb(i*ndf+3*k+1, j*ndf+3*l ), Kb(i*ndf+3*k+2, j*ndf+3*l )}, - {Kb(i*ndf+3*k+0, j*ndf+3*l+1), Kb(i*ndf+3*k+1, j*ndf+3*l+1), Kb(i*ndf+3*k+2, j*ndf+3*l+1)}, - {Kb(i*ndf+3*k+0, j*ndf+3*l+2), Kb(i*ndf+3*k+1, j*ndf+3*l+2), Kb(i*ndf+3*k+2, j*ndf+3*l+2)} + Kb(i*ndf+3*k+0, j*ndf+3*l ), Kb(i*ndf+3*k+1, j*ndf+3*l ), Kb(i*ndf+3*k+2, j*ndf+3*l ), + Kb(i*ndf+3*k+0, j*ndf+3*l+1), Kb(i*ndf+3*k+1, j*ndf+3*l+1), Kb(i*ndf+3*k+2, j*ndf+3*l+1), + Kb(i*ndf+3*k+0, j*ndf+3*l+2), Kb(i*ndf+3*k+1, j*ndf+3*l+2), Kb(i*ndf+3*k+2, j*ndf+3*l+2) }}; if (k == 1) Kab = Ai^Kab; // row rotation block @@ -382,13 +399,16 @@ EuclidFrameTransf::pushResponse(MatrixND&kb, // Kb = kb; - MatrixND Kl; - MatrixND A = getProjection(); + MatrixND& Kl = kb; + const MatrixND A = getProjection(); Kl.addMatrixTripleProduct(0, A, Kb, 1); VectorND Ap = A^p; +#if 0 + p = A^p; +#else Kb.zero(); VectorND<12> qwx{}; for (int i=0; i::pushResponse(MatrixND&kb, Kb.assemble(Kw.template extract<6,12, 6,12>(), ndf, ndf, 1.0); Kl.addMatrixProduct(Kb, A, 1.0); // p = A^p; - +#endif // // Kl += -W'*Pn'*A // Kb.zero(); for (int j=0; j Gj = basis.getRotationGradient(j); + const MatrixND<3,6> Gj = basis.getRotationGradient(j); for (int i=0; i::pushResponse(MatrixND&kb, // Kl = diag(R) * Kl * diag(R)^T FrameTransform::pushRotation(Kl, basis.getRotation()); - return Kl; + return 0; } diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h index c122da8460..1b0d1e77c0 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h @@ -36,84 +36,47 @@ #include #include #include -#include -#include +#include #include "EuclidIsometry.h" class Node; namespace OpenSees { -template -class CrisfieldIsometry : public AlignedIsometry { -public: - CrisfieldIsometry(const Vector3D& vecxz) - : AlignedIsometry{vecxz}, Lr2{}, Lr3{}, v{} - { +namespace { +struct Triad { + Triad(const OpenSees::Matrix3D &E) + : e{{E(0,0),E(1,0),E(2,0)}, // e1 + {E(0,1),E(1,1),E(2,1)}, // e2 + {E(0,2),E(1,2),E(2,2)}} // e3 + { } - MatrixND<3,6> - getRotationGradient(int node) final { - constexpr static Vector3D e1{1, 0, 0}; - - double Ln = this->getLength(); - -#if 1 - static constexpr - MatrixND<1,3> E3 {{{0.0}, {0.0}, {1.0}}}, - E2 {{{0.0}, {1.0}, {0.0}}}; - - - const Matrix3D& Tr = this->getRotation(); - Triad r{Tr^Rbar}; - Vector3D r1 = r[1], r3 = r[3]; - - - Matrix3D A{}; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; - - - auto de3 = this->getBasisVariation(r3, r1, e1, v, A); - - MatrixND<3,12> de1{}; - de1.template insert<0,0>(A, -1.0); - de1.template insert<0,6>(A, 1.0); - - MatrixND<3,12> G{}; - G.template insert<0,0, 1,12>(E2*de3, -1.0); - G.template insert<1,0, 1,12>(E3*de1, -1.0); - G.template insert<2,0, 1,12>(E2*de1, 1.0); + constexpr inline + const Vector3D& operator[](int i) const { + return e[i-1]; + } - if (node == 0) - return G.template extract<0,3, 0, 6>(); - else if (node == nn-1) - return G.template extract<0,3, 6,12>(); - else - return MatrixND<3,6>{}; + const Vector3D e[3]; +}; +} -#else - MatrixND<3,6> Gb{}; - constexpr Matrix3D ix = Hat(e1); +template +class CrisfieldIsometry : public AlignedIsometry { +public: + CrisfieldIsometry(const Vector3D& vecxz) + : AlignedIsometry{vecxz}, Lr2{}, Lr3{}, v{} + { - if (node == 0) { - Gb.template insert<0,0>( ix, -1.0/Ln); - Gb(0,3) = 0.5; - } - else if (node == nn-1) { - Gb.template insert<0,0>( ix, 1.0/Ln); - Gb(0,3) = 0.5; - } - return Gb; -#endif } Matrix3D update_basis(const Matrix3D& RI, const Matrix3D& RJ, const Vector3D& dx) { - Ln = dx.norm(); + // Ln = dx.norm(); + this->AlignedIsometry::Ln = dx.norm(); + double Ln = this->getLength(); { const Triad TrI{RI}, TrJ{RJ}; rI[0] = TrI[1]; @@ -125,9 +88,12 @@ class CrisfieldIsometry : public AlignedIsometry { } { - const Versor qI = VersorFromMatrix(RI); - const Versor qJ = VersorFromMatrix(RJ); - Vector3D gw = CayleyFromVersor(qJ.mult_conj(qI)); + // const Versor qI = Versor::from_matrix(RI); + // const Versor qJ = Versor::from_matrix(RJ); + // Versor qij = qJ.mult_conj(qI); + // qij.normalize(); + Versor qij = Versor::from_matrix(RJ*RI.transpose()); + Vector3D gw = CayleyFromVersor(qij); gw *= 0.5; @@ -145,20 +111,25 @@ class CrisfieldIsometry : public AlignedIsometry { // // Compute the base vectors e2, e3 // + // 'rotate' the mean rotation matrix Rbar on to e1 to + // obtain e2 and e3 Matrix3D E; -#if 1 + if constexpr (orthogonal) { - constexpr double ktol = 50.0*std::numeric_limits::epsilon(); + constexpr double ktol = 1.0*std::numeric_limits::epsilon(); Vector3D r1 { Rbar(0,0), Rbar(1,0), Rbar(2,0) }; // Clamp to avoid NaNs from acos - // double dot = std::clamp(r1.dot(e[0]), -1.0, 1.0); double dot = std::max(-1.0, std::min(1.0, r1.dot(e[0]))); if (std::fabs(dot - 1.0) < ktol) { // Rbar already aligned - v.zero(); - E = Rbar; + v.zero(); + for (int i=0; i<3; i++) { + E(i,0) = e[0][i]; + E(i,1) = Rbar(i,1); + E(i,2) = Rbar(i,2); + } } else if (std::fabs(dot + 1.0) < ktol) { // opposite direction // choose any axis with numerical separation from r1 @@ -166,24 +137,24 @@ class CrisfieldIsometry : public AlignedIsometry { if (v.dot(v) < ktol) v = r1.cross(Vector3D{0.0, 1.0, 0.0}); v *= M_PI / v.norm(); + E = ExpSO3(v)*Rbar; } else { // general case v = r1.cross(e[0]); double angle = std::atan2(v.norm(), dot); v *= angle / v.norm(); + E = ExpSO3(v)*Rbar; } - E = ExpSO3(v)*Rbar; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) e[j][i] = E(i,j); } -#else + else { // Not working with frame-1007? // - // 'rotate' the mean rotation matrix Rbar on to e1 to - // obtain e2 and e3 (using the 'mid-point' procedure) + // Use the 'mid-point' procedure // e2 = r2 - (e1 + r1)*((r2^e1)*0.5); @@ -207,7 +178,7 @@ class CrisfieldIsometry : public AlignedIsometry { for (int j = 0; j < 3; j++) E(i,j) = e[j][i]; } -#endif + // // @@ -222,6 +193,74 @@ class CrisfieldIsometry : public AlignedIsometry { return E; } + MatrixND<12,12> + getRotationJacobian(const VectorND<12>&pl) final { + MatrixND<12,12> dG{}; + + return dG; + } + + // MatrixND<3,6> getRotationGradient(int node) final; + + MatrixND<3,6> + getRotationGradient(int node) final { + constexpr static Vector3D e1{1, 0, 0}; + + double Ln = this->getLength(); + +#if 1 + static constexpr + MatrixND<1,3> E3 {{0.0, 0.0, 1.0}}, + E2 {{0.0, 1.0, 0.0}}; + + const Matrix3D& Tr = this->getRotation(); + Triad r{Tr^Rbar}; + Vector3D r1 = r[1], r3 = r[3]; + + + Matrix3D A{}; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + A(i,j) = (double(i==j) - e1[i]*e1[j])/Ln; + + MatrixND<3,12> de3; + if constexpr (!orthogonal) + de3 = this->getLMatrix(r3, r1, e1, A).transpose(); + else + de3 = this->getBasisVariation(r3, r1, e1, v, A); + + MatrixND<3,12> de1{}; + de1.template insert<0,0>(A, -1.0); + de1.template insert<0,6>(A, 1.0); + + MatrixND<3,12> G{}; + G.template insert<0,0, 1,12>(E2*de3, -1.0); + G.template insert<1,0, 1,12>(E3*de1, -1.0); + G.template insert<2,0, 1,12>(E2*de1, 1.0); + + if (node == 0) + return G.template extract<0,3, 0, 6>(); + else if (node == nn-1) + return G.template extract<0,3, 6,12>(); + else + return MatrixND<3,6>{}; + +#else + MatrixND<3,6> Gb{}; + constexpr Matrix3D ix = Hat(e1); + + if (node == 0) { + Gb.template insert<0,0>( ix, -1.0/Ln); + Gb(0,3) = 0.5; + } + else if (node == nn-1) { + Gb.template insert<0,0>( ix, 1.0/Ln); + Gb(0,3) = 0.5; + } + return Gb; +#endif + } + // // // @@ -252,7 +291,6 @@ class CrisfieldIsometry : public AlignedIsometry { Vector3D Se = rI2.cross(e3); Se -= rI3.cross(e2); for (int i = 0; i < 3; i++) - // T(jmx,i+3) = -Se[i]; T(imx,i+3) = Se[i]; // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; @@ -379,12 +417,6 @@ class CrisfieldIsometry : public AlignedIsometry { T(jnx,i+6) = e1[i]; } - // Combine torsion - for (int i=0; i<12; i++) { - T(jmx,i) -= T(imx,i); - T(imx,i) = 0; - } - return T; } @@ -453,9 +485,6 @@ class CrisfieldIsometry : public AlignedIsometry { kg.assemble(ks33, 3, 3, 1.0); } - // - // Ksigma4 - // { Matrix3D ks99; ks99.zero(); @@ -711,7 +740,7 @@ class CrisfieldIsometry : public AlignedIsometry { { const Vector3D &e1 = e[0]; - // const double Ln = this->getLength(); + const double Ln = this->getLength(); // Ksigma2 = [ K11 K12 -K11 K12 // K12' K22 -K12' K22 @@ -839,6 +868,6 @@ class CrisfieldIsometry : public AlignedIsometry { Vector3D r1, r2, r3; Vector3D e[3], rI[3], rJ[3]; MatrixND<12,3> Lr2, Lr3; - double Ln; + // double Ln; }; } \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h index 1ed032a3bb..62d4eb9928 100644 --- a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h @@ -167,56 +167,6 @@ class AlignedIsometry : public Isometry return 0; } - - // int - // update(std::array& nodes) final - // { - // Matrix3D RI = MatrixFromVersor(nodes[0]->getTrialRotation()); - // Matrix3D RJ = MatrixFromVersor(nodes[nn-1]->getTrialRotation()); - - // Vector3D dx = dX; - // // - // // Update position - // // - // { - // const Vector& uI = nodes[ 0]->getTrialDisp(); - // const Vector& uJ = nodes[nn-1]->getTrialDisp(); - // for (int k = 0; k < 3; k++) - // dx[k] += uJ(k) - uI(k); - - // if (offsets != nullptr) [[unlikely]] { - // dx.addVector(1.0, (*offsets)[ 0], 1.0); - // dx.addVector(1.0, RI*((*offsets)[0]), -1.0); - // dx.addVector(1.0, (*offsets)[nn-1], -1.0); - // dx.addVector(1.0, RJ*((*offsets)[nn-1]), 1.0); - // } - // } - - // // Calculate the deformed length - // Ln = dx.norm(); - - // if (Ln == 0.0) [[unlikely]] { - // opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; - // return -2; - // } - - // // - // // - // // - // R[pres] = this->update_basis(RI, RJ, dx); - - // // - // // - // // - // Vector3D uc = nodes[ic]->getTrialDisp(); - // if (offsets != nullptr) { - // uc.addVector(1.0, (*offsets)[ic], -1.0); - // uc.addVector(1.0, nodes[ic]->getTrialRotation().rotate((*offsets)[ic]), 1.0); - // } - // c[pres] = R[pres]^(Xc + uc); - // return 0; - // } - virtual Vector3D getRotationVariation(int ndf, double* du) { // psi_r = omega diff --git a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h index 95b2895dc1..f96318e0e6 100644 --- a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h @@ -82,19 +82,23 @@ class RankinIsometry : public AlignedIsometry return R; } - virtual + MatrixND<12,12> getRotationJacobian(const VectorND<12>&pwx) final { MatrixND<3,12> NWL{}; const double Ln = this->getLength(); - constexpr static Vector3D e1 {1,0,0}; - constexpr static Matrix3D ex = Hat(e1); + constexpr static Matrix3D ex = Hat(Vector3D {1,0,0}); for (int i=0; i= 202000L + static constinit MatrixND<12,3> Gamma = MakeGamma(); + static constinit MatrixND<12,3> Psi0 = MakePsi(); + MatrixND<12,3> Psi = Psi0; + Psi.template insert<6,0>(ex, -Ln); +#else MatrixND<12,3> Gamma{}; Gamma.template insert<0,0>(ex, 1.0); Gamma(3,0) = -1.0; @@ -102,12 +106,13 @@ class RankinIsometry : public AlignedIsometry MatrixND<12,3> Psi{}; Psi.template insert<3,0>(Eye3, 1.0); - Psi.template insert<6,0>(ex, Ln); + Psi.template insert<6,0>(ex, -Ln); Psi.template insert<9,0>(Eye3, 1.0); - +#endif Matrix3D B = Gamma^Psi; - B.invert(); - return Gamma*B.transpose()*NWL; + Matrix3D A; + B.invert(A); + return Gamma*A.transpose()*NWL; } MatrixND<3,6> @@ -166,5 +171,29 @@ class RankinIsometry : public AlignedIsometry private: Vector3D q; double n = 0; + + + #if __cplusplus >= 202000L + static inline consteval MatrixND<12,3> + MakePsi() + { + MatrixND<12,3> Psi{}; + Psi.template insert<3,0>(Eye3, 1.0); + Psi.template insert<9,0>(Eye3, 1.0); + return Psi; + } + + static inline consteval MatrixND<12,3> + MakeGamma() + { + MatrixND<12,3> Gamma{}; + constexpr Matrix3D ex = Hat(Vector3D {1,0,0}); + Gamma.template insert<0,0>(ex, 1.0); + Gamma(3,0) = -1.0; + Gamma.template insert<6,0>(ex, -1.0); + return Gamma; + } + #endif + }; } // namespace OpenSees \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h b/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h new file mode 100644 index 0000000000..93b5fa2c16 --- /dev/null +++ b/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h @@ -0,0 +1,132 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C.. (2024) +// "On Nonlinear Geometric Transformations of Finite Elements" +// Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +// +// Written: Claudio M. Perez, +// Filip C. Filippou +// University of California, Berkeley +// +// Developed with FEDEASLab [2]. +// +// References: +// +// [2] Filippou, F.C. (1998) +// "FEDEASLab: Finite Elements for Design Evaluation and Analysis of Structures" +// +#pragma once +#include +#include +#include +#include +#include "EuclidIsometry.h" + +template +class SphericalIsometry : public Isometry { +public: + SphericalIsometry(std::array& nodes, const Vector3D& vecxz); + + int initialize() final; + int update() final; + + double getLength() const final; + Matrix3D getRotation() const final; + Vector3D getPosition() final; + Vector3D getPositionVariation(int ndf, double* du) final; + Vector3D getRotationVariation(int ndf, double* du) final; + Matrix3D getRotationDelta() final; + MatrixND<3,6> getRotationGradient(int node) final; +private: + double L; + double Ln; + std::array nodes; + Vector3D vz; // vector in the x-z plane + Vector3D dX; // deformed length vector + Vector3D c[2]; // current position of the center + Matrix3D R[2]; // rotation matrices at the current and previous time step + Vector3D Xc; // center of the isometry +}; + + +template +SphericalIsometry::SphericalIsometry(std::array& nodes, const Vector3D& vecxz) +: nodes(nodes), vz(vecxz), Xc{}, + c{}, R{}, dX{}, Ln(0.0), L(0.0), + offsets(nullptr), offset_flags(0), ic(0) +{ + +} + + +template +int +SphericalIsometry::update() { + + Vector3D e1 = dX; + { + // + // Update state + // + const Vector& uI = nodes[ 0]->getTrialDisp(); + const Vector& uJ = nodes[nn-1]->getTrialDisp(); + for (int k = 0; k < 3; k++) + e1[k] += uJ(k) - uI(k); + + if (offsets != nullptr) [[unlikely]] { + e1.addVector(1.0, (*offsets)[ 0], 1.0); + e1.addVector(1.0, nodes[0]->getTrialRotation().rotate((*offsets)[0]), -1.0); + e1.addVector(1.0, (*offsets)[nn-1], -1.0); + e1.addVector(1.0, nodes[nn-1]->getTrialRotation().rotate((*offsets)[nn-1]), 1.0); + } + + // Calculate the deformed length + Ln = e1.norm(); + + if (Ln == 0.0) [[unlikely]] { + opserr << "\nSouzaFrameTransf: deformed length is 0.0\n"; + return -2; + } + + e1 /= Ln; + } + + { +#if 1 // TRIAD==R2 + constexpr static Vector3D D2 {0,1,0}; + const Vector3D E2 = R[init]*D2; + Vector3D e2 = MatrixFromVersor(nodes[0]->getTrialRotation())*E2; //*R[init]; + e2.addVector(0.5, MatrixFromVersor(nodes[1]->getTrialRotation())*E2, 0.5); + n = e2[0]/e2[1]; + Vector3D e3 = e1.cross(e2); + e3 /= e3.norm(); + + e2 = e3.cross(e1); + + for (int i = 0; i < 3; i++) { + R[pres](i,0) = e1[i]; + R[pres](i,1) = e2[i]; + R[pres](i,2) = e3[i]; + } + Vector3D e2 = vz.cross(e1); +#endif + } + + Vector3D uc = nodes[ic]->getTrialDisp(); + if (offsets != nullptr) { + uc.addVector(1.0, (*offsets)[ic], -1.0); + uc.addVector(1.0, nodes[ic]->getTrialRotation().rotate((*offsets)[ic]), 1.0); + } + Vector3D X = nodes[ic]->getCrds(); + c[pres] = R[pres]^(X + uc); + return 0; +} \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.h b/SRC/coordTransformation/Frame/LinearFrameTransf.h index 1988fea727..39d8519fab 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.h +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.h @@ -41,6 +41,7 @@ class LinearFrameTransf: public FrameTransform int offset_flags = 0); ~LinearFrameTransf(); + const char *getClassType() const {return "LinearFrameTransf";} @@ -61,10 +62,15 @@ class LinearFrameTransf: public FrameTransform VectorND getStateVariation() final; Vector3D getNodePosition(int tag) final; Vector3D getNodeRotationLogarithm(int tag) final; - +#if 0 VectorND pushResponse(VectorND&pl) final; MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; +#else + using Operation = typename FrameTransform::Operation; + int push(VectorND&pl, Operation) final; + int push(MatrixND& kl, const VectorND& pl, Operation) final; +#endif // // method used to rotate consistent mass matrix // const Matrix &getGlobalMatrixFromLocal(const Matrix &local); @@ -79,7 +85,7 @@ class LinearFrameTransf: public FrameTransform double getd1overLdh() final; // TaggedObject - void Print(OPS_Stream &s, int flag = 0) final; + void Print(OPS_Stream &s, int flag) final; // Personal Vector3D getDelta() {return Du;} @@ -92,6 +98,7 @@ class LinearFrameTransf: public FrameTransform const std::array *offset = nullptr, int offset_flags = 0); + template const Vector3D pullPosition(int node) diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index baf2828e3d..0748d28218 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -24,15 +24,16 @@ // and basic coordinate systems // // Adapted: Remo Magalhaes de Souza -// Created: 04/2000 // #pragma once #include +#include #include +#include #include #include #include -#include +#include #include "LinearFrameTransf.h" namespace OpenSees { @@ -382,8 +383,9 @@ LinearFrameTransf::getNodeRotationLogarithm(int node) // Push // template -VectorND -LinearFrameTransf::pushResponse(VectorND&p) +// VectorND +int +LinearFrameTransf::push(VectorND&p, Operation op) { VectorND pa = p; constexpr Vector3D iv{1, 0, 0}; @@ -408,13 +410,16 @@ LinearFrameTransf::pushResponse(VectorND&p) } // 2) Rotate and do joint offsets - auto pg = this->FrameTransform::pushConstant(pa); - return pg; + p = this->FrameTransform::pushConstant(pa); + return 0; } template -MatrixND -LinearFrameTransf::pushResponse(MatrixND&kb, const VectorND&) +// MatrixND +int +LinearFrameTransf::push(MatrixND&kb, + const VectorND&, + Operation op) { MatrixND A{}; @@ -438,9 +443,17 @@ LinearFrameTransf::pushResponse(MatrixND&kb, const Vector } } +#if 0 MatrixND kl; kl.addMatrixTripleProduct(0, A, kb, 1); - return this->FrameTransform::pushConstant(kl); + this->FrameTransform::pushConstant(kl); +#else + MatrixND kl;; + kl.addMatrixTripleProduct(0, A, kb, 1); + kb = this->FrameTransform::pushConstant(kl); + // this->pushRotation(kb, R); + return 0; +#endif } @@ -568,6 +581,53 @@ LinearFrameTransf::getBasicDisplFixedGrad() // Form ug // // TODO(sensitivity) +#if 0 + VectorND ug; + for (int i = 0; i < nn; i++) { + const Vector& u = nodes[i]->getTrialDisp(); + for (int j = 0; j < ndf; j++) { + ug[i*ndf+j] = u(j); + } + } + + if (u_init[0] != 0) { + for (int j = 0; j < ndf; j++) + ug[j] -= (*u_init[0])[j]; + } + + if (u_init[nn-1] != 0) { + for (int j = 0; j < ndf; j++) + ug[j + 6] -= (*u_init[nn-1])[j]; + } + + // + // dub += (T_{bl}' T_{lg} + T_{bl} T_{lg}') * ug + // + int dv = 0; // TODO(sensitivity) + + // TODO: Sensitivity + int di = nodes[0]->getCrdsSensitivity(); + int dj = nodes[1]->getCrdsSensitivity(); + + + // TODO(sensitivity) + // Matrix3D dR = FrameOrientationGradient(xi, xj, vz, di, dj, dv); + // dub = getBasic(ug, 1/L); + + // + // + VectorND ul = LinearFrameTransf::pullConstant(ug, R, offsets); + // + dub[0] += 0; + double dL = this->getLengthGrad(); + double doneOverL = -dL/(L*L); + double tmp = doneOverL * (ul[1] - ul[7]); + dub[1] += tmp; + dub[2] += tmp; + tmp = doneOverL * (ul[8] - ul[2]); + dub[3] += tmp; + dub[4] += tmp; +#endif return wrapper; } @@ -631,4 +691,4 @@ LinearFrameTransf::Print(OPS_Stream &s, int flag) } } -} // namespace OpenSees \ No newline at end of file +} // namespace OpenSees diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h index a774caf258..14a0130220 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h @@ -56,9 +56,14 @@ class PDeltaFrameTransf: public FrameTransform Vector3D getNodePosition(int tag) final; Vector3D getNodeRotationLogarithm(int tag) final; const std::array *getRigidOffsets() const final { return linear.getRigidOffsets();} - +#if 0 VectorND pushResponse(VectorND&pl) final; MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; +#else + using Operation = typename FrameTransform::Operation; + int push(VectorND&pl, Operation) final; + int push(MatrixND& kl, const VectorND& pl, Operation) final; +#endif FrameTransform *getCopy() const final; @@ -68,7 +73,7 @@ class PDeltaFrameTransf: public FrameTransform double getLengthGrad() final; // Tagged Object - void Print(OPS_Stream &s, int flag = 0) final; + void Print(OPS_Stream &s, int flag) final; private: int offset_flags; diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp index 0bbfb3b930..0131130194 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp @@ -100,8 +100,9 @@ PDeltaFrameTransf::getDeformedLength() template -VectorND -PDeltaFrameTransf::pushResponse(VectorND&pl) +// VectorND +int +PDeltaFrameTransf::push(VectorND&pl, Operation op) { // // Include leaning column effects (P-Delta) @@ -117,13 +118,14 @@ PDeltaFrameTransf::pushResponse(VectorND&pl) pl[0*ndf+2] -= Du[2] * N; pl[1*ndf+2] += Du[2] * N; - return linear.pushResponse(pl); + return linear.push(pl, op); } template -MatrixND -PDeltaFrameTransf::pushResponse(MatrixND& kl, const VectorND &pl) +// MatrixND +int +PDeltaFrameTransf::push(MatrixND& kl, const VectorND &pl, Operation op) { // Include geometric stiffness effects in local system; // @@ -138,7 +140,7 @@ PDeltaFrameTransf::pushResponse(MatrixND& kl, const Vecto kl(7, 1) -= NoverL; kl(2, 8) -= NoverL; kl(8, 2) -= NoverL; - return linear.pushResponse(kl, pl); + return linear.push(kl, pl, op); } diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.h b/SRC/coordTransformation/Frame/SouzaFrameTransf.h index 018c8859cb..028214bb3a 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.h +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.h @@ -45,7 +45,6 @@ #include #include "Isometry/CrisfieldIsometry.h" -struct Triad; namespace OpenSees { @@ -81,10 +80,14 @@ class SouzaFrameTransf: public FrameTransform VectorND getStateVariation() final; Vector3D getNodePosition(int tag) final; Vector3D getNodeRotationLogarithm(int tag) final; - +#if 0 VectorND pushResponse(VectorND&pl) final; MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; - +#else + using Operation = typename FrameTransform::Operation; + int push(VectorND&pl, Operation) final; + int push(MatrixND& kl, const VectorND& pl, Operation) final; +#endif // Sensitivity double getLengthGrad() final; const Vector &getBasicDisplTotalGrad(int grad); // final; @@ -92,11 +95,11 @@ class SouzaFrameTransf: public FrameTransform const Vector &getGlobalResistingForceShapeSensitivity(const Vector &pb, const Vector &p0, int gradNumber); // Tagged Object - void Print(OPS_Stream &s, int flag = 0) final; + void Print(OPS_Stream &s, int flag) final; protected: - VectorND<6> pushResponse(const VectorND<6>& pa, int a, int b); + // VectorND<6> pushResponse(const VectorND<6>& pa, int a, int b); private: constexpr static int n = nn*ndf; @@ -152,7 +155,7 @@ class SouzaFrameTransf: public FrameTransform OpenSees::MatrixND T; // transformation from local to global system OpenSees::Matrix3D R0; // rotation from local to global coordinates - CrisfieldIsometry<2> crs; + CrisfieldIsometry<2,false> crs; }; diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp index d5007c2779..66f5533b83 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp @@ -36,14 +36,13 @@ #include #include "SouzaFrameTransf.h" -#include #include #include #include #include #include #include -#include +#include #include "Isometry/CrisfieldIsometry.h" namespace OpenSees { @@ -124,7 +123,7 @@ int SouzaFrameTransf::revertToStart() { ul.zero(); - Q_pres[0] = VersorFromMatrix(R0); + Q_pres[0] = Versor::from_matrix(R0); for (int i=1; i::initialize(std::array& new_nodes) return error; // Compute initial pseudo-vectors for nodal triads - Q_pres[0] = Q_pres[1] = VersorFromMatrix(R0); + Q_pres[0] = Q_pres[1] = Versor::from_matrix(R0); ul.zero(); ulpr.zero(); @@ -315,13 +314,11 @@ SouzaFrameTransf::update() alphaJ[k] = dispJ(k+3); } - // Update the nodal rotations - Q_pres[0] = VersorProduct(Q_pres[0], Versor::from_vector(dAlphaI)); - Q_pres[1] = VersorProduct(Q_pres[1], Versor::from_vector(dAlphaJ)); - // Q_pres[0] = VersorFromMatrix(MatrixFromVersor(Q_pres[0]) * - // MatrixFromVersor(Versor::from_vector(dAlphaI))); - // Q_pres[1] = VersorFromMatrix(MatrixFromVersor(Q_pres[1]) * - // MatrixFromVersor(Versor::from_vector(dAlphaJ))); + // Update the nodal rotations; Note the Hamilton product is assumed! + if (dAlphaI.norm() != 0) + Q_pres[0] = Versor::from_vector(dAlphaI)*Q_pres[0]; + if (dAlphaJ.norm() != 0) + Q_pres[1] = Versor::from_vector(dAlphaJ)*Q_pres[1]; } // @@ -353,8 +350,8 @@ SouzaFrameTransf::update() // Axial ul(inx) = 0; - // ul(jnx) = Ln - L; - ul(jnx) = (dX + (dx-dX)*0.5).dot(dx-dX)*2.0/(Ln+L); + ul(jnx) = Ln - L; + // ul(jnx) = (dX + (dx-dX)*0.5).dot(dx-dX)*2.0/(Ln+L); // Form the transformation tangent T = crs.compute_tangent(ul); @@ -363,8 +360,9 @@ SouzaFrameTransf::update() template -inline VectorND -SouzaFrameTransf::pushResponse(VectorND&pl) +// inline VectorND +int +SouzaFrameTransf::push(VectorND&pl, Operation) { // return T^pl; VectorND pg{}; @@ -373,31 +371,28 @@ SouzaFrameTransf::pushResponse(VectorND&pl) pl(a*ndf+3), pl(a*ndf+4), pl(a*ndf+5)}; for (int b = 0; b<2; b++) { - VectorND<6> pab = pushResponse(pa, a, b); + VectorND<6> pab{}; + for (int i = 0; i < 6; i++) + for (int j = 0; j < 6; j++) + pab[j] += T(a*6 + i, b*6+j) * pa[i]; + // VectorND<6> pab = pushResponse(pa, a, b); pg.assemble(b*6, pab, 1.0); } } - return pg; + pl = pg; // TODO: optimize + return 0; } -template -VectorND<6> -SouzaFrameTransf::pushResponse(const VectorND<6>&pa, int a, int b) -{ - VectorND<6> pg{}; - for (int i = 0; i < 6; i++) - for (int j = 0; j < 6; j++) - pg[j] += T(a*6 + i, b*6+j) * pa[i]; - - return pg; -} // do // K = ag'*Km*ag + Kp // template -MatrixND -SouzaFrameTransf::pushResponse(MatrixND& kl, const VectorND& pl) +// MatrixND +int +SouzaFrameTransf::push(MatrixND& kl, + const VectorND& pl, + Operation op) { MatrixND<12,12> K; K.addMatrixTripleProduct(0.0, T, kl, 1.0); @@ -405,7 +400,8 @@ SouzaFrameTransf::pushResponse(MatrixND& kl, const Vector // Add geometric part kg this->addTangent(K, pl, ul); - return K; + kl = K; // TODO: optimize + return 0; } @@ -429,7 +425,6 @@ SouzaFrameTransf::addTangent(MatrixND<12,12>& kg, // // T' * diag (M .* tan(thetal))*T // - for (int node=0; node<2; node++) { for (int k = 0; k < 3; k++) { const double factor = pl[(node ? jmx : imx) + k] // pl[6*node+3+k] @@ -438,8 +433,9 @@ SouzaFrameTransf::addTangent(MatrixND<12,12>& kg, for (int i = 0; i < 12; i++) { const double Tki = T((node ? jmx : imx) + k,i); - for (int j = 0; j < 12; j++) + for (int j = 0; j < 12; j++) { kg(i,j) += Tki * factor * T((node ? jmx : imx) + k, j); + } } } } diff --git a/SRC/matrix/AxisAngle.h b/SRC/matrix/AxisAngle.h new file mode 100644 index 0000000000..ebfc92521c --- /dev/null +++ b/SRC/matrix/AxisAngle.h @@ -0,0 +1,82 @@ +#pragma once +#include "Vector3D.h" +#include "VectorND.h" +#include "MatrixND.h" +#include "Matrix3D.h" +#include "GroupSO3.h" + +namespace { + +class AxisAngle { +public: + Vector3D vector; + double angle, eta, mu; + + AxisAngle() + : vector{}, + angle(0.0), + eta(0.0), + mu(0.0) + { + } + + explicit + AxisAngle(const Matrix3D& R) + : AxisAngle(LogSO3(R)) + { + } + + explicit + AxisAngle(const Vector3D& v) + : angle(v.norm()), + vector(v) //Utility::RescaleVector(v, angle)) + { + Utility::dLogConst(angle, eta, mu); + } + + inline Matrix3D + dLog() const + { + // + // d_R LogSO3(v) = Eye3 - 0.5*Sv + eta*Sv*Sv; + // + Matrix3D dH = Eye3; + dH.addSpin(vector, -0.5); + dH.addSpinSquare(vector, eta); + return dH; + } + + inline Vector3D + dLog(const Vector3D&p) const + { + // + // d_R LogSO3(v) = Eye3 - 0.5*Sv + eta*Sv*Sv; + // + Vector3D u = p; + u -= vector.cross(p)*0.5; + u += eta*vector.cross(vector.cross(p)); + return u; + } + + inline Matrix3D + ddLog(const Vector3D& p) const + { + // + // -0.5*Hat(v) + eta*(Eye3*th.dot(v) + th.bun(v) - 2.*v.bun(th)) + mu*St2*v.bun(th); + // + const Vector3D& v = this->vector; + + Matrix3D St2 = Hat(vector); + St2 = St2*St2; + Matrix3D dH{}; + dH.addSpin(p, -0.5); + dH.addDiagonal( eta*vector.dot(p)); + dH.addTensorProduct(v, p, eta); + dH.addTensorProduct(p, v, -2.0*eta); + dH.addMatrixProduct(St2, p.bun(v), mu); + + return dH*this->dLog(); + } +}; + +} // namespace \ No newline at end of file diff --git a/SRC/matrix/GroupSO3.h b/SRC/matrix/GroupSO3.h index 5047237a6f..2c17669cf1 100755 --- a/SRC/matrix/GroupSO3.h +++ b/SRC/matrix/GroupSO3.h @@ -5,7 +5,7 @@ // //----------------------------------------------------------------------------// // -// Please cite the following resource in any derivative works: +// The following resource should be cited in derivative works: // // [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; @@ -48,7 +48,10 @@ #include "Vector3D.h" #include using OpenSees::Matrix3D; +using OpenSees::Versor; +static constexpr double SmallAngle = 1e-12; // threshold for small angles +static constexpr double SmallAngle2 = SmallAngle * SmallAngle; // threshold for small angles squared static constexpr Matrix3D Eye3 {{ {1, 0, 0}, @@ -57,8 +60,9 @@ static constexpr Matrix3D Eye3 {{ }}; -static inline Vector3D -Vee(const Matrix3D &X) + +static inline constexpr Vector3D +Vee(const Matrix3D &X) noexcept { // // Return the axial vector x of the given skew-symmetric 3x3 matrix X. @@ -67,16 +71,17 @@ Vee(const Matrix3D &X) } template -inline constexpr Matrix3D -Hat(const Vec3Type &u) +static inline constexpr Matrix3D +Hat(const Vec3Type &u) noexcept { return Matrix3D {{{ 0 , u[2], -u[1]}, {-u[2], 0 , u[0]}, { u[1], -u[0], 0 }}}; } + static inline double -GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) +GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) noexcept { // // Compute coefficients of the Rodrigues formula and their differentials. @@ -111,7 +116,7 @@ GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) // double angle2 = vec.dot(vec); - if (angle2 <= 1e-07) { + if (angle2 <= 1e-12) { // // Maclaurin series in Horner form // @@ -119,17 +124,18 @@ GibSO3(const Vector3D &vec, double *a, double *b=nullptr, double *c=nullptr) a[0] = 1.0 - angle2*(1.0/2.0 - angle2*(1.0/6.0 - angle2/24.0)); a[1] = 1.0 - angle2*(1.0/6.0 - angle2*(1.0/120.0 - angle2/5040.0)); a[2] = 0.5 - angle2*(1.0/24.0 - angle2*(1.0/720.0 - angle2/40320.0)); - a[3] = 1.0/6.0 - angle2/(1.0/120.0 - angle2/(1.0/5040.0 - angle2/362880.0)); + // a[3] = 1.0/6.0 - angle2/(1.0/120.0 - angle2/(1.0/5040.0 - angle2/362880.0)); + a[3] = 1.0/6.0 - angle2*(1.0/120.0 - angle2*(1.0/5040.0 - angle2/362880.0)); } if (b != nullptr) { b[0] = - a[1]; - b[1] = - 1.0/3.0 + angle2*(1.0/30.0 - angle2*(1.0/840.0 - angle2/45360.0)); - b[2] = - 1.0/12.0 + angle2*(1.0/180.0 - angle2*(1.0/6720.0 - angle2/453600.0)); + b[1] = - 1.0/3.0 + angle2*(1.0/30.0 - angle2*(1.0/840.0 - angle2/45360.0)); + b[2] = - 1.0/12.0 + angle2*(1.0/180.0 - angle2*(1.0/6720.0 - angle2/453600.0)); b[3] = - 1.0/60.0 + angle2*(1.0/1260.0 - angle2*(1.0/60480 - angle2/4989600.0)); } if (c != nullptr) { c[0] = - b[1]; - c[1] = b[3] - b[2]; + c[1] = b[3] - b[2]; c[2] = 1.0/90.0 - angle2*(1.0/1680.0 - angle2*(1.0/75600.0 - angle2/5987520.0)); c[3] = 1.0/630.0 - angle2*(1.0/15120.0 - angle2*(1.0/831600.0 - angle2/77837760.0)); } @@ -188,37 +194,6 @@ CayleyFromVersor(const Versor &q) } -static inline Versor -VersorProduct(const Versor &qa, const Versor &qb) -{ - const double qa0 = qa.vector[0], - qa1 = qa.vector[1], - qa2 = qa.vector[2], - qa3 = qa.scalar, - // - qb0 = qb.vector[0], - qb1 = qb.vector[1], - qb2 = qb.vector[2], - qb3 = qb.scalar; - - // Dot product qa.qb - const double qaTqb = qa0*qb0 + qa1*qb1 + qa2*qb2; - - // Cross-product qa x qb - const double - qaxqb0 = qa1*qb2 - qa2*qb1, - qaxqb1 = qa2*qb0 - qa0*qb2, - qaxqb2 = qa0*qb1 - qa1*qb0; - - // - Versor q12; - q12.vector[0] = qa3*qb0 + qb3*qa0 - qaxqb0; - q12.vector[1] = qa3*qb1 + qb3*qa1 - qaxqb1; - q12.vector[2] = qa3*qb2 + qb3*qa2 - qaxqb2; - q12.scalar = qa3*qb3 - qaTqb; - return q12; -} - // R = (q0^2 - q' * q)*I + 2 * q * q' + 2*q0*S(q); static inline Matrix3D @@ -275,52 +250,11 @@ VectorFromVersor(const Versor& q) } -static inline Versor -VersorFromMatrix(const Matrix3D &R) -{ - //===--------------------------------------------------------------------===// - // Form a normalised quaternion (Versor) from a proper orthogonal matrix - // using Spurrier's algorithm - //===--------------------------------------------------------------------===// - Versor q; - - // Trace of the rotation R - const double trR = R(0,0) + R(1,1) + R(2,2); - - // a = max([trR R(0,0) R(1,1) R(2,2)]); - double a = trR; - for (int i = 0; i < 3; i++) - if (R(i,i) > a) - a = R(i,i); - - if (a == trR) { - q.scalar = std::sqrt(1.0 + a)*0.5; - - for (int i = 0; i < 3; i++) { - int j = (i+1)%3; - int k = (i+2)%3; - q.vector[i] = (R(k,j) - R(j,k))/(4.0*q.scalar); - } - } - else { - for (int i = 0; i < 3; i++) - if (a == R(i,i)) { - int j = (i+1)%3; - int k = (i+2)%3; - - q.vector[i] = sqrt(a*0.5 + (1.0 - trR)/4.0); - q.scalar = (R(k,j) - R(j,k))/(4.0*q.vector[i]); - q.vector[j] = (R(j,i) + R(i,j))/(4.0*q.vector[i]); - q.vector[k] = (R(k,i) + R(i,k))/(4.0*q.vector[i]); - } - } - return q; -} - // // Exponential Map // + static inline Matrix3D ExpSO3(const Vector3D &theta) { @@ -328,7 +262,7 @@ ExpSO3(const Vector3D &theta) double a[4]; Matrix3D R = Eye3; - if (GibSO3(theta, a) > 1e-12) { + if (GibSO3(theta, a) > 1e-16) { R.addSpin(theta, a[1]); R.addSpinSquare(theta, a[2]); } @@ -553,7 +487,7 @@ LogSO3(const Matrix3D &R) // function by Claudio Perez 2023 //===--------------------------------------------------------------------===// - return VectorFromVersor(VersorFromMatrix(R)); + return VectorFromVersor(Versor::from_matrix(R)); } @@ -736,33 +670,3 @@ ddLogSO3(const Vector3D& u, const Vector3D& p) return dH*dLogSO3(th); } - -#if 0 - -class Align { -public: - Align(Vector3D& original, Vector3D& target) - : original(original), target(target) - { - } - - // Align a vector to another vector using the exponential map - static Vector3D - rot(const Vector3D &v, const Vector3D &target) - { - // e3 = r3 - (e1 + r1)*((r3^e1)*0.5); - // e2 = r2 - (e1 + r1)*((r2^e1)*0.5); - Vector3D axis = v.cross(target); - double angle = std::acos(v.dot(target)/(v.norm()*target.norm())); - - if (angle < 1e-10) return v; - - return ExpSO3(axis*angle)*v; - } - - private: - Vector3D original; - Vector3D target; -}; - -#endif diff --git a/SRC/matrix/Versor.h b/SRC/matrix/Versor.h index d70b18fbd4..ea838d2ccf 100644 --- a/SRC/matrix/Versor.h +++ b/SRC/matrix/Versor.h @@ -10,37 +10,72 @@ // #pragma once #include +#include #include +#include + -#if 0 namespace OpenSees { -#endif struct Versor { Vector3D vector; double scalar; - inline Versor - conjugate() const { - Versor c; - c.scalar = scalar; - c.vector = -1.0*vector; // element-wise negation - return c; + template + static inline Versor from_vector(const Vec3T &); + + static inline Versor from_matrix(const Matrix3D &); + + template + inline Vec3T + rotate(const Vec3T& u) const { + return u + 2.0 * vector.cross( scalar*u + vector.cross(u) ); + } + + inline void + normalize() { + static constexpr double eps = 1e-12; + + double n2 = scalar*scalar + vector.dot(vector); + + // bad numbers; reset to identity + if (!std::isfinite(n2) || n2 < eps) { + scalar = 1.0; + vector[0] = vector[1] = vector[2] = 0.0; + return; + } + + // already close enough to unit + constexpr double tol = 1e-6; + if (std::abs(n2 - 1.0) < tol) + return; + + // normalize + double inv_n = 1.0 / std::sqrt(n2); + scalar *= inv_n; + vector[0] *= inv_n; + vector[1] *= inv_n; + vector[2] *= inv_n; + } + + inline constexpr Versor + conjugate() const noexcept { + return Versor{{-vector[0], -vector[1], -vector[2]}, scalar}; } inline Versor - conj_mult(const Versor& other) const + conj_mult(const Versor& other) const noexcept { // Equivalent to R_IJ = R_I.T @ R_J, // i.e. q_IJ = conj(q_I)*q_J. - Versor out; - out.scalar = scalar * other.scalar + vector.dot(other.vector); - out.vector = (other.vector * scalar) - (vector * other.scalar) - vector.cross(other.vector); - return out; + Versor qij; + qij.scalar = scalar * other.scalar + vector.dot(other.vector); + qij.vector = (other.vector * scalar) - (vector * other.scalar) - vector.cross(other.vector); + return qij; } inline Versor - mult_conj(const Versor& other) const + mult_conj(const Versor& other) const noexcept { // Equivalent to R_IJ = R_I @ R_J^T, // i.e. q_IJ = q_I * conj(q_J). @@ -53,67 +88,98 @@ struct Versor { return out; } - template - static inline Versor from_vector(const Vec3T &theta); + + // Unary plus + Versor operator+() const { + return *this; + } + + // Unary minus. + Versor operator-() const { + return {{-vector[0], -vector[1], -vector[2]}, -scalar}; + } }; +static_assert(std::is_trivially_copyable::value, "Versor must be trivially copyable"); inline Versor -operator*(const Versor &qa, const Versor &qb) +Versor::from_matrix(const Matrix3D &R) { - const double qa0 = qa.vector[0], - qa1 = qa.vector[1], - qa2 = qa.vector[2], - qa3 = qa.scalar, - qb0 = qb.vector[0], - qb1 = qb.vector[1], - qb2 = qb.vector[2], - qb3 = qb.scalar; - - // Calculate the dot product qa.qb - const double qaTqb = qa0*qb0 + qa1*qb1 + qa2*qb2; - - // Calculate the cross-product qa x qb - const double - qaxqb0 = qa1*qb2 - qa2*qb1, - qaxqb1 = qa2*qb0 - qa0*qb2, - qaxqb2 = qa0*qb1 - qa1*qb0; - - // Calculate the quaternion product - Versor q12; - q12.vector[0] = qa3*qb0 + qb3*qa0 - qaxqb0; - q12.vector[1] = qa3*qb1 + qb3*qa1 - qaxqb1; - q12.vector[2] = qa3*qb2 + qb3*qa2 - qaxqb2; - q12.scalar = qa3*qb3 - qaTqb; - return q12; -} + //===--------------------------------------------------------------------===// + // Form a normalized quaternion (Versor) from a proper orthogonal matrix + // using Spurrier's algorithm + //===--------------------------------------------------------------------===// + Versor q; + + // Trace of the rotation R + const double trR = R(0,0) + R(1,1) + R(2,2); + + // a = max([trR R(0,0) R(1,1) R(2,2)]); + double a = trR; + for (int i = 0; i < 3; i++) + if (R(i,i) > a) + a = R(i,i); + if (a == trR) { + q.scalar = std::sqrt(1.0 + a)*0.5; + for (int i = 0; i < 3; i++) { + int j = (i+1)%3; + int k = (i+2)%3; + q.vector[i] = (R(k,j) - R(j,k))/(4.0*q.scalar); + } + } + else { + for (int i = 0; i < 3; i++) + if (a == R(i,i)) { + int j = (i+1)%3; + int k = (i+2)%3; + + q.vector[i] = std::sqrt(std::max(a*0.5 + (1.0 - trR)/4.0, 0.0)); + q.scalar = (R(k,j) - R(j,k))/(4.0*q.vector[i]); + q.vector[j] = (R(j,i) + R(i,j))/(4.0*q.vector[i]); + q.vector[k] = (R(k,i) + R(i,k))/(4.0*q.vector[i]); + } + } + return q; +} template inline Versor Versor::from_vector(const Vec3T &theta) { - double t = 0.0; + double angle2 = 0.0; for (int i=0; i<3; i++) - t += theta[i]*theta[i]; + angle2 += theta[i]*theta[i]; - t = std::sqrt(t); + double angle = std::sqrt(angle2); Versor q; - if (t == 0) - q.vector.zero(); - + double sc, cs; + if (angle2 < 1e-12) { + sc = 0.5 - angle2 / 48.0; // + angle2*angle2 / 3840.0 - angle2*angle2*angle2 / 362880.0; + cs = 1.0 - angle2 / 8.0; // + angle2*angle2 / 384.0 - angle2*angle2*angle2 / 40320.0; + } else { - const double factor = std::sin(t*0.5) / t; - for (int i = 0; i < 3; i++) - q.vector[i] = theta[i] * factor; + sc = std::sin(angle*0.5) / angle; + cs = std::cos(angle*0.5); } - q.scalar = std::cos(t*0.5); + for (int i = 0; i < 3; i++) + q.vector[i] = theta[i] * sc; + + q.scalar = cs; return q; } -#if 0 + } // namespace OpenSees -#endif \ No newline at end of file + +inline OpenSees::Versor +operator*(const OpenSees::Versor &qa, const OpenSees::Versor &qb) +{ + OpenSees::Versor q12; + q12.scalar = qa.scalar * qb.scalar - qa.vector.dot(qb.vector); + q12.vector = (qb.vector * qa.scalar) + (qa.vector * qb.scalar) + qa.vector.cross(qb.vector); + return q12; +} diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index d2c597c736..6fd0fb0d59 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -233,11 +233,11 @@ CreateFrame(BasicModelBuilder& builder, // ndm == 3 // - if (CheckTransformation(*builder.getDomain(), nodev[0], nodev[1], *theTransf) != TCL_OK) - return nullptr; - if (strstr(name, "Frame") != nullptr) { if (strstr(name, "Exact") == nullptr) { + + if (CheckTransformation(*builder.getDomain(), nodev[0], nodev[nodev.size()-1], *theTransf) != TCL_OK) + return nullptr; std::array nodes {nodev[0], nodev[1]}; FrameTransformBuilder* tb = builder.getTypedObject(transfTag); @@ -341,7 +341,9 @@ CreateFrame(BasicModelBuilder& builder, else if (strcmp(name, "ExactFrame") == 0) { if (!options.shear_flag) { - opserr << OpenSees::PromptValueError << "ExactFrame3d requires shear formulation\n"; + opserr << OpenSees::PromptValueError + << "ExactFrame3d requires shear formulation" + << OpenSees::SignalMessageEnd; return nullptr; } int ndf = builder.getNDF(); @@ -361,8 +363,9 @@ CreateFrame(BasicModelBuilder& builder, } }); if (theElement == nullptr) { - opserr << OpenSees::PromptValueError << "invalid number of dofs for ExactFrame; got " << ndf - << "\n"; + opserr << OpenSees::PromptValueError + << "invalid number of dofs for ExactFrame; got " << ndf + << OpenSees::SignalMessageEnd; return nullptr; } } diff --git a/SRC/runtime/commands/modeling/geomTransf.cpp b/SRC/runtime/commands/modeling/geomTransf.cpp index 12c2726360..9cf79d8292 100644 --- a/SRC/runtime/commands/modeling/geomTransf.cpp +++ b/SRC/runtime/commands/modeling/geomTransf.cpp @@ -1,9 +1,5 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// -// // xara // //===----------------------------------------------------------------------===// @@ -12,14 +8,13 @@ // // Description: Geometric transformation command // -// Written: cmp +// cmp // #include #include #include #include #include -#include #include #include @@ -38,18 +33,15 @@ using namespace OpenSees; int -TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, - Tcl_Size argc, - const char ** const argv) +TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, int argc, + const char ** const argv) { assert(clientData != nullptr); BasicModelBuilder *builder = static_cast(clientData); // Make sure there is a minimum number of arguments if (argc < 3) { - opserr << OpenSees::PromptValueError - << "insufficient number of arguments" - << OpenSees::SignalMessageEnd; + opserr << OpenSees::PromptValueError << "insufficient number of arguments\n"; return TCL_ERROR; } @@ -62,8 +54,7 @@ TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, const char *name = argv[1]; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { opserr << OpenSees::PromptValueError - << "invalid tag" - << OpenSees::SignalMessageEnd; + << "invalid tag\n"; return TCL_ERROR; } @@ -80,9 +71,7 @@ TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, for (int i = 0; i < ndm; ++i) { if (argi == argc || Tcl_GetDouble(interp, argv[argi++], &transform.offsets[1][i]) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid offset at end I" - << OpenSees::SignalMessageEnd; + opserr << OpenSees::PromptValueError << "invalid offset at end I\n"; return TCL_ERROR; } } @@ -91,9 +80,7 @@ TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, for (int i = 0; i < ndm; ++i) { if (argi == argc || Tcl_GetDouble(interp, argv[argi++], &transform.offsets[2][i]) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid offset at end J" - << OpenSees::SignalMessageEnd; + opserr << OpenSees::PromptValueError << "invalid offset at end J\n"; return TCL_ERROR; } } diff --git a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp index 839ae4d216..8d73a37cbc 100644 --- a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp +++ b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp @@ -72,7 +72,9 @@ class FrameTransformBuilder : public TaggedObject { if (getenv("Battini")) return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); else if (getenv("Crisfield")) - return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); + return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); + else if (getenv("Crisfield02")) + return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); else return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); } From c7fa2b9fe2e88ed05754232fbdb5c5b777973770 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:36:46 -0700 Subject: [PATCH 156/261] update --- SRC/domain/node/Node.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SRC/domain/node/Node.h b/SRC/domain/node/Node.h index 11263c73c8..2267f7ec6a 100644 --- a/SRC/domain/node/Node.h +++ b/SRC/domain/node/Node.h @@ -44,9 +44,10 @@ class Element; class Vector; class Matrix; -struct Versor; class Channel; class Renderer; +namespace OpenSees {struct Versor;} +using OpenSees::Versor; class DOF_Group; class NodalThermalAction; //L.Jiang [ SIF ] From 9952b7c8317c2bf2027acc72fa6cf113a2150187 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:37:52 -0700 Subject: [PATCH 157/261] clean up --- .../Frame/Isometry/RankinIsometry.tpp | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 SRC/coordTransformation/Frame/Isometry/RankinIsometry.tpp diff --git a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.tpp b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.tpp deleted file mode 100644 index 73880ccfaa..0000000000 --- a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.tpp +++ /dev/null @@ -1,18 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures -// -//----------------------------------------------------------------------------// -// -// Please cite the following resource in any derivative works: -// -// [1] Perez, C.M., and Filippou F.C. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; -// https://doi.org/10.1002/nme.7506 -// -//===----------------------------------------------------------------------===// From 787c1d16502efd854673651900872856bb2a81ea Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 8 Jul 2025 17:01:31 -0700 Subject: [PATCH 158/261] updates --- .../Frame/BasicFrameTransf.tpp | 10 +- .../Frame/EuclidFrameTransf.h | 3 +- .../Frame/EuclidFrameTransf.tpp | 19 +- .../Frame/Isometry/CrisfieldIsometry.h | 22 +- .../Frame/Isometry/EuclidIsometry.h | 8 +- .../Frame/SouzaFrameTransf.tpp | 2 +- SRC/matrix/MatrixND.h | 207 +++++------ SRC/matrix/MatrixND.tpp | 179 +++++----- SRC/matrix/VectorND.h | 101 ++++-- SRC/matrix/VectorND.tpp | 323 ++++++++++++++++++ 10 files changed, 624 insertions(+), 250 deletions(-) diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index 8a7e662e2f..adba45c4b7 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -164,7 +164,7 @@ BasicFrameTransf3d::getGlobalResistingForce(const Vector &q_pres, const Vec { // transform resisting forces from the basic system to local coordinates - VectorND pl{}; + static VectorND pl{}; pl[0*NDF+0] = -q_pres[jnx]; // Ni pl[0*NDF+3] = -q_pres[jmx]; // Ti pl[0*NDF+4] = q_pres[imy]; @@ -174,7 +174,7 @@ BasicFrameTransf3d::getGlobalResistingForce(const Vector &q_pres, const Vec pl[1*NDF+4] = q_pres[jmy]; pl[1*NDF+5] = q_pres[jmz]; - VectorND pf; + static VectorND pf; pf.zero(); pf[0*NDF + 0] = p0[0]; pf[0*NDF + 1] = p0[1]; @@ -197,7 +197,8 @@ BasicFrameTransf3d::getGlobalStiffMatrix(const Matrix &kb, const Vector &q_ { static constexpr int nwm = ndf - 6; // Number of warping DOFs - VectorND pl{}; + static VectorND pl{}; + pl.zero(); pl[0*NDF+4] = q_pres[imy]; pl[0*NDF+5] = q_pres[imz]; pl[1*NDF+0] = q_pres[jnx]; // Nj @@ -244,7 +245,6 @@ BasicFrameTransf3d::getGlobalStiffMatrix(const Matrix &kb, const Vector &q_ t.push(kl, pl, Operation::Total); #endif - return Wrapper; } @@ -255,7 +255,7 @@ BasicFrameTransf3d::getInitialGlobalStiffMatrix(const Matrix &KB) { static double kb[6][6]; // Basic stiffness static MatrixND<2*ndf,2*ndf> kl; // Local stiffness - double tmp[6][12]{}; // Temporary storage + double tmp[6][12]{}; for (int i = 0; i < 6; i++) for (int j = 0; j < 6; j++) diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h index e0e8f8f4ba..3e8d8898a6 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.h +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -133,14 +133,13 @@ class EuclidFrameTransf: public FrameTransform std::array nodes; std::array ur; // rotation vector - std::array ux; // displacement vector + // std::array ux; // displacement vector std::array *offsets; int offset_flags; Matrix3D R0; Vector3D xi, xj, vz; double L; // undeformed element length - double Ln; // deformed element length IsoT basis; }; diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 5a699005dc..ea2f68f1a8 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -121,7 +121,6 @@ EuclidFrameTransf::initialize(std::array& new_nodes) // calculate the element length L = dx.norm(); - Ln = L; if (L == 0.0) return -2; @@ -158,7 +157,7 @@ template double EuclidFrameTransf::getDeformedLength() { - return Ln; + return basis.getLength(); } @@ -172,9 +171,7 @@ EuclidFrameTransf::update() if (basis.update(nodes) < 0) return -1; - Matrix3D R = basis.getRotation(); - - Ln = basis.getLength(); + const Matrix3D R = basis.getRotation(); for (int i=0; igetTrialRotation(); @@ -191,6 +188,7 @@ EuclidFrameTransf::getNodeRotation(int tag) return nodes[tag]->getTrialRotation(); } + template Vector3D EuclidFrameTransf::getNodeLocation(int node) @@ -347,13 +345,20 @@ EuclidFrameTransf::push(VectorND&p, Operation op) // 3,4) Rotate and joint offsets - pa = this->FrameTransform::pushConstant(pa); + // pa = this->FrameTransform::pushConstant(pa); + Matrix3D R = basis.getRotation(); + for (int i=0; i -// MatrixND int EuclidFrameTransf::push(MatrixND&kb, const VectorND& pb, diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h index 1b0d1e77c0..ed03c173d4 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h @@ -66,7 +66,9 @@ template class CrisfieldIsometry : public AlignedIsometry { public: CrisfieldIsometry(const Vector3D& vecxz) - : AlignedIsometry{vecxz}, Lr2{}, Lr3{}, v{} + : AlignedIsometry{vecxz}, + // Lr2{}, Lr3{}, + v{} { } @@ -187,9 +189,6 @@ class CrisfieldIsometry : public AlignedIsometry { for (int j = 0; j < 3; j++) A(i,j) = (double(i==j) - e[0][i]*e[0][j])/Ln; - Lr2 = this->getLMatrix(r2, r1, e[0], A); - Lr3 = this->getLMatrix(r3, r1, e[0], A); - return E; } @@ -279,7 +278,9 @@ class CrisfieldIsometry : public AlignedIsometry { &rJ1 = rJ[0], &rJ2 = rJ[1], &rJ3 = rJ[2]; - + MatrixND<12,3> Lr2,Lr3; + Lr2 = this->getLMatrix(r2, r1, e[0], A); + Lr3 = this->getLMatrix(r3, r1, e[0], A); // // // @@ -703,10 +704,17 @@ class CrisfieldIsometry : public AlignedIsometry { &rJ1 = rJ[0], &rJ2 = rJ[1], &rJ3 = rJ[2]; + + + MatrixND<12,3> Lr2,Lr3; + Lr2 = this->getLMatrix(r2, r1, e[0], A); + Lr3 = this->getLMatrix(r3, r1, e[0], A); + Matrix3D Sm{}; Sm.addSpin(rI3, m[3]); Sm.addSpin(rI1, m[1]); - MatrixND<12,3> kbar{}; + static MatrixND<12,3> kbar; + kbar.zero(); kbar.addMatrixProduct(Lr2, Sm, -1.0); Sm.zero(); @@ -867,7 +875,7 @@ class CrisfieldIsometry : public AlignedIsometry { Vector3D v; Vector3D r1, r2, r3; Vector3D e[3], rI[3], rJ[3]; - MatrixND<12,3> Lr2, Lr3; + // MatrixND<12,3> Lr2, Lr3; // double Ln; }; } \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h index 62d4eb9928..1efc584b10 100644 --- a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h @@ -168,7 +168,7 @@ class AlignedIsometry : public Isometry } virtual Vector3D - getRotationVariation(int ndf, double* du) { + getRotationVariation(int ndf, double* du) final { // psi_r = omega Vector3D w{}; for (int i=0; i protected: constexpr static int ic = 0; // std::floor(0.5*(nn+1)); - enum { pres, prev, init}; + enum { pres, init}; double L, Ln; Vector3D vz, dX, Xc; - Matrix3D R[3]; - Vector3D c[3]; + Matrix3D R[2]; + Vector3D c[2]; Matrix3D dR; // std::array& nodes; std::array* offsets = nullptr; // offsets diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp index 66f5533b83..021baa7d32 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp @@ -394,7 +394,7 @@ SouzaFrameTransf::push(MatrixND& kl, const VectorND& pl, Operation op) { - MatrixND<12,12> K; + static MatrixND<12,12> K; K.addMatrixTripleProduct(0.0, T, kl, 1.0); // Add geometric part kg diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index 4fabb2cd74..d4ddbc34e4 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -39,33 +39,39 @@ #include "VectorND.h" #include "Matrix.h" #include "Vector.h" +#include "routines/SY3.h" -#if __cplusplus < 202000L -# define consteval -# define requires(X) -#endif #define G23_STACK_MAX 10 namespace OpenSees { template -requires(NR > 0 && NC > 0) -struct MatrixND { +struct alignas(64) MatrixND { double values[NC][NR]; + // std::array values; - // MatrixND(const MatrixND&) = default; // Convert to regular Matrix class - operator Matrix() { return Matrix(&values[0][0], NR, NC);} + operator Matrix() { return Matrix(&(*this)(0,0), NR, NC);} + + operator const Matrix() const { return Matrix(&(*this)(0,0), NR, NC);} - operator const Matrix() const { return Matrix(&values[0][0], NR, NC);} + int + symeig(VectorND& vals) + { + static_assert(NR == 3 && NC == 3); + double work[3][3]; + cmx_eigSY3(values, work, vals.values); + return 0; + } - consteval void zero(); + constexpr void zero() noexcept; + constexpr double determinant() const ; - constexpr MatrixND transpose() const; + constexpr MatrixND transpose() const noexcept; - MatrixND& addDiagonal(const double vol) requires(NR == NC); + constexpr MatrixND& addDiagonal(const double vol) noexcept; template void addMatrix(const MatT& A, const double scale); @@ -100,17 +106,16 @@ struct MatrixND { template void map(F func) const; template void map(F func, MatrixND& destination); - template MatrixND& addSpin(const VecT& V); - template MatrixND& addSpin(const VecT& V, double scale); - template MatrixND& addSpinSquare(const VecT& V, double scale); - template void addSpinProduct(const VecT& a, const VectorND& b, double scale); - template void addMatrixSpinProduct(const MatrixND& A, const VecT& b, double scale); - template void addSpinMatrixProduct(const VectorND& a, const MatT& B, double scale); + template constexpr MatrixND& addSpin(const VecT& V) noexcept; + template constexpr MatrixND& addSpin(const VecT& V, double scale) noexcept; + template constexpr MatrixND& addSpinSquare(const VecT& V, double scale) noexcept; + template constexpr void addSpinProduct(const VecT& a, const VectorND& b, double scale) noexcept; + template constexpr void + addMatrixSpinProduct(const MatrixND& A, const VecT& b, double scale) noexcept; + template constexpr void + addSpinMatrixProduct(const VectorND& a, const MatT& B, double scale) noexcept; int invert(MatrixND &) const; - int invert() { - return Matrix(*this).Invert(); - } #if 0 //template @@ -128,60 +133,51 @@ struct MatrixND { // // Indexing // - constexpr std::array & - operator[](index_t index) - { - return values[index]; - } - - constexpr const std::array & - operator[](index_t index) const - { - return values[index]; - } - // (i,j) indexing constexpr T & - operator()(index_t index_r, index_t index_c) { + operator()(index_t index_r, index_t index_c) noexcept { assert(index_r >= 0 && index_c >= 0); assert(index_r < NR && index_c < NC); return values[index_c][index_r]; } inline constexpr const T & - operator()(index_t index_r, index_t index_c) const { + operator()(index_t index_r, index_t index_c) const noexcept { assert(index_r >= 0 && index_c >= 0); assert(index_r < NR && index_c < NC); return values[index_c][index_r]; } + // constexpr T& operator()(int i, int j) noexcept { return values[j*NR + i]; } + // constexpr const T& operator()(int i, int j) const noexcept { return values[j*NR + i]; } + constexpr MatrixND & - operator=(const Matrix &other) + operator=(const Matrix &other) noexcept { for (index_t j = 0; j < NC; ++j) { for (index_t i = 0; i < NR; ++i) { - values[j][i] = other(i,j); + (*this)(i,j) = other(i,j); } } return *this; } constexpr MatrixND & - operator+=(const double value) { + operator+=(const double value) noexcept { for (index_t j = 0; j < NC; ++j) { for (index_t i = 0; i < NR; ++i) { - values[j][i] += value; + (*this)(i,j) += value; } } return *this; } constexpr MatrixND & - operator+=(const MatrixND &other) { + operator+=(const MatrixND &other) noexcept { for (index_t j = 0; j < NC; ++j) { for (index_t i = 0; i < NR; ++i) { - values[j][i] += other.values[j][i]; + (*this)(i,j) += other(i,j); } } return *this; @@ -192,37 +188,37 @@ struct MatrixND { { for (index_t j = 0; j < NC; ++j) for (index_t i = 0; i < NR; ++i) - values[j][i] -= other.values[j][i]; + (*this)(i,j) -= other(i,j); return *this; } inline constexpr MatrixND & - operator*=(T const scalar) + operator*=(T const scalar) noexcept { for (index_t j = 0; j < NC; ++j) for (index_t i = 0; i < NR; ++i) - values[j][i] *= scalar; + (*this)(i,j) *= scalar; return *this; } inline constexpr MatrixND & - operator/=(T const scalar) + operator/=(T const scalar) noexcept { for (index_t j = 0; j < NC; ++j) for (index_t i = 0; i < NR; ++i) - values[j][i] /= scalar; + (*this)(i,j) /= scalar; return *this; } inline constexpr VectorND - operator^(const VectorND &V) const + operator^(const VectorND &V) const noexcept { VectorND result; - const double *dataPtr = &values[0][0]; + const double *dataPtr = &(*this)(0,0); for (int i=0; i &V, VectorND &res) const - requires(NR == NC) + int + solve(const VectorND &V, VectorND &res) const noexcept { + static_assert(NR == NC); + MatrixND work = *this; int pivot_ind[NR]; int nrhs = 1; @@ -258,34 +256,34 @@ struct MatrixND { int nc = NC; int info = 0; res = V; // X will be overwritten with the solution - DGESV(&nr, &nrhs, &work.values[0][0], &nr, pivot_ind, res.values, &nc, &info); + DGESV(&nr, &nrhs, &work(0,0), &nr, pivot_ind, res.values, &nc, &info); return -abs(info); } template - // requires (NR == NC) && (n == NR) && (n > 0) - int solve(const MatrixND& M, MatrixND& X) const + int solve(const MatrixND& M, MatrixND& X) const noexcept { - static_assert(n == NR, "RHS row-count must match A."); - - MatrixND work = *this; // copy of A to be factorised - int ipiv[NR]{}; - - int n_eq = NR; // order of the system - int nrhs = n; // number of RHS columns - int lda = NR; // leading dim of A - int ldb = NR; // leading dim of X - int info = 0; - - X = M; // copy RHS, DGESV overwrites - DGESV(&n_eq, &nrhs, - work.values[0], &lda, - &ipiv[0], - X.values[0], &ldb, - &info); - - return -std::abs(info); + static_assert(NR == NC, "Matrix must be square."); + static_assert(n == NR, "RHS row-count must match A."); + + MatrixND work = *this; // copy of A to be factorised + int ipiv[NR]{}; + + int n_eq = NR; // order of the system + int nrhs = n; // number of RHS columns + int lda = NR; // leading dim of A + int ldb = NR; // leading dim of X + int info = 0; + + X = M; // copy RHS, DGESV overwrites + DGESV(&n_eq, &nrhs, + &work(0,0), &lda, + &ipiv[0], + &X(0,0), &ldb, + &info); + + return -std::abs(info); } // int solve(const Vector &V, Vector &res) const @@ -324,7 +322,7 @@ struct MatrixND { template inline MatrixND - extract() const + extract() const noexcept { MatrixND m; for (int i=0; i inline MatrixND - extract(int row0, int col0) const + extract(int row0, int col0) const noexcept { MatrixND m; for (int i=0; i inline void - insert(const MatrixND &M, double fact) + template + inline constexpr void + insert(const MatrixND &M, double fact) noexcept { constexpr int final_row = init_row + nr - 1; @@ -362,8 +361,9 @@ struct MatrixND { } } - template inline void - insert(const MatrixND &M, int init_row, int init_col, double fact) + template + inline constexpr void + insert(const MatrixND &M, int init_row, int init_col, double fact) noexcept { [[maybe_unused]] int final_row = init_row + nr - 1; @@ -379,8 +379,9 @@ struct MatrixND { } } - template inline void - assemble(const MatrixND &M, int init_row, int init_col, double fact) + template + constexpr inline void + assemble(const MatrixND &M, int init_row, int init_col, double fact) noexcept { [[maybe_unused]] int final_row = init_row + nr - 1; @@ -436,11 +437,9 @@ struct MatrixND { inline constexpr friend MatrixND operator*(const MatrixND &left, const MatrixND &right) { MatrixND prod; -#if 0 if constexpr (NR*NC > 16) prod.addMatrixProduct(0, left, right, 1); else -#endif for (index_t i = 0; i < NR; ++i) { for (index_t j = 0; j < J; ++j) { prod(i, j) = 0.0; @@ -467,25 +466,7 @@ struct MatrixND { return prod; } - template - inline constexpr friend MatrixND - operator^(const MatrixND &left, const MatrixND &right) { - MatrixND prod; - if constexpr (0 && NR*NC > 16) - prod.addMatrixTransposeProduct(0.0, left, right, 1.0); - else - for (index_t i = 0; i < NC; ++i) { - for (index_t j = 0; j < K; ++j) { - prod(i, j) = 0.0; - for (index_t k = 0; k < NR; ++k) { - prod(i, j) += left(k,i) * right(k,j); - } - } - } - return prod; - } - - + // Matrix*Vector constexpr friend VectorND operator*(const MatrixND &left, const VectorND &right) { VectorND prod; @@ -510,6 +491,26 @@ struct MatrixND { return prod; } + + template + inline constexpr friend MatrixND + operator^(const MatrixND &left, const MatrixND &right) { + MatrixND prod; + if constexpr (NR*NC > 16) + prod.addMatrixTransposeProduct(0.0, left, right, 1.0); + else { + for (index_t i = 0; i < NC; ++i) { + for (index_t j = 0; j < K; ++j) { + prod(i, j) = 0.0; + for (index_t k = 0; k < NR; ++k) { + prod(i, j) += left(k,i) * right(k,j); + } + } + } + } + return prod; + } + friend constexpr MatrixND operator/(MatrixND mat, T scalar) { mat /= scalar; diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index 78dd7ec459..7ec1312c74 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -21,25 +21,46 @@ MatrixND(const T (&)[nc][nr])->MatrixND; template -void -MatrixND::zero() +constexpr void +MatrixND::zero() noexcept { - for (index_t j = 0; j < nc; ++j) { - for (index_t i = 0; i < nr; ++i) { - values[j][i] = 0.0; - } +#if 1 + for (index_t j = 0; j < nc; ++j) { + for (index_t i = 0; i < nr; ++i) { + values[j][i] = 0.0; } + } +#else + values.fill(T{}); +#endif } +#if 0 +template +constexpr double +MatrixND::determinant() const +{ + static_assert(nr == nc, "Matrix must be square"); + static_assert(nr > 1 && nr < 4, "Matrix must be between 2x2 and 3x3"); + if constexpr (nr == 2) { + return values[0][0] * values[1][1] - values[0][1] * values[1][0]; + } + if constexpr (nr == 3) { + return values[0][0] * (values[1][1] * values[2][2] - values[1][2] * values[2][1]) - + values[0][1] * (values[1][0] * values[2][2] - values[1][2] * values[2][0]) + + values[0][2] * (values[1][0] * values[2][1] - values[1][1] * values[2][0]); + } +} +#endif template constexpr MatrixND -MatrixND::transpose() const +MatrixND::transpose() const noexcept { MatrixND result = {}; for (index_t j = 0; j < nc; ++j) { for (index_t i = 0; i < nr; ++i) { - result.values[i][j] = values[j][i]; + result(j,i) = (*this)(i,j); } } return result; @@ -120,35 +141,56 @@ template inline int MatrixND::invert(MatrixND &M) const { static_assert(nr == nc, "Matrix must be square"); - static_assert(nr > 1 && nr < 7, "Matrix must be between 2x2 and 6x6"); + // static_assert(nr > 1 && nr < 7, "Matrix must be between 2x2 and 6x6"); int status = -1; if constexpr (nr == 2) { - cmx_inv2(&this->values[0][0], &M.values[0][0], &status); + cmx_inv2(&(*this)(0,0), &M(0,0), &status); return status; } if constexpr (nr == 3) { - cmx_inv3(&this->values[0][0], &M.values[0][0], &status); + cmx_inv3(&(*this)(0,0), &M(0,0), &status); return status; } if constexpr (nr == 4) { - cmx_inv4(&this->values[0][0], &M.values[0][0], &status); + cmx_inv4(&(*this)(0,0), &M(0,0), &status); return status; } if constexpr (nr == 5) { - cmx_inv5(&this->values[0][0], &M.values[0][0], &status); + cmx_inv5(&(*this)(0,0), &M(0,0), &status); return status; } if constexpr (nr == 6) { - cmx_inv6(&this->values[0][0], &M.values[0][0], &status); + cmx_inv6(&(*this)(0,0), &M(0,0), &status); return status; } + + // Use Lapack + M.zero(); + M.addDiagonal(1.0); // Identity matrix + + MatrixND work = *this; + + int pivot_ind[nr]; + int nrhs = nr; + int info = 0; + int m = nr; + int n = nc; + DGESV(&m, + &nrhs, + &work(0,0), &m, + pivot_ind, + &M(0,0), + &n, + &info); + if (info != 0) + status = -std::abs(info); return status; } -template inline -MatrixND& -MatrixND::addDiagonal(const double diag) +template +constexpr MatrixND& +MatrixND::addDiagonal(const double diag) noexcept { for (int i=0; i inline void MatrixND::addMatrixProduct(const MatrixND& A, const MatT& B, double scale) { - if constexpr (nr*nc < 16) + if constexpr (nr*nc < 48) for (int i=0; i::addMatrixProduct(const MatrixND& A, const MatT& } } -#if 0 +#if 1 template template inline void -MatrixND::addMatrixProduct(double scale_this, const MatrixND& A, const MatT& B, double scale) +MatrixND::addMatrixProduct(double scale_this, + const MatrixND& A, + const MatT& B, double scale) { int m = nr, n = nc, @@ -242,8 +287,8 @@ MatrixND::addMatrixTransposeProduct(double thisFact, double *aijPtr = &values[0][0]; for (int j=0; j::addMatrixTransposeProduct(double thisFact, double *aijPtr = &values[0][0]; for (int j=0; j::addMatrixTransposeProduct(double thisFact, double *aijPtr = &values[0][0]; for (int j=0; j::addMatrixTransposeProduct(double thisFact, } } } -#if 0 - if (thisFact == 1.0) { - for (int j=0; j::addMatrixTripleProduct( const MatrixND &T, const MatrixND &B, double otherFact) - requires(nr == nc) + //requires(nr == nc) { if (otherFact == 0.0 && thisFact == 1.0) return 0; @@ -320,27 +344,6 @@ MatrixND::addMatrixTripleProduct( BT.zero(); BT.addMatrixProduct(B, T, otherFact); this->addMatrixTransposeProduct(thisFact, T, BT, 1.0); - -#if 0 - { - int m = B.numRows, - n = T.numCols, - k = B.numCols, - nrT = T.numRows; - //k = T.numRows; - double zero = 0.0, - one = 1.0; - - DGEMM ("N", "N", &m , &n , &k,&one , B.data, &m, // m - T.data, &nrT, // k - &zero, matrixWork, &m); - - DGEMM ("T", "N", &numRows, &numCols, &k,&otherFact, T.data, &nrT, - matrixWork, &m, // k - &thisFact, data, &numRows); - return 0; - } -#endif return 0; } @@ -370,9 +373,11 @@ MatrixND::addMatrixTripleProduct(double thisFact, template template -inline MatrixND& -MatrixND::addSpin(const VecT& v) requires(NR == 3) +constexpr MatrixND& +MatrixND::addSpin(const VecT& v) noexcept { + static_assert(NR == 3 && NC == 3, "addSpin requires a 3x3 matrix"); + const double v0 = v[0], v1 = v[1], v2 = v[2]; @@ -387,8 +392,8 @@ MatrixND::addSpin(const VecT& v) requires(NR == 3) template template -inline MatrixND& -MatrixND::addSpin(const VecT& v, double mult) +constexpr MatrixND& +MatrixND::addSpin(const VecT& v, double mult) noexcept { const double v0 = mult*v[0], v1 = mult*v[1], @@ -402,11 +407,12 @@ MatrixND::addSpin(const VecT& v, double mult) template -template inline +template +constexpr MatrixND& -MatrixND::addSpinSquare(const VecT& v, const double scale) - requires(NR == NC == 3) +MatrixND::addSpinSquare(const VecT& v, const double scale) noexcept { + static_assert(NR == 3 && NC == 3, "addSpinSquare requires a 3x3 matrix"); const double v1 = v[0], v2 = v[1], v3 = v[2]; @@ -427,21 +433,21 @@ MatrixND::addSpinSquare(const VecT& v, const double scale) template template -inline void -MatrixND::addSpinProduct(const VecT& a, const VectorND& b, const double scale) - requires(NR == NC == 3) +constexpr void +MatrixND::addSpinProduct(const VecT& a, const VectorND& b, const double scale) noexcept { // a^b^ = boa - a.b 1 // where 'o' denotes the tensor product and '.' the dot product // + static_assert(NR == 3 && NC == 3, "Matrix must be 3x3"); this->addTensorProduct(b, a, scale); this->addDiagonal(-b.dot(a)*scale); } template template -inline void -MatrixND::addMatrixSpinProduct(const MatrixND& A, const VecT& b, const double scale) +constexpr void +MatrixND::addMatrixSpinProduct(const MatrixND& A, const VecT& b, const double scale) noexcept { // this += s*A*[b^] // where b^ is the skew-symmetric representation of the three-vector b, s is a scalar, @@ -459,10 +465,11 @@ MatrixND::addMatrixSpinProduct(const MatrixND& A, const VecT& } template -template inline -void MatrixND::addSpinMatrixProduct(const VectorND& a, const MatT& B, const double scale) - requires(NR == NC == 3) +template +constexpr void +MatrixND::addSpinMatrixProduct(const VectorND& a, const MatT& B, const double scale) noexcept { + static_assert(NR == 3 && NC == 3, "Matrix must be 3x3"); // this += s*[a^]*B // where a^ is the skew-symmetric representation of the three-vector a, s is a scalar, // and B a 3x3 matrix. @@ -477,4 +484,4 @@ void MatrixND::addSpinMatrixProduct(const VectorND& a, const MatT (*this)(2, 1) += scale*( -B(0,1)*a[1] + B(1,1)*a[0]); (*this)(2, 2) += scale*( -B(0,2)*a[1] + B(1,2)*a[0]); } -} // namespace OpenSees \ No newline at end of file +} // namespace OpenSees diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index 90b4a19adf..ffcadcdc19 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -33,10 +33,8 @@ #include #include -#if __cplusplus < 202000L -# define consteval -# define requires(X) -#endif + +// #define XARA_VECTOR_FRIENDS namespace OpenSees { @@ -45,7 +43,6 @@ typedef int index_t; template struct MatrixND; template -requires(N > 0) struct VectorND { T values[N]; @@ -70,24 +67,52 @@ struct VectorND { VectorND extract(int a) noexcept; - consteval int + int + addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept; + + VectorND &addCross(const VectorND& a, const VectorND &b, double fact = 1.0) { + static_assert(N == 3); + values[0] += fact * (a.values[1] * b.values[2] - a.values[2] * b.values[1]); + values[1] += fact * (a.values[2] * b.values[0] - a.values[0] * b.values[2]); + values[2] += fact * (a.values[0] * b.values[1] - a.values[1] * b.values[0]); + return *this; + } + +#ifdef XARA_VECTOR_FRIENDS + template + inline int + addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact); + + template + inline int + addMatrixTransposeVector(double thisFact, const MatrixND &m, + const Vector &v, double otherFact); + + inline int + addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact); + + int + addVector(const T thisFact, const Vector &other, const T otherFact) noexcept; +#endif + + constexpr int size() const { return N; } - consteval inline void + constexpr inline void fill(double value) { for (T& item : values) item = value; } - consteval inline void + constexpr inline void zero() { for (T& item : values ) item = 0.0; } - template inline + template constexpr T dot(const VecT &other) const noexcept { T sum = 0.0; @@ -100,7 +125,7 @@ struct VectorND { // Tensor product, also known as the "bun" product template constexpr inline MatrixND - bun(const VectorND &other) const { + bun(const VectorND &other) const noexcept { if constexpr (N == 3 && nc == 3) return MatrixND {{ {values[0]*other[0], values[1]*other[0], values[2]*other[0]}, @@ -120,24 +145,27 @@ struct VectorND { } // Return the cross product this vector with another vector, b. - template inline constexpr - void - cross(const VecB& b, VecC& c) requires(N==3) const noexcept { - c[0] = values[1] * b[2] - values[2] * b[1]; - c[1] = values[2] * b[0] - values[0] * b[2]; - c[2] = values[0] * b[1] - values[1] * b[0]; - return c; + template + constexpr void + cross(const VecB& b, VecC& c) const noexcept { + static_assert(N == 3, "Cross product is only defined for 3D vectors."); + c[0] = values[1] * b[2] - values[2] * b[1]; + c[1] = values[2] * b[0] - values[0] * b[2]; + c[2] = values[0] * b[1] - values[1] * b[0]; + return c; } - template inline constexpr - VectorND - cross(const Vec3T& b) const noexcept requires(N==3) { - VectorND<3> c; - c[0] = values[1] * b[2] - values[2] * b[1]; - c[1] = values[2] * b[0] - values[0] * b[2]; - c[2] = values[0] * b[1] - values[1] * b[0]; - return c; + template + constexpr VectorND + cross(const Vec3T& b) const noexcept { + static_assert(N == 3, "Cross product is only defined for 3D vectors."); + // Return a new vector that is the cross product of this vector and b. + VectorND<3> c; + c[0] = values[1] * b[2] - values[2] * b[1]; + c[1] = values[2] * b[0] - values[0] * b[2]; + c[2] = values[0] * b[1] - values[1] * b[0]; + return c; } @@ -146,7 +174,8 @@ struct VectorND { return std::sqrt(std::fabs(this->dot(*this))); } - inline double normalize() { + inline double + normalize() { double n = norm(); if (n != 0.0) @@ -158,17 +187,19 @@ struct VectorND { // inline constexpr T& - operator[](index_t index) { + operator[](index_t index) noexcept { + assert(index >= 0 && index < N); return values[index]; } inline constexpr const T& - operator[](index_t index) const { + operator[](index_t index) const noexcept { + assert(index >= 0 && index < N); return values[index]; } inline constexpr T& - operator()(index_t index) { + operator()(index_t index) noexcept { return values[index]; } @@ -186,7 +217,7 @@ struct VectorND { inline VectorND & - operator/=(const double &right) { + operator/=(const double &right) noexcept { for (index_t i=0; i< N; i++) values[i] /= right; return *this; @@ -194,7 +225,7 @@ struct VectorND { inline VectorND - operator/(const double &right) const { + operator/(const double &right) const noexcept { VectorND res(*this); res /= right; return res; @@ -224,9 +255,9 @@ struct VectorND { return *this; } - inline + constexpr inline VectorND & - operator+=(const Vector &right) { + operator+=(const Vector &right) noexcept { assert(right.Size() == N); for (int i=0; i< N; i++) values[i] += right[i]; @@ -262,8 +293,8 @@ struct VectorND { #include "VectorND.tpp" template -inline OpenSees::VectorND -operator * (double a, const OpenSees::VectorND& b) { +constexpr inline OpenSees::VectorND +operator * (double a, const OpenSees::VectorND& b) noexcept { return b * a; } diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index 6bfe26e162..ea35a60018 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -8,6 +8,7 @@ // #include #include "VectorND.h" +#include "blasdecl.h" namespace OpenSees { @@ -61,4 +62,326 @@ VectorND::extract(int a) noexcept return v; } +#ifdef XARA_VECTOR_FRIENDS +template +int +VectorND::addVector(const T thisFact, const Vector &other, const T otherFact) noexcept +{ + if (otherFact == 0.0 && thisFact == 1.0) + return 0; + + else if (thisFact == 1.0) { + // want: this += other * otherFact + double *dataPtr = values; + double *otherDataPtr = other.theData; + if (otherFact == 1.0) { + // no point doing a multiplication if otherFact == 1.0 + for (int i=0; i +int +VectorND::addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept +{ + if (otherFact == 0.0 && thisFact == 1.0) + return 0; + + else if (thisFact == 1.0) { + // want: this += other * otherFact + double *dataPtr = values; + const double * otherDataPtr = other.values; + if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0 + for (int i=0; i +template +inline int +VectorND::addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact) +{ + // check the sizes are compatable + assert(NC == v.sz); + + // see if quick return + if (thisFact == 1.0 && otherFact == 0.0) + return 0; + + else { + int incr = 1, + i = N, + n = NC; + DGEMV("N", &i, &n, + &otherFact, + &m.values[0][0], &i, + v.theData, &incr, + &thisFact, + values, + &incr); + + return 0; + } +} + + +template +template +inline int +VectorND::addMatrixTransposeVector(double thisFact, const MatrixND &m, const Vector &v, double otherFact) +{ + // check the sizes are compatable + assert(NR == v.sz); + + + if (thisFact == 1.0 && otherFact == 0.0) + return 0; + + else { + int incr = 1, + i = NR, + n = N; + DGEMV("T", &i, &n, + &otherFact, + &m.values[0][0], &i, + v.theData, &incr, + &thisFact, + values, &incr); + return 0; + } +} + + +template +inline int +VectorND::addMatrixVector(const double thisFact, const Matrix &m, const Vector &v, const double otherFact) +{ + // check the sizes are compatable + assert(N == m.noRows()); + assert(m.noCols() == v.sz); + + // see if quick return + if (thisFact == 1.0 && otherFact == 0.0) + return 0; + +#ifdef VECTOR_BLAS + else if (v.sz > 10) { + int incr = 1, + i = m.numRows, + n = m.numCols; + return + DGEMV("N", &i, &n, + &otherFact, + m.data, &i, + v.theData, &incr, + &thisFact, + values, &incr); + } +#endif + + else if (thisFact == 1.0) { + + // want: this += m * v * otherFact + if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0 + int otherSize = v.sz; + double *matrixDataPtr = m.data; + const double *otherDataPtr = v.theData; + for (int i=0; i Date: Tue, 8 Jul 2025 17:19:59 -0700 Subject: [PATCH 159/261] cleaning up --- .../Frame/Isometry/CrisfieldIsometry.h | 46 ++++++------ .../Frame/Isometry/EuclidIsometry.h | 3 +- .../Frame/Isometry/RankinIsometry.h | 5 +- SRC/matrix/MatrixND.h | 11 +-- SRC/matrix/MatrixND.tpp | 74 +++++-------------- SRC/matrix/VectorND.h | 2 +- .../transform/FrameTransformBuilder.hpp | 3 +- 7 files changed, 47 insertions(+), 97 deletions(-) diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h index ed03c173d4..190bd14bfe 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h @@ -289,21 +289,21 @@ class CrisfieldIsometry : public AlignedIsometry { // T1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', O', O']'; // (-S(rI3)*e2 + S(rI2)*e3) - Vector3D Se = rI2.cross(e3); - Se -= rI3.cross(e2); + Vector3D rxe = rI2.cross(e3); + rxe -= rI3.cross(e2); for (int i = 0; i < 3; i++) - T(imx,i+3) = Se[i]; + T(imx,i+3) = rxe[i]; // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; Vector3D At = A*rI2; // (-S(rI2)*e1 + S(rI1)*e2)' - Se = rI1.cross(e2); - Se -= rI2.cross(e1); + rxe = rI1.cross(e2); + rxe -= rI2.cross(e1); for (int i = 0; i < 3; i++) { T(imz,i ) = At[i]; - T(imz,i+3) = Se[i]; + T(imz,i+3) = rxe[i]; T(imz,i+6) = -At[i]; } @@ -312,38 +312,38 @@ class CrisfieldIsometry : public AlignedIsometry { At = A*rI3; // -S(rI3)*e1 + S(rI1)*e3 - Se = rI1.cross(e3); - Se -= rI3.cross(e1); + rxe = rI1.cross(e3); + rxe -= rI3.cross(e1); for (int i = 0; i < 3; i++) { - T(imy,i ) = At[i]*-1; - T(imy,i+3) = Se[i]*-1; - T(imy,i+6) = -At[i]*-1; + T(imy,i ) = - At[i]; + T(imy,i+3) = -rxe[i]; + T(imy,i+6) = At[i]; } // T4 = [ O', O', O', (-S(rJ3)*e2 + S(rJ2)*e3)']'; - Se = rJ2.cross(e3); - Se -= rJ3.cross(e2); + rxe = rJ2.cross(e3); + rxe -= rJ3.cross(e2); for (int i = 0; i < 3; i++) - T(jmx, i+9) = Se[i]; // S(rJ2)*e3 - S(rJ3)*e2 + T(jmx, i+9) = rxe[i]; // S(rJ2)*e3 - S(rJ3)*e2 // T5 = [(A*rJ2)', O', -(A*rJ2)', (-S(rJ2)*e1 + S(rJ1)*e2)']'; At = A*rJ2; - Se = rJ1.cross(e2); - Se -= rJ2.cross(e1); + rxe = rJ1.cross(e2); + rxe -= rJ2.cross(e1); for (int i = 0; i < 3; i++) { T(jmz, i ) = At[i]; T(jmz, i+6) = -At[i]; - T(jmz, i+9) = Se[i]; // (-S(rJ2)*e1 + S(rJ1)*e2) + T(jmz, i+9) = rxe[i]; // (-S(rJ2)*e1 + S(rJ1)*e2) } // T6 = [(A*rJ3)', O', -(A*rJ3)', (-S(rJ3)*e1 + S(rJ1)*e3)']' - At = A*rJ3; - Se = rJ1.cross(e3); // (-S(rJ3)*e1 + S(rJ1)*e3) - Se -= rJ3.cross(e1); + At = A*rJ3; + rxe = rJ1.cross(e3); // (-S(rJ3)*e1 + S(rJ1)*e3) + rxe -= rJ3.cross(e1); for (int i = 0; i < 3; i++) { - T(jmy,i ) = At[i]*-1; - T(jmy,i+6) = -At[i]*-1; - T(jmy,i+9) = Se[i]*-1; + T(jmy,i ) = -At[i]; + T(jmy,i+6) = At[i]; + T(jmy,i+9) = -rxe[i]; } // diff --git a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h index 1efc584b10..32afddd6e7 100644 --- a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h @@ -223,13 +223,12 @@ class AlignedIsometry : public Isometry protected: constexpr static int ic = 0; // std::floor(0.5*(nn+1)); - enum { pres, init}; + enum {pres, init}; double L, Ln; Vector3D vz, dX, Xc; Matrix3D R[2]; Vector3D c[2]; Matrix3D dR; - // std::array& nodes; std::array* offsets = nullptr; // offsets }; diff --git a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h index f96318e0e6..a42a3e22ba 100644 --- a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h @@ -37,7 +37,6 @@ #include "EuclidIsometry.h" class Node; -#define TRIAD C2 namespace OpenSees { @@ -173,7 +172,7 @@ class RankinIsometry : public AlignedIsometry double n = 0; - #if __cplusplus >= 202000L +#if __cplusplus >= 202000L static inline consteval MatrixND<12,3> MakePsi() { @@ -193,7 +192,7 @@ class RankinIsometry : public AlignedIsometry Gamma.template insert<6,0>(ex, -1.0); return Gamma; } - #endif +#endif }; } // namespace OpenSees \ No newline at end of file diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index d4ddbc34e4..c1a0850dad 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -34,12 +34,10 @@ #include #include #include -#include #include "VectorND.h" #include "Matrix.h" #include "Vector.h" -#include "routines/SY3.h" #define G23_STACK_MAX 10 @@ -57,14 +55,7 @@ struct alignas(64) MatrixND { operator const Matrix() const { return Matrix(&(*this)(0,0), NR, NC);} - int - symeig(VectorND& vals) - { - static_assert(NR == 3 && NC == 3); - double work[3][3]; - cmx_eigSY3(values, work, vals.values); - return 0; - } + int symeig(VectorND& vals); constexpr void zero() noexcept; constexpr double determinant() const ; diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index 7ec1312c74..9d59c3eba7 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -10,9 +10,7 @@ // #pragma once #include "MatrixND.h" -#include "blasdecl.h" -#include "routines/cmx.h" -#include "routines/SY3.h" + namespace OpenSees { @@ -35,6 +33,16 @@ MatrixND::zero() noexcept #endif } + +template +int +MatrixND::symeig(VectorND& vals) +{ + static_assert(nr == nc, "Matrix must be square"); + static_assert(rc == 3 && nc == 3); + return -1; +} + #if 0 template constexpr double @@ -141,7 +149,6 @@ template inline int MatrixND::invert(MatrixND &M) const { static_assert(nr == nc, "Matrix must be square"); - // static_assert(nr > 1 && nr < 7, "Matrix must be between 2x2 and 6x6"); int status = -1; if constexpr (nr == 2) { @@ -165,26 +172,6 @@ MatrixND::invert(MatrixND &M) const return status; } - // Use Lapack - M.zero(); - M.addDiagonal(1.0); // Identity matrix - - MatrixND work = *this; - - int pivot_ind[nr]; - int nrhs = nr; - int info = 0; - int m = nr; - int n = nc; - DGESV(&m, - &nrhs, - &work(0,0), &m, - pivot_ind, - &M(0,0), - &n, - &info); - if (info != 0) - status = -std::abs(info); return status; } @@ -227,41 +214,12 @@ template inline void MatrixND::addMatrixProduct(const MatrixND& A, const MatT& B, double scale) { - if constexpr (nr*nc < 48) - for (int i=0; i(&A(0,0)), &m, - const_cast(&B(0,0)), &k, - &one, &(*this)(0,0), &m); - } + for (int i=0; i -template inline -void -MatrixND::addMatrixProduct(double scale_this, - const MatrixND& A, - const MatT& B, double scale) -{ - int m = nr, - n = nc, - k = nk; - DGEMM("N", "N", &m, &n, &k, &scale, - const_cast(&A(0,0)), &m, - const_cast(&B(0,0)), &k, - &scale_this, &(*this)(0,0), &m); -} -#endif // B'*C template @@ -272,6 +230,7 @@ MatrixND::addMatrixTransposeProduct(double thisFact, const MatT& C, double otherFact) { +#if 0 if constexpr (nr*nc > 16) { int m = nr, n = nc, @@ -282,6 +241,7 @@ MatrixND::addMatrixTransposeProduct(double thisFact, &thisFact, &(*this)(0,0), &m); return; } +#endif if (thisFact == 1.0) { double *aijPtr = &values[0][0]; diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index ffcadcdc19..08aa6578dd 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -34,7 +34,7 @@ #include -// #define XARA_VECTOR_FRIENDS +#define XARA_VECTOR_FRIENDS namespace OpenSees { diff --git a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp index 8d73a37cbc..a862357443 100644 --- a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp +++ b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp @@ -31,7 +31,8 @@ class FrameTransformBuilder : public TaggedObject { : ndm(ndm), TaggedObject(t), vz{{0, 0, 0}}, offsets{}, offset_flags(0) { - strncpy(name, n, 128); + // strncpy(name, n, 128); + snprintf(name, sizeof(name), "%s", n); // offset_flags |= LogIter; } From 8efb41d3178aa6e5d8aed2772022abe5a50e0b12 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 8 Jul 2025 17:27:54 -0700 Subject: [PATCH 160/261] clean up --- SRC/matrix/GroupSO3.h | 38 ++++++----------------- SRC/matrix/MatrixND.tpp | 67 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 70 insertions(+), 35 deletions(-) diff --git a/SRC/matrix/GroupSO3.h b/SRC/matrix/GroupSO3.h index 2c17669cf1..6680b91998 100755 --- a/SRC/matrix/GroupSO3.h +++ b/SRC/matrix/GroupSO3.h @@ -38,6 +38,7 @@ // performant. // // Written: Claudio M. Perez +// 2023 // #pragma once @@ -304,8 +305,6 @@ TanSO3(const Vector3D &vec, char repr='L') // Compute right or left differential of the exponential. // //===--------------------------------------------------------------------===// - // function by Claudio Perez 2023 - //===--------------------------------------------------------------------===// double a[4]; GibSO3(vec, a); @@ -350,8 +349,6 @@ TExpSO3(const Vector3D &v) // // T = a[1]*Eye3 + a[2]*v.hat() + a[3]*v.bun(v); // -// ========================================================================================= -// function by Claudio Perez 2023 // ----------------------------------------------------------------------------------------- // Form first Gib coefficients @@ -379,9 +376,6 @@ ddTanSO3(const Vector3D &v, const Vector3D &p, const Vector3D &q) // + vov*(c[1]*p.dot(q) + c[2]*(vxp.dot(q)) + c[3]*v.dot(p)*v.dot(q)); // // ========================================================================================= - // function by Claudio Perez 2023 - // ----------------------------------------------------------------------------------------- - // double a[4], b[4], c[4]; GibSO3(v, a, b, c); @@ -418,9 +412,6 @@ dTanSO3(const Vector3D &v, const Vector3D &p, char repr='L') // // repr 'L' or 'R' indicating left or right representation, // respectively, for the tangent space of SO(3) - // ========================================================================================= - // function by Claudio Perez 2023 - // ----------------------------------------------------------------------------------------- double a[4], b[4]; @@ -440,11 +431,6 @@ dTanSO3(const Vector3D &v, const Vector3D &p, char repr='L') inline Matrix3D dExpSO3(const Vector3D &v, const Vector3D &p) { - // - // ========================================================================================= - // function by Claudio Perez 2023 - // ----------------------------------------------------------------------------------------- - // double a[4], b[4]; GibSO3(v, a, b); @@ -484,8 +470,6 @@ LogSO3(const Matrix3D &R) // derivatives. // //===--------------------------------------------------------------------===// - // function by Claudio Perez 2023 - //===--------------------------------------------------------------------===// return VectorFromVersor(Versor::from_matrix(R)); } @@ -496,13 +480,12 @@ LogC90(const Matrix3D &R) { //===--------------------------------------------------------------------===// // - // Crisfield M (1990) A consistent co-rotational formulation for non-linear, + // Crisfield's approximation to the logarithm on SO(3) + // + // - Crisfield M (1990) A consistent co-rotational formulation for non-linear, // three-dimensional, beam-elements // //===--------------------------------------------------------------------===// - // function by Claudio Perez 2024 - //===--------------------------------------------------------------------===// - // Crisfield's approximation to the logarithm on SO(3) return Vector3D { -std::asin(0.5*(R(1,2) - R(2,1))), @@ -627,13 +610,12 @@ RescaleVector(const Vector3D &v, double &angle) inline Matrix3D dLogSO3(const Vector3D &v, double* a=nullptr) { -// -// d_R LogSO3(v) = Eye3 - 0.5*Sv + eta*Sv*Sv; -// -// ========================================================================================= -// function by Claudio Perez 2023 -// ----------------------------------------------------------------------------------------- -// + //===--------------------------------------------------------------------===// + // + // d_R LogSO3(v) = Eye3 - 0.5*Sv + eta*Sv*Sv; + // + //===--------------------------------------------------------------------===// + // double angle = v.norm(); const Vector3D u = Utility::RescaleVector(v, angle); diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index 9d59c3eba7..e38df0686e 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -11,6 +11,9 @@ #pragma once #include "MatrixND.h" +#include "blasdecl.h" +#include "routines/cmx.h" +#include "routines/SY3.h" namespace OpenSees { @@ -40,7 +43,9 @@ MatrixND::symeig(VectorND& vals) { static_assert(nr == nc, "Matrix must be square"); static_assert(rc == 3 && nc == 3); - return -1; + double work[3][3]; + cmx_eigSY3(values, work, vals.values); + return 0; } #if 0 @@ -172,6 +177,27 @@ MatrixND::invert(MatrixND &M) const return status; } + // Use Lapack + M.zero(); + M.addDiagonal(1.0); // Identity matrix + + MatrixND work = *this; + + int pivot_ind[nr]; + int nrhs = nr; + int info = 0; + int m = nr; + int n = nc; + DGESV(&m, + &nrhs, + &work(0,0), &m, + pivot_ind, + &M(0,0), + &n, + &info); + + if (info != 0) + status = -std::abs(info); return status; } @@ -214,12 +240,41 @@ template inline void MatrixND::addMatrixProduct(const MatrixND& A, const MatT& B, double scale) { - for (int i=0; i(&A(0,0)), &m, + const_cast(&B(0,0)), &k, + &one, &(*this)(0,0), &m); + } } +#if 1 +template +template inline +void +MatrixND::addMatrixProduct(double scale_this, + const MatrixND& A, + const MatT& B, double scale) +{ + int m = nr, + n = nc, + k = nk; + DGEMM("N", "N", &m, &n, &k, &scale, + const_cast(&A(0,0)), &m, + const_cast(&B(0,0)), &k, + &scale_this, &(*this)(0,0), &m); +} +#endif // B'*C template @@ -230,7 +285,6 @@ MatrixND::addMatrixTransposeProduct(double thisFact, const MatT& C, double otherFact) { -#if 0 if constexpr (nr*nc > 16) { int m = nr, n = nc, @@ -241,7 +295,6 @@ MatrixND::addMatrixTransposeProduct(double thisFact, &thisFact, &(*this)(0,0), &m); return; } -#endif if (thisFact == 1.0) { double *aijPtr = &values[0][0]; From 81e23794b2580f77ebd4e23271b0d83bed37b7b2 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 8 Jul 2025 18:45:32 -0700 Subject: [PATCH 161/261] remove blas include --- SRC/matrix/VectorND.tpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index ea35a60018..c2e3f3fb4f 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -8,7 +8,6 @@ // #include #include "VectorND.h" -#include "blasdecl.h" namespace OpenSees { @@ -384,4 +383,4 @@ VectorND::addMatrixVector(const double thisFact, const Matrix &m, const Vec return 0; } -} // namespace OpenSees \ No newline at end of file +} // namespace OpenSees From d9b46ab8b646135bf7161863969e851d8b599f03 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 8 Jul 2025 18:53:33 -0700 Subject: [PATCH 162/261] remove Vector friend --- SRC/matrix/VectorND.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index 08aa6578dd..ffcadcdc19 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -34,7 +34,7 @@ #include -#define XARA_VECTOR_FRIENDS +// #define XARA_VECTOR_FRIENDS namespace OpenSees { From 1faa9432fa6175a15c179f9224288d22b775a23b Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 8 Jul 2025 19:10:20 -0700 Subject: [PATCH 163/261] fix --- SRC/matrix/VectorND.tpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index c2e3f3fb4f..af97352e99 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -190,7 +190,7 @@ inline int VectorND::addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact) { // check the sizes are compatable - assert(NC == v.sz); + assert(NC == v.Size()); // see if quick return if (thisFact == 1.0 && otherFact == 0.0) @@ -219,7 +219,7 @@ inline int VectorND::addMatrixTransposeVector(double thisFact, const MatrixND &m, const Vector &v, double otherFact) { // check the sizes are compatable - assert(NR == v.sz); + assert(NR == v.Size()); if (thisFact == 1.0 && otherFact == 0.0) @@ -246,14 +246,14 @@ VectorND::addMatrixVector(const double thisFact, const Matrix &m, const Vec { // check the sizes are compatable assert(N == m.noRows()); - assert(m.noCols() == v.sz); + assert(m.noCols() == v.Size()); // see if quick return if (thisFact == 1.0 && otherFact == 0.0) return 0; #ifdef VECTOR_BLAS - else if (v.sz > 10) { + else if (v.Size() > 10) { int incr = 1, i = m.numRows, n = m.numCols; @@ -271,7 +271,7 @@ VectorND::addMatrixVector(const double thisFact, const Matrix &m, const Vec // want: this += m * v * otherFact if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0 - int otherSize = v.sz; + int otherSize = v.Size(); double *matrixDataPtr = m.data; const double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec } } else if (otherFact == -1.0) { // no point doing multiplication if otherFact = -1.0 - int otherSize = v.sz; + int otherSize = v.Size(); double *matrixDataPtr = m.data; const double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec } } else { // have to do the multiplication - int otherSize = v.sz; + int otherSize = v.Size(); double *matrixDataPtr = m.data; double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec if (otherFact == 1.0) { // avoid multiplication when otherFact = 1.0 - int otherSize = v.sz; + int otherSize = v.Size(); const double *matrixDataPtr = m.data; const double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec else if (otherFact == -1.0) { // avoid multiplication when otherFact = -1.0 - int otherSize = v.sz; + int otherSize = v.Size(); double *matrixDataPtr = m.data; const double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec } } else { - int otherSize = v.sz; + int otherSize = v.Size(); double *matrixDataPtr = m.data; double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec values[i] *= thisFact; if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0 - int otherSize = v.sz; + int otherSize = v.Size(); double *matrixDataPtr = m.data; double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec values[j] += *matrixDataPtr++ * otherData; } } else if (otherFact == -1.0) { // no point doing multiplication if otherFact = 1.0 - int otherSize = v.sz; + int otherSize = v.Size(); double *matrixDataPtr = m.data; double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec values[j] -= *matrixDataPtr++ * otherData; } } else { - int otherSize = v.sz; + int otherSize = v.Size(); double *matrixDataPtr = m.data; double *otherDataPtr = v.theData; for (int i=0; i Date: Tue, 8 Jul 2025 20:19:05 -0700 Subject: [PATCH 164/261] remove Vector friend --- SRC/matrix/VectorND.tpp | 124 ++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index af97352e99..7c3bf48c09 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -121,68 +121,6 @@ VectorND::addVector(const T thisFact, const Vector &other, const T otherFac return 0; } -#endif // XARA_VECTOR_FRIENDS - -template -int -VectorND::addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept -{ - if (otherFact == 0.0 && thisFact == 1.0) - return 0; - - else if (thisFact == 1.0) { - // want: this += other * otherFact - double *dataPtr = values; - const double * otherDataPtr = other.values; - if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0 - for (int i=0; i template @@ -382,5 +320,67 @@ VectorND::addMatrixVector(const double thisFact, const Matrix &m, const Vec // successfull return 0; } +#endif // XARA_VECTOR_FRIENDS + +template +int +VectorND::addVector(const T thisFact, const VectorND &other, const T otherFact) noexcept +{ + if (otherFact == 0.0 && thisFact == 1.0) + return 0; + + else if (thisFact == 1.0) { + // want: this += other * otherFact + double *dataPtr = values; + const double * otherDataPtr = other.values; + if (otherFact == 1.0) { // no point doing a multiplication if otherFact == 1.0 + for (int i=0; i Date: Wed, 9 Jul 2025 03:07:57 -0700 Subject: [PATCH 165/261] adding support for Transient -numSubLevels -numSubSteps in Python --- SRC/interpreter/OpenSeesCommands.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/SRC/interpreter/OpenSeesCommands.cpp b/SRC/interpreter/OpenSeesCommands.cpp index 0fa877a2f3..ddb846308f 100644 --- a/SRC/interpreter/OpenSeesCommands.cpp +++ b/SRC/interpreter/OpenSeesCommands.cpp @@ -861,6 +861,26 @@ OpenSeesCommands::setTransientAnalysis(bool suppress) theSOE = new ProfileSPDLinSOE(*theSolver); } + // Get the number of sub-levels and sub-steps + OPS_ResetCurrentInputArg(2); + int numSubLevels = 0; + int numSubSteps = 10; + int numData = 1; + while (OPS_GetNumRemainingInputArgs() >= 2) { + const char* opt = OPS_GetString(); + if (strcmp(opt, "-numSubLevels") == 0 || strcmp(opt, "numSubLevels") == 0) { + if (OPS_GetIntInput(&numData, &numSubLevels) < 0) { + opserr << "WARNING analysis Transient - failed to read -numSubLevels \n"; + return; + } + } else if (strcmp(opt, "-numSubSteps") == 0 || strcmp(opt, "numSubSteps") == 0) { + if (OPS_GetIntInput(&numData, &numSubSteps) < 0) { + opserr << "WARNING analysis Transient - failed to read -numSubSteps \n"; + return; + } + } + } + theTransientAnalysis = new DirectIntegrationAnalysis(*theDomain, *theHandler, *theNumberer, @@ -868,7 +888,7 @@ OpenSeesCommands::setTransientAnalysis(bool suppress) *theAlgorithm, *theSOE, *theTransientIntegrator, - theTest); + theTest, numSubLevels, numSubSteps); if (theEigenSOE != 0) { theTransientAnalysis->setEigenSOE(*theEigenSOE); } From aaa3312a794c5443abbc231412eba8a6dbeb7357 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 10 Jul 2025 23:05:20 -0700 Subject: [PATCH 166/261] change matrix layout --- .../Frame/BasicFrameTransf.tpp | 44 +++++--- .../Frame/EuclidFrameTransf.tpp | 27 +++-- .../Frame/Isometry/CrisfieldIsometry.h | 2 +- .../Frame/Isometry/EuclidIsometry.h | 3 +- .../Frame/Isometry/RankinIsometry.h | 1 + .../Frame/LinearFrameTransf.h | 2 +- .../Frame/LinearFrameTransf.tpp | 14 +-- .../Frame/PDeltaFrameTransf3d.tpp | 1 + .../Frame/SouzaFrameTransf.h | 4 - .../Frame/SouzaFrameTransf.tpp | 14 +-- SRC/matrix/GroupSO3.h | 12 +-- SRC/matrix/MatrixND.h | 100 ++++++++---------- SRC/matrix/MatrixND.tpp | 15 +-- SRC/matrix/VectorND.h | 11 +- SRC/matrix/VectorND.tpp | 33 +++--- 15 files changed, 144 insertions(+), 139 deletions(-) diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index adba45c4b7..ae01d7bf2e 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -41,6 +41,7 @@ template int BasicFrameTransf3d::commitState() { + // linear.commit(); return t.commit(); } @@ -48,6 +49,7 @@ template int BasicFrameTransf3d::revertToLastCommit() { + // linear.revertToLastCommit(); return t.revertToLastCommit(); } @@ -55,6 +57,7 @@ template int BasicFrameTransf3d::revertToStart() { + // linear.revertToStart(); return t.revertToStart(); } @@ -62,6 +65,7 @@ template int BasicFrameTransf3d::update() { + // linear.update(); return t.update(); } @@ -93,7 +97,7 @@ template double BasicFrameTransf3d::getInitialLength() { - return t.getInitialLength(); + return linear.getInitialLength(); } template @@ -112,7 +116,7 @@ BasicFrameTransf3d::getBasicTrialDisp() static Vector wrapper(ub); Vector3D wi = t.getNodeRotationLogarithm(0), wj = t.getNodeRotationLogarithm(1); - ub[0] = t.getDeformedLength() - t.getInitialLength(); // t.getNodePosition(1)[0]; + ub[0] = t.getDeformedLength() - t.getInitialLength(); // t.getNodePosition(1)[0]; // ub[1] = wi[2]; ub[2] = wj[2]; ub[3] = wi[1]; @@ -164,15 +168,24 @@ BasicFrameTransf3d::getGlobalResistingForce(const Vector &q_pres, const Vec { // transform resisting forces from the basic system to local coordinates + static constexpr int nwm = ndf - 6; // Number of warping DOFs + static VectorND pl{}; - pl[0*NDF+0] = -q_pres[jnx]; // Ni - pl[0*NDF+3] = -q_pres[jmx]; // Ti + pl.zero(); pl[0*NDF+4] = q_pres[imy]; pl[0*NDF+5] = q_pres[imz]; pl[1*NDF+0] = q_pres[jnx]; // Nj pl[1*NDF+3] = q_pres[jmx]; // Tj pl[1*NDF+4] = q_pres[jmy]; pl[1*NDF+5] = q_pres[jmz]; + for (int i=0; i pf; pf.zero(); @@ -182,11 +195,11 @@ BasicFrameTransf3d::getGlobalResistingForce(const Vector &q_pres, const Vec pf[1*NDF + 1] = p0[2]; pf[1*NDF + 2] = p0[4]; - static VectorND pg; - static Vector wrapper(pg); + static Vector wrapper(pl); + t.push(pl, Operation::Total); + linear.push(pf, Operation::Total); + pl += pf; - pg = t.pushResponse(pl); - pg += linear.pushResponse(pf); return wrapper; } @@ -214,7 +227,9 @@ BasicFrameTransf3d::getGlobalStiffMatrix(const Matrix &kb, const Vector &q_ pl[0*NDF+0] = -q_pres[jnx]; // Ni pl[0*NDF+3] = -q_pres[jmx]; // Ti + // static MatrixND<2*NDF,2*NDF> kl; + static Matrix Wrapper(kl); kl.zero(); for (int i=0; i::getGlobalStiffMatrix(const Matrix &kb, const Vector &q_ kl(0*NDF+3, i) = kl(i, 0*NDF+3) = i==0? kl(NDF+3, NDF+0): (i==3? kl(NDF+3, NDF+3) : -kl( NDF+3, i)); } -#if 0 - static MatrixND<2*NDF,2*NDF> Kg; - static Matrix Wrapper(Kg); - - Kg = t.pushResponse(kl, pl); -#else - static Matrix Wrapper(kl); t.push(kl, pl, Operation::Total); -#endif return Wrapper; } @@ -254,6 +261,7 @@ const Matrix & BasicFrameTransf3d::getInitialGlobalStiffMatrix(const Matrix &KB) { static double kb[6][6]; // Basic stiffness + static MatrixND<2*ndf,2*ndf> kl; // Local stiffness double tmp[6][12]{}; @@ -273,6 +281,8 @@ BasicFrameTransf3d::getInitialGlobalStiffMatrix(const Matrix &KB) tmp[i][10] = kb[i][4]; tmp[i][11] = kb[i][2]; } + + kl.zero(); // TODO: // Now compute T'_{bl}*(kb*T_{bl}) for (int i = 0; i < 12; i++) { @@ -321,6 +331,7 @@ BasicFrameTransf3d::getGlobalMatrixFromLocal(const Matrix &M) return wrapper; } + template const Vector & BasicFrameTransf3d::getPointGlobalCoordFromLocal(const Vector &xl) @@ -329,6 +340,7 @@ BasicFrameTransf3d::getPointGlobalCoordFromLocal(const Vector &xl) return xg; } + template const Vector & BasicFrameTransf3d::getPointGlobalDisplFromBasic(double xi, const Vector &uxb) diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index ea2f68f1a8..cc2b20f536 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -14,7 +14,7 @@ //===----------------------------------------------------------------------===// // -// Written: cmp +// Written: Claudio M. Perez // Created: 04/2025 // @@ -249,7 +249,7 @@ EuclidFrameTransf::getStateVariation() } } - Matrix3D R = basis.getRotation(); + const Matrix3D R = basis.getRotation(); // (1) Global Offsets // Do ui -= ri x wi @@ -275,8 +275,8 @@ EuclidFrameTransf::getStateVariation() // Projection { - Vector3D wr = basis.getRotationVariation(ndf, &ul[0]); - Vector3D dc = basis.getPositionVariation(ndf, &ul[0]); + const Vector3D wr = basis.getRotationVariation(ndf, &ul[0]); + const Vector3D dc = basis.getPositionVariation(ndf, &ul[0]); for (int i=0; igetNodePosition(i); @@ -409,7 +409,7 @@ EuclidFrameTransf::push(MatrixND&kb, Kl.addMatrixTripleProduct(0, A, Kb, 1); - VectorND Ap = A^p; + const VectorND Ap = A^p; #if 0 p = A^p; @@ -420,12 +420,17 @@ EuclidFrameTransf::push(MatrixND&kb, for (int j=0; j<6; j++) qwx[i*6+j] = p[i*ndf+j] - Ap[i*ndf+j]; - const MatrixND<12,12> Kw = basis.getRotationJacobian(qwx); - Kb.assemble(Kw.template extract<0, 6, 0, 6>(), 0, 0, 1.0); - Kb.assemble(Kw.template extract<0, 6, 6,12>(), 0, ndf, 1.0); - Kb.assemble(Kw.template extract<6,12, 0, 6>(), ndf, 0, 1.0); - Kb.assemble(Kw.template extract<6,12, 6,12>(), ndf, ndf, 1.0); - Kl.addMatrixProduct(Kb, A, 1.0); + if constexpr (ndf == 6) { + Kl.addMatrixProduct(basis.getRotationJacobian(qwx), A, 1.0); + } + else { + const MatrixND<12,12> Kw = basis.getRotationJacobian(qwx); + Kb.assemble(Kw.template extract<0, 6, 0, 6>(), 0, 0, 1.0); + Kb.assemble(Kw.template extract<0, 6, 6,12>(), 0, ndf, 1.0); + Kb.assemble(Kw.template extract<6,12, 0, 6>(), ndf, 0, 1.0); + Kb.assemble(Kw.template extract<6,12, 6,12>(), ndf, ndf, 1.0); + Kl.addMatrixProduct(Kb, A, 1.0); + } // p = A^p; #endif diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h index 190bd14bfe..61f701e4b7 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h @@ -163,7 +163,7 @@ class CrisfieldIsometry : public AlignedIsometry { Vector3D tmp; tmp = e[0]; tmp += r1; - + e[1] = tmp; { e[1] *= 0.5*r2.dot(e[0]); diff --git a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h index 32afddd6e7..14f23f1e3f 100644 --- a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h @@ -35,7 +35,8 @@ class Isometry virtual int initialize(std::array& nodes) =0; virtual int update(std::array& nodes) =0; - virtual int update(const Matrix3D& RI, const Matrix3D& RJ, const Vector3D& dx, + virtual int update(const Matrix3D& RI, + const Matrix3D& RJ, const Vector3D& dx, std::array& nodes) =0; virtual double getLength() const =0; diff --git a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h index a42a3e22ba..96bfcdfed3 100644 --- a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h @@ -92,6 +92,7 @@ class RankinIsometry : public AlignedIsometry for (int i=0; i= 202000L static constinit MatrixND<12,3> Gamma = MakeGamma(); static constinit MatrixND<12,3> Psi0 = MakePsi(); diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.h b/SRC/coordTransformation/Frame/LinearFrameTransf.h index 39d8519fab..d3665d30c7 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.h +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.h @@ -59,9 +59,9 @@ class LinearFrameTransf: public FrameTransform int revertToLastCommit() final; int revertToStart() final; - VectorND getStateVariation() final; Vector3D getNodePosition(int tag) final; Vector3D getNodeRotationLogarithm(int tag) final; + VectorND getStateVariation() final; #if 0 VectorND pushResponse(VectorND&pl) final; MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index 0748d28218..dcf7a7c341 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -2,10 +2,6 @@ // // xara // https://xara.so -//----------------------------------------------------------------------------// -// -// FEDEASLab -// Finite Elements for Design Evaluation and Analysis of Structures // //----------------------------------------------------------------------------// // @@ -23,6 +19,7 @@ // transformation for a space frame between the global // and basic coordinate systems // +// Written: Claudio M. Perez // Adapted: Remo Magalhaes de Souza // #pragma once @@ -249,7 +246,7 @@ template double LinearFrameTransf::getDeformedLength() { - return L; + return L+Du[0]; } @@ -334,7 +331,7 @@ template VectorND LinearFrameTransf::getStateVariation() { - static VectorND ug; + VectorND ug; for (int i=0; igetIncrDeltaDisp(); for (int j = 0; j < ndf; j++) { @@ -359,6 +356,7 @@ LinearFrameTransf::getNodePosition(int node) return v; } + template Vector3D LinearFrameTransf::getNodeRotationLogarithm(int node) @@ -415,7 +413,6 @@ LinearFrameTransf::push(VectorND&p, Operation op) } template -// MatrixND int LinearFrameTransf::push(MatrixND&kb, const VectorND&, @@ -448,7 +445,7 @@ LinearFrameTransf::push(MatrixND&kb, kl.addMatrixTripleProduct(0, A, kb, 1); this->FrameTransform::pushConstant(kl); #else - MatrixND kl;; + MatrixND kl; kl.addMatrixTripleProduct(0, A, kb, 1); kb = this->FrameTransform::pushConstant(kl); // this->pushRotation(kb, R); @@ -467,7 +464,6 @@ LinearFrameTransf::getCopy() const xz(1) = R(1,2); xz(2) = R(2,2); - LinearFrameTransf *theCopy = new LinearFrameTransf(this->getTag(), xz, offsets); theCopy->nodes = nodes; diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp index 0131130194..0b3d9ec9c5 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp @@ -2,6 +2,7 @@ // // xara // https://xara.so +// //===----------------------------------------------------------------------===// // // OpenSees - Open System for Earthquake Engineering Simulation diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.h b/SRC/coordTransformation/Frame/SouzaFrameTransf.h index 028214bb3a..9f2dc3d334 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.h +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.h @@ -97,10 +97,6 @@ class SouzaFrameTransf: public FrameTransform // Tagged Object void Print(OPS_Stream &s, int flag) final; -protected: - - // VectorND<6> pushResponse(const VectorND<6>& pa, int a, int b); - private: constexpr static int n = nn*ndf; diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp index 021baa7d32..82234f831c 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp @@ -2,6 +2,7 @@ // // xara // https://xara.so +// //----------------------------------------------------------------------------// // // OpenSees - Open System for Earthquake Engineering Simulation @@ -324,10 +325,10 @@ SouzaFrameTransf::update() // // 2) Form transformation // + const Matrix3D RIR0 = MatrixFromVersor(Q_pres[0]), + RJR0 = MatrixFromVersor(Q_pres[1]); - crs.update(MatrixFromVersor(Q_pres[0]), - MatrixFromVersor(Q_pres[1]), - dx, nodes); + crs.update(RIR0, RJR0, dx, nodes); // // 3) Local deformations @@ -338,12 +339,12 @@ SouzaFrameTransf::update() // Rotations { - Matrix3D e = crs.getRotation(); - vr[0] = LogC90(e^MatrixFromVersor(Q_pres[0])); + const Matrix3D e = crs.getRotation(); + vr[0] = LogC90(e^RIR0); for (int i=0; i<3; i++) ul[imx+i] = vr[0][i]; - vr[1] = LogC90(e^MatrixFromVersor(Q_pres[1])); + vr[1] = LogC90(e^RJR0); for (int i=0; i<3; i++) ul[jmx+i] = vr[1][i]; } @@ -375,7 +376,6 @@ SouzaFrameTransf::push(VectorND&pl, Operation) for (int i = 0; i < 6; i++) for (int j = 0; j < 6; j++) pab[j] += T(a*6 + i, b*6+j) * pa[i]; - // VectorND<6> pab = pushResponse(pa, a, b); pg.assemble(b*6, pab, 1.0); } } diff --git a/SRC/matrix/GroupSO3.h b/SRC/matrix/GroupSO3.h index 6680b91998..2c694f8072 100755 --- a/SRC/matrix/GroupSO3.h +++ b/SRC/matrix/GroupSO3.h @@ -55,9 +55,9 @@ static constexpr double SmallAngle = 1e-12; // threshold for small angles static constexpr double SmallAngle2 = SmallAngle * SmallAngle; // threshold for small angles squared static constexpr Matrix3D Eye3 {{ - {1, 0, 0}, - {0, 1, 0}, - {0, 0, 1} + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 }}; @@ -75,9 +75,9 @@ template static inline constexpr Matrix3D Hat(const Vec3Type &u) noexcept { - return Matrix3D {{{ 0 , u[2], -u[1]}, - {-u[2], 0 , u[0]}, - { u[1], -u[0], 0 }}}; + return Matrix3D {{ 0 , u[2], -u[1], + -u[2], 0 , u[0], + u[1], -u[0], 0 }}; } diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index c1a0850dad..3b38137e57 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -46,8 +46,30 @@ namespace OpenSees { template struct alignas(64) MatrixND { - double values[NC][NR]; - // std::array values; + // double values[NC][NR]; + std::array values; + + // + // Indexing + // + // (i,j) indexing + // constexpr T & + // operator()(index_t index_r, index_t index_c) noexcept { + // assert(index_r >= 0 && index_c >= 0); + // assert(index_r < NR && index_c < NC); + // return values[index_c][index_r]; + // } + + // inline constexpr const T & + // operator()(index_t index_r, index_t index_c) const noexcept { + // assert(index_r >= 0 && index_c >= 0); + // assert(index_r < NR && index_c < NC); + // return values[index_c][index_r]; + // } + constexpr T& operator()(int i, int j) noexcept { return values[j*NR + i]; } + constexpr const T& operator()(int i, int j) const noexcept { return values[j*NR + i]; } + + constexpr T* data() noexcept { return &(*this)(0,0); } // Convert to regular Matrix class @@ -58,6 +80,7 @@ struct alignas(64) MatrixND { int symeig(VectorND& vals); constexpr void zero() noexcept; + constexpr double determinant() const ; constexpr MatrixND transpose() const noexcept; @@ -108,41 +131,6 @@ struct alignas(64) MatrixND { int invert(MatrixND &) const; -#if 0 -//template -//void addSpinAtRow(const VecT& V, size_t row_index); -//template -//void addSpinAtRow(const VecT& V, size_t vector_index, size_t matrix_row_index); -//template -//MatrixND& addSpin(const VecT& V, double mult) requires(NR == 3); -//template -//void addSpinAtRow(const VecT& V, double mult, size_t row_index); -//template -//void addSpinAtRow(const VecT& V, double mult, size_t vector_index, size_t matrix_row_index); -#endif - - // - // Indexing - // - // (i,j) indexing - constexpr T & - operator()(index_t index_r, index_t index_c) noexcept { - assert(index_r >= 0 && index_c >= 0); - assert(index_r < NR && index_c < NC); - return values[index_c][index_r]; - } - - inline constexpr const T & - operator()(index_t index_r, index_t index_c) const noexcept { - assert(index_r >= 0 && index_c >= 0); - assert(index_r < NR && index_c < NC); - return values[index_c][index_r]; - } - // constexpr T& operator()(int i, int j) noexcept { return values[j*NR + i]; } - // constexpr const T& operator()(int i, int j) const noexcept { return values[j*NR + i]; } - - - constexpr MatrixND & operator=(const Matrix &other) noexcept { @@ -175,7 +163,7 @@ struct alignas(64) MatrixND { } constexpr MatrixND & - operator-=(const MatrixND &other) + operator-=(const MatrixND &other) noexcept { for (index_t j = 0; j < NC; ++j) for (index_t i = 0; i < NR; ++i) @@ -207,16 +195,16 @@ struct alignas(64) MatrixND { inline constexpr VectorND operator^(const VectorND &V) const noexcept { - VectorND result; + VectorND result; - const double *dataPtr = &(*this)(0,0); - for (int i=0; i inline constexpr friend MatrixND - operator*(const MatrixND &left, const MatrixND &right) { + operator*(const MatrixND &left, const MatrixND &right) noexcept { MatrixND prod; if constexpr (NR*NC > 16) prod.addMatrixProduct(0, left, right, 1); @@ -444,7 +432,7 @@ struct alignas(64) MatrixND { template friend MatrixND - operator*(const MatrixND &left, const Matrix &right) { + operator*(const MatrixND &left, const Matrix &right) noexcept { MatrixND prod; for (index_t i = 0; i < NR; ++i) { for (index_t j = 0; j < J; ++j) { @@ -459,7 +447,7 @@ struct alignas(64) MatrixND { // Matrix*Vector constexpr friend VectorND - operator*(const MatrixND &left, const VectorND &right) { + operator*(const MatrixND &left, const VectorND &right) noexcept { VectorND prod; for (index_t i = 0; i < NR; ++i) { prod[i] = 0.0; @@ -471,7 +459,7 @@ struct alignas(64) MatrixND { } friend VectorND - operator*(const MatrixND &left, const Vector &right) { + operator*(const MatrixND &left, const Vector &right) noexcept { VectorND prod; for (index_t i = 0; i < NR; ++i) { prod[i] = 0.0; @@ -487,7 +475,7 @@ struct alignas(64) MatrixND { inline constexpr friend MatrixND operator^(const MatrixND &left, const MatrixND &right) { MatrixND prod; - if constexpr (NR*NC > 16) + if constexpr (NR*NC > 48) prod.addMatrixTransposeProduct(0.0, left, right, 1.0); else { for (index_t i = 0; i < NC; ++i) { diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index e38df0686e..af1aac33b5 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -25,7 +25,7 @@ template constexpr void MatrixND::zero() noexcept { -#if 1 +#if 0 for (index_t j = 0; j < nc; ++j) { for (index_t i = 0; i < nr; ++i) { values[j][i] = 0.0; @@ -42,9 +42,10 @@ int MatrixND::symeig(VectorND& vals) { static_assert(nr == nc, "Matrix must be square"); - static_assert(rc == 3 && nc == 3); + static_assert(nr == 3 && nc == 3); double work[3][3]; - cmx_eigSY3(values, work, vals.values); + return -1; + // cmx_eigSY3(data(), work, &vals[0]); return 0; } @@ -111,7 +112,7 @@ MatrixND::assemble(const VectorND &v, int init_row, int init_col, d assert((init_row >= 0) && (final_row < NR)); for (int j=0; j::addMatrixTransposeProduct(double thisFact, } if (thisFact == 1.0) { - double *aijPtr = &values[0][0]; + double *aijPtr =this->data(); for (int j=0; j::addMatrixTransposeProduct(double thisFact, } } } else if (thisFact == 0.0) { - double *aijPtr = &values[0][0]; + double *aijPtr =this->data(); for (int j=0; j::addMatrixTransposeProduct(double thisFact, } } } else { - double *aijPtr = &values[0][0]; + double *aijPtr =this->data(); for (int j=0; j #include - -// #define XARA_VECTOR_FRIENDS +#ifndef NO_XARA_VECTOR_FRIENDS +#define XARA_VECTOR_FRIENDS +#endif namespace OpenSees { @@ -128,9 +129,9 @@ struct VectorND { bun(const VectorND &other) const noexcept { if constexpr (N == 3 && nc == 3) return MatrixND {{ - {values[0]*other[0], values[1]*other[0], values[2]*other[0]}, - {values[0]*other[1], values[1]*other[1], values[2]*other[1]}, - {values[0]*other[2], values[1]*other[2], values[2]*other[2]} + values[0]*other[0], values[1]*other[0], values[2]*other[0] , + values[0]*other[1], values[1]*other[1], values[2]*other[1] , + values[0]*other[2], values[1]*other[2], values[2]*other[2] }}; else { diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index 7c3bf48c09..c2d9935b7c 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -8,6 +8,7 @@ // #include #include "VectorND.h" +#include "blasdecl.h" namespace OpenSees { @@ -122,13 +123,14 @@ VectorND::addVector(const T thisFact, const Vector &other, const T otherFac return 0; } + template template inline int VectorND::addMatrixVector(double thisFact, const MatrixND &m, const Vector& v, double otherFact) { // check the sizes are compatable - assert(NC == v.Size()); + assert(NC == v.sz); // see if quick return if (thisFact == 1.0 && otherFact == 0.0) @@ -140,7 +142,7 @@ VectorND::addMatrixVector(double thisFact, const MatrixND &m n = NC; DGEMV("N", &i, &n, &otherFact, - &m.values[0][0], &i, + &m(0,0), &i, v.theData, &incr, &thisFact, values, @@ -157,7 +159,7 @@ inline int VectorND::addMatrixTransposeVector(double thisFact, const MatrixND &m, const Vector &v, double otherFact) { // check the sizes are compatable - assert(NR == v.Size()); + assert(NR == v.sz); if (thisFact == 1.0 && otherFact == 0.0) @@ -169,7 +171,7 @@ VectorND::addMatrixTransposeVector(double thisFact, const MatrixND::addMatrixVector(const double thisFact, const Matrix &m, const Vec { // check the sizes are compatable assert(N == m.noRows()); - assert(m.noCols() == v.Size()); + assert(m.noCols() == v.sz); // see if quick return if (thisFact == 1.0 && otherFact == 0.0) return 0; #ifdef VECTOR_BLAS - else if (v.Size() > 10) { + else if (v.sz > 10) { int incr = 1, i = m.numRows, n = m.numCols; @@ -209,7 +211,7 @@ VectorND::addMatrixVector(const double thisFact, const Matrix &m, const Vec // want: this += m * v * otherFact if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0 - int otherSize = v.Size(); + int otherSize = v.sz; double *matrixDataPtr = m.data; const double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec } } else if (otherFact == -1.0) { // no point doing multiplication if otherFact = -1.0 - int otherSize = v.Size(); + int otherSize = v.sz; double *matrixDataPtr = m.data; const double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec } } else { // have to do the multiplication - int otherSize = v.Size(); + int otherSize = v.sz; double *matrixDataPtr = m.data; double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec if (otherFact == 1.0) { // avoid multiplication when otherFact = 1.0 - int otherSize = v.Size(); + int otherSize = v.sz; const double *matrixDataPtr = m.data; const double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec else if (otherFact == -1.0) { // avoid multiplication when otherFact = -1.0 - int otherSize = v.Size(); + int otherSize = v.sz; double *matrixDataPtr = m.data; const double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec } } else { - int otherSize = v.Size(); + int otherSize = v.sz; double *matrixDataPtr = m.data; double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec values[i] *= thisFact; if (otherFact == 1.0) { // no point doing multiplication if otherFact = 1.0 - int otherSize = v.Size(); + int otherSize = v.sz; double *matrixDataPtr = m.data; double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec values[j] += *matrixDataPtr++ * otherData; } } else if (otherFact == -1.0) { // no point doing multiplication if otherFact = 1.0 - int otherSize = v.Size(); + int otherSize = v.sz; double *matrixDataPtr = m.data; double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec values[j] -= *matrixDataPtr++ * otherData; } } else { - int otherSize = v.Size(); + int otherSize = v.sz; double *matrixDataPtr = m.data; double *otherDataPtr = v.theData; for (int i=0; i::addMatrixVector(const double thisFact, const Matrix &m, const Vec // successfull return 0; } + #endif // XARA_VECTOR_FRIENDS template From c77ffdd5145521ce9ae97541437110145b1cdbbc Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 10 Jul 2025 23:06:34 -0700 Subject: [PATCH 167/261] move xblas.h --- SRC/matrix/MatrixND.h | 11 +-- SRC/matrix/MatrixND.tpp | 12 +-- SRC/matrix/VectorND.h | 3 - SRC/matrix/VectorND.tpp | 2 +- SRC/matrix/routines/xblas.h | 95 +++++++++++++++++++ .../commands/modeling/element/frames.cpp | 21 ++-- 6 files changed, 121 insertions(+), 23 deletions(-) create mode 100644 SRC/matrix/routines/xblas.h diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index 3b38137e57..6e2a37649a 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -39,9 +39,6 @@ #include "Matrix.h" #include "Vector.h" - -#define G23_STACK_MAX 10 - namespace OpenSees { template @@ -450,10 +447,10 @@ struct alignas(64) MatrixND { operator*(const MatrixND &left, const VectorND &right) noexcept { VectorND prod; for (index_t i = 0; i < NR; ++i) { - prod[i] = 0.0; - for (index_t k = 0; k < NC; ++k) { - prod[i] += left(i,k) * right[k]; - } + prod[i] = 0.0; + for (index_t k = 0; k < NC; ++k) { + prod[i] += left(i,k) * right[k]; + } } return prod; } diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index af1aac33b5..fc5157b99e 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -11,7 +11,7 @@ #pragma once #include "MatrixND.h" -#include "blasdecl.h" +#include "routines/xblas.h" #include "routines/cmx.h" #include "routines/SY3.h" @@ -127,11 +127,11 @@ MatrixND::assembleTranspose(const MatrixND &M, int init } for (int i=0; i #include -#ifndef NO_XARA_VECTOR_FRIENDS -#define XARA_VECTOR_FRIENDS -#endif namespace OpenSees { diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index c2d9935b7c..0ee9b84b8f 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -8,7 +8,7 @@ // #include #include "VectorND.h" -#include "blasdecl.h" +#include "routines/xblas.h" namespace OpenSees { diff --git a/SRC/matrix/routines/xblas.h b/SRC/matrix/routines/xblas.h new file mode 100644 index 0000000000..0384677984 --- /dev/null +++ b/SRC/matrix/routines/xblas.h @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +#ifndef blasdecl_H +#define blasdecl_H + +#ifndef _WIN32 +# define DAXPY daxpy_ +# define DSCAL dscal_ +# define DGEMV dgemv_ +// Level 3 +# define DGETRF dgetrf_ +# define DGETRI dgetri_ +# define DGEMM dgemm_ +// Lapack +# define DGESV dgesv_ +# define DGETRS dgetrs_ +# define DGBSV dgbsv_ +# define DGBTRS dgbtrs_ +# define DPBSV dpbsv_ +# define DPBTRS dpbtrs_ +#endif + +extern "C" { + // Level 1 + // x = alpha * x + beta * y + void DAXPY (int*, double*, double*, const int*, double*, const int*); + void DSCAL (int*, double*, double*, const int*); + void DGEMV (const char* trans, int* M, int* N, + double* alpha, + const double* A, int* lda, + double* X, int* incX, + double* beta, + double* Y, int* incY); +// Level 3 +#if 0 + void DGESV(int *N, int *NRHS, double *A, int *LDA, + int *iPiv, double *B, int *LDB, int *INFO); + void DGETRS(char *TRANS, unsigned int sizeT, + int *N, int *NRHS, double *A, int *LDA, + int *iPiv, double *B, int *LDB, int *INFO); +#endif + + void DGETRF(int *M, int *N, double *A, int *LDA, + int *iPiv, int *INFO); + + void DGETRI(int *N, double *A, int *LDA, + int *iPiv, double *Work, int *WORKL, int *INFO); + + void DGEMM(const char* transA, const char* transB, int* M, int* N, int* K, + double* alpha, + double* A, const int* lda, + double* B, const int* ldb, + double* beta, + double* C, const int* ldc); + +// +// Lapack +// +// FullGen +int DGESV(int *N, int *NRHS, double *A, int *LDA, + int *iPiv, double *B, int *LDB, int *INFO); + +int DGETRS(char *TRANS, + int *N, int *NRHS, double *A, int *LDA, + int *iPiv, double *B, int *LDB, int *INFO); + +// BandGen +int DGBSV(int *N, int *KL, int *KU, int *NRHS, double *A, + int *LDA, int *iPiv, double *B, int *LDB, + int *INFO); + +int DGBTRS(char *TRANS, + int *N, int *KL, int *KU, int *NRHS, + double *A, int *LDA, int *iPiv, + double *B, int *LDB, int *INFO); + +// BandSPD +int DPBSV(char *UPLO, + int *N, int *KD, int *NRHS, + double *A, int *LDA, double *B, int *LDB, + int *INFO); + +int DPBTRS(char *UPLO, + int *N, int *KD, int *NRHS, + double *A, int *LDA, double *B, int *LDB, + int *INFO); +} + +#endif // blasdecl_H diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index 6fd0fb0d59..ee6ec69be0 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -116,12 +116,21 @@ CheckTransformation(Domain& domain, int iNode, int jNode, CrdTransf& transform) } if (transform.initialize(ni, nj) != 0) { - opserr << OpenSees::PromptValueError - << "transformation with tag " << transform.getTag() - << " could not be initialized with nodes " - << iNode << " and " << jNode - << "; check orientation" - << OpenSees::SignalMessageEnd; + if (transform.getInitialLength() <= 0.0) { + opserr << OpenSees::PromptValueError + << "element has zero or negative initial length " + << transform.getInitialLength() + << "; check for duplicate nodes" + << OpenSees::SignalMessageEnd; + } + else { + opserr << OpenSees::PromptValueError + << "transformation with tag " << transform.getTag() + << " could not be initialized with nodes " + << iNode << " and " << jNode + << "; check orientation" + << OpenSees::SignalMessageEnd; + } return TCL_ERROR; } return TCL_OK; From dbdbd39530a721158dd36c7115cf778a0a4376a5 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 10 Jul 2025 23:17:29 -0700 Subject: [PATCH 168/261] add cmx.h --- SRC/matrix/routines/cmx.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 SRC/matrix/routines/cmx.h diff --git a/SRC/matrix/routines/cmx.h b/SRC/matrix/routines/cmx.h new file mode 100644 index 0000000000..c9cc19faa7 --- /dev/null +++ b/SRC/matrix/routines/cmx.h @@ -0,0 +1,28 @@ +#ifndef cmx_h +#define cmx_h + +#ifdef __cplusplus +extern "C" { +#endif + +int cmx_inv2 (const double *a, double *ainv, int*ok_flag); +int cmx_inv3 (const double *a, double *ainv, int*ok_flag); +int cmx_inv4 (const double *a, double *ainv, int*ok_flag); +int cmx_inv5 (const double *a, double *ainv, int*ok_flag); +int cmx_inv6 (const double *a, double *ainv, int*ok_flag); +int cmx_inv6_v2(const double *a, double *ainv, int*ok_flag); +int cmx_inv6_v3(const double *a, double *ainv, int*ok_flag); + +#define cmx_inv(a, inv, flag) _Generic(&(a), \ + double(*)[ 4]: cmx_inv2, \ + double(*)[ 9]: cmx_inv3, \ + double(*)[16]: cmx_inv4, \ + double(*)[25]: cmx_inv5, \ + double(*)[36]: cmx_inv6 \ + )(a, inv, flag) + +#ifdef __cplusplus +} +#endif + +#endif // cmx_h From a73e4bb27f2a8137f97e1a6066d2afcb60ddeae8 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 10 Jul 2025 23:28:20 -0700 Subject: [PATCH 169/261] clean matrix class --- SRC/matrix/MatrixND.h | 4 ---- SRC/matrix/MatrixND.tpp | 38 -------------------------------------- 2 files changed, 42 deletions(-) diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index 6e2a37649a..6f2b369015 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -74,12 +74,8 @@ struct alignas(64) MatrixND { operator const Matrix() const { return Matrix(&(*this)(0,0), NR, NC);} - int symeig(VectorND& vals); - constexpr void zero() noexcept; - constexpr double determinant() const ; - constexpr MatrixND transpose() const noexcept; constexpr MatrixND& addDiagonal(const double vol) noexcept; diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index fc5157b99e..ba00056806 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -13,7 +13,6 @@ #include "routines/xblas.h" #include "routines/cmx.h" -#include "routines/SY3.h" namespace OpenSees { @@ -25,47 +24,10 @@ template constexpr void MatrixND::zero() noexcept { -#if 0 - for (index_t j = 0; j < nc; ++j) { - for (index_t i = 0; i < nr; ++i) { - values[j][i] = 0.0; - } - } -#else values.fill(T{}); -#endif } -template -int -MatrixND::symeig(VectorND& vals) -{ - static_assert(nr == nc, "Matrix must be square"); - static_assert(nr == 3 && nc == 3); - double work[3][3]; - return -1; - // cmx_eigSY3(data(), work, &vals[0]); - return 0; -} - -#if 0 -template -constexpr double -MatrixND::determinant() const -{ - static_assert(nr == nc, "Matrix must be square"); - static_assert(nr > 1 && nr < 4, "Matrix must be between 2x2 and 3x3"); - if constexpr (nr == 2) { - return values[0][0] * values[1][1] - values[0][1] * values[1][0]; - } - if constexpr (nr == 3) { - return values[0][0] * (values[1][1] * values[2][2] - values[1][2] * values[2][1]) - - values[0][1] * (values[1][0] * values[2][2] - values[1][2] * values[2][0]) + - values[0][2] * (values[1][0] * values[2][1] - values[1][1] * values[2][0]); - } -} -#endif template constexpr MatrixND From f57985f6a9202b5d29a926e763346798367cf369 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 11 Jul 2025 15:37:06 -0700 Subject: [PATCH 170/261] add nodeRotation command --- SRC/runtime/commands/domain/nodes.cpp | 148 +++++++++++++++++------- SRC/runtime/commands/modeling/nodes.cpp | 106 ++++++++--------- 2 files changed, 158 insertions(+), 96 deletions(-) diff --git a/SRC/runtime/commands/domain/nodes.cpp b/SRC/runtime/commands/domain/nodes.cpp index efca072f00..7627afe957 100644 --- a/SRC/runtime/commands/domain/nodes.cpp +++ b/SRC/runtime/commands/domain/nodes.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file implements commands for interacting with nodes // in the domain. // @@ -14,11 +15,14 @@ #include #include #include +// Framework #include #include +#include #include #include #include +#include #include #include #include @@ -33,7 +37,7 @@ static int resDataSize = 0; int -getNodeTags(ClientData clientData, Tcl_Interp *interp, int argc, +getNodeTags(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -52,7 +56,7 @@ getNodeTags(ClientData clientData, Tcl_Interp *interp, int argc, } int -findID(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +findID(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); Domain *theDomain = (Domain*)clientData; @@ -91,14 +95,18 @@ findID(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const ar } int -setNodeCoord(ClientData clientData, Tcl_Interp *interp, int argc, +setNodeCoord(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { + // + // setNodeCoord nodeTag? dim? value? + // assert(clientData != nullptr); Domain *domain = (Domain*)clientData; - if (argc < 4) { - opserr << "WARNING want - setNodeCoord nodeTag? dim? value?\n"; + opserr << OpenSees::PromptValueError + << "expected setNodeCoord nodeTag? dim? value?" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -142,7 +150,7 @@ setNodeCoord(ClientData clientData, Tcl_Interp *interp, int argc, } int -nodeDisp(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +nodeDisp(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); Domain *domain = (Domain*)clientData; @@ -198,7 +206,7 @@ nodeDisp(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const } int -nodeMass(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +nodeMass(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); Domain *the_domain = (Domain*)clientData; @@ -240,7 +248,7 @@ nodeMass(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const } int -nodePressure(ClientData clientData, Tcl_Interp *interp, int argc, +nodePressure(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -265,7 +273,7 @@ nodePressure(ClientData clientData, Tcl_Interp *interp, int argc, } int -nodeBounds(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +nodeBounds(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); Domain *the_domain = (Domain*)clientData; @@ -295,7 +303,7 @@ nodeBounds(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** cons } int -nodeVel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +nodeVel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); Domain *the_domain = (Domain*)clientData; @@ -354,7 +362,7 @@ nodeVel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const a } int -setNodeVel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +setNodeVel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); Domain *the_domain = (Domain*)clientData; @@ -411,7 +419,7 @@ setNodeVel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** cons } int -setNodeDisp(ClientData clientData, Tcl_Interp *interp, int argc, +setNodeDisp(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -471,7 +479,7 @@ setNodeDisp(ClientData clientData, Tcl_Interp *interp, int argc, int -setNodeAccel(ClientData clientData, Tcl_Interp *interp, int argc, +setNodeAccel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -531,7 +539,7 @@ setNodeAccel(ClientData clientData, Tcl_Interp *interp, int argc, } int -nodeAccel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +nodeAccel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -583,7 +591,7 @@ nodeAccel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const } int -nodeUnbalance(ClientData clientData, Tcl_Interp *interp, int argc, +nodeUnbalance(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -641,7 +649,42 @@ nodeUnbalance(ClientData clientData, Tcl_Interp *interp, int argc, } int -nodeResponse(ClientData clientData, Tcl_Interp *interp, int argc, +nodeRotation(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, + TCL_Char ** const argv) +{ + assert(clientData != nullptr); + Domain *the_domain = (Domain*)clientData; + + if (argc < 2) { + opserr << "WARNING want - nodeRotation tag\n"; + return TCL_ERROR; + } + + int tag; + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING could not read nodeTag? \n"; + return TCL_ERROR; + } + + // TODO: This may need some adjusting for PartitionedDomains and parallel + Node *theNode = the_domain->getNode(tag); + if (theNode == nullptr) + return TCL_ERROR; + + Versor rotation = theNode->getTrialRotation(); + + Tcl_Obj* list = Tcl_NewListObj(4, nullptr); + for (int i = 0; i < 3; ++i) + Tcl_ListObjAppendElement(interp, list, Tcl_NewDoubleObj(rotation.vector[i])); + Tcl_ListObjAppendElement(interp, list, Tcl_NewDoubleObj(rotation.scalar)); + + Tcl_SetObjResult(interp, list); + + return TCL_OK; +} + +int +nodeResponse(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -662,18 +705,39 @@ nodeResponse(ClientData clientData, Tcl_Interp *interp, int argc, opserr << "WARNING nodeResponse nodeTag? dof? - could not read dof? \n"; return TCL_ERROR; } + if (Tcl_GetInt(interp, argv[3], &responseID) != TCL_OK) { - opserr << "WARNING nodeResponse nodeTag? dof? responseID? - could not read " - "responseID? \n"; - return TCL_ERROR; + if (strcmp(argv[3], "displacement") == 0) + responseID = (int)NodeData::Disp; + else if (strcmp(argv[3], "velocity") == 0) + responseID = (int)NodeData::Vel; + else if (strcmp(argv[3], "acceleration") == 0) + responseID = (int)NodeData::Accel; + else if (strcmp(argv[3], "resiudal") == 0) + responseID = (int)NodeData::UnbalancedLoad; + else { + opserr << "WARNING unknown response " << argv[3] << "\n"; + return TCL_ERROR; + } } dof--; - const Vector *nodalResponse = - the_domain->getNodeResponse(tag, (NodeData)responseID); + const Vector *nodalResponse = nullptr; + if (false) { + // This would need some adjusting for PartitionedDomain + Node *theNode = the_domain->getNode(tag); + if (theNode == nullptr) + return TCL_ERROR; + + nodalResponse = theNode->getResponse((NodeData)responseID); + + } else + nodalResponse = + the_domain->getNodeResponse(tag, (NodeData)responseID); + - if (nodalResponse == 0 || nodalResponse->Size() < dof || dof < 0) + if (nodalResponse == nullptr || nodalResponse->Size() < dof || dof < 0) // TODO: add error message return TCL_ERROR; @@ -683,7 +747,7 @@ nodeResponse(ClientData clientData, Tcl_Interp *interp, int argc, } int -nodeEigenvector(ClientData clientData, Tcl_Interp *interp, int argc, +nodeEigenvector(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -757,7 +821,7 @@ nodeEigenvector(ClientData clientData, Tcl_Interp *interp, int argc, } int -calculateNodalReactions(ClientData clientData, Tcl_Interp *interp, int argc, +calculateNodalReactions(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -784,7 +848,7 @@ calculateNodalReactions(ClientData clientData, Tcl_Interp *interp, int argc, } int -nodeReaction(ClientData clientData, Tcl_Interp *interp, int argc, +nodeReaction(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -841,20 +905,20 @@ nodeReaction(ClientData clientData, Tcl_Interp *interp, int argc, } int -nodeCoord(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +nodeCoord(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); Domain *the_domain = (Domain*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "want - nodeCoord nodeTag? \n"; + opserr << OpenSees::PromptValueError << "want - nodeCoord nodeTag? \n"; return TCL_ERROR; } int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "nodeCoord nodeTag? dim? - could not read nodeTag? \n"; + opserr << OpenSees::PromptValueError << "nodeCoord nodeTag? dim? - could not read nodeTag? \n"; return TCL_ERROR; } @@ -871,7 +935,7 @@ nodeCoord(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const strcmp(argv[2], "3") == 0) dim = 2; else { - opserr << G3_ERROR_PROMPT << "" << "nodeCoord nodeTag? dim? - could not read dim? \n"; + opserr << OpenSees::PromptValueError << "" << "nodeCoord nodeTag? dim? - could not read dim? \n"; return TCL_ERROR; } } @@ -879,7 +943,7 @@ nodeCoord(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const Node *theNode = the_domain->getNode(tag); if (theNode == nullptr) { - opserr << G3_ERROR_PROMPT << "Unable to retrieve node with tag '" << tag << "'\n"; + opserr << OpenSees::PromptValueError << "Unable to retrieve node with tag '" << tag << "'\n"; return TCL_ERROR; } @@ -904,7 +968,7 @@ nodeCoord(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const } int -retainedNodes(ClientData clientData, Tcl_Interp *interp, int argc, +retainedNodes(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -913,7 +977,7 @@ retainedNodes(ClientData clientData, Tcl_Interp *interp, int argc, int cNode; if (argc > 1) { if (Tcl_GetInt(interp, argv[1], &cNode) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "retainedNodes - could not read cNode? \n"; + opserr << OpenSees::PromptValueError << "retainedNodes - could not read cNode? \n"; return TCL_ERROR; } all = 0; @@ -950,33 +1014,39 @@ retainedNodes(ClientData clientData, Tcl_Interp *interp, int argc, int -nodeDOFs(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +nodeDOFs(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); Domain *the_domain = (Domain*)clientData; if (argc != 2) { - opserr << G3_ERROR_PROMPT << "expected - nodeDOFs nodeTag?\n"; + opserr << OpenSees::PromptValueError + << "Missing required arguments" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "nodeDOFs nodeTag?\n"; + opserr << OpenSees::PromptValueError << "nodeDOFs nodeTag?\n"; return TCL_ERROR; } Node *theNode = the_domain->getNode(tag); if (theNode == nullptr) { - opserr << G3_ERROR_PROMPT << "nodeDOFs node " << tag << " not found" << endln; + opserr << OpenSees::PromptValueError + << "node with tag " << tag << " not found" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } int numDOF = theNode->getNumberDOF(); DOF_Group *theDOFgroup = theNode->getDOF_GroupPtr(); if (theDOFgroup == nullptr) { - opserr << G3_ERROR_PROMPT << "nodeDOFs DOF group null" << endln; + opserr << OpenSees::PromptValueError + << "nodeDOFs DOF group null" + << OpenSees::SignalMessageEnd; return -1; } diff --git a/SRC/runtime/commands/modeling/nodes.cpp b/SRC/runtime/commands/modeling/nodes.cpp index c8f3be9360..cd296f98b3 100644 --- a/SRC/runtime/commands/modeling/nodes.cpp +++ b/SRC/runtime/commands/modeling/nodes.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file implements commands that configure Node objects // for an analysis. // @@ -20,7 +21,9 @@ #include #include -#define G3_MAX_NUM_DOFS 1000000000000 +#define HeapNode Node + +// #define G3_MAX_NUM_DOFS 1000000000000 #define G3_NUM_DOF_BUFFER 20 int @@ -37,71 +40,58 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, int ndf = builder->getNDF(); // make sure corect number of arguments on command line - if (argc < 2 + ndm) { - opserr << G3_ERROR_PROMPT << "insufficient arguments, expected:\n"; - opserr << " node nodeTag? [ndm coordinates?] <-mass [ndf values?]>\n"; + if (argc < 2 + 1) { // ndm) { + opserr << OpenSees::PromptValueError + << "insufficient arguments" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } - Node *theNode = 0; + Node *theNode = nullptr; // read the node id int nodeId; if (Tcl_GetInt(interp, argv[1], &nodeId) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodeTag\n"; + opserr << OpenSees::PromptValueError << "invalid nodeTag\n"; opserr << " Want: node nodeTag? [ndm coordinates?] <-mass [ndf values?]>\n"; return TCL_ERROR; } // read in the coordinates and create the node - double xLoc, yLoc, zLoc; - if (ndm == 1) { + double xLoc=0, yLoc=0, zLoc=0; + if (ndm >= 1 && argc >= 3) { // create a node in 1d space if (Tcl_GetDouble(interp, argv[2], &xLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid coordinate\n"; + opserr << OpenSees::PromptValueError + << "invalid coordinate " << argv[2] + << OpenSees::SignalMessageEnd; return TCL_ERROR; } } - else if (ndm == 2) { - // create a node in 2d space - if (Tcl_GetDouble(interp, argv[2], &xLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid 1st coordinate\n"; - opserr << "node: " << nodeId << "\n"; - return TCL_ERROR; - } + if (ndm >= 2 && argc >= 4) { if (Tcl_GetDouble(interp, argv[3], &yLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid 2nd coordinate\n"; - opserr << "node: " << nodeId << "\n"; + opserr << OpenSees::PromptValueError + << "invalid 2nd coordinate " << argv[3] + << OpenSees::SignalMessageEnd; return TCL_ERROR; } } - else if (ndm == 3) { - // create a node in 3d space - if (Tcl_GetDouble(interp, argv[2], &xLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid 1st coordinate\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[3], &yLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid 2nd coordinate\n"; - return TCL_ERROR; - } + if (ndm >= 3 && argc >= 5) { if (Tcl_GetDouble(interp, argv[4], &zLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid 3rd coordinate\n"; + opserr << OpenSees::PromptValueError + << "invalid 3rd coordinate " << argv[4] + << OpenSees::SignalMessageEnd; return TCL_ERROR; } - - } else { - opserr << G3_ERROR_PROMPT << "unsupported model dimension\n"; - return TCL_ERROR; } // check for -ndf override option int currentArg = 2 + ndm; if (currentArg < argc && strcmp(argv[currentArg], "-ndf") == 0) { if (Tcl_GetInt(interp, argv[currentArg + 1], &ndf) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodal ndf given for node " << nodeId << "\n"; + opserr << OpenSees::PromptValueError << "invalid nodal ndf given for node " << nodeId << "\n"; return TCL_ERROR; } currentArg += 2; @@ -112,12 +102,13 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, // switch (ndm) { case 1: - theNode = new Node(nodeId, ndf, xLoc); + theNode = new HeapNode(nodeId, ndf, xLoc); break; case 2: - theNode = new Node(nodeId, ndf, xLoc, yLoc); + theNode = new HeapNode(nodeId, ndf, xLoc, yLoc); break; case 3: +#if 0 if (getenv("NODE")) { switch (ndf) { case 3: @@ -127,11 +118,12 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, theNode = new NodeND<3, 6>(nodeId, xLoc, yLoc, zLoc); break; default: - theNode = new Node(nodeId, ndf, xLoc, yLoc, zLoc); + theNode = new HeapNode(nodeId, ndf, xLoc, yLoc, zLoc); break; } } else - theNode = new Node(nodeId, ndf, xLoc, yLoc, zLoc); +#endif + theNode = new HeapNode(nodeId, ndf, xLoc, yLoc, zLoc); break; } @@ -139,7 +131,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, if (strcmp(argv[currentArg], "-mass") == 0) { currentArg++; if (argc < currentArg + ndf) { - opserr << G3_ERROR_PROMPT << "incorrect number of nodal mass terms\n"; + opserr << OpenSees::PromptValueError << "incorrect number of nodal mass terms\n"; opserr << "node: " << nodeId << "\n"; return TCL_ERROR; } @@ -148,7 +140,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, Matrix mass(ndf, ndf); for (int i = 0; i < ndf; ++i) { if (Tcl_GetDouble(interp, argv[currentArg++], &theMass) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodal mass term"; + opserr << OpenSees::PromptValueError << "invalid nodal mass term"; opserr << " at dof " << i + 1 << "\n"; return TCL_ERROR; } @@ -159,7 +151,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, } else if (strcmp(argv[currentArg], "-dispLoc") == 0) { currentArg++; if (argc < currentArg + ndm) { - opserr << G3_ERROR_PROMPT << "incorrect number of nodal display location terms, " + opserr << OpenSees::PromptValueError << "incorrect number of nodal display location terms, " "need ndm\n"; return TCL_ERROR; } @@ -167,7 +159,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, double theCrd; for (int i = 0; i < ndm; ++i) { if (Tcl_GetDouble(interp, argv[currentArg++], &theCrd) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodal mass term\n"; + opserr << OpenSees::PromptValueError << "invalid nodal mass term\n"; opserr << "node: " << nodeId << ", dof: " << i + 1 << "\n"; return TCL_ERROR; } @@ -178,7 +170,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, } else if (strcmp(argv[currentArg], "-disp") == 0) { currentArg++; if (argc < currentArg + ndf) { - opserr << G3_ERROR_PROMPT << "incorrect number of nodal disp terms\n"; + opserr << OpenSees::PromptValueError << "incorrect number of nodal disp terms\n"; opserr << "node: " << nodeId << "\n"; return TCL_ERROR; } @@ -186,7 +178,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, double theDisp; for (int i = 0; i < ndf; ++i) { if (Tcl_GetDouble(interp, argv[currentArg++], &theDisp) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodal disp term\n"; + opserr << OpenSees::PromptValueError << "invalid nodal disp term\n"; opserr << "node: " << nodeId << ", dof: " << i + 1 << "\n"; return TCL_ERROR; } @@ -198,7 +190,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, } else if (strcmp(argv[currentArg], "-vel") == 0) { currentArg++; if (argc < currentArg + ndf) { - opserr << G3_ERROR_PROMPT << "incorrect number of nodal vel terms, "; + opserr << OpenSees::PromptValueError << "incorrect number of nodal vel terms, "; opserr << "expected " << ndf << "\n"; return TCL_ERROR; } @@ -207,7 +199,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, Vector disp(ndf); for (int i = 0; i < ndf; ++i) { if (Tcl_GetDouble(interp, argv[currentArg++], &theDisp) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodal vel term at "; + opserr << OpenSees::PromptValueError << "invalid nodal vel term at "; opserr << " dof " << i + 1 << "\n"; return TCL_ERROR; } @@ -224,7 +216,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, // add the node to the domain // if (theTclDomain->addNode(theNode) == false) { - opserr << G3_ERROR_PROMPT << "failed to add node to the domain\n"; + opserr << OpenSees::PromptValueError << "failed to add node to the domain\n"; delete theNode; return TCL_ERROR; } @@ -244,7 +236,7 @@ TclCommand_addNodalMass(ClientData clientData, Tcl_Interp *interp, int argc, // make sure at least one other argument if (argc < (1 + ndf)) { - opserr << G3_ERROR_PROMPT << "insufficient arguments, expected:\n" + opserr << OpenSees::PromptValueError << "insufficient arguments, expected:\n" " mass nodeId <" << ndf << " mass values>\n"; return TCL_ERROR; } @@ -252,7 +244,7 @@ TclCommand_addNodalMass(ClientData clientData, Tcl_Interp *interp, int argc, // get the id of the node int nodeId; if (Tcl_GetInt(interp, argv[1], &nodeId) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodeId: " << argv[1]; + opserr << OpenSees::PromptValueError << "invalid nodeId: " << argv[1]; opserr << " - mass nodeId " << ndf << " forces\n"; return TCL_ERROR; } @@ -262,7 +254,7 @@ TclCommand_addNodalMass(ClientData clientData, Tcl_Interp *interp, int argc, for (int i=0; isetMass(mass, nodeId) != 0) { - opserr << G3_ERROR_PROMPT << "failed to set mass at node " << nodeId << "\n"; + opserr << OpenSees::PromptValueError << "failed to set mass at node " << nodeId << "\n"; return TCL_ERROR; } @@ -292,13 +284,13 @@ TclCommand_getNDM(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char if (argc > 1) { int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "ndm nodeTag? \n"; + opserr << OpenSees::PromptValueError << "ndm nodeTag? \n"; return TCL_ERROR; } Node *theNode = the_domain->getNode(tag); if (theNode == nullptr) { - opserr << G3_ERROR_PROMPT << "nodeTag " << tag << " does not exist \n"; + opserr << OpenSees::PromptValueError << "nodeTag " << tag << " does not exist \n"; return TCL_ERROR; } const Vector &coords = theNode->getCrds(); @@ -323,12 +315,12 @@ TclCommand_getNDF(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char if (argc > 1) { int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "ndf nodeTag? \n"; + opserr << OpenSees::PromptValueError << "ndf nodeTag? \n"; return TCL_ERROR; } Node *theNode = the_domain->getNode(tag); if (theNode == nullptr) { - opserr << G3_ERROR_PROMPT << "nodeTag " << tag << " does not exist \n"; + opserr << OpenSees::PromptValueError << "nodeTag " << tag << " does not exist \n"; return TCL_ERROR; } ndf = theNode->getNumberDOF(); From b9b63b24ac2720ad205a0afa433e75128610fc89 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 11 Jul 2025 20:35:07 -0700 Subject: [PATCH 171/261] some fixes for windows --- .../Frame/EuclidFrameTransf.tpp | 15 ---- .../Frame/Isometry/CrisfieldIsometry.h | 5 +- .../Frame/Isometry/LinearIsometry.h | 81 +++++++++++++++++++ .../Frame/Isometry/SphericalIsometry.h | 2 - .../Frame/LinearFrameTransf.h | 7 +- .../Frame/LinearFrameTransf.tpp | 7 +- .../Frame/PDeltaFrameTransf3d.h | 7 +- .../Frame/SouzaFrameTransf.h | 7 +- 8 files changed, 91 insertions(+), 40 deletions(-) create mode 100644 SRC/coordTransformation/Frame/Isometry/LinearIsometry.h diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index cc2b20f536..f731fae980 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -205,23 +205,8 @@ template Vector3D EuclidFrameTransf::getNodePosition(int node) { -#if 0 - const Vector& ug = nodes[node]->getTrialDisp(); - - Vector3D u; - for (int i=0; i<3; i++) - u[i] = ug[i]; - - if (offsets != nullptr) [[unlikely]] { - u.addVector(1.0, (*offsets)[node], -1.0); - u.addVector(1.0, nodes[node]->getTrialRotation().rotate((*offsets)[node]), 1.0); - } - - u.addVector(1.0, basis.getPosition(), -1.0); -#else Vector3D u = this->pullPosition<&Node::getTrialDisp>(node); u -= basis.getPosition(); -#endif u += basis.getRotationDelta()^(nodes[node]->getCrds()); return u; diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h index 61f701e4b7..35a2b088c9 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h @@ -134,11 +134,12 @@ class CrisfieldIsometry : public AlignedIsometry { } } else if (std::fabs(dot + 1.0) < ktol) { // opposite direction + static constexpr double pi = 3.14159265358979323846; // choose any axis with numerical separation from r1 v = r1.cross(Vector3D{1.0, 0.0, 0.0}); if (v.dot(v) < ktol) v = r1.cross(Vector3D{0.0, 1.0, 0.0}); - v *= M_PI / v.norm(); + v *= pi / v.norm(); E = ExpSO3(v)*Rbar; } else { // general case @@ -878,4 +879,4 @@ class CrisfieldIsometry : public AlignedIsometry { // MatrixND<12,3> Lr2, Lr3; // double Ln; }; -} \ No newline at end of file +} diff --git a/SRC/coordTransformation/Frame/Isometry/LinearIsometry.h b/SRC/coordTransformation/Frame/Isometry/LinearIsometry.h new file mode 100644 index 0000000000..a2646f4c32 --- /dev/null +++ b/SRC/coordTransformation/Frame/Isometry/LinearIsometry.h @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//----------------------------------------------------------------------------// +// +// Please cite the following resource in any derivative works: +// +// [1] Perez, C.M., and Filippou F.C. (2024) +// "On Nonlinear Geometric Transformations of Finite Elements" +// Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// + +// +// Written: Claudio M. Perez, +// Filip C. Filippou +// University of California, Berkeley +// +// Developed with FEDEASLab [2]. +// +// References: +// +// [2] Filippou, F.C. (1998) +// "FEDEASLab: Finite Elements for Design Evaluation and Analysis of Structures" +// +// [3] Nour-Omid, B. and Rankin, C.C. (1991) "Finite rotation analysis and +// consistent linearization using projectors", +// Computer Methods in Applied Mechanics and Engineering, 93(3), pp. 353–384. +// Available at: https://doi.org/10.1016/0045-7825(91)90248-5. +// +#pragma once +#include +#include +#include +#include "EuclidIsometry.h" + +class Node; +#define TRIAD C2 + +namespace OpenSees { + +template +class LinearIsometry : public AlignedIsometry +{ +public: + LinearIsometry(const Vector3D& vecxz) + : AlignedIsometry(vecxz) + { + } + + Matrix3D + update_basis(const Matrix3D&, const Matrix3D&, const Vector3D&) final + { + return this->AlignedIsometry::R[init]; + } + + MatrixND<3,6> + getRotationGradient(int node) final { + MatrixND<3,6> Gb{}; + + constexpr Matrix3D ix = Hat(Vector3D {1, 0, 0}); + + const double Ln = this->getLength(); + + if (node == 0) { + Gb.template insert<0,0>( ix, -1.0/Ln); + Gb(0,3) = 0.5; + } + else if (node == nn-1) { + Gb.template insert<0,0>( ix, 1.0/Ln); + Gb(0,3) = 0.5; + } + return Gb; + } +private: + using AlignedIsometry::init; + double L; +}; +} // namespace OpenSees \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h b/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h index 93b5fa2c16..1a10102e83 100644 --- a/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h @@ -101,7 +101,6 @@ SphericalIsometry::update() { } { -#if 1 // TRIAD==R2 constexpr static Vector3D D2 {0,1,0}; const Vector3D E2 = R[init]*D2; Vector3D e2 = MatrixFromVersor(nodes[0]->getTrialRotation())*E2; //*R[init]; @@ -118,7 +117,6 @@ SphericalIsometry::update() { R[pres](i,2) = e3[i]; } Vector3D e2 = vz.cross(e1); -#endif } Vector3D uc = nodes[ic]->getTrialDisp(); diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.h b/SRC/coordTransformation/Frame/LinearFrameTransf.h index d3665d30c7..75cda8bf28 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.h +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.h @@ -62,15 +62,12 @@ class LinearFrameTransf: public FrameTransform Vector3D getNodePosition(int tag) final; Vector3D getNodeRotationLogarithm(int tag) final; VectorND getStateVariation() final; -#if 0 - VectorND pushResponse(VectorND&pl) final; - MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; -#else + using Operation = typename FrameTransform::Operation; int push(VectorND&pl, Operation) final; int push(MatrixND& kl, const VectorND& pl, Operation) final; -#endif + // // method used to rotate consistent mass matrix // const Matrix &getGlobalMatrixFromLocal(const Matrix &local); diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index dcf7a7c341..5a59044b7b 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -440,17 +440,12 @@ LinearFrameTransf::push(MatrixND&kb, } } -#if 0 - MatrixND kl; - kl.addMatrixTripleProduct(0, A, kb, 1); - this->FrameTransform::pushConstant(kl); -#else + MatrixND kl; kl.addMatrixTripleProduct(0, A, kb, 1); kb = this->FrameTransform::pushConstant(kl); // this->pushRotation(kb, R); return 0; -#endif } diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h index 14a0130220..ae82e3f1fc 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h @@ -56,14 +56,11 @@ class PDeltaFrameTransf: public FrameTransform Vector3D getNodePosition(int tag) final; Vector3D getNodeRotationLogarithm(int tag) final; const std::array *getRigidOffsets() const final { return linear.getRigidOffsets();} -#if 0 - VectorND pushResponse(VectorND&pl) final; - MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; -#else + using Operation = typename FrameTransform::Operation; int push(VectorND&pl, Operation) final; int push(MatrixND& kl, const VectorND& pl, Operation) final; -#endif + FrameTransform *getCopy() const final; diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.h b/SRC/coordTransformation/Frame/SouzaFrameTransf.h index 9f2dc3d334..cad97523b5 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.h +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.h @@ -80,14 +80,11 @@ class SouzaFrameTransf: public FrameTransform VectorND getStateVariation() final; Vector3D getNodePosition(int tag) final; Vector3D getNodeRotationLogarithm(int tag) final; -#if 0 - VectorND pushResponse(VectorND&pl) final; - MatrixND pushResponse(MatrixND& kl, const VectorND& pl) final; -#else + using Operation = typename FrameTransform::Operation; int push(VectorND&pl, Operation) final; int push(MatrixND& kl, const VectorND& pl, Operation) final; -#endif + // Sensitivity double getLengthGrad() final; const Vector &getBasicDisplTotalGrad(int grad); // final; From 4a3c46895cea69acad2c9d33a4f46a537b290428 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 11 Jul 2025 21:23:06 -0700 Subject: [PATCH 172/261] Making surface loads work for shell elements --- SRC/element/surfaceLoad/SurfaceLoad.cpp | 68 ++++++++++---- SRC/element/surfaceLoad/SurfaceLoad.h | 12 ++- SRC/element/surfaceLoad/TriSurfaceLoad.cpp | 104 ++++++++++++++------- SRC/element/surfaceLoad/TriSurfaceLoad.h | 13 ++- 4 files changed, 137 insertions(+), 60 deletions(-) diff --git a/SRC/element/surfaceLoad/SurfaceLoad.cpp b/SRC/element/surfaceLoad/SurfaceLoad.cpp index 962bbc424c..09186a4623 100644 --- a/SRC/element/surfaceLoad/SurfaceLoad.cpp +++ b/SRC/element/surfaceLoad/SurfaceLoad.cpp @@ -47,9 +47,10 @@ double SurfaceLoad :: oneOverRoot3 = 1.0/sqrt(3.0); double SurfaceLoad :: GsPts[4][2]; -Matrix SurfaceLoad::tangentStiffness(SL_NUM_DOF, SL_NUM_DOF); -Vector SurfaceLoad::internalForces(SL_NUM_DOF); -Vector SurfaceLoad::theVector(SL_NUM_DOF); +Matrix SurfaceLoad::tangentStiffness12(12,12); +Matrix SurfaceLoad::tangentStiffness24(24,24); +Vector SurfaceLoad::internalForces12(12); +Vector SurfaceLoad::internalForces24(24); #include static int num_SurfaceLoad = 0; @@ -100,14 +101,15 @@ OPS_SurfaceLoad(void) SurfaceLoad::SurfaceLoad(int tag, int Nd1, int Nd2, int Nd3, int Nd4, double pressure) :Element(tag,ELE_TAG_SurfaceLoad), myExternalNodes(SL_NUM_NODE), + numDOF(0), theMatrix(0), theVector(0), g1(SL_NUM_NDF), g2(SL_NUM_NDF), myNhat(SL_NUM_NDF), myNI(SL_NUM_NODE), - dcrd1(SL_NUM_NDF), - dcrd2(SL_NUM_NDF), - dcrd3(SL_NUM_NDF), - dcrd4(SL_NUM_NDF) + dcrd1(3), + dcrd2(3), + dcrd3(3), + dcrd4(3) { myExternalNodes(0) = Nd1; myExternalNodes(1) = Nd2; @@ -126,19 +128,26 @@ SurfaceLoad::SurfaceLoad(int tag, int Nd1, int Nd2, int Nd3, int Nd4, double pre my_pressure = pressure; mLoadFactor = 1.0; + + tangentStiffness12.Zero(); + tangentStiffness24.Zero(); + + internalForces12.Zero(); + internalForces24.Zero(); } SurfaceLoad::SurfaceLoad() :Element(0,ELE_TAG_SurfaceLoad), myExternalNodes(SL_NUM_NODE), + numDOF(0), theMatrix(0), theVector(0), g1(SL_NUM_NDF), g2(SL_NUM_NDF), myNhat(SL_NUM_NDF), myNI(SL_NUM_NODE), - dcrd1(SL_NUM_NDF), - dcrd2(SL_NUM_NDF), - dcrd3(SL_NUM_NDF), - dcrd4(SL_NUM_NDF) + dcrd1(3), + dcrd2(3), + dcrd3(3), + dcrd4(3) { } @@ -168,7 +177,7 @@ SurfaceLoad::getNodePtrs(void) int SurfaceLoad::getNumDOF(void) { - return SL_NUM_DOF; + return numDOF; } void @@ -188,7 +197,24 @@ SurfaceLoad::setDomain(Domain *theDomain) dcrd2 = theNodes[1]->getCrds(); dcrd3 = theNodes[2]->getCrds(); dcrd4 = theNodes[3]->getCrds(); + if (3 != dcrd1.Size() || 3 != dcrd2.Size() || 3 != dcrd3.Size() || 3 != dcrd4.Size()) { + opserr << "SurfaceLoad::setDomain() - nodes are not defined in three dimensions" << endln; + return; + } + int ndf1 = theNodes[0]->getNumberDOF(); + int ndf2 = theNodes[1]->getNumberDOF(); + int ndf3 = theNodes[2]->getNumberDOF(); + int ndf4 = theNodes[3]->getNumberDOF(); + if (ndf1 != ndf2 || ndf1 != ndf3 || ndf1 != ndf4) { + opserr << "SurfaceLoad::setDomain() - nodes have differing numbers of DOFs" << endln; + return; + } + + numDOF = SL_NUM_NODE*ndf1; + theMatrix = (numDOF == 12) ? &tangentStiffness12 : &tangentStiffness24; + theVector = (numDOF == 12) ? &internalForces12 : &internalForces24; + // call the base class method this->DomainComponent::setDomain(theDomain); } @@ -254,14 +280,15 @@ SurfaceLoad::UpdateBase(double Xi, double Eta) const Matrix & SurfaceLoad::getTangentStiff(void) { - tangentStiffness.Zero(); - return tangentStiffness; + //theMatrix->Zero(); + return *theMatrix; } const Matrix & SurfaceLoad::getInitialStiff(void) { - return getTangentStiff(); + //theMatrix->Zero(); + return *theMatrix; } void @@ -296,22 +323,23 @@ SurfaceLoad::addInertiaLoadToUnbalance(const Vector &accel) const Vector & SurfaceLoad::getResistingForce() { - internalForces.Zero(); + theVector->Zero(); + int nodeDOF = (numDOF == 12) ? 3 : 6; // loop over Gauss points for(int i = 0; i < 4; i++) { this->UpdateBase(GsPts[i][0],GsPts[i][1]); // loop over nodes - for(int j = 0; j < 4; j++) { - // loop over dof + for(int j = 0; j < SL_NUM_NODE; j++) { + // loop over displacement dof for(int k = 0; k < 3; k++) { - internalForces[j*3+k] = internalForces[j*3+k] - mLoadFactor*my_pressure*myNhat(k)*myNI(j); + (*theVector)[j*nodeDOF+k] -= mLoadFactor*my_pressure*myNhat(k)*myNI(j); } } } - return internalForces; + return *theVector; } const Vector & diff --git a/SRC/element/surfaceLoad/SurfaceLoad.h b/SRC/element/surfaceLoad/SurfaceLoad.h index 87b96ebc2a..f2d396e26d 100644 --- a/SRC/element/surfaceLoad/SurfaceLoad.h +++ b/SRC/element/surfaceLoad/SurfaceLoad.h @@ -97,10 +97,16 @@ class SurfaceLoad : public Element int UpdateBase(double Xi, double Eta); ID myExternalNodes; // contains the tags of the end nodes - static Matrix tangentStiffness; // Tangent Stiffness matrix - static Vector internalForces; // vector of Internal Forces - static Vector theVector; // vector to return the residual + static Matrix tangentStiffness12; // Tangent Stiffness matrix for 4 x 3 dofs/node + static Vector internalForces12; // vector of Internal Forces for 4 x 3 dofs/node + static Matrix tangentStiffness24; // Tangent Stiffness matrix for 4 x 6 dofs/node + static Vector internalForces24; // vector of Internal Forces for 4 x 6 dofs/node + int numDOF; // number of element dofs (12 or 24) + + Matrix *theMatrix; + Vector *theVector; + double my_pressure; // pressure applied to surface of element Node *theNodes[SL_NUM_NODE]; diff --git a/SRC/element/surfaceLoad/TriSurfaceLoad.cpp b/SRC/element/surfaceLoad/TriSurfaceLoad.cpp index 543f532e28..d0d8245534 100644 --- a/SRC/element/surfaceLoad/TriSurfaceLoad.cpp +++ b/SRC/element/surfaceLoad/TriSurfaceLoad.cpp @@ -45,10 +45,10 @@ double TriSurfaceLoad::oneOverRoot3 = 1.0/sqrt(3.0); double TriSurfaceLoad::GsPts[1][1]; -Matrix TriSurfaceLoad::tangentStiffness(SL_NUM_DOF, SL_NUM_DOF); -Matrix TriSurfaceLoad::mass(SL_NUM_DOF, SL_NUM_DOF); -Matrix TriSurfaceLoad::damp(SL_NUM_DOF, SL_NUM_DOF); -Vector TriSurfaceLoad::internalForces(SL_NUM_DOF); +Matrix TriSurfaceLoad::tangentStiffness9(9,9); +Matrix TriSurfaceLoad::tangentStiffness18(18,18); +Vector TriSurfaceLoad::internalForces9(9); +Vector TriSurfaceLoad::internalForces18(18); #include static int num_TriSurfaceLoad = 0; @@ -109,13 +109,14 @@ OPS_TriSurfaceLoad(void) TriSurfaceLoad::TriSurfaceLoad(int tag, int Nd1, int Nd2, int Nd3, double pressure, double rhoH_) :Element(tag,ELE_TAG_TriSurfaceLoad), myExternalNodes(SL_NUM_NODE), + numDOF(0), theMatrix(0), theVector(0), g1(SL_NUM_NDF), g2(SL_NUM_NDF), myNhat(SL_NUM_NDF), myNI(SL_NUM_NODE), - dcrd1(SL_NUM_NDF), - dcrd2(SL_NUM_NDF), - dcrd3(SL_NUM_NDF) + dcrd1(3), + dcrd2(3), + dcrd3(3) { myExternalNodes(0) = Nd1; myExternalNodes(1) = Nd2; @@ -127,18 +128,25 @@ TriSurfaceLoad::TriSurfaceLoad(int tag, int Nd1, int Nd2, int Nd3, double pressu rhoH = rhoH_; mLoadFactor = 1.0; + + tangentStiffness9.Zero(); + tangentStiffness18.Zero(); + + internalForces9.Zero(); + internalForces18.Zero(); } TriSurfaceLoad::TriSurfaceLoad() :Element(0,ELE_TAG_TriSurfaceLoad), myExternalNodes(SL_NUM_NODE), + numDOF(0), theMatrix(0), theVector(0), g1(SL_NUM_NDF), g2(SL_NUM_NDF), myNhat(SL_NUM_NDF), myNI(SL_NUM_NODE), - dcrd1(SL_NUM_NDF), - dcrd2(SL_NUM_NDF), - dcrd3(SL_NUM_NDF) + dcrd1(3), + dcrd2(3), + dcrd3(3) { GsPts[0][0] = 1.0/3; my_pressure = 0; @@ -172,7 +180,7 @@ TriSurfaceLoad::getNodePtrs(void) int TriSurfaceLoad::getNumDOF(void) { - return SL_NUM_DOF; + return numDOF; } void @@ -190,7 +198,23 @@ TriSurfaceLoad::setDomain(Domain *theDomain) dcrd1 = theNodes[0]->getCrds(); dcrd2 = theNodes[1]->getCrds(); dcrd3 = theNodes[2]->getCrds(); + if (3 != dcrd1.Size() || 3 != dcrd2.Size() || 3 != dcrd3.Size()) { + opserr << "TriSurfaceLoad::setDomain() - nodes are not defined in three dimensions" << endln; + return; + } + + int ndf1 = theNodes[0]->getNumberDOF(); + int ndf2 = theNodes[1]->getNumberDOF(); + int ndf3 = theNodes[2]->getNumberDOF(); + if (ndf1 != ndf2 || ndf1 != ndf3) { + opserr << "TriSurfaceLoad::setDomain() - nodes have differing numbers of DOFs" << endln; + return; + } + numDOF = SL_NUM_NODE*ndf1; + theMatrix = (numDOF == 9) ? &tangentStiffness9 : &tangentStiffness18; + theVector = (numDOF == 9) ? &internalForces9 : &internalForces18; + // call the base class method this->DomainComponent::setDomain(theDomain); } @@ -252,14 +276,17 @@ TriSurfaceLoad::UpdateBase(double Xi, double Eta) const Matrix & TriSurfaceLoad::getTangentStiff(void) { - tangentStiffness.Zero(); - return tangentStiffness; + theMatrix->Zero(); // have to call bc of getMass + + return *theMatrix; } const Matrix & TriSurfaceLoad::getInitialStiff(void) { - return getTangentStiff(); + theMatrix->Zero(); // have to call bc of getMass + + return *theMatrix; } void @@ -295,22 +322,23 @@ TriSurfaceLoad::addInertiaLoadToUnbalance(const Vector &accel) const Vector & TriSurfaceLoad::getResistingForce() { - internalForces.Zero(); + theVector->Zero(); + int nodeDOF = (numDOF == 9) ? 3 : 6; // loop over Gauss points for(int i = 0; i < 1; i++) { this->UpdateBase(GsPts[i][0],GsPts[i][0]); // loop over nodes - for(int j = 0; j < 3; j++) { - // loop over dof + for(int j = 0; j < SL_NUM_NODE; j++) { + // loop over displacement dof for(int k = 0; k < 3; k++) { - internalForces[j*3+k] = internalForces[j*3+k] - mLoadFactor*my_pressure*myNhat(k)*myNI(j); + (*theVector)[j*nodeDOF+k] -= mLoadFactor*my_pressure*myNhat(k)*myNI(j); } } } - return internalForces; + return *theVector; } const Vector & @@ -319,7 +347,7 @@ TriSurfaceLoad::getResistingForceIncInertia() static Vector accel(SL_NUM_DOF); accel.Zero(); - internalForces = getResistingForce(); + *theVector = getResistingForce(); int pos = 0; for (int i = 0; i < SL_NUM_NODE; ++i) @@ -327,11 +355,19 @@ TriSurfaceLoad::getResistingForceIncInertia() const Vector &a = theNodes[i]->getAccel(); accel(pos++) = a(i); } + + if (rhoH != 0.0) { + double Area = myNhat.Norm(); + double m = rhoH*Area/3; + int nodeDOF = (numDOF == 9) ? 3 : 6; + for (int i = 0; i < 3; i++) { + (*theVector)(i) -= m*accel(i); + (*theVector)(i+nodeDOF) -= m*accel(i+nodeDOF); + (*theVector)(i+2*nodeDOF) -= m*accel(i+2*nodeDOF); + } + } - mass = getMass(); - internalForces.addMatrixVector(1.0, mass, accel, -1.0); - - return internalForces; + return *theVector; } int @@ -454,17 +490,19 @@ TriSurfaceLoad::getResponse(int responseID, Information &eleInfo) // Compute a mass matrix using zangar's idea: const Matrix & TriSurfaceLoad::getMass(void) { - double Area = myNhat.Norm(); - - mass.Zero(); + theMatrix->Zero(); - if(rhoH > 0) + if(rhoH != 0) { - for (int i = 0; i < SL_NUM_DOF; ++i) - { - mass(i,i) = rhoH * Area /3; - } + double Area = myNhat.Norm(); + double m = rhoH*Area/3; + int nodeDOF = (numDOF == 9) ? 3 : 6; + for (int i = 0; i < 3; i++) { + (*theMatrix)(i,i) = m; + (*theMatrix)(i+nodeDOF,i+nodeDOF) = m; + (*theMatrix)(i+2*nodeDOF,i+2*nodeDOF) = m; + } } - return mass; + return *theMatrix; } diff --git a/SRC/element/surfaceLoad/TriSurfaceLoad.h b/SRC/element/surfaceLoad/TriSurfaceLoad.h index 097b60321a..77bb1cfad3 100644 --- a/SRC/element/surfaceLoad/TriSurfaceLoad.h +++ b/SRC/element/surfaceLoad/TriSurfaceLoad.h @@ -97,11 +97,16 @@ class TriSurfaceLoad : public Element int UpdateBase(double Xi, double Eta); ID myExternalNodes; // contains the tags of the end nodes - static Matrix tangentStiffness; // Tangent Stiffness matrix - static Matrix mass; // mass matrix - static Matrix damp; // damping matrix - static Vector internalForces; // vector of Internal Forces + static Matrix tangentStiffness9; // Tangent Stiffness matrix for 3 x 3 dofs/node + static Matrix tangentStiffness18; // Tangent Stiffness matrix for 3 x 6 dofs/node + static Vector internalForces9; // vector of Internal Forces for 3 x 3 dofs/node + static Vector internalForces18; // vector of Internal Forces for 3 x 6 dofs/node + + int numDOF; // number of element dofs (9 or 18) + Matrix *theMatrix; + Vector *theVector; + double my_pressure; // pressure applied to surface of element double rhoH; // A density per unit area to compute a mass matrix (lumped) From 3d992d0da2f427aefd391a45be52c650dcce5383 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 11 Jul 2025 23:47:27 -0700 Subject: [PATCH 173/261] consolidate node response commands and add `nodeRotation` --- SRC/runtime/commands/domain/nodes.cpp | 580 ++++++++++++++---------- SRC/runtime/commands/modeling/nodes.cpp | 338 -------------- 2 files changed, 341 insertions(+), 577 deletions(-) delete mode 100644 SRC/runtime/commands/modeling/nodes.cpp diff --git a/SRC/runtime/commands/domain/nodes.cpp b/SRC/runtime/commands/domain/nodes.cpp index 7627afe957..74a7def909 100644 --- a/SRC/runtime/commands/domain/nodes.cpp +++ b/SRC/runtime/commands/domain/nodes.cpp @@ -113,8 +113,9 @@ setNodeCoord(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING setNodeCoord nodeTag? dim? value? - could not read " - "nodeTag? \n"; + opserr << OpenSees::PromptValueError + << "could not read nodeTag" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -134,29 +135,351 @@ setNodeCoord(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, Node *theNode = domain->getNode(tag); - if (theNode == nullptr) { - // TODO: add error message - return TCL_ERROR; - } + if (theNode == nullptr) { + // TODO: add error message + return TCL_ERROR; + } + + // + // TODO: Check dimensions + + Vector coords(theNode->getCrds()); + coords(dim - 1) = value; + theNode->setCrds(coords); + domain->domainChange(); + + return TCL_OK; +} + + + +#if 1 + +template +int +nodeResponseTemplate(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + assert(clientData != nullptr); + Domain *domain = (Domain*)clientData; + + if (argc < 2) { + opserr << "WARNING want - nodeDisp nodeTag? \n"; + return TCL_ERROR; + } + + int tag; + int dof = -1; + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING could not read nodeTag? \n"; + return TCL_ERROR; + } + + if (argc > 2) { + if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { + opserr << "WARNING nodeDisp nodeTag? dof? - could not read dof? \n"; + return TCL_ERROR; + } + } + + dof--; + + const Vector *nodalResponse = domain->getNodeResponse(tag, Response); + + if (nodalResponse == nullptr) + // TODO: add error message + return TCL_ERROR; + + int size = nodalResponse->Size(); + + if (dof >= 0) { + + if (dof >= size) { + opserr << OpenSees::PromptValueError + << "dofTag too large" + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } + + Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); + + } else { + char buffer[40]; + for (int i = 0; i < size; ++i) { + sprintf(buffer, "%35.20f", (*nodalResponse)(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + return TCL_OK; +} + +int +nodeDisp(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + return nodeResponseTemplate(clientData, interp, argc, argv); +} +int +nodeVel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + return nodeResponseTemplate(clientData, interp, argc, argv); +} + +int +nodeAccel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + return nodeResponseTemplate(clientData, interp, argc, argv); +} + +int +nodeUnbalance(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + return nodeResponseTemplate(clientData, interp, argc, argv); +} + +int +nodeReaction(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + return nodeResponseTemplate(clientData, interp, argc, argv); +} + +#else +int +nodeDisp(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + assert(clientData != nullptr); + Domain *domain = (Domain*)clientData; + + if (argc < 2) { + opserr << "WARNING want - nodeDisp nodeTag? \n"; + return TCL_ERROR; + } + + int tag; + int dof = -1; + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING could not read nodeTag? \n"; + return TCL_ERROR; + } + + if (argc > 2) { + if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { + opserr << "WARNING nodeDisp nodeTag? dof? - could not read dof? \n"; + return TCL_ERROR; + } + } + + dof--; + + const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::Disp); + + if (nodalResponse == nullptr) + // TODO: add error message + return TCL_ERROR; + + int size = nodalResponse->Size(); + + if (dof >= 0) { + + if (dof >= size) { + opserr << "WARNING nodeDisp nodeTag? dof? - dofTag? too large\n"; + return TCL_ERROR; + } + + Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); + + } else { + char buffer[40]; + for (int i = 0; i < size; ++i) { + sprintf(buffer, "%35.20f", (*nodalResponse)(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + return TCL_OK; +} + +int +nodeVel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + assert(clientData != nullptr); + Domain *the_domain = (Domain*)clientData; + + if (argc < 2) { + opserr << "WARNING want - nodeVel nodeTag? \n"; + return TCL_ERROR; + } + + int tag; + int dof = -1; + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING nodeVel nodeTag? dof? - could not read nodeTag? \n"; + return TCL_ERROR; + } + if (argc > 2) { + if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { + opserr << "WARNING nodeVel nodeTag? dof? - could not read dof? \n"; + return TCL_ERROR; + } + } + + dof--; + + const Vector *nodalResponse = the_domain->getNodeResponse(tag, NodeData::Vel); + + if (nodalResponse == nullptr) + // TODO: add error message + return TCL_ERROR; + + int size = nodalResponse->Size(); + + if (dof >= 0) { + if (size < dof) + // TODO: add error message + return TCL_ERROR; + + double value = (*nodalResponse)(dof); + + // now we copy the value to the tcl string that is returned + char buffer[40]; + sprintf(buffer, "%35.20f", value); + Tcl_SetResult(interp, buffer, TCL_VOLATILE); + + } else { + + char buffer[40]; + for (int i = 0; i < size; ++i) { + sprintf(buffer, "%35.20f", (*nodalResponse)(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + return TCL_OK; +} + +int +nodeAccel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + assert(clientData != nullptr); + + Domain *the_domain = (Domain *)clientData; + + if (argc < 2) { + opserr << "WARNING want - nodeAccel nodeTag? dof?\n"; + return TCL_ERROR; + } + + int tag; + int dof = -1; + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING nodeAccel nodeTag? dof? - could not read nodeTag? \n"; + return TCL_ERROR; + } + if (argc > 2) { + if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { + opserr << "WARNING nodeAccel nodeTag? dof? - could not read dof? \n"; + return TCL_ERROR; + } + } + + dof--; + + const Vector *nodalResponse = the_domain->getNodeResponse(tag, NodeData::Accel); + if (nodalResponse == nullptr) + // TODO: add error message + return TCL_ERROR; + + int size = nodalResponse->Size(); + + if (dof >= 0) { + if (size < dof) + return TCL_ERROR; + + Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); + + } else { + char buffer[40]; + for (int i = 0; i < size; ++i) { + sprintf(buffer, "%35.20f", (*nodalResponse)(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + return TCL_OK; +} + + +int +nodeUnbalance(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, + TCL_Char ** const argv) +{ + assert(clientData != nullptr); + Domain *domain = (Domain*)clientData; + + if (argc < 2) { + opserr << "WARNING want - nodeUnbalance nodeTag? \n"; + return TCL_ERROR; + } + + int tag; + int dof = -1; + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr + << "WARNING nodeUnbalance nodeTag? dof? - could not read nodeTag? \n"; + return TCL_ERROR; + } + + if (argc > 2) { + if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { + opserr << "WARNING nodeUnbalance nodeTag? dof? - could not read dof? \n"; + return TCL_ERROR; + } + } + + dof--; + + const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::UnbalancedLoad); + + if (nodalResponse == nullptr) + // TODO: add error message + return TCL_ERROR; + + int size = nodalResponse->Size(); + + if (dof >= 0) { + + if (dof >= size) { + opserr << "WARNING nodeUnbalance nodeTag? dof? - dofTag? too large\n"; + return TCL_ERROR; + } - // - // TODO: Check dimensions + Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); - Vector coords(theNode->getCrds()); - coords(dim - 1) = value; - theNode->setCrds(coords); + } else { + char buffer[40]; + for (int i = 0; i < size; ++i) { + sprintf(buffer, "%35.20f", (*nodalResponse)(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } return TCL_OK; } + int -nodeDisp(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +nodeReaction(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, + TCL_Char ** const argv) { assert(clientData != nullptr); Domain *domain = (Domain*)clientData; if (argc < 2) { - opserr << "WARNING want - nodeDisp nodeTag? \n"; + opserr << "WARNING want - nodeReaction nodeTag? \n"; return TCL_ERROR; } @@ -164,20 +487,20 @@ nodeDisp(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** c int dof = -1; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING nodeDisp nodeTag? dof? - could not read nodeTag? \n"; + opserr << "WARNING nodeReaction nodeTag? dof? - could not read nodeTag? \n"; return TCL_ERROR; } if (argc > 2) { if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeDisp nodeTag? dof? - could not read dof? \n"; + opserr << "WARNING nodeReaction nodeTag? dof? - could not read dof? \n"; return TCL_ERROR; } } dof--; - const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::Disp); + const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::Reaction); if (nodalResponse == nullptr) // TODO: add error message @@ -188,7 +511,7 @@ nodeDisp(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** c if (dof >= 0) { if (dof >= size) { - opserr << "WARNING nodeDisp nodeTag? dof? - dofTag? too large\n"; + opserr << "WARNING nodeReaction nodeTag? dof? - dofTag? too large\n"; return TCL_ERROR; } @@ -204,6 +527,7 @@ nodeDisp(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** c return TCL_OK; } +#endif int nodeMass(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) @@ -302,64 +626,6 @@ nodeBounds(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** return TCL_OK; } -int -nodeVel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *the_domain = (Domain*)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeVel nodeTag? \n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING nodeVel nodeTag? dof? - could not read nodeTag? \n"; - return TCL_ERROR; - } - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeVel nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = the_domain->getNodeResponse(tag, NodeData::Vel); - - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - if (size < dof) - // TODO: add error message - return TCL_ERROR; - - double value = (*nodalResponse)(dof); - - // now we copy the value to the tcl string that is returned - char buffer[40]; - sprintf(buffer, "%35.20f", value); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); - - } else { - - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} int setNodeVel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) @@ -538,115 +804,7 @@ setNodeAccel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, return TCL_OK; } -int -nodeAccel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - - Domain *the_domain = (Domain *)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeAccel nodeTag? dof?\n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING nodeAccel nodeTag? dof? - could not read nodeTag? \n"; - return TCL_ERROR; - } - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeAccel nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = the_domain->getNodeResponse(tag, NodeData::Accel); - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - if (size < dof) - return TCL_ERROR; - - Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); - - } else { - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} - -int -nodeUnbalance(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *domain = (Domain*)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeUnbalance nodeTag? \n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr - << "WARNING nodeUnbalance nodeTag? dof? - could not read nodeTag? \n"; - return TCL_ERROR; - } - - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeUnbalance nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::UnbalancedLoad); - - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - - if (dof >= size) { - opserr << "WARNING nodeUnbalance nodeTag? dof? - dofTag? too large\n"; - return TCL_ERROR; - } - - Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); - - } else { - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - return TCL_OK; -} int nodeRotation(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, @@ -847,62 +1005,6 @@ calculateNodalReactions(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc return TCL_OK; } -int -nodeReaction(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *domain = (Domain*)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeReaction nodeTag? \n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING nodeReaction nodeTag? dof? - could not read nodeTag? \n"; - return TCL_ERROR; - } - - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeReaction nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::Reaction); - - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - - if (dof >= size) { - opserr << "WARNING nodeReaction nodeTag? dof? - dofTag? too large\n"; - return TCL_ERROR; - } - - Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); - - } else { - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} int nodeCoord(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) diff --git a/SRC/runtime/commands/modeling/nodes.cpp b/SRC/runtime/commands/modeling/nodes.cpp deleted file mode 100644 index cd296f98b3..0000000000 --- a/SRC/runtime/commands/modeling/nodes.cpp +++ /dev/null @@ -1,338 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// -//===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// -// Description: This file implements commands that configure Node objects -// for an analysis. -// -// Author: cmp -// -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define HeapNode Node - -// #define G3_MAX_NUM_DOFS 1000000000000 -#define G3_NUM_DOF_BUFFER 20 - -int -TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - - BasicModelBuilder *builder = static_cast(clientData); - - Domain *theTclDomain = builder->getDomain(); - - int ndm = builder->getNDM(); - int ndf = builder->getNDF(); - - // make sure corect number of arguments on command line - if (argc < 2 + 1) { // ndm) { - opserr << OpenSees::PromptValueError - << "insufficient arguments" - << OpenSees::SignalMessageEnd; - return TCL_ERROR; - } - - Node *theNode = nullptr; - - // read the node id - int nodeId; - if (Tcl_GetInt(interp, argv[1], &nodeId) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid nodeTag\n"; - opserr << " Want: node nodeTag? [ndm coordinates?] <-mass [ndf values?]>\n"; - return TCL_ERROR; - } - - // read in the coordinates and create the node - double xLoc=0, yLoc=0, zLoc=0; - if (ndm >= 1 && argc >= 3) { - // create a node in 1d space - if (Tcl_GetDouble(interp, argv[2], &xLoc) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid coordinate " << argv[2] - << OpenSees::SignalMessageEnd; - return TCL_ERROR; - } - } - - if (ndm >= 2 && argc >= 4) { - if (Tcl_GetDouble(interp, argv[3], &yLoc) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid 2nd coordinate " << argv[3] - << OpenSees::SignalMessageEnd; - return TCL_ERROR; - } - } - - if (ndm >= 3 && argc >= 5) { - if (Tcl_GetDouble(interp, argv[4], &zLoc) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid 3rd coordinate " << argv[4] - << OpenSees::SignalMessageEnd; - return TCL_ERROR; - } - } - - // check for -ndf override option - int currentArg = 2 + ndm; - if (currentArg < argc && strcmp(argv[currentArg], "-ndf") == 0) { - if (Tcl_GetInt(interp, argv[currentArg + 1], &ndf) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid nodal ndf given for node " << nodeId << "\n"; - return TCL_ERROR; - } - currentArg += 2; - } - - // - // create the node - // - switch (ndm) { - case 1: - theNode = new HeapNode(nodeId, ndf, xLoc); - break; - case 2: - theNode = new HeapNode(nodeId, ndf, xLoc, yLoc); - break; - case 3: -#if 0 - if (getenv("NODE")) { - switch (ndf) { - case 3: - theNode = new NodeND<3, 3>(nodeId, xLoc, yLoc, zLoc); - break; - case 6: - theNode = new NodeND<3, 6>(nodeId, xLoc, yLoc, zLoc); - break; - default: - theNode = new HeapNode(nodeId, ndf, xLoc, yLoc, zLoc); - break; - } - } else -#endif - theNode = new HeapNode(nodeId, ndf, xLoc, yLoc, zLoc); - break; - } - - while (currentArg < argc) { - if (strcmp(argv[currentArg], "-mass") == 0) { - currentArg++; - if (argc < currentArg + ndf) { - opserr << OpenSees::PromptValueError << "incorrect number of nodal mass terms\n"; - opserr << "node: " << nodeId << "\n"; - return TCL_ERROR; - } - - double theMass; - Matrix mass(ndf, ndf); - for (int i = 0; i < ndf; ++i) { - if (Tcl_GetDouble(interp, argv[currentArg++], &theMass) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid nodal mass term"; - opserr << " at dof " << i + 1 << "\n"; - return TCL_ERROR; - } - mass(i, i) = theMass; - } - theNode->setMass(mass); - - } else if (strcmp(argv[currentArg], "-dispLoc") == 0) { - currentArg++; - if (argc < currentArg + ndm) { - opserr << OpenSees::PromptValueError << "incorrect number of nodal display location terms, " - "need ndm\n"; - return TCL_ERROR; - } - Vector displayLoc(ndm); - double theCrd; - for (int i = 0; i < ndm; ++i) { - if (Tcl_GetDouble(interp, argv[currentArg++], &theCrd) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid nodal mass term\n"; - opserr << "node: " << nodeId << ", dof: " << i + 1 << "\n"; - return TCL_ERROR; - } - displayLoc(i) = theCrd; - } - theNode->setDisplayCrds(displayLoc); - - } else if (strcmp(argv[currentArg], "-disp") == 0) { - currentArg++; - if (argc < currentArg + ndf) { - opserr << OpenSees::PromptValueError << "incorrect number of nodal disp terms\n"; - opserr << "node: " << nodeId << "\n"; - return TCL_ERROR; - } - Vector disp(ndf); - double theDisp; - for (int i = 0; i < ndf; ++i) { - if (Tcl_GetDouble(interp, argv[currentArg++], &theDisp) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid nodal disp term\n"; - opserr << "node: " << nodeId << ", dof: " << i + 1 << "\n"; - return TCL_ERROR; - } - disp(i) = theDisp; - } - theNode->setTrialDisp(disp); - theNode->commitState(); - - } else if (strcmp(argv[currentArg], "-vel") == 0) { - currentArg++; - if (argc < currentArg + ndf) { - opserr << OpenSees::PromptValueError << "incorrect number of nodal vel terms, "; - opserr << "expected " << ndf << "\n"; - return TCL_ERROR; - } - - double theDisp; - Vector disp(ndf); - for (int i = 0; i < ndf; ++i) { - if (Tcl_GetDouble(interp, argv[currentArg++], &theDisp) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid nodal vel term at "; - opserr << " dof " << i + 1 << "\n"; - return TCL_ERROR; - } - disp(i) = theDisp; - } - theNode->setTrialVel(disp); - theNode->commitState(); - - } else - currentArg++; - } - - // - // add the node to the domain - // - if (theTclDomain->addNode(theNode) == false) { - opserr << OpenSees::PromptValueError << "failed to add node to the domain\n"; - delete theNode; - return TCL_ERROR; - } - - return TCL_OK; -} - -int -TclCommand_addNodalMass(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder *builder = static_cast(clientData); - Domain *theTclDomain = builder->getDomain(); - - int ndf = argc - 2; - - // make sure at least one other argument - if (argc < (1 + ndf)) { - opserr << OpenSees::PromptValueError << "insufficient arguments, expected:\n" - " mass nodeId <" << ndf << " mass values>\n"; - return TCL_ERROR; - } - - // get the id of the node - int nodeId; - if (Tcl_GetInt(interp, argv[1], &nodeId) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid nodeId: " << argv[1]; - opserr << " - mass nodeId " << ndf << " forces\n"; - return TCL_ERROR; - } - - // check for mass terms - Matrix mass(ndf,ndf); - for (int i=0; isetMass(mass, nodeId) != 0) { - opserr << OpenSees::PromptValueError << "failed to set mass at node " << nodeId << "\n"; - return TCL_ERROR; - } - - // if get here we have sucessfully created the node and added it to the domain - return TCL_OK; -} - - - -int -TclCommand_getNDM(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder* builder = static_cast(clientData); - Domain *the_domain = builder->getDomain(); - - int ndm; - - if (argc > 1) { - int tag; - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << OpenSees::PromptValueError << "ndm nodeTag? \n"; - return TCL_ERROR; - } - - Node *theNode = the_domain->getNode(tag); - if (theNode == nullptr) { - opserr << OpenSees::PromptValueError << "nodeTag " << tag << " does not exist \n"; - return TCL_ERROR; - } - const Vector &coords = theNode->getCrds(); - ndm = coords.Size(); - - } else { - ndm = builder->getNDM(); - } - - Tcl_SetObjResult(interp, Tcl_NewIntObj(ndm)); - return TCL_OK; -} - -int -TclCommand_getNDF(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder* builder = static_cast(clientData); - Domain *the_domain = builder->getDomain(); - int ndf; - - if (argc > 1) { - int tag; - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << OpenSees::PromptValueError << "ndf nodeTag? \n"; - return TCL_ERROR; - } - Node *theNode = the_domain->getNode(tag); - if (theNode == nullptr) { - opserr << OpenSees::PromptValueError << "nodeTag " << tag << " does not exist \n"; - return TCL_ERROR; - } - ndf = theNode->getNumberDOF(); - - } else { - ndf = builder->getNDF(); - } - - char buffer[G3_NUM_DOF_BUFFER]; - sprintf(buffer, "%d", ndf); - - Tcl_AppendResult(interp, buffer, NULL); - - return TCL_OK; -} From 097a663e6ecc6d95693fb3c5c1e9b8ec241fe9e0 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 11 Jul 2025 23:48:47 -0700 Subject: [PATCH 174/261] restore nodes.cpp --- SRC/runtime/commands/modeling/nodes.cpp | 346 ++++++++++++++++++++++++ 1 file changed, 346 insertions(+) create mode 100644 SRC/runtime/commands/modeling/nodes.cpp diff --git a/SRC/runtime/commands/modeling/nodes.cpp b/SRC/runtime/commands/modeling/nodes.cpp new file mode 100644 index 0000000000..c8f3be9360 --- /dev/null +++ b/SRC/runtime/commands/modeling/nodes.cpp @@ -0,0 +1,346 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// Description: This file implements commands that configure Node objects +// for an analysis. +// +// Author: cmp +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define G3_MAX_NUM_DOFS 1000000000000 +#define G3_NUM_DOF_BUFFER 20 + +int +TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + assert(clientData != nullptr); + + BasicModelBuilder *builder = static_cast(clientData); + + Domain *theTclDomain = builder->getDomain(); + + int ndm = builder->getNDM(); + int ndf = builder->getNDF(); + + // make sure corect number of arguments on command line + if (argc < 2 + ndm) { + opserr << G3_ERROR_PROMPT << "insufficient arguments, expected:\n"; + opserr << " node nodeTag? [ndm coordinates?] <-mass [ndf values?]>\n"; + return TCL_ERROR; + } + + Node *theNode = 0; + + // read the node id + int nodeId; + if (Tcl_GetInt(interp, argv[1], &nodeId) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid nodeTag\n"; + opserr << " Want: node nodeTag? [ndm coordinates?] <-mass [ndf values?]>\n"; + return TCL_ERROR; + } + + // read in the coordinates and create the node + double xLoc, yLoc, zLoc; + if (ndm == 1) { + // create a node in 1d space + if (Tcl_GetDouble(interp, argv[2], &xLoc) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid coordinate\n"; + return TCL_ERROR; + } + } + + else if (ndm == 2) { + // create a node in 2d space + if (Tcl_GetDouble(interp, argv[2], &xLoc) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid 1st coordinate\n"; + opserr << "node: " << nodeId << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[3], &yLoc) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid 2nd coordinate\n"; + opserr << "node: " << nodeId << "\n"; + return TCL_ERROR; + } + } + + else if (ndm == 3) { + // create a node in 3d space + if (Tcl_GetDouble(interp, argv[2], &xLoc) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid 1st coordinate\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[3], &yLoc) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid 2nd coordinate\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[4], &zLoc) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid 3rd coordinate\n"; + return TCL_ERROR; + } + + } else { + opserr << G3_ERROR_PROMPT << "unsupported model dimension\n"; + return TCL_ERROR; + } + + // check for -ndf override option + int currentArg = 2 + ndm; + if (currentArg < argc && strcmp(argv[currentArg], "-ndf") == 0) { + if (Tcl_GetInt(interp, argv[currentArg + 1], &ndf) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid nodal ndf given for node " << nodeId << "\n"; + return TCL_ERROR; + } + currentArg += 2; + } + + // + // create the node + // + switch (ndm) { + case 1: + theNode = new Node(nodeId, ndf, xLoc); + break; + case 2: + theNode = new Node(nodeId, ndf, xLoc, yLoc); + break; + case 3: + if (getenv("NODE")) { + switch (ndf) { + case 3: + theNode = new NodeND<3, 3>(nodeId, xLoc, yLoc, zLoc); + break; + case 6: + theNode = new NodeND<3, 6>(nodeId, xLoc, yLoc, zLoc); + break; + default: + theNode = new Node(nodeId, ndf, xLoc, yLoc, zLoc); + break; + } + } else + theNode = new Node(nodeId, ndf, xLoc, yLoc, zLoc); + break; + } + + while (currentArg < argc) { + if (strcmp(argv[currentArg], "-mass") == 0) { + currentArg++; + if (argc < currentArg + ndf) { + opserr << G3_ERROR_PROMPT << "incorrect number of nodal mass terms\n"; + opserr << "node: " << nodeId << "\n"; + return TCL_ERROR; + } + + double theMass; + Matrix mass(ndf, ndf); + for (int i = 0; i < ndf; ++i) { + if (Tcl_GetDouble(interp, argv[currentArg++], &theMass) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid nodal mass term"; + opserr << " at dof " << i + 1 << "\n"; + return TCL_ERROR; + } + mass(i, i) = theMass; + } + theNode->setMass(mass); + + } else if (strcmp(argv[currentArg], "-dispLoc") == 0) { + currentArg++; + if (argc < currentArg + ndm) { + opserr << G3_ERROR_PROMPT << "incorrect number of nodal display location terms, " + "need ndm\n"; + return TCL_ERROR; + } + Vector displayLoc(ndm); + double theCrd; + for (int i = 0; i < ndm; ++i) { + if (Tcl_GetDouble(interp, argv[currentArg++], &theCrd) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid nodal mass term\n"; + opserr << "node: " << nodeId << ", dof: " << i + 1 << "\n"; + return TCL_ERROR; + } + displayLoc(i) = theCrd; + } + theNode->setDisplayCrds(displayLoc); + + } else if (strcmp(argv[currentArg], "-disp") == 0) { + currentArg++; + if (argc < currentArg + ndf) { + opserr << G3_ERROR_PROMPT << "incorrect number of nodal disp terms\n"; + opserr << "node: " << nodeId << "\n"; + return TCL_ERROR; + } + Vector disp(ndf); + double theDisp; + for (int i = 0; i < ndf; ++i) { + if (Tcl_GetDouble(interp, argv[currentArg++], &theDisp) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid nodal disp term\n"; + opserr << "node: " << nodeId << ", dof: " << i + 1 << "\n"; + return TCL_ERROR; + } + disp(i) = theDisp; + } + theNode->setTrialDisp(disp); + theNode->commitState(); + + } else if (strcmp(argv[currentArg], "-vel") == 0) { + currentArg++; + if (argc < currentArg + ndf) { + opserr << G3_ERROR_PROMPT << "incorrect number of nodal vel terms, "; + opserr << "expected " << ndf << "\n"; + return TCL_ERROR; + } + + double theDisp; + Vector disp(ndf); + for (int i = 0; i < ndf; ++i) { + if (Tcl_GetDouble(interp, argv[currentArg++], &theDisp) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid nodal vel term at "; + opserr << " dof " << i + 1 << "\n"; + return TCL_ERROR; + } + disp(i) = theDisp; + } + theNode->setTrialVel(disp); + theNode->commitState(); + + } else + currentArg++; + } + + // + // add the node to the domain + // + if (theTclDomain->addNode(theNode) == false) { + opserr << G3_ERROR_PROMPT << "failed to add node to the domain\n"; + delete theNode; + return TCL_ERROR; + } + + return TCL_OK; +} + +int +TclCommand_addNodalMass(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder *builder = static_cast(clientData); + Domain *theTclDomain = builder->getDomain(); + + int ndf = argc - 2; + + // make sure at least one other argument + if (argc < (1 + ndf)) { + opserr << G3_ERROR_PROMPT << "insufficient arguments, expected:\n" + " mass nodeId <" << ndf << " mass values>\n"; + return TCL_ERROR; + } + + // get the id of the node + int nodeId; + if (Tcl_GetInt(interp, argv[1], &nodeId) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "invalid nodeId: " << argv[1]; + opserr << " - mass nodeId " << ndf << " forces\n"; + return TCL_ERROR; + } + + // check for mass terms + Matrix mass(ndf,ndf); + for (int i=0; isetMass(mass, nodeId) != 0) { + opserr << G3_ERROR_PROMPT << "failed to set mass at node " << nodeId << "\n"; + return TCL_ERROR; + } + + // if get here we have sucessfully created the node and added it to the domain + return TCL_OK; +} + + + +int +TclCommand_getNDM(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder* builder = static_cast(clientData); + Domain *the_domain = builder->getDomain(); + + int ndm; + + if (argc > 1) { + int tag; + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "ndm nodeTag? \n"; + return TCL_ERROR; + } + + Node *theNode = the_domain->getNode(tag); + if (theNode == nullptr) { + opserr << G3_ERROR_PROMPT << "nodeTag " << tag << " does not exist \n"; + return TCL_ERROR; + } + const Vector &coords = theNode->getCrds(); + ndm = coords.Size(); + + } else { + ndm = builder->getNDM(); + } + + Tcl_SetObjResult(interp, Tcl_NewIntObj(ndm)); + return TCL_OK; +} + +int +TclCommand_getNDF(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder* builder = static_cast(clientData); + Domain *the_domain = builder->getDomain(); + int ndf; + + if (argc > 1) { + int tag; + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << G3_ERROR_PROMPT << "ndf nodeTag? \n"; + return TCL_ERROR; + } + Node *theNode = the_domain->getNode(tag); + if (theNode == nullptr) { + opserr << G3_ERROR_PROMPT << "nodeTag " << tag << " does not exist \n"; + return TCL_ERROR; + } + ndf = theNode->getNumberDOF(); + + } else { + ndf = builder->getNDF(); + } + + char buffer[G3_NUM_DOF_BUFFER]; + sprintf(buffer, "%d", ndf); + + Tcl_AppendResult(interp, buffer, NULL); + + return TCL_OK; +} From c42e9a333e5a054e8422afccff55aaaadb614a14 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Fri, 11 Jul 2025 23:56:52 -0700 Subject: [PATCH 175/261] clean up nodeResponse template --- SRC/runtime/commands/domain/nodes.cpp | 331 ++------------------------ 1 file changed, 26 insertions(+), 305 deletions(-) diff --git a/SRC/runtime/commands/domain/nodes.cpp b/SRC/runtime/commands/domain/nodes.cpp index 74a7def909..401b6268c8 100644 --- a/SRC/runtime/commands/domain/nodes.cpp +++ b/SRC/runtime/commands/domain/nodes.cpp @@ -153,47 +153,53 @@ setNodeCoord(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, -#if 1 - template int nodeResponseTemplate(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); - Domain *domain = (Domain*)clientData; + Domain *domain = static_cast(clientData); if (argc < 2) { - opserr << "WARNING want - nodeDisp nodeTag? \n"; + opserr << OpenSees::PromptValueError + << "Insufficient arguments" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } int tag; - int dof = -1; - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING could not read nodeTag? \n"; + opserr << OpenSees::PromptValueError + << "Failed to read nodeTag" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } + int dof = -1; if (argc > 2) { if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeDisp nodeTag? dof? - could not read dof? \n"; + opserr << OpenSees::PromptValueError + << "Failed to read dof" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } } dof--; - const Vector *nodalResponse = domain->getNodeResponse(tag, Response); + const Vector *response = domain->getNodeResponse(tag, Response); - if (nodalResponse == nullptr) - // TODO: add error message + if (response == nullptr) { + opserr << OpenSees::PromptValueError + << "Node " << tag << " does not have a response of type " + << argv[1] + << OpenSees::SignalMessageEnd; return TCL_ERROR; + } - int size = nodalResponse->Size(); + Tcl_Size size = response->Size(); if (dof >= 0) { - if (dof >= size) { opserr << OpenSees::PromptValueError << "dofTag too large" @@ -201,14 +207,14 @@ nodeResponseTemplate(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, T return TCL_ERROR; } - Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*response)(dof))); + } + else { + Tcl_Obj* list = Tcl_NewListObj(size, nullptr); + for (int i = 0; i < size; ++i) + Tcl_ListObjAppendElement(interp, list, Tcl_NewDoubleObj((*response)(i))); - } else { - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } + Tcl_SetObjResult(interp, list); } return TCL_OK; @@ -243,291 +249,6 @@ nodeReaction(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char return nodeResponseTemplate(clientData, interp, argc, argv); } -#else -int -nodeDisp(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *domain = (Domain*)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeDisp nodeTag? \n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING could not read nodeTag? \n"; - return TCL_ERROR; - } - - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeDisp nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::Disp); - - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - - if (dof >= size) { - opserr << "WARNING nodeDisp nodeTag? dof? - dofTag? too large\n"; - return TCL_ERROR; - } - - Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); - - } else { - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} - -int -nodeVel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *the_domain = (Domain*)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeVel nodeTag? \n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING nodeVel nodeTag? dof? - could not read nodeTag? \n"; - return TCL_ERROR; - } - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeVel nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = the_domain->getNodeResponse(tag, NodeData::Vel); - - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - if (size < dof) - // TODO: add error message - return TCL_ERROR; - - double value = (*nodalResponse)(dof); - - // now we copy the value to the tcl string that is returned - char buffer[40]; - sprintf(buffer, "%35.20f", value); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); - - } else { - - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} - -int -nodeAccel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - - Domain *the_domain = (Domain *)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeAccel nodeTag? dof?\n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING nodeAccel nodeTag? dof? - could not read nodeTag? \n"; - return TCL_ERROR; - } - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeAccel nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = the_domain->getNodeResponse(tag, NodeData::Accel); - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - if (size < dof) - return TCL_ERROR; - - Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); - - } else { - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} - - -int -nodeUnbalance(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *domain = (Domain*)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeUnbalance nodeTag? \n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr - << "WARNING nodeUnbalance nodeTag? dof? - could not read nodeTag? \n"; - return TCL_ERROR; - } - - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeUnbalance nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::UnbalancedLoad); - - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - - if (dof >= size) { - opserr << "WARNING nodeUnbalance nodeTag? dof? - dofTag? too large\n"; - return TCL_ERROR; - } - - Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); - - } else { - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} - - -int -nodeReaction(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *domain = (Domain*)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeReaction nodeTag? \n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING nodeReaction nodeTag? dof? - could not read nodeTag? \n"; - return TCL_ERROR; - } - - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeReaction nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::Reaction); - - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - - if (dof >= size) { - opserr << "WARNING nodeReaction nodeTag? dof? - dofTag? too large\n"; - return TCL_ERROR; - } - - Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); - - } else { - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} -#endif int nodeMass(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) From b47149d64394ea5085747fe7212bd4efd89dce17 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Sun, 13 Jul 2025 15:47:08 -0700 Subject: [PATCH 176/261] Applying penalty stiffness to initial tangent --- SRC/material/uniaxial/PenaltyMaterial.cpp | 9 +++++++++ SRC/material/uniaxial/PenaltyMaterial.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/SRC/material/uniaxial/PenaltyMaterial.cpp b/SRC/material/uniaxial/PenaltyMaterial.cpp index 492d9f9362..2859c3571f 100644 --- a/SRC/material/uniaxial/PenaltyMaterial.cpp +++ b/SRC/material/uniaxial/PenaltyMaterial.cpp @@ -163,6 +163,15 @@ PenaltyMaterial::getTangent(void) return 0.0; } +double +PenaltyMaterial::getInitialTangent(void) +{ + if (theMaterial) + return theMaterial->getInitialTangent() + penalty; + else + return 0.0; +} + double PenaltyMaterial::getDampTangent(void) { diff --git a/SRC/material/uniaxial/PenaltyMaterial.h b/SRC/material/uniaxial/PenaltyMaterial.h index 712a61fdf4..3256f780cf 100644 --- a/SRC/material/uniaxial/PenaltyMaterial.h +++ b/SRC/material/uniaxial/PenaltyMaterial.h @@ -50,7 +50,7 @@ class PenaltyMaterial : public UniaxialMaterial double getStress(void); double getTangent(void); double getDampTangent(void); - double getInitialTangent(void) {return theMaterial->getInitialTangent();} + double getInitialTangent(void); int commitState(void); int revertToLastCommit(void); From adc49f78a8c4d99eccd74e4dd634330bfd112aa8 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Tue, 15 Jul 2025 10:35:15 +0200 Subject: [PATCH 177/261] implex_control, time_user_define, autoregularization _series_component --- SRC/material/uniaxial/ASDSteel1DMaterial.cpp | 275 +++++++++++++++++-- SRC/material/uniaxial/ASDSteel1DMaterial.h | 20 +- 2 files changed, 266 insertions(+), 29 deletions(-) diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp index bbc91aad9f..9995859742 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.cpp +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.cpp @@ -61,6 +61,12 @@ // anonymous namespace for utilities namespace { + + enum ErrorCodes { + EC_Generic = -1, + EC_IMPLEX_Error_Control = -10 + }; + inline double sign(double x) { return x == 0.0 ? 0.0 : (x > 0.0 ? 1.0 : -1.0); } /** @@ -495,7 +501,7 @@ namespace { stress_commit = data(pos++); } /* - Series comonent. + Series component. */ class SeriesComponent { @@ -515,11 +521,13 @@ namespace { if (lch_anchor == 0.0) { lch_anchor = lch_anchor_compute(params); if (slip_material) { - // if the slip material supports the lch_ref parameter, let's set it to the anchorage length - Parameter lch_param(0, 0, 0, 0); - const char* the_args[] = { "lch_ref" }; - if (slip_material->setParameter(the_args, 1, lch_param) != -1) { - lch_param.update(lch_anchor); + if (params.auto_regularization) { + // if the slip material supports the lch_ref parameter, let's set it to the anchorage length + Parameter lch_param(0, 0, 0, 0); + const char* the_args[] = { "lch_ref" }; + if (slip_material->setParameter(the_args, 1, lch_param) != -1) { + lch_param.update(lch_anchor); + } } } } @@ -1736,6 +1744,42 @@ namespace { e3.deserialize(data, pos); e0.deserialize(data, pos); } + class GlobalParameters { + private: + double max_error = 0.0; + double avg_error = 0.0; + int avg_counter = 0; + private: + GlobalParameters() = default; + GlobalParameters(const GlobalParameters&) = delete; + GlobalParameters& operator = (const GlobalParameters&) = delete; + public: + static GlobalParameters& instance() { + static GlobalParameters _instance; + return _instance; + } + inline double getMaxError() const { + return max_error; + } + inline void setMaxError(double x) { + max_error = x; + } + inline double getAverageError() { + if (avg_counter > 0) { + avg_error /= static_cast(avg_counter); + avg_counter = 0; + } + return avg_error; + } + inline void accumulateAverageError(double x) { + avg_error += x; + ++avg_counter; + } + inline void setAverageError(double x) { + avg_error = x; + avg_counter = 0; + } + }; } @@ -1763,7 +1807,7 @@ void* OPS_ASDSteel1DMaterial() opserr << "Using ASDSteel1D - Developed by: Alessia Casalucci, Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; first_done = true; } - static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu <-implex> <-auto_regularization> <-buckling $lch < $r>> <-fracture <$r>> <-slip $matTag <$r>> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; + static const char* msg = "uniaxialMaterial ASDSteel1D $tag $E $sy $su $eu <-implex> <-implexControl $implexErrorTolerance $implexTimeReductionLimit> <-auto_regularization> <-buckling $lch < $r>> <-fracture <$r>> <-slip $matTag <$r>> <-K_alpha $K_alpha> <-max_iter $max_iter> <-tolU $tolU> <-tolR $tolR>"; // check arguments int numArgs = OPS_GetNumRemainingInputArgs(); @@ -1785,6 +1829,9 @@ void* OPS_ASDSteel1DMaterial() double lch = 0.0; double r = 0.0; // default to 0.0, means not provided bool implex = false; + bool implex_control = false; + double implex_error_tolerance = 0.05; + double implex_time_redution_limit = 0.01; bool auto_regularization = false; bool buckling = false; bool fracture = false; @@ -1843,6 +1890,17 @@ void* OPS_ASDSteel1DMaterial() if (strcmp(value, "-implex") == 0) { implex = true; } + if (strcmp(value, "-implexControl") == 0) { + implex_control = true; + if (OPS_GetNumRemainingInputArgs() < 2) { + opserr << "nDMaterial ASDConcrete1D Error: '-implexControl' given without the next 2 arguments $implexErrorTolerance $implexTimeReductionLimit.\n"; + return nullptr; + } + if (!lam_optional_double("implexErrorTolerance", implex_error_tolerance)) + return nullptr; + if (!lam_optional_double("implexTimeReductionLimit", implex_time_redution_limit)) + return nullptr; + } if (strcmp(value, "-auto_regularization") == 0) { auto_regularization = true; } @@ -1865,7 +1923,7 @@ void* OPS_ASDSteel1DMaterial() OPS_ResetCurrentInputArg(-1); } else { - // radius give, do cheks + // radius give, do checks if (trial_radius != r && r != 0.0) { opserr << "UniaxialMaterial ASDSteel1D: radius provied in -buckling (" << trial_radius << ") does not match the one provided in -slip or -fracture (" << r << "). Please use it only once.\n"; return nullptr; @@ -1890,7 +1948,7 @@ void* OPS_ASDSteel1DMaterial() OPS_ResetCurrentInputArg(-1); } else { - // radius give, do cheks + // radius give, do checks if (trial_radius != r && r != 0.0) { opserr << "UniaxialMaterial ASDSteel1D: radius provied in -fracture (" << trial_radius << ") does not match the one provided in -slip or -buckling (" << r << "). Please use it only once.\n"; return nullptr; @@ -1933,7 +1991,7 @@ void* OPS_ASDSteel1DMaterial() OPS_ResetCurrentInputArg(-1); } else { - // radius give, do cheks + // radius give, do checks if (trial_radius != r && r != 0.0) { opserr << "UniaxialMaterial ASDSteel1D: radius provied in -slip (" << trial_radius << ") does not match the one provided in -buckling or -fracture (" << r << "). Please use it only once.\n"; return nullptr; @@ -2011,6 +2069,9 @@ void* OPS_ASDSteel1DMaterial() params.H2 = H2 * (1.0 - alpha); params.gamma2 = gamma2; params.implex = implex; + params.implex_control = implex_control; + params.implex_error_tolerance = implex_error_tolerance; + params.implex_time_redution_limit = implex_time_redution_limit; params.auto_regularization = auto_regularization; params.buckling = buckling; params.fracture = fracture; @@ -2088,10 +2149,14 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) { params.lch_element = ops_TheActiveElement ? ops_TheActiveElement->getCharacteristicLength()/2 : params.length; // save dT - dtime_n = ops_Dt; - if (!commit_done) { - dtime_n_commit = dtime_n; + if (!dtime_is_user_defined) { + dtime_n = ops_Dt; + if (!commit_done) { + dtime_0 = dtime_n; + dtime_n_commit = dtime_n; + } } + // time factor for explicit extrapolation double time_factor = 1.0; if (params.implex && (dtime_n_commit > 0.0)) time_factor = dtime_n / dtime_n_commit; @@ -2102,11 +2167,53 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) asd_print("MAT set trial (" << (int)params.implex << ")"); int retval; - // time factor for explicit extrapolation (todo: make a unique function) + double epl = 0.0; - if (params.buckling) { + if (params.buckling) { // se buckling farlo con l'energia ottenuta da rve (incremento spostamento * incremento forze (u - u commit)*(residuo-residuo commit) e normalizzarlo con una frazione della lunghezza* sigmay * Area //regularization for element length lower than physical length (weighted average) - retval = homogenize(params.implex); + + if (params.implex) { + if (params.implex_control) { + double area = M_PI * params.radius * params.radius; + bool elastic_correction = params.lch_element > params.length; + // implicit solution + double retval = homogenize(false); + if (retval != 0) return retval; + + Vector U_impl = elastic_correction && params.auto_regularization ? pdata->rve_m.sv.UG_el : pdata->rve_m.sv.UG; + double N_impl = N_rve_last; + double sigma_impl = N_impl / stress; + + pdata->rve_m.revertToLastCommit(); + + // explicit solution + retval = homogenize(true); + if (retval != 0) return retval; + + Vector U_expl = elastic_correction && params.auto_regularization ? pdata->rve_m.sv.UG_el : pdata->rve_m.sv.UG; + double N_expl = N_rve_last; + double sigma_expl = N_expl / stress; + + Vector dU_err = U_expl - U_impl; + + // L2 Norm + double norm_dU = dU_err.Norm(); + double implex_error_u = norm_dU / params.radius; + double implex_error_N = (sigma_expl - sigma_impl) / params.sy; + implex_error = std::max(implex_error_u, implex_error_N); + if (implex_error > params.implex_error_tolerance) { + if (dtime_n >= params.implex_time_redution_limit * dtime_0) { + retval = EC_IMPLEX_Error_Control; + } + } + } + else { + retval = homogenize(true); + } + } + else { + retval = homogenize(false); + } C = C_rve; stress = stress_rve; epl = pdata->rve_m.e2.section.series.steel_material.epl; @@ -2116,7 +2223,34 @@ int ASDSteel1DMaterial::setTrialStrain(double v, double r) else { //computation of sigma and tangent of steel pdata->steel_comp.revertToLastCommit(); - retval = pdata->steel_comp.compute(params, params.implex, time_factor, strain, stress, C); + + if (params.implex) { + if (params.implex_control) { + double sigma_macro = 0.0; + double tangent_macro = 0.0; + // implicit solution + int retval = pdata->steel_comp.compute(params, false, 1.0, strain, sigma_macro, tangent_macro); + double sigma_impl = sigma_macro; + pdata->steel_comp.revertToLastCommit(); + // explicit solution + retval = pdata->steel_comp.compute(params, true, time_factor, strain, stress, C); + double sigma_expl = stress; + + implex_error = std::abs(sigma_expl - sigma_impl) / params.sy; //semplifica + if (implex_error > params.implex_error_tolerance) { + if (dtime_n >= params.implex_time_redution_limit * dtime_0) { + retval = EC_IMPLEX_Error_Control; + } + } + } + else { + retval = pdata->steel_comp.compute(params, true, time_factor, strain, stress, C); + } + } + + else { + retval = pdata->steel_comp.compute(params, params.implex, time_factor, strain, stress, C); + } epl = pdata->steel_comp.steel_material.epl; } if (params.fracture) { @@ -2169,15 +2303,42 @@ int ASDSteel1DMaterial::commitState(void) if (params.implex) { if (params.buckling) { asd_print("MAT commit (" << (int)false << ")"); - int retval = homogenize(false); + double area = M_PI * params.radius * params.radius; + bool elastic_correction = params.lch_element > params.length; + Vector U_expl = elastic_correction && params.auto_regularization ? pdata->rve_m.sv.UG_el : pdata->rve_m.sv.UG; + double N_expl = N_rve_last; + double sigma_expl = N_expl / stress; + + // implicit solution + double retval = homogenize(false); + + Vector U_impl = elastic_correction && params.auto_regularization ? pdata->rve_m.sv.UG_el : pdata->rve_m.sv.UG; + double N_impl = N_rve_last; + double sigma_impl = N_impl / stress; + + Vector dU_err = U_expl - U_impl; + + // Norm + double norm_dU = dU_err.Norm(); + double implex_error_u = norm_dU / params.radius; + double implex_error_N = (sigma_expl - sigma_impl) / params.sy; + implex_error = std::max(implex_error_u, implex_error_N); + GlobalParameters::instance().setMaxError(std::max(implex_error, GlobalParameters::instance().getMaxError())); + GlobalParameters::instance().accumulateAverageError(implex_error); if (retval < 0) return retval; } else { + double sigma_expl = stress; double sigma_macro = 0.0; double tangent_macro = 0.0; int retval = pdata->steel_comp.compute(params, false, 1.0, strain, sigma_macro, tangent_macro); + double sigma_impl = sigma_macro; + implex_error = std::abs(sigma_expl - sigma_impl) / params.sy; + GlobalParameters::instance().setMaxError(std::max(implex_error, GlobalParameters::instance().getMaxError())); + GlobalParameters::instance().accumulateAverageError(implex_error); if (retval < 0) return retval; } + } // compute energy @@ -2236,6 +2397,11 @@ int ASDSteel1DMaterial::revertToStart(void) // implex dtime_n = 0.0; dtime_n_commit = 0.0; + dtime_0 = 0.0; + dtime_is_user_defined = false; + // IMPL-EX error + implex_error = 0.0; + // Commit flag commit_done = false; // output variables @@ -2281,6 +2447,9 @@ int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) ddata(counter++) = static_cast(getTag()); ddata(counter++) = dtime_n; ddata(counter++) = dtime_n_commit; + ddata(counter++) = dtime_0; + ddata(counter++) = static_cast(dtime_is_user_defined); + ddata(counter++) = implex_error; ddata(counter++) = static_cast(commit_done); ddata(counter++) = strain; ddata(counter++) = strain_commit; @@ -2300,6 +2469,9 @@ int ASDSteel1DMaterial::sendSelf(int commitTag, Channel &theChannel) ddata(counter++) = params.gamma1; ddata(counter++) = params.gamma2; ddata(counter++) = static_cast(params.implex); + ddata(counter++) = static_cast(params.implex_control); + ddata(counter++) = params.implex_error_tolerance; + ddata(counter++) = params.implex_time_redution_limit; ddata(counter++) = static_cast(params.auto_regularization); ddata(counter++) = static_cast(params.buckling); ddata(counter++) = static_cast(params.fracture); @@ -2361,6 +2533,9 @@ int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectB setTag(ddata(counter++)); dtime_n = ddata(counter++); dtime_n_commit = ddata(counter++); + dtime_0 = ddata(counter++); + dtime_is_user_defined = static_cast(ddata(counter++)); + implex_error = ddata(counter++); commit_done = static_cast(ddata(counter++)); strain = ddata(counter++); strain_commit = ddata(counter++); @@ -2381,6 +2556,9 @@ int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectB params.gamma1 = ddata(counter++); params.gamma2 = ddata(counter++); params.implex = static_cast(ddata(counter++)); + params.implex_control = static_cast(ddata(counter++)); + params.implex_error_tolerance = ddata(counter++); + params.implex_time_redution_limit = ddata(counter++); params.auto_regularization = static_cast(ddata(counter++)); params.buckling = static_cast(ddata(counter++)); params.fracture = static_cast(ddata(counter++)); @@ -2407,6 +2585,21 @@ int ASDSteel1DMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectB int ASDSteel1DMaterial::setParameter(const char** argv, int argc, Parameter& param) { + + // 1000 - time + if (strcmp(argv[0], "dTime") == 0) { + param.setValue(dtime_n); + return param.addObject(2000, this); + } + if (strcmp(argv[0], "dTimeCommit") == 0) { + param.setValue(dtime_n_commit); + return param.addObject(2001, this); + } + if (strcmp(argv[0], "dTimeInitial") == 0) { + param.setValue(dtime_0); + return param.addObject(2002, this); + } + // default return -1; } @@ -2414,6 +2607,21 @@ int ASDSteel1DMaterial::setParameter(const char** argv, int argc, Parameter& par int ASDSteel1DMaterial::updateParameter(int parameterID, Information& info) { switch (parameterID) { + + // 2000 - time + case 2000: + dtime_n = info.theDouble; + dtime_is_user_defined = true; + return 0; + case 2001: + dtime_n_commit = info.theDouble; + dtime_is_user_defined = true; + return 0; + case 2002: + dtime_0 = info.theDouble; + dtime_is_user_defined = true; + return 0; + // default default: return -1; @@ -2440,8 +2648,9 @@ Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Strea static std::vector lb_buckling_ratio = { "BI" }; static std::vector lb_damage = { "D" }; static std::vector lb_eqpl_strain = { "PLE" }; - static std::vector lb_slip_resp = { "Slip", "Tau" }; + static std::vector lb_time = { "dTime", "dTimeCommit", "dTimeInitial" }; + static std::vector lb_implex_error = { "Error" }; @@ -2459,6 +2668,12 @@ Response* ASDSteel1DMaterial::setResponse(const char** argv, int argc, OPS_Strea if (strcmp(argv[0], "SlipResponse") == 0){ return make_resp(1004, getSlipResponse(), &lb_slip_resp); } + if (strcmp(argv[0], "time") == 0 || strcmp(argv[0], "Time") == 0) { + return make_resp(1005, getTimeIncrements(), &lb_time); + } + if (strcmp(argv[0], "implexError") == 0 || strcmp(argv[0], "ImplexError") == 0) { + return make_resp(1006, getImplexError(), &lb_implex_error); + } } // otherwise return base-class response @@ -2474,12 +2689,16 @@ int ASDSteel1DMaterial::getResponse(int responseID, Information& matInformation) // 1000 - base steel output case 1001: return matInformation.setVector(getBucklingIndicator()); + // 1002 - damage case 1002: return matInformation.setVector(getDamage()); case 1003: return matInformation.setVector(getEqPlStrain()); case 1004: return matInformation.setVector(getSlipResponse()); + // 1005 - internal time + case 1005: return matInformation.setVector(getTimeIncrements()); + case 1006: return matInformation.setVector(getImplexError()); default: break; } @@ -2547,6 +2766,22 @@ const Vector& ASDSteel1DMaterial::getSlipResponse() const return d; } +const Vector& ASDSteel1DMaterial::getTimeIncrements() const +{ + static Vector d(3); + d(0) = dtime_n; + d(1) = dtime_n_commit; + d(2) = dtime_0; + return d; +} + +const Vector& ASDSteel1DMaterial::getImplexError() const +{ + static Vector d(1); + d(0) = implex_error; + return d; +} + int ASDSteel1DMaterial::homogenize(bool do_implex) { // return value @@ -2585,7 +2820,7 @@ int ASDSteel1DMaterial::homogenize(bool do_implex) if (retval != 0) { return retval; } - + N_rve_last = N; // from micro stress/tangent to macro stress/tangent area = M_PI * params.radius * params.radius; diff --git a/SRC/material/uniaxial/ASDSteel1DMaterial.h b/SRC/material/uniaxial/ASDSteel1DMaterial.h index 449d390671..f477cbd193 100644 --- a/SRC/material/uniaxial/ASDSteel1DMaterial.h +++ b/SRC/material/uniaxial/ASDSteel1DMaterial.h @@ -22,9 +22,9 @@ // $Date: 2025-01-03 11:29:01 $ // $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/ASDSteel1DMaterial.cpp,v $ -// Alessia Casalucci - ASDEA Software, Italy +// Alessia Casalucci, Massimo Petracca, Guido Camata - ASDEA Software, Italy // -// todo... +// A unified and efficient plastic-damage material model for steel bars including fracture, bond-slip, and buckling via multiscale homogenization // #ifndef ASDSteel1DMaterial_h @@ -38,13 +38,6 @@ #include #include -/** -todo: global material - flag computed_once -> if false -> call update - revert to start -> call update (TO SET INITIAL DATA) - -*/ - class ASDSteel1DMaterialPIMPL; class ASDSteel1DMaterial : public UniaxialMaterial @@ -65,6 +58,9 @@ class ASDSteel1DMaterial : public UniaxialMaterial double gamma2 = 0.0; // misc bool implex = false; + bool implex_control = false; + double implex_error_tolerance = 0.0; + double implex_time_redution_limit = 0.0; bool auto_regularization = true; bool buckling = false; bool fracture = false; @@ -132,6 +128,8 @@ class ASDSteel1DMaterial : public UniaxialMaterial const Vector& getEqPlStrain() const; const Vector& getSlipResponse() const; const Vector& getSteelResponse() const; + const Vector& getTimeIncrements() const; + const Vector& getImplexError() const; private: @@ -140,7 +138,10 @@ class ASDSteel1DMaterial : public UniaxialMaterial // state variables - implex double dtime_n = 0.0; double dtime_n_commit = 0.0; + double dtime_0 = 0.0; + bool dtime_is_user_defined = false; bool commit_done = false; + double implex_error = 0.0; // strain, stress and tangent (homogenized) double strain = 0.0; double strain_commit = 0.0; @@ -150,6 +151,7 @@ class ASDSteel1DMaterial : public UniaxialMaterial double stress_rve = 0.0; double stress_rve_commit = 0.0; double C_rve = 0.0; + double N_rve_last = 0.0; // other variables for output purposes double energy = 0.0; From cb5d631fd4d08560719fa7342457075ee3b2d455 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Tue, 15 Jul 2025 16:09:29 -0700 Subject: [PATCH 178/261] clean up --- SRC/matrix/MatrixND.h | 254 ++++++---------------------------------- SRC/matrix/MatrixND.tpp | 3 - 2 files changed, 37 insertions(+), 220 deletions(-) diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index 6f2b369015..93a1c1c9a0 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -9,23 +9,6 @@ // Desctiption: MatrixND is a fixed-size matrix class that is suitable for // stack-allocation. // -// -// This code is influenced by the following sources -// List initialization: -// - https://stackoverflow.com/questions/42068882/list-initialization-for-a-matrix-class -// -// Style/practices -// - https://quuxplusone.github.io/blog/2021/04/03/static-constexpr-whittling-knife/ -// -// Operator overloading / semantics -// - https://stackoverflow.com/questions/9851188/does-it-make-sense-to-use-move-semantics-for-operator-and-or-operator/9851423#9851423 -// -// Compile-time template restrictions/concepts: -// - https://codereview.stackexchange.com/questions/259038/compile-time-matrix-class -// (C++ 20) -// - https://github.com/calebzulawski/cotila/ -// (C++ 17) -// //===----------------------------------------------------------------------===// // // Claudio Perez @@ -43,31 +26,16 @@ namespace OpenSees { template struct alignas(64) MatrixND { - // double values[NC][NR]; std::array values; // // Indexing // - // (i,j) indexing - // constexpr T & - // operator()(index_t index_r, index_t index_c) noexcept { - // assert(index_r >= 0 && index_c >= 0); - // assert(index_r < NR && index_c < NC); - // return values[index_c][index_r]; - // } - - // inline constexpr const T & - // operator()(index_t index_r, index_t index_c) const noexcept { - // assert(index_r >= 0 && index_c >= 0); - // assert(index_r < NR && index_c < NC); - // return values[index_c][index_r]; - // } - constexpr T& operator()(int i, int j) noexcept { return values[j*NR + i]; } - constexpr const T& operator()(int i, int j) const noexcept { return values[j*NR + i]; } + inline constexpr T& operator()(int i, int j) noexcept { return values[j*NR + i]; } + inline constexpr const T& operator()(int i, int j) const noexcept { return values[j*NR + i]; } constexpr T* data() noexcept { return &(*this)(0,0); } - + inline constexpr const T* data() const noexcept { return values.data(); } // Convert to regular Matrix class operator Matrix() { return Matrix(&(*this)(0,0), NR, NC);} @@ -124,6 +92,40 @@ struct alignas(64) MatrixND { int invert(MatrixND &) const; + template + inline MatrixND + extract() const noexcept; + + template + inline MatrixND + extract(int row0, int col0) const noexcept; + + template + inline constexpr void + insert(const MatrixND &M, double fact) noexcept; + + template + inline constexpr void + insert(const MatrixND &M, int init_row, int init_col, double fact) noexcept; + + template + constexpr inline void + assemble(const MatrixND &M, int init_row, int init_col, double fact) noexcept; + + template inline void + assemble(const VectorND &v, int init_row, int init_col, double fact) noexcept; + + template inline void + assembleTranspose(const MatrixND &M, int init_row, int init_col, double fact) noexcept; + + template void + assembleTranspose(const VectorND &v, int init_row, int init_col, double scale) noexcept; + + +// +// Operators +// + constexpr MatrixND & operator=(const Matrix &other) noexcept { @@ -200,187 +202,6 @@ struct alignas(64) MatrixND { return result; } - // - // - // - - constexpr T - trace() const noexcept - { - static_assert(NR == NC); - T sum = 0.0; - for (index_t i = 0; i < NR; ++i) { - sum += (*this)(i,i); - } - return sum; - } - - - int - solve(const VectorND &V, VectorND &res) const noexcept - { - static_assert(NR == NC); - - MatrixND work = *this; - int pivot_ind[NR]; - int nrhs = 1; - int nr = NR; - int nc = NC; - int info = 0; - res = V; // X will be overwritten with the solution - DGESV(&nr, &nrhs, &work(0,0), &nr, pivot_ind, res.values, &nc, &info); - return -abs(info); - } - - - template - int solve(const MatrixND& M, MatrixND& X) const noexcept - { - static_assert(NR == NC, "Matrix must be square."); - static_assert(n == NR, "RHS row-count must match A."); - - MatrixND work = *this; // copy of A to be factorised - int ipiv[NR]{}; - - int n_eq = NR; // order of the system - int nrhs = n; // number of RHS columns - int lda = NR; // leading dim of A - int ldb = NR; // leading dim of X - int info = 0; - - X = M; // copy RHS, DGESV overwrites - DGESV(&n_eq, &nrhs, - &work(0,0), &lda, - &ipiv[0], - &X(0,0), &ldb, - &info); - - return -std::abs(info); - } - - // int solve(const Vector &V, Vector &res) const - // requires(NR == NC) - // { - - // MatrixND work = *this; - // int pivot_ind[NR]; - // int nrhs = 1; - // int nr = NR; - // int nc = NC; - // int info = 0; - // res = V; // X will be overwritten with the solution - // DGESV(&nr, &nrhs, &work.values[0][0], &nr, &pivot_ind[0], res.theData, &nc, &info); - // return -abs(info); - // } - - - // int - // solve(const Matrix &M, Matrix &res) - // { - // Matrix slver(*this); - // return slver.Solve(M, res); - - // MatrixND work = *this; - // int pivot_ind[NR]; - // int nrhs = M.noCols(); - // int nr = NR; - // int nc = NC; - // int info = 0; - // res = M; // M will be overwritten with the solution - // DGESV(&nr, &nrhs, &work(0,0), &nr, &pivot_ind[0], &res(0,0), &nc, &info); - // return -abs(info); - // } - - - template - inline MatrixND - extract() const noexcept - { - MatrixND m; - for (int i=0; i - inline MatrixND - extract(int row0, int col0) const noexcept - { - MatrixND m; - for (int i=0; i - inline constexpr void - insert(const MatrixND &M, double fact) noexcept - { - - constexpr int final_row = init_row + nr - 1; - constexpr int final_col = init_col + nc - 1; - static_assert((init_row >= 0) && (final_row < NR) && (init_col >= 0) && (final_col < NC), - "MatrixND::insert: init_row, init_col, nr, nc out of bounds"); - - for (int i=0; i - inline constexpr void - insert(const MatrixND &M, int init_row, int init_col, double fact) noexcept - { - - [[maybe_unused]] int final_row = init_row + nr - 1; - [[maybe_unused]] int final_col = init_col + nc - 1; - assert((init_row >= 0) && (final_row < NR) && (init_col >= 0) && (final_col < NC)); - - for (int i=0; i - constexpr inline void - assemble(const MatrixND &M, int init_row, int init_col, double fact) noexcept - { - - [[maybe_unused]] int final_row = init_row + nr - 1; - [[maybe_unused]] int final_col = init_col + nc - 1; - assert((init_row >= 0) && (final_row < NR) && (init_col >= 0) && (final_col < NC)); - - for (int i=0; i inline void - assemble(const VectorND &v, int init_row, int init_col, double fact) noexcept; - - template inline void - assembleTranspose(const MatrixND &M, int init_row, int init_col, double fact) noexcept; - - template void - assembleTranspose(const VectorND &v, int init_row, int init_col, double scale) noexcept; - - -// -// Operators -// friend constexpr MatrixND operator+(MatrixND left, const MatrixND &right) noexcept { left += right; @@ -463,7 +284,6 @@ struct alignas(64) MatrixND { return prod; } - template inline constexpr friend MatrixND operator^(const MatrixND &left, const MatrixND &right) { diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index ba00056806..16ac15ab3a 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -28,7 +28,6 @@ MatrixND::zero() noexcept } - template constexpr MatrixND MatrixND::transpose() const noexcept @@ -341,8 +340,6 @@ MatrixND::addMatrixTripleProduct(double thisFact, } - - // // 3D // From 8ecda7e3ab7f5d844a121b17092f49f6ad0c3687 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Wed, 16 Jul 2025 02:53:39 -0700 Subject: [PATCH 179/261] clean dead code --- .../Frame/EuclidFrameTransf.tpp | 5 ----- .../Frame/Isometry/CrisfieldIsometry.h | 18 +----------------- .../Frame/SouzaFrameTransf.tpp | 18 ++++++++---------- 3 files changed, 9 insertions(+), 32 deletions(-) diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index f731fae980..578a5e2cfa 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -395,10 +395,7 @@ EuclidFrameTransf::push(MatrixND&kb, const VectorND Ap = A^p; -#if 0 - p = A^p; -#else Kb.zero(); VectorND<12> qwx{}; for (int i=0; i::push(MatrixND&kb, Kb.assemble(Kw.template extract<6,12, 6,12>(), ndf, ndf, 1.0); Kl.addMatrixProduct(Kb, A, 1.0); } - // p = A^p; -#endif // // Kl += -W'*Pn'*A diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h index 35a2b088c9..931d00e1bb 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h @@ -134,7 +134,7 @@ class CrisfieldIsometry : public AlignedIsometry { } } else if (std::fabs(dot + 1.0) < ktol) { // opposite direction - static constexpr double pi = 3.14159265358979323846; + static constexpr double pi = 3.14159265358979323846; // choose any axis with numerical separation from r1 v = r1.cross(Vector3D{1.0, 0.0, 0.0}); if (v.dot(v) < ktol) @@ -208,7 +208,6 @@ class CrisfieldIsometry : public AlignedIsometry { double Ln = this->getLength(); -#if 1 static constexpr MatrixND<1,3> E3 {{0.0, 0.0, 1.0}}, E2 {{0.0, 1.0, 0.0}}; @@ -244,21 +243,6 @@ class CrisfieldIsometry : public AlignedIsometry { return G.template extract<0,3, 6,12>(); else return MatrixND<3,6>{}; - -#else - MatrixND<3,6> Gb{}; - constexpr Matrix3D ix = Hat(e1); - - if (node == 0) { - Gb.template insert<0,0>( ix, -1.0/Ln); - Gb(0,3) = 0.5; - } - else if (node == nn-1) { - Gb.template insert<0,0>( ix, 1.0/Ln); - Gb(0,3) = 0.5; - } - return Gb; -#endif } // diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp index 82234f831c..8a5d9a4f42 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp @@ -231,7 +231,8 @@ SouzaFrameTransf::initialize(std::array& new_nodes) return error; // Compute initial pseudo-vectors for nodal triads - Q_pres[0] = Q_pres[1] = Versor::from_matrix(R0); + Q_pres[0] = Versor::from_matrix(R0); + Q_pres[1] = Q_pres[0]; ul.zero(); ulpr.zero(); @@ -361,7 +362,6 @@ SouzaFrameTransf::update() template -// inline VectorND int SouzaFrameTransf::push(VectorND&pl, Operation) { @@ -388,19 +388,17 @@ SouzaFrameTransf::push(VectorND&pl, Operation) // K = ag'*Km*ag + Kp // template -// MatrixND int SouzaFrameTransf::push(MatrixND& kl, const VectorND& pl, Operation op) -{ - static MatrixND<12,12> K; - K.addMatrixTripleProduct(0.0, T, kl, 1.0); +{ + MatrixND<12,12> KT = kl*T; + kl.addMatrixTransposeProduct(0.0, T, KT, 1.0); - // Add geometric part kg - this->addTangent(K, pl, ul); + // Add geometric part + this->addTangent(kl, pl, ul); - kl = K; // TODO: optimize return 0; } @@ -427,7 +425,7 @@ SouzaFrameTransf::addTangent(MatrixND<12,12>& kg, // for (int node=0; node<2; node++) { for (int k = 0; k < 3; k++) { - const double factor = pl[(node ? jmx : imx) + k] // pl[6*node+3+k] + const double factor = pl[(node ? jmx : imx) + k] * std::tan(ul[(node ? jmx : imx) + k]); From bf7cfc849605190f8712724f5cc4cbb4021c0ab3 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Wed, 16 Jul 2025 12:52:14 -0700 Subject: [PATCH 180/261] Update ExpressNewton.cpp --- SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp b/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp index d187e4441f..01308c7b29 100644 --- a/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp +++ b/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp @@ -165,8 +165,8 @@ ExpressNewton::sendSelf(int cTag, Channel &theChannel) static Vector data(4); data(0) = nIter; data(1) = kMultiplier1; - data(1) = kMultiplier2; - data(2) = factorOnce; + data(2) = kMultiplier2; + data(3) = factorOnce; return theChannel.sendVector(this->getDbTag(), cTag, data); From 238065e1d90a3b78d6996583f7fda582309638f5 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Wed, 16 Jul 2025 18:15:18 -0700 Subject: [PATCH 181/261] clean up comments, headers --- SRC/matrix/MatrixND.h | 2 +- SRC/matrix/VectorND.h | 20 +------------------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index 93a1c1c9a0..bf1bb8ca8a 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -14,7 +14,7 @@ // Claudio Perez // #pragma once -#include +#include #include #include diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index ec52d1163f..043aecac41 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -6,29 +6,11 @@ // https://xara.so //===----------------------------------------------------------------------===// // -// This code is influenced by the following sources -// list initialization: -// - https://stackoverflow.com/questions/42068882/list-initialization-for-a-matrix-class -// -// style/practices -// - https://quuxplusone.github.io/blog/2021/04/03/static-constexpr-whittling-knife/ -// -// Operator overloading / semantics -// - https://stackoverflow.com/questions/9851188/does-it-make-sense-to-use-move-semantics-for-operator-and-or-operator/9851423#9851423 -// -// compile-time template restrictions/concepts: -// - https://codereview.stackexchange.com/questions/259038/compile-time-matrix-class -// (C++ 20) -// - https://github.com/calebzulawski/cotila/ -// (C++ 17) -// -//===----------------------------------------------------------------------===// -// // Claudio Perez // #ifndef VectorND_H #define VectorND_H -#include +#include #include #include #include From d2142dfa00512646f70df5b3e26202ce4228505c Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 21 Jul 2025 11:25:16 -0700 Subject: [PATCH 182/261] update some methods --- SRC/coordTransformation/Frame/BasicFrameTransf.h | 4 ++-- SRC/coordTransformation/Frame/BasicFrameTransf.tpp | 4 ++-- SRC/runtime/commands/modeling/element/frames.cpp | 4 ---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.h b/SRC/coordTransformation/Frame/BasicFrameTransf.h index 140a2e0e3f..da64e873b6 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.h +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.h @@ -73,11 +73,11 @@ class BasicFrameTransf3d: public CrdTransf // // Sensitivity // - const Vector & getBasicDisplFixedGrad() final; + const Vector & getBasicTrialDispShapeSensitivity() final; const Vector & getBasicDisplTotalGrad(int grad) final; const Vector &getGlobalResistingForceShapeSensitivity(const Vector &basicForce, const Vector &p0, int grad) final; bool isShapeSensitivity() final; - double getLengthGrad() final; + double getdLdh() final; double getd1overLdh() final; diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index ae01d7bf2e..0d59c30009 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -370,7 +370,7 @@ BasicFrameTransf3d::isShapeSensitivity() template double -BasicFrameTransf3d::getLengthGrad() +BasicFrameTransf3d::getdLdh() { return t.getLengthGrad(); } @@ -400,7 +400,7 @@ BasicFrameTransf3d::getGlobalResistingForceShapeSensitivity(const Vector &p template const Vector & -BasicFrameTransf3d::getBasicDisplFixedGrad() +BasicFrameTransf3d::getBasicTrialDispShapeSensitivity() { static VectorND<6> dub; static Vector wrapper(dub); diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index ee6ec69be0..d15920b7c1 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -320,10 +320,6 @@ CreateFrame(BasicModelBuilder& builder, static_loop<0, 3>([&](auto nwm) constexpr { if (nwm.value + 6 == ndf) { - // Create the transform -#if 0 || defined(NEW_TRANSFORM) - FrameTransform<2,6+nwm.value> *tran = tb->template create<2,6+nwm.value>(); -#endif if (!options.shear_flag) { static_loop<2,30>([&](auto nip) constexpr { if (nip.value == sections.size()) From 81e72c2a8992f3d83c8176515dba7dff860cb871 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Mon, 21 Jul 2025 11:28:16 -0700 Subject: [PATCH 183/261] Update BasicFrameTransf.h --- SRC/coordTransformation/Frame/BasicFrameTransf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.h b/SRC/coordTransformation/Frame/BasicFrameTransf.h index da64e873b6..613aa41e3f 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.h +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.h @@ -92,8 +92,6 @@ class BasicFrameTransf3d: public CrdTransf void Print(OPS_Stream &s, int flag) final; - FrameTransform<2,ndf> &t; - LinearFrameTransf<2,ndf> linear; private: using Operation = typename FrameTransform<2,ndf>::Operation; @@ -132,6 +130,8 @@ class BasicFrameTransf3d: public CrdTransf } static constexpr auto iq = set_indices(); + FrameTransform<2,ndf> &t; + LinearFrameTransf<2,ndf> linear; }; } // namespace OpenSees From beffd758fe71a0f74edfb9855f7212442e606b3e Mon Sep 17 00:00:00 2001 From: alec0498 Date: Wed, 23 Jul 2025 12:24:24 +0200 Subject: [PATCH 184/261] remove vs mod files --- .../FEM_ObjectBrokerAllClasses.cpp | 8 ++++---- .../TclModelBuilderUniaxialMaterialCommand.cpp | 4 ++-- Win64/proj/actor/Debug/Actor.sbr | 0 Win64/proj/actor/Debug/Channel.sbr | 0 Win64/proj/actor/Debug/ChannelAddress.sbr | 0 Win64/proj/actor/Debug/FEM_ObjectBroker.sbr | 0 .../actor/Debug/FEM_ObjectBrokerAllClasses.sbr | 0 Win64/proj/actor/Debug/HTTP.sbr | 0 Win64/proj/actor/Debug/Message.sbr | 0 Win64/proj/actor/Debug/MovableObject.sbr | 0 Win64/proj/actor/Debug/ObjectBroker.sbr | 0 Win64/proj/actor/Debug/Shadow.sbr | 0 Win64/proj/actor/Debug/Socket.sbr | 0 Win64/proj/actor/Debug/TCP_Socket.sbr | 0 Win64/proj/actor/Debug/UDP_Socket.sbr | 0 .../proj/actor/Debug/actor.Build.CppClean.log | 0 Win64/proj/actor/Debug/actor.lib.recipe | 7 ------- .../actor/Debug/actor.tlog/CL.command.1.tlog | Bin 128506 -> 0 bytes .../proj/actor/Debug/actor.tlog/CL.read.1.tlog | Bin 251234 -> 0 bytes .../actor/Debug/actor.tlog/CL.write.1.tlog | Bin 7428 -> 0 bytes .../proj/actor/Debug/actor.tlog/Cl.items.tlog | 13 ------------- .../Debug/actor.tlog/Lib-link.read.1.tlog | Bin 3182 -> 0 bytes .../Debug/actor.tlog/Lib-link.write.1.tlog | Bin 1594 -> 0 bytes .../actor/Debug/actor.tlog/Lib.command.1.tlog | Bin 2664 -> 0 bytes .../Debug/actor.tlog/actor.lastbuildstate | 2 -- .../Debug/actor.tlog/bscmake.command.1.tlog | Bin 2194 -> 0 bytes .../actor/Debug/actor.tlog/bscmake.read.1.tlog | Bin 3134 -> 0 bytes .../Debug/actor.tlog/bscmake.write.1.tlog | Bin 1612 -> 0 bytes .../Debug/actor.vcxproj.FileListAbsolute.txt | 0 29 files changed, 6 insertions(+), 28 deletions(-) delete mode 100644 Win64/proj/actor/Debug/Actor.sbr delete mode 100644 Win64/proj/actor/Debug/Channel.sbr delete mode 100644 Win64/proj/actor/Debug/ChannelAddress.sbr delete mode 100644 Win64/proj/actor/Debug/FEM_ObjectBroker.sbr delete mode 100644 Win64/proj/actor/Debug/FEM_ObjectBrokerAllClasses.sbr delete mode 100644 Win64/proj/actor/Debug/HTTP.sbr delete mode 100644 Win64/proj/actor/Debug/Message.sbr delete mode 100644 Win64/proj/actor/Debug/MovableObject.sbr delete mode 100644 Win64/proj/actor/Debug/ObjectBroker.sbr delete mode 100644 Win64/proj/actor/Debug/Shadow.sbr delete mode 100644 Win64/proj/actor/Debug/Socket.sbr delete mode 100644 Win64/proj/actor/Debug/TCP_Socket.sbr delete mode 100644 Win64/proj/actor/Debug/UDP_Socket.sbr delete mode 100644 Win64/proj/actor/Debug/actor.Build.CppClean.log delete mode 100644 Win64/proj/actor/Debug/actor.lib.recipe delete mode 100644 Win64/proj/actor/Debug/actor.tlog/CL.command.1.tlog delete mode 100644 Win64/proj/actor/Debug/actor.tlog/CL.read.1.tlog delete mode 100644 Win64/proj/actor/Debug/actor.tlog/CL.write.1.tlog delete mode 100644 Win64/proj/actor/Debug/actor.tlog/Cl.items.tlog delete mode 100644 Win64/proj/actor/Debug/actor.tlog/Lib-link.read.1.tlog delete mode 100644 Win64/proj/actor/Debug/actor.tlog/Lib-link.write.1.tlog delete mode 100644 Win64/proj/actor/Debug/actor.tlog/Lib.command.1.tlog delete mode 100644 Win64/proj/actor/Debug/actor.tlog/actor.lastbuildstate delete mode 100644 Win64/proj/actor/Debug/actor.tlog/bscmake.command.1.tlog delete mode 100644 Win64/proj/actor/Debug/actor.tlog/bscmake.read.1.tlog delete mode 100644 Win64/proj/actor/Debug/actor.tlog/bscmake.write.1.tlog delete mode 100644 Win64/proj/actor/Debug/actor.vcxproj.FileListAbsolute.txt diff --git a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp index e72c2b27fe..65cb73fe09 100644 --- a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp +++ b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp @@ -1846,11 +1846,11 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) case MAT_TAG_QzLiq1: return new QzLiq1(); - //case MAT_TAG_TzSandCPT: - // return new TzSandCPT(); + case MAT_TAG_TzSandCPT: + return new TzSandCPT(); - //case MAT_TAG_QbSandCPT: - // return new QbSandCPT(); + case MAT_TAG_QbSandCPT: + return new QbSandCPT(); case MAT_TAG_Hysteretic: return new HystereticMaterial(); diff --git a/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp b/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp index aabefbf071..ce4cae0f3d 100644 --- a/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp +++ b/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp @@ -2169,7 +2169,7 @@ TclModelBuilderUniaxialMaterialCommand (ClientData clientData, Tcl_Interp *inter else return TCL_ERROR; } - /* if (strcmp(argv[1], "TzSandCPT") == 0) { + if (strcmp(argv[1], "TzSandCPT") == 0) { void* theMat = OPS_TzSandCPT(); if (theMat != 0) theMaterial = (UniaxialMaterial*)theMat; @@ -2182,7 +2182,7 @@ TclModelBuilderUniaxialMaterialCommand (ClientData clientData, Tcl_Interp *inter theMaterial = (UniaxialMaterial*)theMat; else return TCL_ERROR; - } */ + } // Fedeas #if defined(_STEEL2) || defined(OPSDEF_UNIAXIAL_FEDEAS) if (theMaterial == 0) diff --git a/Win64/proj/actor/Debug/Actor.sbr b/Win64/proj/actor/Debug/Actor.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/Channel.sbr b/Win64/proj/actor/Debug/Channel.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/ChannelAddress.sbr b/Win64/proj/actor/Debug/ChannelAddress.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/FEM_ObjectBroker.sbr b/Win64/proj/actor/Debug/FEM_ObjectBroker.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/FEM_ObjectBrokerAllClasses.sbr b/Win64/proj/actor/Debug/FEM_ObjectBrokerAllClasses.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/HTTP.sbr b/Win64/proj/actor/Debug/HTTP.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/Message.sbr b/Win64/proj/actor/Debug/Message.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/MovableObject.sbr b/Win64/proj/actor/Debug/MovableObject.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/ObjectBroker.sbr b/Win64/proj/actor/Debug/ObjectBroker.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/Shadow.sbr b/Win64/proj/actor/Debug/Shadow.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/Socket.sbr b/Win64/proj/actor/Debug/Socket.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/TCP_Socket.sbr b/Win64/proj/actor/Debug/TCP_Socket.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/UDP_Socket.sbr b/Win64/proj/actor/Debug/UDP_Socket.sbr deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/actor.Build.CppClean.log b/Win64/proj/actor/Debug/actor.Build.CppClean.log deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Win64/proj/actor/Debug/actor.lib.recipe b/Win64/proj/actor/Debug/actor.lib.recipe deleted file mode 100644 index a53f9611dc..0000000000 --- a/Win64/proj/actor/Debug/actor.lib.recipe +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/Win64/proj/actor/Debug/actor.tlog/CL.command.1.tlog b/Win64/proj/actor/Debug/actor.tlog/CL.command.1.tlog deleted file mode 100644 index d50b3e41da95765a765f09ce0f27e5f2d99d783f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128506 zcmeHQU5^{bv7P4t`47gv+k)d4LvQ;*Zq^c)yj;?j1mYTktRw~$C6ILyJ3l_T=S;EP zU&E;$k}C(n!D4s$G2PSM(_K|vb^6r5|MkD!b@#N}bvNCt`xd{?yJfe+d;Xnu_uT{j z&hU4K-!-n?b(i?N!T0NfufM<*EBySv`(5{>d((Y}zjxgi_}OKDLyZg6xxro5xatxu z;Js%3UG8w7d%R!c{i^?KElI!iYGIC6^J9(nTzAj*J-x!~sWq(dOl`)cGtaA~<>@|0s}}g( zV76@fJ{~h}^;{gPcZX*l?sna;8On$0y|~A$;i}v0*Y86wYbaURkC*7rvj60{TX*@S zHr;pq+zI9R{GUy(g|%Mx?OXOzf>P)jvvP({`TDr^ZoS^3h2?Yg*Lm4b){=iVy$+5( z&fdSXFRpQCC1ZVEoEQ%-egLYB@5KYC$Pm+xp(hh*2uQ= zvoP|9t*Npkb@l_s-d4zIt(c<+v;z4IC?BWQR?CA@gU``c*6csmvX^Wb?YevXr!C7l z-(uI*Z90cta=dPidfjy9sTN{dAIHU>p!K@VKB`A3tuyHLX_c;mbO;|JuqwoHP*NU2tKvE{%MxH z*P526<<)U`O?xHH8?%D_y2G=e_U7v;rS2gg7JIw!xY0blhEx;nFo%w}Lh7fH*Ug=S zjT2|PuWP*e%#X_zNNA4;_7)j8~2NN2n4PpRXM^O11=GOiGJOhZ0}(6aN!fKI!&c|$4Lym^(cy&d{{ zN}u_(Ia+hbIquJXtGiP}y+m6+bqmZ_>1&bWM*XoyGkBub{VvDX=f|~v2MdWldXwBi zk3LqP+WmB;WPGd^<)h}^CDm2*+E{FJS}BtPAtvIL&D*!@UiIsT{^0glZCMBH#$#e9 zoF!Y>HokRJ-Z4n%ub`i%_BfRNLqpke*3^+B@9wD`OFu9pR&7!Cv?Ngj9H%x7M;`#? zGBu)aY5RR-6l;b$`IP-<)lwfv!E9S^{K_Z)HS`Ym0E}l$kFmCwZ0W`7sL|!qq0O@F z?W?K%|E4cTpQcx`?t$GoU#%AyN8)bGJ8b(s`dOo&I9NUx`#ZLm*!5Nd?YV6~d#r|6 z-H&}u@4LTs@9_I){IW0KbzklOzd(GBpZtI;U*mgT`BV21@8015Q~YJg|LgvWZ+P7j zSK9wy_9ZD5zVGizJJxVA_8INGtNvC z^zQ>|XFvbmy-mLP5j}o~ad^M~bdD<+`^@o7wqMToAY8pR7Eksu&pFyOy=;_9UtrGM zpiXH8A~Z5$C@THnH;<=C>+TPX~h$?kH_@Vzi-!9ou*skVxQL90(+1pJyXXdD4s zUyKh5gLVk##(m`28K1-Wfnn5KirQgW`bNg@P{$PMKM)2@7_=6YrZ8w@7*=7>C`+gd z%qQ7`M->K*`@*0-Yv~*?f$^-0C*cq45U*s!oe6_xXLw7zi!f+mriR$LFlZ?bD2z@X zIcL0v(E)G$<$F`_YTKg;gC-2x&YK@$e89Zx6>n&GsJU&PZtxwdK_<-DAC zmt2zygVq{F3OF)h(1x_5FlfP2%~vDO(Y2!2>KH*C1s4Wwi6}17g!IhTs5N2Ggh6`( zG}&*9LCY~=V;Hg1uxL5LxV%sPt&nLg@|EZCgiI4VTF~Y#b4JLtl;=>$wA4Pf*I_o5 zwxN(|fkV&RwU#3%WLiG6giMS3_(Q9Wb4bWEA=5lrQ|o+Mg@#rWGA+i|g-jb`VDo0# zVN`*TX>pE?jZ)-!5<8mD>^U})DH}%M4-_&@$TUMB=Mkg)osen9`C9WFd-7k%G_j+J z9j)HAe~y!UO19j%q=PRKMN)0m@#Cu(AjF0rGH zou#b(q9s1b-}9t7+{BJX``@w}i5-pXv)=qE*Q?mk#EvF*v}u_$Q>ojI7&{H8c8Jm4 zm?kZs%`oS?P;0){Jx@%s)a6#IF?}niXIsvyQa>?wfpU5>8&$-}DW~T+pGdvljmK3v zJ<}a)&CE=B#na_}#;tOdj$_G`(^EM;Ee;yFa5>lLi)O4sIX#cdEUKKIb?mE_{SkTQ z?TyFEp2tFrZK2OXIXyYz#?QkOY0Bw2gd!53TFC+?)S7a79%3_$SvQr_lbn~S^P!$VBb?t)uzM={XcL6rY;-)RfcnqL;w`xj8-0gCF~?Fl_XfJO>WQ*hiT6=>a)h zuYpupb-(X^2i^C^)qu5xFY`yypT(@ctex?`8SX$Xvn5awQ}ycuvgoeCuE>Ztb#H5) za_aL{9}}}2yr-eb&l9z*H6i1e!nKh@^VsVlFAdB#|rDGp**2Mt|(9Fm{&QE z#w$sID3{UfZo4I&;wt+mMBbHpTtT8rpK%jwLMALb_&YONjhAMt5vlskSZ zHn#DTC-r(4YE7s$;?cOPymM{!(#jWV%`kO_qqCVrYlC=`8P0?eS^TWYYZ5)z-2ID< zZGpYx5|}!%u^rNmS6H*$UteLIINPT0v!f0@r7Y*GP;2&-ltXk3XXeea!-xar5RE?J zu~8CgO{g`Y*5X>Jqx?dx@hn5|+Vk8Xb=JCPK=osLt>Za-{=}32Ewy`f9F~q=Nukz+ zTD$KpX+Lw1P-|mRQK8nZ-Q8Ha-;b|78C6S2q1J?26B}E~6+xSZ{x_l4gj$R7-cUts_x6H+eH;WN;vh`7`4 zA>WM!KkT^7n)Mk~T4tWO)5M(?IJU}YP25LvCJBYcoze9D(+y-8*^t7yH=)qdcyTSG zghI>LVLd{rjc~fXNxZh_QxXbIC^T=5)R9C+ZRg$h{izf`>-b@u1-VTF3lzOrJ~Fj6 zhDlz!l&Nld9~Wp3`I(;g7??ZMx58_`g=4+tZh-h(p={^Y)B@9sjO zjm2hjc_{9*A)Hh?f8%R!-ql*O)q*>8mT6jkmuSUZ!4_haw2gDqJpFcUi)1`>pMbaW z#!1|1;!YC^O(-;>(8`#ICpk-0i%@7|mQL++EF<0Cct_pO^XxbHp{{Jvu*%ua-GjK(Ql`TT_*|a$kyY-i?4%YWs+6qs-_g#nEJYXlJzIMT9`q%xJ=-9oqHI zA-$QWJw$5AAwpk-=SQfu<2mdS`tFI~oqqQc@1=a6#Ow-_CQO>Qmg=}7W4OYk4etu3 zBBO*!6Ej*o=Txt?fI1T>kmuawxlgWv z2j~|*WwRph@Y+Z0)@vuP`#Ea1-rx5qU2mkk`c{~WmVH;4w0wt|W4yRt`9$s6((kds zJ8$$;l#X|8eLv!WjenVUn^r#Tbi7h|e9*hvW-_Jti;3+?d*|Jyp0g1xHC}f7+ni55 zdJz0lWqxX5(o)Y%*mb9~-69y2e#T7Tjd4B?+w&n>WY%=*3U{-3?KI5adGBo}bm@=! zw0&mZDVOH(PSXSVTiu-+>LuFpsatT3dmiHfYs(4wSfd#{QOu#(a$4xvxtdDufbD*) zJ_(an#zdx$v@mJHq?wPHwib8KLzyeNGa%ypvcVFqJ=rCWPt0hvS;UMcOxm07FF@UW zzbOt>lr$!-bO=Nx+&Z1k?@9(5qTFSd{jxz4cebQ||yHB$- zcKu%K)J$2zsT~swuV;;LYFszMsl`ZC>UAvlWWuQlr)K+d+G?e>7JQnezePATMnaCw zoyqK@$9d_*oi@!<5l$_S=G7J=b*1@OELK7P`SJFqxYMEp4YG3@ipcYkPOFX2l#!Tq zzYk?upCz@9J6fD~hP{IE7&D&bwX?1zjo?o&O&dlywcM9-+zb1AHg65*yN>*wxYNX)MoZ%uJtCZ%xYKGYE0-_AsS#mo*1m9R z!l|X6onSQzrzY++ai@tpO*pkOCgSaEN^iJuYSX;3Wz5nW?;J59?leQfkwNaVkKudc zSI*b3;o)d!Kr2hPm#n?b<&)>i^EsgFdg!4MPVEUWNy4cKr^faFxHz@baAT)o))*}% zT4@Pv9@l()Cu~|R8EXkEY#Qx{XV7?diqO-R^_b@8sKlW*9EGaKt)7d*rU{#tBNB4I zt@3&@$E2N+pT@2y4mILd#G!TxufMQq<*Bh!gSY#<%H6Lx)M8}GctFh?k>bdB7G^r< zM{Pf(b@H{aX=BJ0p8F?8D)6@!#i2&K zJ1|9g)=cTwYvaG;IT-E>m;zsJ^VYyb<)QF5s>OB%iU)9)6L z=@zYKes@O0$pgun$-lAeKY8xfU0U)R;9rSg4CNW6cs98f)=H*aF{IH?8)oC!j!O(_ zVn{PNAciz!uq`E1lqoSQuuy2VCK3v*^h8h(rR-y;T8L?VLZOiZ)lLXnM4Z`QX`j#r z2`FRF!kLP(5ekj-Sqy1uR4*X@Y5k^rbl%*n5eLzFrtNlz`c}O^-m7WqELJ8@F{H)a zK|K$NauGvX*gXk_7UxQeCyTE=`4q2YyqD64r+>tdR%5B^wI~!?8w*74;}AnyJjWsw znoww|y&CkI7}CU$CWbUIq_v+GEq#8T-B)^2g+hy#bU8M(^LWaA>XXkp*x>r+Zb;nBp37Ol;eIU_t;Jo&;iYr>;N|8$6P4kKi^2Vn+#p0sY^ z707+H`3WH5(S%2{{h;t@!>dhrv>|VHt>J`66CRCtFweWhSfO#uP>)fIJsiRBmg_V| zyoE;_%0QSRq=;Km#!j)K36CZ`THLGF7#QKv($hS`qs6(BBFo}yPvgfcg-3gWoqK9e z=R5s+Eeek&JX&0Tc}&?`ceY0p9!+?(RN{oVhVW>@qX~~DJeu%m%Gl{y61m;6>(7%g zH;C|P7Bi^5;WcNCSkZ=1bz(&mE7}vpvH#kA-bW5*;Kuq1OlOoxYoG$IJF%iY>E3of zcOUWh19G&!?%s7zftL8HAEVnnSKOz?qj^ZN^WxIBh$;z}7V;#9{acI95iU*HI#XYE z%bXD|O}I4fil?7&5iTvT=}p~F&3iu(WceLh$eC9Yy4++JK@rp3*@fPoJKt467RebZ;fh-Cv669US;c4 zwobF7a^!ISjx2z!r)rd~GxaRg$fX)Z=t;E0I>alPBFy6JDW$}dCS2MON~V+#Tf{!o z&%8O7Uc1AtmYnjKkC6db%nk39d^{@v|hV*Ch^bQKeaMQMpoVYJ|Qoq*UogdbDv=R$Ctfr?3K;u zVSBbi^EZ_lGpCL3dGD=koyykPK7W<1Q`tJpY@*86Ieyln_7sy2NjF~5eLafQ;%`!YQjReMSQ$rBO!(zT50dT1xnW)V-Cc+$j^#`XVcacLe>?Ee9u C`OzW( diff --git a/Win64/proj/actor/Debug/actor.tlog/CL.read.1.tlog b/Win64/proj/actor/Debug/actor.tlog/CL.read.1.tlog deleted file mode 100644 index d6d1c1b09e077086bbf70aa93efe00ec17dcdd11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 251234 zcmeI5*>W5?vZnL8&H5d5*?n-o zr`2cs{b29kZG8OJK5=XR{<-=`k#GO9_ctG}zSusl?H@aSGAQHcZ|&Lsu%8%C?>gLp zy>x}o_Fn()9P3@Ztn_(xZjYW;>GL^Oh|m4X&i}h%@W`-tYLAarf7t)f#nhFK?VCOu zjosUKu!sA}-*jbv|6rKESUq-l=$}o6jk|EadN!!I9Y^;4mwUh`N;~N=#~lja&d#Bi z&vtexq__6^jjevyz4vByW_ttg_p3Lnf7vd7U;VcFw|&zOd;Qwz>c$@N-dB76V2_?w z?^o~aH}8VyZ}u5zgje5oKOa^f>^nZ#D?ER)PaNB75B5k<@t5b0pgOiaf-6Be7F*nk zi|%i3Y+pBq#|OjGcYE#LcFd{1>GlhLF6{j$!^k`P`CyM&@yh;vGfaThpZ3~!d-cg4 z-`GDWg73e7dG-D3li}-={q5V;NBjSi{r+g5$j^Z9xa+?4!QSK69`bJPJ1idZ4mf9S z$u~O{D2&HH?Np(TL*5tMnp=Nndl|cr^4ul8$Il)8BU|na=iZ@2$N6be!4p1DJF2}l z435R#Vemw-ESc_E4n22r*CU)@4~^r(w3o4zQRDW*Wzn&Y9Ycvl^x5ti8oeJ}>V(DN z{XmuTcl6TTDbXX3;x3_0qF<-@9&bsfmI~H)u&n3##tXai;hXle^Hb|Jw`S+E_g`CO zf2%yTilHm4D6~7Q=76iYJR+X0kddbU@33qSruz}SA& zm3l*R>Pp|8i`LR_eQixq-hR8>gu^jdp2wfI4+M2FAibdX5piqhqJ-&K8HQ?qE;SvZ za36Q&VEBxXMtCRi`Fykcp1#)ei}iQQty*fWbZ_yqse9Sot2bUx=y9KV-#yEh`E{G% zC*9_SZJyHHf17IHDRpngmPd`dc}npV`|(^iPwA3znDibuPwBpKt>!6RHjbFnuRK9S zX?=Ngr}(Fur&O`x{EVBY6diwDoIS@~^OO=#4>?C<>EMYX9!pk2`aIQY$JshBS;r04eaokz1$g9kyWC+ zBC^u>bh)*+!8Uc(Bijc#FjN12JjTe$AXAKN88BP}gZb$}@At+Tl-o0%>i5S&eMrcL zf}>sjI+^8Rf+}?PepWn_I#6JfKHBb23m34S)vF@jrZ#?R73x1#M=h)Vm zdh54;cmJ+-(yv=)y(`P+DY>6}I}7v&G?}?}Bw5c{Ty%Gi%uVtWKN}5%SHv%oHsn4Y z*>7Uk*OO0e%$hkA`QJ=E!TfvhQz8p`49xe<`5vAOcQ=OLW6Sd41m|6O&V1z@vLUKC zvRxb%rh*h-XgU|B4?%m#hviO+73HfdyDB=sz2TLd;gY*cZ*+dzORoIQ&Jn&Mj-tG% z<<`d*<1XIW>2h21tg-QyV2;C~8IpMaY?M-+I^+=fZRN=u;kh& zwk}c={4BYys-M_1x&BM8j5VlRg|2Y1_|B20)O}F_fpv9lP%Mi9>VQtV%xdudY;_Y~ zi}F*gC+mwCn{4&>2E+DqKdksEnmW2toS$-7JNRi9KQ}VZxIENdJe$N)9aGA^4{JY< zUAEv)+shZbImc^vb@OhPh?@|ZI5ACkeD&I4lyv-xg%JR2g_p^o)X>Fd;d$V4J< zjml&T9_mi8;IZeQyZb_xJK1B0x|?Hz9i3KM#i8#)cmGg#p_9-a#&Y2Dk{e0AYaOje zF1nua{cN{5=SpMo?s12wCbh@HU!HD)HzH_!imMSrCSt?0v9Nl?H8Skp?64okIS-ZJ z1m4eH#_XXy%>)iOzT-rBm~uJ}xs+gSECnwQWsgbu1r@VAY`>N0HDq~@p;(WcgNVOs z)9;+zx*i_C^bCyH*S>EZPzL+JGcL)ZQ^&Ks$KGbkczGU12Rh$8mO5SV==rR5qS)T_ zrtl0Yo&kIveqg*eTVIs}WTASxD*>{=ZN{IhN0}IQfo*U$QXBQSk0Bc~-`iN~_PD>t z?tUJ+FEZ}7bhujNnR#VyI<7Qk59OtI56>Y}I9*}-UR+}^>+zl{nt!O!KXz12OpP4# zL#C!j%cKYyt;m5xJ&|XNc7$%k&vq*E<)s-%X^-~Jc7(_K^7l9;v?tC+wHgWh0B9_k*_8${jAgPlyEJ8AESe1p>c(E~BiVxU4zNKic={3G}!v8&SuY2D0gIQm;S5Gvf&A*u}&yq+VW|G%sD9*=qRf&du^B z$6tAoa3$_<$#Z6RA=*lx8ezT1M9H<4H325^5iNb%U%Hrn&}+bcsAXP8#~NDy-p+o> z)2F}M5FAUwfNpzhl#jexa@{YscV?1k<&t!+S&-O-)H^P@$8_bm>qW`^a*`)jRex4k zYG|FSMOHbpb1Q56^gXoH@#e-j(xt80cPc4)W>Dp0*Y}1RkCH3NHv+$*6X zXVqrVjpIJW&@S0=p?4A4v3cjc!?IrKV?fn0obT^qgNHc|bkUI4C$&ru>xAO-(T@7a z+F|X49+p_{@L%}gn0=Jbn!7idv|A3j$NU*(BV$uB-wzqXY?*QOEgtuidet`V4lf(p z8+ywj-*LPzoEZJt#@q^zCkCHFo9pX&4|OMxFEUY{kwe`@euF}9k#pk@Sf_NGI`n%3 zt*JJinWjUX_76=$iVqxi&MkIc$Q?e^+e04H7vsq2#l#p=%lNRUD&+*}zWzQL#GII_ z*ADykP`|2ujJZ4I_2U4|A>V*Uv*T}GWW_kU!=r}vXx1#AD>A9Z(1y=F=p=$CsfXu~c@lMQyYZy*n2jMiWZbIS=Fq*G_{t97 zH!Gjt7|!8YUTMP5q3(hlJ1k3CX0cZgj}6sb-27Xc0L5>jHuz_WQS~z$^C-^HTnnwB z&f$5lhIvJ6feNn0-+ZFq&EM>#TRaKg2*Di@!WgiinC+B9pQfmoZ-x{uo6KsZ}1d|^Qw|7Q|&-p^w=<}{zJN@!Jh}09^zRg zVY)R~p6uSz|E}lYW#y69e6YSHORxE7g*9{BmaW_y#_bYo=D1yAO?Hdi`EyN!I;_~K zyjO?sg_CrKpPfgsqj@cwp2CMuzQk(K_P(p7RyrCD^&-l~0_H#M8Cd|E-)kRFUJbGi0>>Iyj}(hcap?4;Rxl28?u_D{m8~SHfYNFo&Gdmu6lK05tm-=tkYug zTI1P|p9R0i`-1l}uQo~{$j_$a8OJ+Mp$K?bb{_a-@- z5O5Mlq?Wz4Jq(-RS(X}y;pyYV%VG!4g-`U(bU0a2$1gn%mZTZ^24$Npxh|cKn8yB> zQL3!gk{a6|w#IdrYr*uduVyR6`!2b1-^l^%Op$0hmXz;a(bKj30iPD-fLJBqdP$n% zT)%eqE;%1ags(6(|G#*z^HFg|`~{6;ct z6Hdy~$GKquUPtE@xL565~7_1Uo3|Y(Z8RMN9hAI42Ic$U#hT%#v6o0lHM4NC?mMd&p6{;YAhTDm( zoHK7V#qMS*VCPH0KtkElz6-X)M^YZX)hG5ejEr%Q8plEBM=h!f2mWK-yd4VaFXHpq{%J2TZ|AA$$;}5dQatxN=oXPJM;#&eRvaDPt_(Cq zdFItG#zB&M$ZBH(jNBVfo74InhlyUw_FQIZY+xS}HP|15G!ACUIH7f! zP=ZUcqxF^MwYq!UmF2nYWoaJPR|Z{lbO%2Nj=3o!=M1_>wN@8j%5TXsdtPSM{(c8f ztaPQhC*kOB49lI;JH-|X-S@firPm{uJ&wREvnDodZ*l3~z_V2kTz=0(>*sd0ypEj3 zynZB6S8w4gy>HzjG)&dpub)I6{4@V%iF-}%vHEC)NBMr=tv=2!D>kh)H-GNyga7P& z8zr=ce2vn3$mMJq4Lsi!-qj_rH}AAQahIXJEQ7_qf-gk6?=4~gk0Y0eTvQ-rt`8Oa z7iQtm=bKqZb5qfDNZu9D759N=er~iG8a(DppVT+Yy~}wp)nD?~(|L$Yy8II*EU#&h zl;9GZAR)_?YD=_2I!5OrZYG}{ku-Vn zxQ|G7bt#Cm9p>)k@Rqopyd+s3&PF;+r)dA@nJ68rghsn{(qf)OTp+8~!hD8hxJDse-<;^tB(#|Cr;u=f*P{o+{{+5z5Zw z!|Sty`)JCxJKtBlPVkxKE{nv z_5-hRlQ@O+{aB82$M7Z-&pMhc%jbk>Gqh9BY)SZ|cUg#Hy77aj{G99Jh&zQ`kWM8|RTmcII-p?|}!IR--GhEEBzv(*D)`jcFaP<&j zt1d9Uf4hD-wNu%#iZ14*ve2s2RX();H` z$lt(UR|gmCt5PS4#(vjvlJ)m%(aKlD5fg%-;W|+D(pnkIeP&XBx7I&{twkRlZX{mz zxw~tD3!)s4-EaE4ufs6(nh&^6>@4N&fnO3CS%=;Sr17or3S-}ek&1U{&I_dImU!@} z01Ekhz$S^rqxchbPCSO7kIDt8J-~#v+s}*k1ljOCjxp*1fA~3}G^mbTNqCM&+RJ&3 zH$0|siLw~XJ>Hxj6(UIA{_#}JZQQp{uNWNn{V6_6>;)S@5yY}M8(OFQ?yz*wSkbP~ zu>yt6g~`9VZ>Q%@EX9UiU4F$f*d5xNBd~y-^)tFzIp1V zw*j*;(A~B@R>Q~*>ou8yzT5d?Ru5d&ugEU6DO~& z6*zd@r7MMZPTY(+p+4hjoucN%%)YQJjh7T&ECDd3E|r?b;^R(jgKSQm_1!MRzEgg) z{rx#9Y5Pj#3W*;Ey;0useLdyu7MquD+4A_@cY01b<%0X2e`ZbzjJ`!TlOc}39WQgz z03nUf~wfoM(~g%}N82(Vw|Q+Qo&Py4$$aXAfwrx#m?lh|d)bK;zv ziN^+SEItK!^e)Wed7oKlC2Sk|b3OjjLIvj$@H7&_L>C04_}9*Sy|T>GKZjggfK$n`{PC*MBTRHyrMro+Tpm4T_Bg@w+^u9=I)c~YxHM1LMFq5tlo zb^dqZbxzEyb8g0ES{etWKo&b7)Prfn*M#UzsOcuu+5f2;C=$RUBJ-I{KB8?8Clj?iWC`zSX?HR@kG zAN|nlbyh8t{kUo8!U5hGGP2{?5Pp4Z8zLE{F`>v5*{(>}`Bn?L@yIXrt|Tudx1v~8 z5!Lu}b3t)so<1T$SGIEhxWu;;4ZbiNt?VlOx8v)W-rGEvHU0OZ3FJE|x7Mj)tj>D# z(SRy)p)Wm}>zjLyK!y`{Q=LV`FT@+-DU_Q(rB0N`FTR91Wk@L)=cMiVU`+ecslL!B zHisbfiPLY!ZRj`e1&?_i_jJp09Nm5CWaF|t1BpoeFm)|Q_7C1N-@fxMW%7vyZ3Ybh zO^12{^dIm`9d@5dKPM&Z3(K5$=5<&?MpeKS6TrXErjfn2{+;RkKVD8oT|WM_b6N5< zh9Ow;44}i1J#=PVsTN&sgJVg2D2quIS~>lME`Rj;AnSZC9+t0@^N(F%nvbj98sAcl zi|h&IxDhcOdVS7YL%sqTP@>EudrWVo{I#jrS1qu(Fq~L@o5)w;89(VaA68BP-7)YN zQzvs9MOF`M7ms$sIBzo0uMd6~$`3w`_Ay<@A{+Wo`$_Mle2aPBOYl6UpH8WJIwW*7 zqneMXw0J|`{~!MjS+V473by#u;a(G6=HBt?pR>x{c(plTn^OXfh3%}9#psUT440f! zeCBiV+ub1I^wR27FOc=PN-6Q@jJO+H6%l(n*DECUIlXxx*oUIWLU8*+waNg!vuE;q zGR5I+ulqg^1WVumNYP!0W7fdHw)OYfza}K8UlM)ARiCYjoU4wfQ==$OKUL!7YbaJh z1u8v1(|6}ugM6ox1-~2F$^DoLf699mZP->b_2uPE&=rs>)MbjJ%j)1&@%MSE$fm=m zEN;K>Q4>rOj&_CKSJ;|^rz@87N`n%`@9&X)_?$qdqf?k4^<^wiq zhj`ik>ZB6f_0kD!!`#aU-r%On#+BEk?~>{RKAuMxxw9x8JK#|%Nt<^WCr^hta9DrfQaOBJG1a&6=O5cY`u75>G^q4%=e^z2 zA@vCrc=HR{!>=3d8Akje=vwrri>cNN<#Bi6Gd`jFVYgRyBDYt)hJ8Z%#W2Xfa%Zgm zeJ4gqidKdWY-q=5R6K_Z(-Cc|7b#!k(Z1`lv(j0$#0o%<-wWNf#v1r;re~Ap_&Ty( zFc+CP))G6y_J-!loD8`QSDgm6KV?CgXc9s9?|Vh&?@XoL{CgD7kJp^U9-Q* zB_#j))^;`Y?o>)lPd%=~39I!rG#~chpX2sNO~}0a8@H}3ZF(PKp^<|UYz`orirYEX zp5E1K-0EZrAyw3SgIa|-sVjvcWTym)fUggJhh&}y$Kl(a_Ws`dUZl@ULLPhp+_p5v z8g@4~uHqH@=v(R4h(#~EKUQ2~f5y!5cTF;xrejC?K z9Se^;gwKxt7EdNgd9Am3hPY7rnW>n3eQkN@(C?R9kth}zp$kgQy<>gLyCxgFCM@!r zDt8EbLS8rd0&BuW1^`jeC1GHK-&NS)QhB?pr@$K?wQd}i}IW#JJVP@SlM9p?Gg&;6BP zCQQ?S_QI4}U>N%B5|G3(0N|T%&2`LfK6A88Fn}kn9t?4OpD5F<(XirkwXj0>h#Qk* z=mXc2&xUS6Sin%+vwa`Dj(bTQD8@T`r4RD@YqjiTPvN#L%kvC;AL_c@mZLJf|0BNDgW? z;W{3Gh|g28$z3MTdV25C{mvwYg}X$Q4Bfi)S$#3yz0@kpa47BQ)G8(LTT3@uYKQr% zOYV4BDl9`k!)w>yeSRJ_v5~{FBz9`@UfsuS5G;*}<#~ROgY~s*?S6SFvq{D+g8{sh zz5S5i#?qW&`|8VJKz?m}BzKmlQhLX+g}m&_>1s=#bh`RBzE}DL)*)HvKJ{Q&lK+HW zcIi-bQO>y?aK0}5j6`IrKT8fu+g|L43KksWwgq`lDs;-6a0ukBh%fK^?mnBXF z%DlC^32%TWhgy-cYwLb|=_V1u8L;2fZyR`~u1%JN&P+3PsK2A`f;?8O7@kjEA%;>> zFLf8f6M&VbsXBe822=i%kk&Dlhk?DN zIt*BllqZiY$enqpEniK~@w_dy(vVCov$tTmzzajZAa+;johr9UlmjOzzasV|^^;4j zB#f#@Noi~CTZgMl7Mk6TxfgbrC{}e zYr3Mmv2&9Zik9%E+b!5(zfXpbclPta9ba~OY*MNG35T`)%V?$ z<4^XtZ%v#1WdAs!5T|cJg&8I*L&Hy9Y4EU?g=Jrw%}#QJLd<=l=l!b!9pTV zx%(;s*}w>z2l6NoES!-ruX= z2H`EXi@ab@kO^yKtt0t=c5(K)9x%Zr&OommO|9~CmZ2smc;(1~AOeTfo&*&&wAFQEo8!Jo`m|KDbAmnc(SUm3N4I$Ajt#vY5*7eW>Fg)yjB4e!jr! ziMtFzER1@BlDU6aSbn%m3{idGk+jPnhNT~tr~b(yohipHRBWQhc{)vKU0Kak1pMr1 zjn_QE7&J|FJivzb1YKO=Le9T>+TR%G3tZ2KOv|+bzmVoM$!Xsjm8!FmI?8j8eBf2O z6&;RMry<((AwyChta8I-@vc{@i$0dEB_fY0;O(#Oe0|+*VeH&AXD@cGAo|w%cIw}N zl)fHJE2X1G{n$g$3a~A%yV$P}UV)v6?HFj@mmKSJ#y#<{_$(y@e4M3jVvtJ8(eM)2 z5>#XXQ$OvA%7!5GVnqzW_R)!!A!^$#m$p=nh;F1{!7EJ-l&3q1Mpi$^RalaC$W6@q z)YQ_qL`mdCJ($g$_Z?mys#J&g(Mjz3^prw%++{#fZR3N^m67EMmMfDqUf`kssuxLo zx%$g)8nZ9dEz1Xv=vWZ@ExbX6B))P&Pgf@0m|N(_1Iy_V-Dif7U#Prjb()q=uZGa= z(Hqu$Y3LqpQ(_L9LrtHSude9++I;38yIwhU^UP9>g)W}nv?#%JVsPdCq-txOF=Sq{ z-UJgpx$65KhiEHgLDbiYhoJl1={IDL_|R>Dkt&pso96>6*@Eh$Tfeq3_Vk4cc29Vs zBNu+Y`u^>d;*X5Vy+Ecju?hOo6;-@H=d$?!hF@Vh*yxKOPy_fKUx-P9s(Gz9G=jQ`YF|GT6NFFP^@BXNqS{}jW16SWn>Rp2J8_n>X{6Ulu3UAzseUF* zYA>i)86BSKjqNKdMqT=S&=vO7qZ5w;neATU@yfEN!#Wa$I{f;%9w~*>7xqI3S$&^+ z3K^CMDe*8*IU?FY=hh$>SbbK(c5V=&J zli?H6v>4*|ni@k6yg$g+{mc7J38IF0+eE>6W(B>rN}Q80o)Wof+@JIA?%`dae_ncK zB0c8N{S*deaZJ1IYjPgtr ziS#t@W(dmASzD8RJwY4ipS0;b z9EPz?=hV|#;_|7w^_4?Mge%w(weM~Y8_xr5^>eeg zLD#19Y?l-%?qpee>N_*(YU-UI`sZHm>BIaDi+RofhWhJG&t+o~}3Du_ajFshW zI?wKL;GXuwB*1tINt@2|nvX$uG|oTrC9T8-+jO3NyyrUO_+Eq>eoywZpp0kX_>f;Q zMD=|~!cv>gGbLLPS&>gd3EpT=T(3>%xnJ$i@1zm;S^@rPDtP?O5z1*2T5QvKsBPL+ zA51-pp(7X>?QJ^GcE5U%EAj`l={&=6>Xg3Pbe?Uw`SKdJ={&pgu=pmbD#wQ&EN&`@ zLXJlL+$&*AP_^kiyZH=hWt+}3#*UD^>~T5| z9V^--oH1vJwDN*0`8?VroXrw3_U5%oIIm{{4)OMD7u`jJf3Ho#8Drt6=h!CUjI}Xx zyb+IXlW@k!Mf^oz&qF6zJb~)s?!_z8CgJQ-O%P892^n&=Em+B)c#?`Q$l4^FF zKOYno)4C6c}u1dY|Jhd+VXcOqn#_H)>$dk~e?^YbmA!XupC^O+ z$^MdAPt0OM)1cz!%6{wB_bYmgeX_rPyZUJVf3n{n?Gt%tf;RhtsYD)obu&u~ec;UC ztFO-v-{Us>fDLgDmw6>mW83PLJ|*X!gZ^wpTpk@~G45 zz8a-z-ey1jGJfZ+(IC~~|6KjU9{tB82j@R-re|z>O<7qs*?v1#d{NhKAd8wB2j?gSFdqv}L_f zLps_%dJ-BxlhChC%epjeD}A2IxM`Xgw~KGZuSSnue0xC)-2C1=D{r5tJxyDRwaoaj z=jra?SrdgGJ5OH!Y$~2x`~Z6P8$W1%$L4n=D`Z{M? z7%6>kK6{To%@)0F(c2ckIXA28vq_Oxnu`j^))^~D%EPoNhUXi~ z9+S_e#o{q$9*QR$RNA(u7;=8n{vhO3y=NmfZ$k4X{C&L%HKb$T-85L*^(%>$SwIf* ziFuCHOGa}e&N}V!!XgAet4r}AD8uaA&n6AY2SwNQ0d3qLM0p_fb5&CeGRgg`{qTFY ze#9Q_{Zq@1B!g&tmjI8ukfujQUVZH@r514oyrpN(H~}~Q`h{zGgzw&{67O@Y@A=~e zLooIc1AOPTt+a9i|iCsk57`oDk)qc)b~+BMa7G9`{?`iby%(x$!)rksi6;ZI=lh zv~=q3;@q3sm}71lIp@SgX(q z_gosbf>(}QS|S=qui7_4xJx1Q0TUY0kx|+C3*LM{_02dery27OACM^{oE)n_X+Gdm zC3p{=GH``I9}q(QM;$jK?}!d}KHv%ym+9nvVL!gkRs7Z?=lJr1DNkofj)Fg)ac}aQ z3N~)1AG(J_JaqR_75MlVPFz8l>KYG*KTQ}sF^ky~COKawmymN3=+6glyRtK-_67~o z6UNXR)vpT=swc=|D#Q0dZzN?r+w_V@CFr< z_{t5gj?Mb>q^WayOfNWg4V4$I?$$Wd=PuHOZOR?=c9y<;9v*E|Vh+R#fsK4xPbYY7 z@tKb{F{CyRO*NLg&SUBkrV~3sZ*>B~mLT(z^(L5@hqIOEsnOA9m}!_}Ej(f}EzZ)d#l<5TQBL*Jg&WwOa?pQhw|d zvY5g`7L1Sc6t5shmpa?}ezqKMMCR_zCjrm*;^7j`$QV*CqK}g##{%rt*B~UP6(98C zsZlp#Uw2QQ$N-Zk4FX@*SNkDi65#Vegc5IOWRkZuSl&I^{suVp@R(yUw z@D$U!4~Ud4M;@;~DksxeaQVO$6R0jtKkyR+m)!G&BjxjbH+_ZrTR(N)_ZGYK6WdL1 zoe$~`IacI7dgw=tEibup)$ykKnJ}rnpgcn+*wSa%S5}PXxci_h?5Rg59tASny~N{{ zWly(iBnox-^>aN^3TMj9hYm7t{S2|xsY3GLt4eY9r=4Ygj{D8a&F9WM7_Hn|@3|0D z7@j`^C6Uue?ar<7P<~TyiDcHi3uQV!83x0=pM16*)eJ*x#T`h-uQNPDcl_UPgEPfN z44-7|vUMPMjvfr>$OdXHJjl@i6S9;nPCXwh8$5P^ZBuwSL-@>%MLQpCa>;k2wR`gj zppCrgsE@fW(BG4B@OSp}A=0L>LRBTH8ED*gc^B{PQ)JYE;iuJmt3!QjKls%?+W(*I z_eXnO6%3cQ9(Pz;8j-R#p|{3_Ud@8@&27{rS1@{=&mo@ed#*aOCb;A3*fExemx?=W z?xc#YLG%?3#t)P_VR%-3eRebM!hPP25 z=nDGIQg`b^W;^&lA9e!N9xD#q?SY~l%kfyiRj~1t% z14a53Kl3!DWeCd9bGglw>8+s6{4>R1n<;}%;LC!QX4q!RV9k%E<2F+UZwc7iMVHEX z0lwLM?oBV_+f12#G3;|rOHKuCrcCZr+{}eyYb4}SkJa&)_k^^WGW+nykPp~q%E;5c z`BtPHC7nHj7r$;~EQgMmWUwK;!3L}WHg7g!daiAz%r5$>ENeW|^|RK~`_N{}gh=98 z{uZBQn}Fl*ek%Tw^0wMqxFBmYWyZ?#Hd6*Ew2S98ru{I#E}osyX3D(gV-N=0 zOqpGLmBgK6DhqYoZKli{tNK-L(C$8dQDQv7#fSWgA*$~?5|-LbnW^-Juc*zG!S_BL zgX(tJX38+viR|!wd0tMF_;lJ#nJE;S`d~vJD|%zMnKIk`>Oro^A3#>W59zBjY%^uX zpI)0OGtTBAKP=>o$FT=bbWeSsuPSsw6mm2?)BuE@0#w6>eg}SL7z$r0WL~U@A=o~; z;`?o;%;x%yKKs4Rl-X3{(&MPjl-aI9q?&V^DZ{;6ubG0L+Dw^kx2?^T86P9=C*2^4 zz4Wl5w@;fXBk$NYO3x?Vc+u+GOd0xCjK76#rp#{mYBOav=SrnoR6Mz*wpU>@Wc9nS z%l8;}hWCiAHdAI7t_r=inKIjLuGr@udY;v${1_(cdD~2xF=yCj%50X2F-5hRGMn*~ zO6YjvM{S;vLKft-hd!O_nnQhUW(Zqtrpzw7gJQmIrp)d*YcplG$4lBwna%P?yi}gZ zP@}E5cy0M3$l^I00X`p)#WP8KLDpub4CkA)nKHXngr;|oZ1zK#DRaE~ zPnTIVcFId%zfV2C=E2-|-I~d1rsF`KO@jQ}eS%CprG<$`-|d@^EVh1XkB?S=*#GO@ z49Bm8f8(=BTsS0MXY*|0@!u4~nNQeBpQqaN_!a07qI~g3!*~2_>NnCai!(d#I{%|l zU+#f{7$PQs=w#NbUZ(Dtd4yAU8lMi8#+w|`5Y^R`>yZJry!;8mRK)D^5{u5 zyxP1Ir06cN)C8&FwcHbH7iFN1(f-4pbdHbH8M$%1Wy6tuRzz97&h zGPKvuxaV};;I*Hlb%W()kDzQ5q!dfPGEe!uvpL%YscW-&=jy(qY@=Yc*RSG9J(z+{ zc^GYi)PB9igv&rVV{NNa{4+i0HbKgx4bH^xHbH8;wvy6un;^A+-zu^=+XSh9n~t1v z?0q_|rBvD`NX^r^PUk~qTy1IECP+=yjnbR()i}?c*(=oU^?a!I>83D-?87!e>NQV7 zinnyqP@5pN%?Gm$bKY#k^jzBnsa^C{Po4i#nrjoJUZ0zgVk|z(HbLrj?5VCsSZfoc z#&?WKr>wLIQm<(tqBB0#CP|NQt+Xvgn0gXC2B2NC;tjb5oq2Mts}$Q1gY^JO;MNX!rBC>vGEzBl%`!2j@-{(gGoDhJ(owLM7%fZSpul>i+?)Eq(m} diff --git a/Win64/proj/actor/Debug/actor.tlog/CL.write.1.tlog b/Win64/proj/actor/Debug/actor.tlog/CL.write.1.tlog deleted file mode 100644 index aff6d07ed0c8ded35cc31c3d837f73dd1111f93f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7428 zcmdT|%Tj|d6uoO_{1sM?3wKb^TKiz2j}4dgB00v)=ro8ff{)0-SVCTV=!G+T3%xAl1rnP|E53~O zn7@`cSRxzg0DW_iHfI~lWni_Ql-zIlOHREi0dE zaj3|{UK3XqZ68TWNc;r(+fU!TZsi7yFN?t^c}7gSmpja**X_n*6~zlVz_#r78Em=4 z`)iTv-iB7roH}EKuv#EBL@YNdWRU4!;`zCNjXvzLbFU!mv+PxwT*gN7BQzf`UhA;2 z_$dDnq5J#(ZY2L8#P?Rj6)sDIblrwuWPf<5N24qTuiqDWn-ycL{|{mIqS1z zshQ}`%B~#QxWDyxTo_iV7n{x0?9kXq%$*)q zJhGXX9%dX9R~NCJmy{T}w(K)2Y!Ei`af&O4>0oS+R-ts_E$}?s>716r-u#Y5#{E$#J>Cj}>lbmYxmze8Syr`nuRHgtX<{`pua+Gk-rn zUX|!UJEh9>%vGq?iniS|Rcg3r+;`e2r+u%xFdFNTXT<83xoiI08)9`@{OF%CYIEOR zIEj|nQ1LU%r({L!H)Y@Eo5qcEn#K`)>^a#%v*i;Y+^M!fDHxf(E zT+8|NrIbT#BTjVY&Z^12h)gM9^%>L0*>{iMNzkDtZ+=rgYg;9sGqYojscyxy36=f}auCr9 diff --git a/Win64/proj/actor/Debug/actor.tlog/Lib-link.write.1.tlog b/Win64/proj/actor/Debug/actor.tlog/Lib-link.write.1.tlog deleted file mode 100644 index dd80495393d7aa9e4fd7c71e89579943715a7616..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1594 zcmc(fyAFad6o&uV#8+`L4sHdisO1tavJia{pI!Y53_57yPz>QfIi=sZKkgUB+NxI~ zt24J#p^~+iR=H}VMfU1+V7<|L&_+7)H2mGLx8mKO5UJJv?fVL?-+K$fiIrkQ&gCti zlV$KX!EYa%Ixu+$CDV0^q#a@&!7g+{Q~jB4h`hrlM<#qMd_=-#BBkaU>N6}Qn{sQY zXd9eW(0ztZaj?dY8S@<0$5+yP6;%&io8V^`IIcB}c<7QQFsXr4(xdYcTjtLv;!+Fj R`F*ZCW_Lj*D6#O)4V?MRwvid2ePs z^XB9IMTwSbmCERek*U;%wVjO$Rm_ID)lT=UZ*<-5#(Ll$@psL)Tb?aKtVXME@2}Xk z-@XOmNwmg>g3DSyC0B&MDSq47RDqfAV9E8mkEH2h9>ZPgk)7>7vqwZe!={Xru(7Za z340Q2a;_#n!?NW2vyI4T6P&B0`XVYNgUeNnJLj-I9y3jsQB_y9DSqw($F+hZ>8hj- z%v8g(p+=`;Y|x)mjF-C50^b|zWT`p6w~WJ_q2=*_X1o2lW}p<{*sic**mX{xTHUqX zz<~a&Te`yR2;DKc+&a}G79EP~9bY+atv=Xz9!h@)_&ZX+zWd;wtKK27hqT#;@2B$m jVD#&%AJUj=`k;V+45QX0wsdqpE}aXq@cp0G<*cr39Z*4Nk-w%;SxMsxH3 zfz>hd-+_=4EjY!R&!2u=w1}8fV)G2S;Mg;8R{DhP81A!%dCzR2H%8UJ<45qHbE=&C z@O*eyLf^-N?5oMg&^W6m8b@Svtng?B)fjQlIcVqi9UA!@Ys}noO%eD*AQ(K|zY`3noeTLM)`VZBx_3o;?w#Q|?SdYFex1K|}`3s|ZL_h!l diff --git a/Win64/proj/actor/Debug/actor.tlog/bscmake.read.1.tlog b/Win64/proj/actor/Debug/actor.tlog/bscmake.read.1.tlog deleted file mode 100644 index 72e8c734c7a4c2750177239e89b4d526e2f4d165..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3134 zcmc(g-A=+l5Jtai6JLc3HC}kvKLKfJ(_JJOqA$X;180hfsFiv%B~3T8ZMSD;c4xlB z{#}`#v{kM`uiT|-HOy@+v{Ya$7`Iw$&iqji*o|7gc)?0oAF*3(`$wvkrr(}VSe^2I z=S0dh!;2-Cc|R^KA?BReEJMMa{S2ql2iZ=^ebHs!GFxlGti3uvA^#;_mF$P*!?NPN zA2Uv0~jh2e80WP=d3Z$R_LlYC)Txlb_0~GtC{G|ijW#= zc1-4qp7a;LIT~ZN0>X42c0l4Dk??X#e~SGLiWS@(B-g8n65mE^IZgR@$Uct diff --git a/Win64/proj/actor/Debug/actor.vcxproj.FileListAbsolute.txt b/Win64/proj/actor/Debug/actor.vcxproj.FileListAbsolute.txt deleted file mode 100644 index e69de29bb2..0000000000 From c833271c033b451d3def0fdfe7afd178fae9b281 Mon Sep 17 00:00:00 2001 From: alec0498 Date: Wed, 23 Jul 2025 12:26:54 +0200 Subject: [PATCH 185/261] remove vs mod files 2 --- Win64/OpenSees.sln | 232 +---------------------- Win64/proj/actor/actor.vcxproj | 164 ---------------- Win64/proj/openSeesPy/OpenSeesPy.vcxproj | 2 +- Win64/proj/quickMain/quickMain.vcxproj | 4 +- 4 files changed, 5 insertions(+), 397 deletions(-) diff --git a/Win64/OpenSees.sln b/Win64/OpenSees.sln index 5f17bf8677..c36a6f938f 100644 --- a/Win64/OpenSees.sln +++ b/Win64/OpenSees.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.12.35527.113 d17.12 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32413.511 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "actor", "proj\actor\actor.vcxproj", "{D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}" EndProject @@ -60,582 +60,354 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "quickMain", "proj\quickMain EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug.DLL|Win32 = Debug.DLL|Win32 Debug.DLL|x64 = Debug.DLL|x64 Debug.DLL|x86 = Debug.DLL|x86 - Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 - Release.DLL|Win32 = Release.DLL|Win32 Release.DLL|x64 = Release.DLL|x64 Release.DLL|x86 = Release.DLL|x86 - Release|Win32 = Release|Win32 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|Win32 - {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug.DLL|Win32.Build.0 = Debug.DLL|Win32 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug|Win32.ActiveCfg = Debug|Win32 - {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug|Win32.Build.0 = Debug|Win32 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug|x64.ActiveCfg = Debug|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug|x64.Build.0 = Debug|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Debug|x86.ActiveCfg = Debug|x64 - {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release.DLL|Win32.ActiveCfg = Release.DLL|Win32 - {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release.DLL|Win32.Build.0 = Release.DLL|Win32 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release.DLL|x64.Build.0 = Release.DLL|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release|Win32.ActiveCfg = Release|Win32 - {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release|Win32.Build.0 = Release|Win32 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release|x64.ActiveCfg = Release|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release|x64.Build.0 = Release|x64 {D9026BC0-B5BF-3BE9-E9CB-3491638F2C38}.Release|x86.ActiveCfg = Release|x64 - {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug|Win32.ActiveCfg = Debug|x64 - {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug|Win32.Build.0 = Debug|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug|x64.ActiveCfg = Debug|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug|x64.Build.0 = Debug|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Debug|x86.ActiveCfg = Debug|x64 - {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release.DLL|x64.Build.0 = Release.DLL|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release|Win32.ActiveCfg = Release|x64 - {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release|Win32.Build.0 = Release|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release|x64.ActiveCfg = Release|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release|x64.Build.0 = Release|x64 {71832CB0-ED48-1CAF-ECB3-B9AD954D38E5}.Release|x86.ActiveCfg = Release|x64 - {310DC5FA-1613-D953-4008-15056952E467}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {310DC5FA-1613-D953-4008-15056952E467}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {310DC5FA-1613-D953-4008-15056952E467}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {310DC5FA-1613-D953-4008-15056952E467}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {310DC5FA-1613-D953-4008-15056952E467}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {310DC5FA-1613-D953-4008-15056952E467}.Debug|Win32.ActiveCfg = Debug|x64 - {310DC5FA-1613-D953-4008-15056952E467}.Debug|Win32.Build.0 = Debug|x64 {310DC5FA-1613-D953-4008-15056952E467}.Debug|x64.ActiveCfg = Debug|x64 {310DC5FA-1613-D953-4008-15056952E467}.Debug|x64.Build.0 = Debug|x64 {310DC5FA-1613-D953-4008-15056952E467}.Debug|x86.ActiveCfg = Debug|x64 - {310DC5FA-1613-D953-4008-15056952E467}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {310DC5FA-1613-D953-4008-15056952E467}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {310DC5FA-1613-D953-4008-15056952E467}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {310DC5FA-1613-D953-4008-15056952E467}.Release.DLL|x64.Build.0 = Release.DLL|x64 {310DC5FA-1613-D953-4008-15056952E467}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {310DC5FA-1613-D953-4008-15056952E467}.Release|Win32.ActiveCfg = Release|x64 - {310DC5FA-1613-D953-4008-15056952E467}.Release|Win32.Build.0 = Release|x64 {310DC5FA-1613-D953-4008-15056952E467}.Release|x64.ActiveCfg = Release|x64 {310DC5FA-1613-D953-4008-15056952E467}.Release|x64.Build.0 = Release|x64 {310DC5FA-1613-D953-4008-15056952E467}.Release|x86.ActiveCfg = Release|x64 - {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug|Win32.ActiveCfg = Debug|x64 - {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug|Win32.Build.0 = Debug|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug|x64.ActiveCfg = Debug|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug|x64.Build.0 = Debug|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Debug|x86.ActiveCfg = Debug|x64 - {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release.DLL|x64.Build.0 = Release.DLL|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release|Win32.ActiveCfg = Release|x64 - {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release|Win32.Build.0 = Release|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release|x64.ActiveCfg = Release|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release|x64.Build.0 = Release|x64 {63511522-EBEF-1468-AD6B-0F365CA756A9}.Release|x86.ActiveCfg = Release|x64 - {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug|Win32.ActiveCfg = Debug|x64 - {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug|Win32.Build.0 = Debug|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug|x64.ActiveCfg = Debug|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug|x64.Build.0 = Debug|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Debug|x86.ActiveCfg = Debug|x64 - {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release.DLL|x64.Build.0 = Release.DLL|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release|Win32.ActiveCfg = Release|x64 - {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release|Win32.Build.0 = Release|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release|x64.ActiveCfg = Release|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release|x64.Build.0 = Release|x64 {542B4EC8-400F-4BE5-A0A1-A53E8830606C}.Release|x86.ActiveCfg = Release|x64 - {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug|Win32.ActiveCfg = Debug|x64 - {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug|Win32.Build.0 = Debug|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug|x64.ActiveCfg = Debug|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug|x64.Build.0 = Debug|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Debug|x86.ActiveCfg = Debug|x64 - {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release.DLL|x64.Build.0 = Release.DLL|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release|Win32.ActiveCfg = Release|x64 - {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release|Win32.Build.0 = Release|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release|x64.ActiveCfg = Release|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release|x64.Build.0 = Release|x64 {0775A4B2-93D2-4440-83B7-C1DF58021602}.Release|x86.ActiveCfg = Release|x64 - {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug|Win32.ActiveCfg = Debug|x64 - {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug|Win32.Build.0 = Debug|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug|x64.ActiveCfg = Debug|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug|x64.Build.0 = Debug|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Debug|x86.ActiveCfg = Debug|x64 - {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release.DLL|x64.Build.0 = Release.DLL|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release|Win32.ActiveCfg = Release|x64 - {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release|Win32.Build.0 = Release|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release|x64.ActiveCfg = Release|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release|x64.Build.0 = Release|x64 {2B908396-B6B4-C511-D0E2-87620530AAA2}.Release|x86.ActiveCfg = Release|x64 - {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug|Win32.ActiveCfg = Debug|x64 - {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug|Win32.Build.0 = Debug|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug|x64.ActiveCfg = Debug|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug|x64.Build.0 = Debug|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Debug|x86.ActiveCfg = Debug|x64 - {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release.DLL|x64.Build.0 = Release.DLL|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release|Win32.ActiveCfg = Release|x64 - {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release|Win32.Build.0 = Release|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release|x64.ActiveCfg = Release|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release|x64.Build.0 = Release|x64 {10BE1D68-585D-6B54-0C7F-0CF2962C52F1}.Release|x86.ActiveCfg = Release|x64 - {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug.DLL|x86.ActiveCfg = Release|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug.DLL|x86.Build.0 = Release|x64 - {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug|Win32.ActiveCfg = Debug|x64 - {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug|Win32.Build.0 = Debug|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug|x64.ActiveCfg = Debug|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug|x64.Build.0 = Debug|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Debug|x86.ActiveCfg = Debug|x64 - {8062B50D-A609-33D0-8223-81D898DE05D5}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {8062B50D-A609-33D0-8223-81D898DE05D5}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release.DLL|x64.Build.0 = Release.DLL|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release.DLL|x86.ActiveCfg = Release|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release.DLL|x86.Build.0 = Release|x64 - {8062B50D-A609-33D0-8223-81D898DE05D5}.Release|Win32.ActiveCfg = Release|x64 - {8062B50D-A609-33D0-8223-81D898DE05D5}.Release|Win32.Build.0 = Release|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release|x64.ActiveCfg = Release|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release|x64.Build.0 = Release|x64 {8062B50D-A609-33D0-8223-81D898DE05D5}.Release|x86.ActiveCfg = Release|x64 - {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug|Win32.ActiveCfg = Debug|x64 - {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug|Win32.Build.0 = Debug|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug|x64.ActiveCfg = Debug|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug|x64.Build.0 = Debug|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Debug|x86.ActiveCfg = Debug|x64 - {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release.DLL|x64.Build.0 = Release.DLL|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release|Win32.ActiveCfg = Release|x64 - {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release|Win32.Build.0 = Release|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release|x64.ActiveCfg = Release|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release|x64.Build.0 = Release|x64 {771CF0B5-A9ED-0CBA-DCC2-94EE2FF499E8}.Release|x86.ActiveCfg = Release|x64 - {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug|Win32.ActiveCfg = Debug|x64 - {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug|Win32.Build.0 = Debug|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug|x64.ActiveCfg = Debug|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug|x64.Build.0 = Debug|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Debug|x86.ActiveCfg = Debug|x64 - {A6947A93-DFD1-060E-F426-AE10230F7861}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {A6947A93-DFD1-060E-F426-AE10230F7861}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Release.DLL|x64.Build.0 = Release.DLL|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {A6947A93-DFD1-060E-F426-AE10230F7861}.Release|Win32.ActiveCfg = Release|x64 - {A6947A93-DFD1-060E-F426-AE10230F7861}.Release|Win32.Build.0 = Release|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Release|x64.ActiveCfg = Release|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Release|x64.Build.0 = Release|x64 {A6947A93-DFD1-060E-F426-AE10230F7861}.Release|x86.ActiveCfg = Release|x64 - {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug|Win32.ActiveCfg = Debug|x64 - {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug|Win32.Build.0 = Debug|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug|x64.ActiveCfg = Debug|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug|x64.Build.0 = Debug|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Debug|x86.ActiveCfg = Debug|x64 - {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release.DLL|x64.Build.0 = Release.DLL|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release|Win32.ActiveCfg = Release|x64 - {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release|Win32.Build.0 = Release|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release|x64.ActiveCfg = Release|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release|x64.Build.0 = Release|x64 {B3B28EAB-160F-635A-CD8A-4C4BAA55CF78}.Release|x86.ActiveCfg = Release|x64 - {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug|Win32.ActiveCfg = Debug|x64 - {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug|Win32.Build.0 = Debug|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug|x64.ActiveCfg = Debug|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug|x64.Build.0 = Debug|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Debug|x86.ActiveCfg = Debug|x64 - {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release.DLL|x64.Build.0 = Release.DLL|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release|Win32.ActiveCfg = Release|x64 - {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release|Win32.Build.0 = Release|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release|x64.ActiveCfg = Release|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release|x64.Build.0 = Release|x64 {A2422B53-1A88-CBC2-AAA3-3A727C91E852}.Release|x86.ActiveCfg = Release|x64 - {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug|Win32.ActiveCfg = Debug|x64 - {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug|Win32.Build.0 = Debug|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug|x64.ActiveCfg = Debug|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug|x64.Build.0 = Debug|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Debug|x86.ActiveCfg = Debug|x64 - {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release.DLL|x64.Build.0 = Release.DLL|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release|Win32.ActiveCfg = Release|x64 - {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release|Win32.Build.0 = Release|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release|x64.ActiveCfg = Release|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release|x64.Build.0 = Release|x64 {D4304671-12AD-A3AB-E4C8-90005C96311C}.Release|x86.ActiveCfg = Release|x64 - {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug|Win32.ActiveCfg = Debug|x64 - {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug|Win32.Build.0 = Debug|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug|x64.ActiveCfg = Debug|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug|x64.Build.0 = Debug|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Debug|x86.ActiveCfg = Debug|x64 - {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release.DLL|x64.Build.0 = Release.DLL|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release|Win32.ActiveCfg = Release|x64 - {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release|Win32.Build.0 = Release|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release|x64.ActiveCfg = Release|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release|x64.Build.0 = Release|x64 {C7EE51CA-305A-4F27-9CB0-85114FC32172}.Release|x86.ActiveCfg = Release|x64 - {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug|Win32.ActiveCfg = Debug|x64 - {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug|Win32.Build.0 = Debug|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug|x64.ActiveCfg = Debug|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug|x64.Build.0 = Debug|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Debug|x86.ActiveCfg = Debug|x64 - {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release.DLL|x64.Build.0 = Release.DLL|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release|Win32.ActiveCfg = Release|x64 - {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release|Win32.Build.0 = Release|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release|x64.ActiveCfg = Release|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release|x64.Build.0 = Release|x64 {DEBED636-6061-42B1-B277-FAB92DF0E446}.Release|x86.ActiveCfg = Release|x64 - {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug|Win32.ActiveCfg = Debug|x64 - {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug|Win32.Build.0 = Debug|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug|x64.ActiveCfg = Debug|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug|x64.Build.0 = Debug|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Debug|x86.ActiveCfg = Debug|x64 - {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release.DLL|x64.Build.0 = Release.DLL|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release|Win32.ActiveCfg = Release|x64 - {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release|Win32.Build.0 = Release|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release|x64.ActiveCfg = Release|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release|x64.Build.0 = Release|x64 {D1C15272-E650-4BE0-9DAF-B79F984D623D}.Release|x86.ActiveCfg = Release|x64 - {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug|Win32.ActiveCfg = Debug|x64 - {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug|Win32.Build.0 = Debug|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug|x64.ActiveCfg = Debug|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug|x64.Build.0 = Debug|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Debug|x86.ActiveCfg = Debug|x64 - {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release.DLL|x64.Build.0 = Release.DLL|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release|Win32.ActiveCfg = Release|x64 - {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release|Win32.Build.0 = Release|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release|x64.ActiveCfg = Release|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release|x64.Build.0 = Release|x64 {5BB0E918-CE81-7129-15F5-2A3470E92427}.Release|x86.ActiveCfg = Release|x64 - {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug|Win32.ActiveCfg = Debug|x64 - {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug|Win32.Build.0 = Debug|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug|x64.ActiveCfg = Debug|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug|x64.Build.0 = Debug|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Debug|x86.ActiveCfg = Debug|x64 - {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release.DLL|x64.Build.0 = Release.DLL|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release|Win32.ActiveCfg = Release|x64 - {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release|Win32.Build.0 = Release|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release|x64.ActiveCfg = Release|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release|x64.Build.0 = Release|x64 {85F9E3F0-A6E0-6A77-9683-7150B4BE5A09}.Release|x86.ActiveCfg = Release|x64 - {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug|Win32.ActiveCfg = Debug|x64 - {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug|Win32.Build.0 = Debug|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug|x64.ActiveCfg = Debug|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug|x64.Build.0 = Debug|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Debug|x86.ActiveCfg = Debug|x64 - {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release.DLL|x64.Build.0 = Release.DLL|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release|Win32.ActiveCfg = Release|x64 - {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release|Win32.Build.0 = Release|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release|x64.ActiveCfg = Release|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release|x64.Build.0 = Release|x64 {C7780C72-E360-AB77-79D6-F5CEB52C2F00}.Release|x86.ActiveCfg = Release|x64 - {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug|Win32.ActiveCfg = Debug|x64 - {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug|Win32.Build.0 = Debug|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug|x64.ActiveCfg = Debug|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug|x64.Build.0 = Debug|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Debug|x86.ActiveCfg = Debug|x64 - {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release.DLL|x64.Build.0 = Release.DLL|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release|Win32.ActiveCfg = Release|x64 - {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release|Win32.Build.0 = Release|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release|x64.ActiveCfg = Release|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release|x64.Build.0 = Release|x64 {767A7605-A645-C010-DCDD-F981DD6E0A61}.Release|x86.ActiveCfg = Release|x64 - {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug|Win32.ActiveCfg = Debug|x64 - {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug|Win32.Build.0 = Debug|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug|x64.ActiveCfg = Debug|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug|x64.Build.0 = Debug|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Debug|x86.ActiveCfg = Debug|x64 - {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release.DLL|x64.Build.0 = Release.DLL|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release|Win32.ActiveCfg = Release|x64 - {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release|Win32.Build.0 = Release|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release|x64.ActiveCfg = Release|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release|x64.Build.0 = Release|x64 {931A4DE5-3AF2-18C7-6370-37E5DEDA392A}.Release|x86.ActiveCfg = Release|x64 - {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug|Win32.ActiveCfg = Debug|x64 - {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug|Win32.Build.0 = Debug|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug|x64.ActiveCfg = Debug|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug|x64.Build.0 = Debug|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Debug|x86.ActiveCfg = Debug|x64 - {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release.DLL|x64.Build.0 = Release.DLL|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release|Win32.ActiveCfg = Release|x64 - {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release|Win32.Build.0 = Release|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release|x64.ActiveCfg = Release|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release|x64.Build.0 = Release|x64 {E68180C9-479C-A9C1-3832-CEF06B7F9D8C}.Release|x86.ActiveCfg = Release|x64 - {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug|Win32.ActiveCfg = Debug|x64 - {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug|Win32.Build.0 = Debug|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug|x64.ActiveCfg = Debug|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug|x64.Build.0 = Debug|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Debug|x86.ActiveCfg = Debug|x64 - {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release.DLL|x64.Build.0 = Release.DLL|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release|Win32.ActiveCfg = Release|x64 - {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release|Win32.Build.0 = Release|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release|x64.ActiveCfg = Release|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release|x64.Build.0 = Release|x64 {3285D0EF-7169-F5BE-C3AC-3752AAEBB765}.Release|x86.ActiveCfg = Release|x64 - {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug|Win32.ActiveCfg = Debug|x64 - {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug|Win32.Build.0 = Debug|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug|x64.ActiveCfg = Debug|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug|x64.Build.0 = Debug|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Debug|x86.ActiveCfg = Debug|x64 - {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release.DLL|x64.Build.0 = Release.DLL|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release|Win32.ActiveCfg = Release|x64 - {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release|Win32.Build.0 = Release|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release|x64.ActiveCfg = Release|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release|x64.Build.0 = Release|x64 {B4F48ABB-2789-4753-AA82-7E2C1954D31A}.Release|x86.ActiveCfg = Release|x64 - {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug|Win32.ActiveCfg = Debug|x64 - {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug|Win32.Build.0 = Debug|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug|x64.ActiveCfg = Debug|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug|x64.Build.0 = Debug|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Debug|x86.ActiveCfg = Debug|x64 - {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release.DLL|x64.Build.0 = Release.DLL|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release|Win32.ActiveCfg = Release|x64 - {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release|Win32.Build.0 = Release|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release|x64.ActiveCfg = Release|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release|x64.Build.0 = Release|x64 {72CEB368-613B-3977-7BE6-0155A5F1DDBC}.Release|x86.ActiveCfg = Release|x64 - {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug.DLL|Win32.ActiveCfg = Debug.DLL|x64 - {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug.DLL|Win32.Build.0 = Debug.DLL|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug.DLL|x86.ActiveCfg = Debug.DLL|x64 - {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug|Win32.ActiveCfg = Debug|x64 - {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug|Win32.Build.0 = Debug|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug|x64.ActiveCfg = Debug|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug|x64.Build.0 = Debug|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Debug|x86.ActiveCfg = Debug|x64 - {F26CA968-C7ED-4246-A732-388C23BF8822}.Release.DLL|Win32.ActiveCfg = Release.DLL|x64 - {F26CA968-C7ED-4246-A732-388C23BF8822}.Release.DLL|Win32.Build.0 = Release.DLL|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Release.DLL|x64.Build.0 = Release.DLL|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Release.DLL|x86.ActiveCfg = Release.DLL|x64 - {F26CA968-C7ED-4246-A732-388C23BF8822}.Release|Win32.ActiveCfg = Release|x64 - {F26CA968-C7ED-4246-A732-388C23BF8822}.Release|Win32.Build.0 = Release|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Release|x64.ActiveCfg = Release|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Release|x64.Build.0 = Release|x64 {F26CA968-C7ED-4246-A732-388C23BF8822}.Release|x86.ActiveCfg = Release|x64 - {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug.DLL|Win32.ActiveCfg = Debug|Win32 - {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug.DLL|Win32.Build.0 = Debug|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug.DLL|x64.ActiveCfg = Debug|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug.DLL|x64.Build.0 = Debug|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug.DLL|x86.ActiveCfg = Debug|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug.DLL|x86.Build.0 = Debug|Win32 - {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug|Win32.ActiveCfg = Debug|Win32 - {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug|Win32.Build.0 = Debug|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug|x64.ActiveCfg = Debug|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug|x64.Build.0 = Debug|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug|x86.ActiveCfg = Debug|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Debug|x86.Build.0 = Debug|Win32 - {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release.DLL|Win32.ActiveCfg = Release|Win32 - {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release.DLL|Win32.Build.0 = Release|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release.DLL|x64.ActiveCfg = Release|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release.DLL|x64.Build.0 = Release|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release.DLL|x86.ActiveCfg = Release|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release.DLL|x86.Build.0 = Release|Win32 - {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release|Win32.ActiveCfg = Release|Win32 - {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release|Win32.Build.0 = Release|Win32 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release|x64.ActiveCfg = Release|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release|x64.Build.0 = Release|x64 {79627CFD-A1B2-437B-BA21-2D2D67378B4D}.Release|x86.ActiveCfg = Release|Win32 diff --git a/Win64/proj/actor/actor.vcxproj b/Win64/proj/actor/actor.vcxproj index addadd0f1f..fed81d6829 100644 --- a/Win64/proj/actor/actor.vcxproj +++ b/Win64/proj/actor/actor.vcxproj @@ -1,34 +1,18 @@  - - Debug.DLL - Win32 - Debug.DLL x64 - - Debug - Win32 - Debug x64 - - Release.DLL - Win32 - Release.DLL x64 - - Release - Win32 - Release x64 @@ -46,68 +30,36 @@ MultiByte v143 - - StaticLibrary - MultiByte - v143 - StaticLibrary MultiByte v142 - - StaticLibrary - MultiByte - v142 - StaticLibrary MultiByte v142 - - StaticLibrary - MultiByte - v142 - StaticLibrary MultiByte v143 - - StaticLibrary - MultiByte - v143 - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 @@ -149,35 +101,6 @@ .\..\..\obj\actor\release\$(MSBuildProjectName).log - - - OnlyExplicitInline - ..\..\..\src\material\section\repres\section;..\..\..\src\element\surfaceLoad;..\..\..\src\damping;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\backbone;..\..\..\src\material\section\integration;..\..\..\SRC\element\RockingBC;..\..\..\SRC\element\PFEMElement;..\..\..\src\material\uniaxial\limitState;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\material\nD\stressDensityModel;..\..\..\src\element\twoNodeLink;..\..\..\src\element\elastomericBearing;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\element\triangle;..\..\..\SRC\domain\pattern\drm;..\..\..\src\material\uniaxial\snap;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\api;..\..\..\SRC\element\upU;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\SRC\tcl;..\..\..\SRC\element\UP-ucsd;..\..\..\src\actor\machineBroker;..\..\..\SRC\actor\shadow;..\..\..\src\package;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\shell;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\section\fiber;..\..\..\src\element\fourNodeQuad;..\..\..\src\material\backbone;..\..\..\src\material\state;..\..\..\src\material\state\stiffness;..\..\..\src\material\state\deformation;..\..\..\src\material\state\strength;..\..\..\src\material\nD;..\..\..\src\coordTransformation;..\..\..\src\domain\groundMotion;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\analysis\integrator;..\..\..\src\analysis\fe_ele;..\..\..\src\analysis\dof_grp;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\symSparse;..\..\..\src\analysis\model\simple;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\analysis\algorithm\domaindecompAlgo;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\domain\domain\single;..\..\..\src\convergenceTest;..\..\..\src\analysis\analysis;..\..\..\src\recorder;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\analysis\algorithm;..\..\..\src\system_of_eqn;..\..\..\src\graph\graph;..\..\..\src\graph\numberer;..\..\..\src\analysis\numberer;..\..\..\src\analysis\fe_ele\transformation;..\..\..\src\analysis\fe_ele\lagrange;..\..\..\src\analysis\fe_ele\penalty;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\domain\subdomain;..\..\..\src\domain\constraints;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src\domain\node;..\..\..\src\element;..\..\..\src\matrix;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src;..\..\..\src\actor\actor;..\..\..\src\analysis\handler;..\..\..\src\material\section;..\..\..\src\modelbuilder;..\..\..\src\renderer;..\..\..\src\modelbuilder\tcl;..\..\..\src\tagged\storage;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\patch;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfBar;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfLayer;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\cell;..\..\..\src\element\nonlinearBeamColumn;..\..\..\src\element\nonlinearBEamCOlumn\quadrule;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\nonlinearBeamColumn\fiber;..\..\..\src\material;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\domain\load;..\..\..\src\domain\pattern;..\..\..\src\element\zeroLength;..\..\..\src\element\feap;..\..\..\src\element\truss;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material\uniaxial;..\..\..\src\actor\address;..\..\..\src\actor\message;..\..\..\src\nDarray;..\..\..\src\material\uniaxial\fedeas;..\..\..\src\material\uniaxial\drain;..\..\..\src\element\8nbrick;..\..\..\src\element\brick;..\..\..\src\material\uniaxial\py;..\..\..\src\material\nd\soil;..\..\..\src\element\joint;..\..\..\src\material\nd\feap;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreaded - true - .\..\..\obj\actor\release/actor.pch - .\..\..\obj\actor\release/ - .\..\..\obj\actor\release/ - .\..\..\obj\actor\release/ - Level3 - true - Cdecl - Default - - - .\..\..\lib\release\actor.lib - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - .\..\..\obj\actor\release\$(MSBuildProjectName).log - - OnlyExplicitInline @@ -207,35 +130,6 @@ .\..\..\obj\actor\release\$(MSBuildProjectName).log - - - OnlyExplicitInline - ..\..\..\src\material\section\repres\section;..\..\..\src\element\surfaceLoad;..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\backbone;..\..\..\src\material\section\integration;..\..\..\SRC\element\RockingBC;..\..\..\SRC\element\PFEMElement;..\..\..\src\material\uniaxial\limitState;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\material\nD\stressDensityModel;..\..\..\src\element\twoNodeLink;..\..\..\src\element\elastomericBearing;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\element\triangle;..\..\..\SRC\domain\pattern\drm;..\..\..\src\material\uniaxial\snap;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\api;..\..\..\SRC\element\upU;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\SRC\tcl;..\..\..\SRC\element\UP-ucsd;..\..\..\src\actor\machineBroker;..\..\..\SRC\actor\shadow;..\..\..\src\package;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\shell;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\beamWithHinges;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\section\fiber;..\..\..\src\element\fourNodeQuad;..\..\..\src\material\backbone;..\..\..\src\material\state;..\..\..\src\material\state\stiffness;..\..\..\src\material\state\deformation;..\..\..\src\material\state\strength;..\..\..\src\material\nD;..\..\..\src\coordTransformation;..\..\..\src\domain\groundMotion;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\analysis\integrator;..\..\..\src\analysis\fe_ele;..\..\..\src\analysis\dof_grp;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\symSparse;..\..\..\src\analysis\model\simple;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\analysis\algorithm\domaindecompAlgo;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\domain\domain\single;..\..\..\src\convergenceTest;..\..\..\src\analysis\analysis;..\..\..\src\recorder;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\analysis\algorithm;..\..\..\src\system_of_eqn;..\..\..\src\graph\graph;..\..\..\src\graph\numberer;..\..\..\src\analysis\numberer;..\..\..\src\analysis\fe_ele\transformation;..\..\..\src\analysis\fe_ele\lagrange;..\..\..\src\analysis\fe_ele\penalty;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\domain\subdomain;..\..\..\src\domain\constraints;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src\domain\node;..\..\..\src\element;..\..\..\src\matrix;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src;..\..\..\src\actor\actor;..\..\..\src\analysis\handler;..\..\..\src\material\section;..\..\..\src\modelbuilder;..\..\..\src\renderer;..\..\..\src\modelbuilder\tcl;..\..\..\src\tagged\storage;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\patch;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfBar;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfLayer;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\cell;..\..\..\src\element\nonlinearBeamColumn;..\..\..\src\element\nonlinearBEamCOlumn\quadrule;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\nonlinearBeamColumn\fiber;..\..\..\src\material;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\domain\load;..\..\..\src\domain\pattern;..\..\..\src\element\zeroLength;..\..\..\src\element\feap;..\..\..\src\element\truss;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material\uniaxial;..\..\..\src\actor\address;..\..\..\src\actor\message;..\..\..\src\nDarray;..\..\..\src\material\uniaxial\fedeas;..\..\..\src\material\uniaxial\drain;..\..\..\src\element\8nbrick;..\..\..\src\element\brick;..\..\..\src\material\uniaxial\py;..\..\..\src\material\nd\soil;..\..\..\src\element\joint;..\..\..\src\material\nd\feap;c:\Program Files\tcl;c:\Program Files\tcl\include;..\..\..\src\damping;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - .\..\..\obj\actor\release/actor.pch - .\..\..\obj\actor\release/ - .\..\..\obj\actor\release/ - .\..\..\obj\actor\release/ - Level3 - true - Cdecl - Default - - - .\..\..\lib\release\actor.lib - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - .\..\..\obj\actor\release\$(MSBuildProjectName).log - - Disabled @@ -265,35 +159,6 @@ .\..\..\obj\actor\debug\$(MSBuildProjectName).log - - - Disabled - ..\..\..\src\material\section\repres\section;..\..\..\src\element\surfaceLoad;..\..\..\src\damping;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\backbone;..\..\..\src\material\section\integration;..\..\..\SRC\element\RockingBC;..\..\..\SRC\element\PFEMElement;..\..\..\src\material\uniaxial\limitState;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\material\nD\stressDensityModel;..\..\..\src\element\twoNodeLink;..\..\..\src\element\elastomericBearing;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\element\triangle;..\..\..\SRC\domain\pattern\drm;..\..\..\src\material\uniaxial\snap;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\api;..\..\..\SRC\element\upU;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\SRC\tcl;..\..\..\SRC\element\UP-ucsd;..\..\..\src\actor\machineBroker;..\..\..\SRC\actor\shadow;..\..\..\src\package;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\shell;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\section\fiber;..\..\..\src\element\fourNodeQuad;..\..\..\src\material\backbone;..\..\..\src\material\state;..\..\..\src\material\state\stiffness;..\..\..\src\material\state\deformation;..\..\..\src\material\state\strength;..\..\..\src\material\nD;..\..\..\src\coordTransformation;..\..\..\src\domain\groundMotion;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\analysis\integrator;..\..\..\src\analysis\fe_ele;..\..\..\src\analysis\dof_grp;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\symSparse;..\..\..\src\analysis\model\simple;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\analysis\algorithm\domaindecompAlgo;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\domain\domain\single;..\..\..\src\convergenceTest;..\..\..\src\analysis\analysis;..\..\..\src\recorder;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\analysis\algorithm;..\..\..\src\system_of_eqn;..\..\..\src\graph\graph;..\..\..\src\graph\numberer;..\..\..\src\analysis\numberer;..\..\..\src\analysis\fe_ele\transformation;..\..\..\src\analysis\fe_ele\lagrange;..\..\..\src\analysis\fe_ele\penalty;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\domain\subdomain;..\..\..\src\domain\constraints;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src\domain\node;..\..\..\src\element;..\..\..\src\matrix;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src;..\..\..\src\actor\actor;..\..\..\src\analysis\handler;..\..\..\src\material\section;..\..\..\src\modelbuilder;..\..\..\src\renderer;..\..\..\src\modelbuilder\tcl;..\..\..\src\tagged\storage;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\patch;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfBar;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfLayer;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\cell;..\..\..\src\element\nonlinearBeamColumn;..\..\..\src\element\nonlinearBEamCOlumn\quadrule;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\nonlinearBeamColumn\fiber;..\..\..\src\material;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\domain\load;..\..\..\src\domain\pattern;..\..\..\src\element\zeroLength;..\..\..\src\element\feap;..\..\..\src\element\truss;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material\uniaxial;..\..\..\src\actor\address;..\..\..\src\actor\message;..\..\..\src\nDarray;..\..\..\src\material\uniaxial\fedeas;..\..\..\src\material\uniaxial\drain;..\..\..\src\element\8nbrick;..\..\..\src\element\brick;..\..\..\src\material\uniaxial\py;..\..\..\src\material\nd\soil;..\..\..\src\element\joint;..\..\..\src\material\nd\feap;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) - _DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebug - .\..\..\obj\actor\debug/actor.pch - .\..\..\obj\actor\debug/ - .\..\..\obj\actor\debug/ - .\..\..\obj\actor\debug/ - true - Level3 - true - ProgramDatabase - Default - EnableFastChecks - - - .\..\..\lib\debug\actor.lib - true - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - .\..\..\obj\actor\debug\$(MSBuildProjectName).log - - Disabled @@ -323,35 +188,6 @@ .\..\..\obj\actor\debug\$(MSBuildProjectName).log - - - Disabled - ..\..\..\src\material\section\repres\section;..\..\..\src\element\surfaceLoad;..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\backbone;..\..\..\src\material\section\integration;..\..\..\SRC\element\RockingBC;..\..\..\SRC\element\PFEMElement;..\..\..\src\material\uniaxial\limitState;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\material\nD\stressDensityModel;..\..\..\src\element\twoNodeLink;..\..\..\src\element\elastomericBearing;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\element\triangle;..\..\..\SRC\domain\pattern\drm;..\..\..\src\material\uniaxial\snap;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\api;..\..\..\SRC\element\upU;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\SRC\tcl;..\..\..\SRC\element\UP-ucsd;..\..\..\src\actor\machineBroker;..\..\..\SRC\actor\shadow;..\..\..\src\package;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\shell;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\beamWithHinges;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\section\fiber;..\..\..\src\element\fourNodeQuad;..\..\..\src\material\backbone;..\..\..\src\material\state;..\..\..\src\material\state\stiffness;..\..\..\src\material\state\deformation;..\..\..\src\material\state\strength;..\..\..\src\material\nD;..\..\..\src\coordTransformation;..\..\..\src\domain\groundMotion;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\analysis\integrator;..\..\..\src\analysis\fe_ele;..\..\..\src\analysis\dof_grp;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\symSparse;..\..\..\src\analysis\model\simple;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\analysis\algorithm\domaindecompAlgo;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\domain\domain\single;..\..\..\src\convergenceTest;..\..\..\src\analysis\analysis;..\..\..\src\recorder;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\analysis\algorithm;..\..\..\src\system_of_eqn;..\..\..\src\graph\graph;..\..\..\src\graph\numberer;..\..\..\src\analysis\numberer;..\..\..\src\analysis\fe_ele\transformation;..\..\..\src\analysis\fe_ele\lagrange;..\..\..\src\analysis\fe_ele\penalty;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\domain\subdomain;..\..\..\src\domain\constraints;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src\domain\node;..\..\..\src\element;..\..\..\src\matrix;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src;..\..\..\src\actor\actor;..\..\..\src\analysis\handler;..\..\..\src\material\section;..\..\..\src\modelbuilder;..\..\..\src\renderer;..\..\..\src\modelbuilder\tcl;..\..\..\src\tagged\storage;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\patch;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfBar;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\reinfLayer;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\cell;..\..\..\src\element\nonlinearBeamColumn;..\..\..\src\element\nonlinearBEamCOlumn\quadrule;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\nonlinearBeamColumn\fiber;..\..\..\src\material;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\domain\load;..\..\..\src\domain\pattern;..\..\..\src\element\zeroLength;..\..\..\src\element\feap;..\..\..\src\element\truss;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material\uniaxial;..\..\..\src\actor\address;..\..\..\src\actor\message;..\..\..\src\nDarray;..\..\..\src\material\uniaxial\fedeas;..\..\..\src\material\uniaxial\drain;..\..\..\src\element\8nbrick;..\..\..\src\element\brick;..\..\..\src\material\uniaxial\py;..\..\..\src\material\nd\soil;..\..\..\src\element\joint;..\..\..\src\material\nd\feap;c:\Program Files\tcl;c:\Program Files\tcl\include;..\..\..\src\damping;%(AdditionalIncludeDirectories) - _DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - .\..\..\obj\actor\debug/actor.pch - .\..\..\obj\actor\debug/ - .\..\..\obj\actor\debug/ - .\..\..\obj\actor\debug/ - true - Level3 - true - ProgramDatabase - Default - EnableFastChecks - - - .\..\..\lib\debug\actor.lib - true - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - .\..\..\obj\actor\debug\$(MSBuildProjectName).log - - diff --git a/Win64/proj/openSeesPy/OpenSeesPy.vcxproj b/Win64/proj/openSeesPy/OpenSeesPy.vcxproj index b566b5a4c7..20742a8ab4 100644 --- a/Win64/proj/openSeesPy/OpenSeesPy.vcxproj +++ b/Win64/proj/openSeesPy/OpenSeesPy.vcxproj @@ -198,7 +198,7 @@ actor.lib;analysis.lib;arpack.lib;blas.lib;cblas.lib;convergence.lib;cssparse.lib;damage.lib;database.lib;DoddRestrepo.lib;domain.lib;drain.lib;element.lib;feap.lib;fedeas.lib;glu32.lib;graph.lib;handler.lib;ifconsol.lib;lapack.lib;libifcoremt.lib;libmmt.lib;material.lib;matrix.lib;modelbuilder.lib;opengl32.lib;optimization.lib;PML.lib;python39.lib;recorder.lib;reliability.lib;renderer.lib;sdmuc.lib;superLU.lib;system.lib;tagged.lib;tcl.lib;tcl86t.lib;tk86t.lib;umfpackC.lib;utility.lib;wsock32.lib;%(AdditionalDependencies) $(OutDir)opensees.pyd true - C:\Program Files\Tcl\lib;C:\ProgramData\Anaconda3\libs;..\..\lib;C:\Develop\OpenSees\Win64\lib\debug;..\..\lib\debug;%(AdditionalLibraryDirectories) + C:\Program Files\Tcl\lib;C:\ProgramData\Anaconda3\libs;..\..\lib;..\..\lib\debug;%(AdditionalLibraryDirectories) libcmt.lib;%(IgnoreSpecificDefaultLibraries) true $(OutDir)$(ProjectName).pdb diff --git a/Win64/proj/quickMain/quickMain.vcxproj b/Win64/proj/quickMain/quickMain.vcxproj index e1fb528a0d..9d382c783c 100644 --- a/Win64/proj/quickMain/quickMain.vcxproj +++ b/Win64/proj/quickMain/quickMain.vcxproj @@ -32,7 +32,7 @@ Application MultiByte - v143 + v142 Application @@ -42,7 +42,7 @@ Application MultiByte - v143 + v142 From 3d58f570b08ab7fb3be02a4542e91edfaa3092c0 Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Wed, 23 Jul 2025 14:05:32 +0200 Subject: [PATCH 186/261] adding setparameter to wrapper materials --- SRC/material/nD/PlaneStressLayeredMaterial.cpp | 13 ++++++++++++- SRC/material/nD/PlaneStressLayeredMaterial.h | 2 +- SRC/material/nD/PlaneStressRebarMaterial.cpp | 5 +++++ SRC/material/nD/PlaneStressRebarMaterial.h | 2 ++ SRC/material/nD/PlateFiberMaterialThermal.cpp | 5 +++++ SRC/material/nD/PlateFiberMaterialThermal.h | 1 + SRC/material/nD/PlateFromPlaneStressMaterial.cpp | 8 +++++++- SRC/material/nD/PlateFromPlaneStressMaterial.h | 2 ++ .../nD/PlateFromPlaneStressMaterialThermal.cpp | 5 +++++ .../nD/PlateFromPlaneStressMaterialThermal.h | 2 ++ SRC/material/nD/PlateRebarMaterial.cpp | 5 +++++ SRC/material/nD/PlateRebarMaterial.h | 2 ++ SRC/material/nD/PlateRebarMaterialThermal.cpp | 5 +++++ SRC/material/nD/PlateRebarMaterialThermal.h | 2 ++ 14 files changed, 56 insertions(+), 3 deletions(-) diff --git a/SRC/material/nD/PlaneStressLayeredMaterial.cpp b/SRC/material/nD/PlaneStressLayeredMaterial.cpp index 5da7d56e8a..235352291c 100644 --- a/SRC/material/nD/PlaneStressLayeredMaterial.cpp +++ b/SRC/material/nD/PlaneStressLayeredMaterial.cpp @@ -440,7 +440,18 @@ PlaneStressLayeredMaterial::recvSelf(int commitTag, Channel &theChannel, FEM_Obj -Response* +int PlaneStressLayeredMaterial::setParameter(const char** argv, int argc, Parameter& param) +{ + // forward to the sub-materials + int res = -1; + for (int i = 0; i < nLayers; ++i) { + if (theFibers[i]->setParameter(argv, argc, param) == 0) + res = 0; + } + return res; +} + +Response* PlaneStressLayeredMaterial::setResponse (const char **argv, int argc, OPS_Stream &output) { diff --git a/SRC/material/nD/PlaneStressLayeredMaterial.h b/SRC/material/nD/PlaneStressLayeredMaterial.h index b9b2e08fc6..5442030edd 100644 --- a/SRC/material/nD/PlaneStressLayeredMaterial.h +++ b/SRC/material/nD/PlaneStressLayeredMaterial.h @@ -71,7 +71,7 @@ class PlaneStressLayeredMaterial : public NDMaterial { int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); - + int setParameter(const char** argv, int argc, Parameter& param); Response *setResponse (const char **argv, int argc, OPS_Stream &s); int getResponse (int responseID, Information &matInformation); diff --git a/SRC/material/nD/PlaneStressRebarMaterial.cpp b/SRC/material/nD/PlaneStressRebarMaterial.cpp index e81e364145..1cbfa9a0e5 100644 --- a/SRC/material/nD/PlaneStressRebarMaterial.cpp +++ b/SRC/material/nD/PlaneStressRebarMaterial.cpp @@ -381,5 +381,10 @@ PlaneStressRebarMaterial::recvSelf(int commitTag, Channel &theChannel, FEM_Objec opserr << "PlaneStressRebarMaterial::recvSelf() - failed to receive material1" << endln; return res; +} + +int PlaneStressRebarMaterial::setParameter(const char** argv, int argc, Parameter& param) +{ + return theMat->setParameter(argv, argc, param); } diff --git a/SRC/material/nD/PlaneStressRebarMaterial.h b/SRC/material/nD/PlaneStressRebarMaterial.h index 5c689568eb..bd51881486 100644 --- a/SRC/material/nD/PlaneStressRebarMaterial.h +++ b/SRC/material/nD/PlaneStressRebarMaterial.h @@ -66,6 +66,8 @@ class PlaneStressRebarMaterial: public NDMaterial{ int sendSelf(int commitTag, Channel &theChannel); int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + int setParameter(const char** argv, int argc, Parameter& param); + private : UniaxialMaterial *theMat ; double angle, c, s; diff --git a/SRC/material/nD/PlateFiberMaterialThermal.cpp b/SRC/material/nD/PlateFiberMaterialThermal.cpp index ce12e5a1f3..57b255dd79 100644 --- a/SRC/material/nD/PlateFiberMaterialThermal.cpp +++ b/SRC/material/nD/PlateFiberMaterialThermal.cpp @@ -578,6 +578,11 @@ PlateFiberMaterialThermal::recvSelf(int commitTag, Channel &theChannel, FEM_Obje opserr << "PlateFiberMaterialThermal::sendSelf() - failed to send vector material\n"; return res; +} + +int PlateFiberMaterialThermal::setParameter(const char** argv, int argc, Parameter& param) +{ + return theMaterial->setParameter(argv, argc, param); } diff --git a/SRC/material/nD/PlateFiberMaterialThermal.h b/SRC/material/nD/PlateFiberMaterialThermal.h index a9a3423e91..a56c3cecd5 100644 --- a/SRC/material/nD/PlateFiberMaterialThermal.h +++ b/SRC/material/nD/PlateFiberMaterialThermal.h @@ -100,6 +100,7 @@ class PlateFiberMaterialThermal: public NDMaterial{ int sendSelf(int commitTag, Channel &theChannel); int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + int setParameter(const char** argv, int argc, Parameter& param); private : diff --git a/SRC/material/nD/PlateFromPlaneStressMaterial.cpp b/SRC/material/nD/PlateFromPlaneStressMaterial.cpp index 89cd2b82d2..35dff87b09 100644 --- a/SRC/material/nD/PlateFromPlaneStressMaterial.cpp +++ b/SRC/material/nD/PlateFromPlaneStressMaterial.cpp @@ -404,5 +404,11 @@ PlateFromPlaneStressMaterial::setResponse(const char** argv, int argc, OPS_Strea return NDMaterial::setResponse(argv, argc, output); // not implemented, get default (zero) response from NDMaterial return theResponse; // implemented, get damage response from theMat -} +} + //setResponse - added by V.K. Papanikolaou [AUTh] - end + +int PlateFromPlaneStressMaterial::setParameter(const char** argv, int argc, Parameter& param) +{ + return theMat->setParameter(argv, argc, param); +} diff --git a/SRC/material/nD/PlateFromPlaneStressMaterial.h b/SRC/material/nD/PlateFromPlaneStressMaterial.h index 4e562cc2d8..b6420f8a40 100644 --- a/SRC/material/nD/PlateFromPlaneStressMaterial.h +++ b/SRC/material/nD/PlateFromPlaneStressMaterial.h @@ -96,6 +96,8 @@ class PlateFromPlaneStressMaterial: public NDMaterial{ Response* setResponse(const char** argv, int argc, OPS_Stream& s); //setResponse - added by V.K. Papanikolaou [AUTh] - end + int setParameter(const char** argv, int argc, Parameter& param); + private : NDMaterial *theMat ; //pointer to three dimensional material double gmod; diff --git a/SRC/material/nD/PlateFromPlaneStressMaterialThermal.cpp b/SRC/material/nD/PlateFromPlaneStressMaterialThermal.cpp index 40d920b055..79a7123bfc 100644 --- a/SRC/material/nD/PlateFromPlaneStressMaterialThermal.cpp +++ b/SRC/material/nD/PlateFromPlaneStressMaterialThermal.cpp @@ -373,6 +373,11 @@ PlateFromPlaneStressMaterialThermal::recvSelf(int commitTag, Channel &theChannel opserr << "PlateFromPlaneStressMaterialThermal::sendSelf() - failed to receive material1" << endln; return res; +} + +int PlateFromPlaneStressMaterialThermal::setParameter(const char** argv, int argc, Parameter& param) +{ + return theMat->setParameter(argv, argc, param); } diff --git a/SRC/material/nD/PlateFromPlaneStressMaterialThermal.h b/SRC/material/nD/PlateFromPlaneStressMaterialThermal.h index 25abaddda7..6c9db5990d 100644 --- a/SRC/material/nD/PlateFromPlaneStressMaterialThermal.h +++ b/SRC/material/nD/PlateFromPlaneStressMaterialThermal.h @@ -97,6 +97,8 @@ class PlateFromPlaneStressMaterialThermal: public NDMaterial{ int sendSelf(int commitTag, Channel &theChannel); int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + int setParameter(const char** argv, int argc, Parameter& param); + private : NDMaterial *theMat ; //pointer to three dimensional material double gmod; diff --git a/SRC/material/nD/PlateRebarMaterial.cpp b/SRC/material/nD/PlateRebarMaterial.cpp index fb4aacf539..a432dfa349 100644 --- a/SRC/material/nD/PlateRebarMaterial.cpp +++ b/SRC/material/nD/PlateRebarMaterial.cpp @@ -396,5 +396,10 @@ PlateRebarMaterial::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroke opserr << "PlateRebarMaterial::sendSelf() - failed to receive material1" << endln; return res; +} + +int PlateRebarMaterial::setParameter(const char** argv, int argc, Parameter& param) +{ + return theMat->setParameter(argv, argc, param); } diff --git a/SRC/material/nD/PlateRebarMaterial.h b/SRC/material/nD/PlateRebarMaterial.h index fee3c67ca5..d1166ddcda 100644 --- a/SRC/material/nD/PlateRebarMaterial.h +++ b/SRC/material/nD/PlateRebarMaterial.h @@ -93,6 +93,8 @@ class PlateRebarMaterial: public NDMaterial{ int sendSelf(int commitTag, Channel &theChannel); int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + int setParameter(const char** argv, int argc, Parameter& param); + private : UniaxialMaterial *theMat ; double angle, c, s; diff --git a/SRC/material/nD/PlateRebarMaterialThermal.cpp b/SRC/material/nD/PlateRebarMaterialThermal.cpp index 33939a752e..ced8f7e3c5 100644 --- a/SRC/material/nD/PlateRebarMaterialThermal.cpp +++ b/SRC/material/nD/PlateRebarMaterialThermal.cpp @@ -390,6 +390,11 @@ PlateRebarMaterialThermal::recvSelf(int commitTag, Channel &theChannel, FEM_Obje opserr << "PlateRebarMaterialThermal::sendSelf() - failed to receive material1" << endln; return res; +} + +int PlateRebarMaterialThermal::setParameter(const char** argv, int argc, Parameter& param) +{ + return theMat->setParameter(argv, argc, param); } diff --git a/SRC/material/nD/PlateRebarMaterialThermal.h b/SRC/material/nD/PlateRebarMaterialThermal.h index 746a471a7c..4eb0b7ee84 100644 --- a/SRC/material/nD/PlateRebarMaterialThermal.h +++ b/SRC/material/nD/PlateRebarMaterialThermal.h @@ -100,6 +100,8 @@ class PlateRebarMaterialThermal: public NDMaterial{ int sendSelf(int commitTag, Channel &theChannel); int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + int setParameter(const char** argv, int argc, Parameter& param); + private : UniaxialMaterial *theMat ; double angle, c, s; From 6e5a524589797cca30185b7e030a3b66ab727920 Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Wed, 23 Jul 2025 15:11:18 +0200 Subject: [PATCH 187/261] add lch function to FB element 3D --- .../forceBeamColumn/ForceBeamColumn3d.cpp | 18 ++++++++++++++++++ .../forceBeamColumn/ForceBeamColumn3d.h | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp b/SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp index 51add0480c..fc661adc9c 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp +++ b/SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp @@ -1072,6 +1072,9 @@ void double xL = xi[i]; double xL1 = xL-1.0; double wtL = wt[i]*L; + + // store the length of the current integration point + current_section_lch = wtL; // calculate total section forces // Ss = b*Se + bp*currDistrLoad; @@ -1302,6 +1305,10 @@ void } } + // reset it to the default (whole length) in case the getChatacteristiLength function + // is called in the wrong place + current_section_lch = L; + if (!isTorsion) { f(5,5) = DefaultLoverGJ; vr(5) = SeTrial(5)*DefaultLoverGJ; @@ -3670,6 +3677,17 @@ ForceBeamColumn3d::getResponse(int responseID, Information &eleInfo) else return -1; +} + +double ForceBeamColumn3d::getCharacteristicLength(void) +{ + // The default implementation of Element::getCharacteristicLength() + // returns the whole element length. + // However, FB element localizes only in a 1 integration point + // so we should return the i-th integration-point's length + if (current_section_lch > 0.0) + return current_section_lch; + return Element::getCharacteristicLength(); } int diff --git a/SRC/element/forceBeamColumn/ForceBeamColumn3d.h b/SRC/element/forceBeamColumn/ForceBeamColumn3d.h index 83c2f36bf6..72be657e66 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumn3d.h +++ b/SRC/element/forceBeamColumn/ForceBeamColumn3d.h @@ -124,6 +124,9 @@ class ForceBeamColumn3d: public Element Response *setResponse(const char **argv, int argc, OPS_Stream &s); int getResponse(int responseID, Information &eleInformation); + + // calculate the characteristic length for this element + double getCharacteristicLength(void); // AddingSensitivity:BEGIN ////////////////////////////////////////// int setParameter(const char **argv, int argc, Parameter ¶m); @@ -201,6 +204,10 @@ class ForceBeamColumn3d: public Element Damping *theDamping; + // this variable holds the length of the i-th integration point + // undergoing the update (FB element localizes at the integration point level) + double current_section_lch = 0.0; + static Matrix theMatrix; static Vector theVector; static double workArea[]; From c564bfdbfce7b8edf098d06780c557d688903771 Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Wed, 23 Jul 2025 15:17:54 +0200 Subject: [PATCH 188/261] add lch function to FB element 2D --- .../forceBeamColumn/ForceBeamColumn2d.cpp | 18 ++++++++++++++++++ .../forceBeamColumn/ForceBeamColumn2d.h | 9 ++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/SRC/element/forceBeamColumn/ForceBeamColumn2d.cpp b/SRC/element/forceBeamColumn/ForceBeamColumn2d.cpp index 8a5074d8eb..183cf72357 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumn2d.cpp +++ b/SRC/element/forceBeamColumn/ForceBeamColumn2d.cpp @@ -1347,6 +1347,9 @@ ForceBeamColumn2d::update() double xL1 = xL-1.0; double wtL = wt[i]*L; + // store the length of the current integration point + current_section_lch = wtL; + // calculate total section forces // Ss = b*Se + bp*currDistrLoad; // Ss.addMatrixVector(0.0, b[i], Se, 1.0); @@ -1510,6 +1513,10 @@ ForceBeamColumn2d::update() } } + // reset it to the default (whole length) in case the getChatacteristiLength function + // is called in the wrong place + current_section_lch = L; + // calculate element stiffness matrix // invert3by3Matrix(f, kv); if (f.Solve(I, kvTrial) < 0) @@ -3413,6 +3420,17 @@ ForceBeamColumn2d::getResponse(int responseID, Information &eleInfo) else return -1; +} + +double ForceBeamColumn2d::getCharacteristicLength(void) +{ + // The default implementation of Element::getCharacteristicLength() + // returns the whole element length. + // However, FB element localizes only in a 1 integration point + // so we should return the i-th integration-point's length + if (current_section_lch > 0.0) + return current_section_lch; + return Element::getCharacteristicLength(); } int diff --git a/SRC/element/forceBeamColumn/ForceBeamColumn2d.h b/SRC/element/forceBeamColumn/ForceBeamColumn2d.h index 486980c9d2..1c02712892 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumn2d.h +++ b/SRC/element/forceBeamColumn/ForceBeamColumn2d.h @@ -124,7 +124,10 @@ class ForceBeamColumn2d: public Element Response *setResponse(const char **argv, int argc, OPS_Stream &s); int getResponse(int responseID, Information &eleInformation); - + + // calculate the characteristic length for this element + double getCharacteristicLength(void); + // AddingSensitivity:BEGIN ////////////////////////////////////////// int setParameter(const char **argv, int argc, Parameter ¶m); int updateParameter(int parameterID, Information &info); @@ -197,6 +200,10 @@ class ForceBeamColumn2d: public Element Matrix *Ki; + // this variable holds the length of the i-th integration point + // undergoing the update (FB element localizes at the integration point level) + double current_section_lch = 0.0; + static Matrix theMatrix; static Vector theVector; static double workArea[]; From 2cf232868ab2140b7ecd7dcdc5fd13464ca81a9b Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Wed, 23 Jul 2025 10:31:58 -0700 Subject: [PATCH 189/261] remove commented out bits. --- .../Frame/BasicFrameTransf.h | 7 +- .../Frame/BasicFrameTransf.tpp | 170 ++++++---- .../Frame/EuclidFrameTransf.tpp | 43 ++- .../Frame/FrameTransform.h | 82 ++++- .../Frame/FrameTransform.tpp | 167 +++++----- .../Frame/Isometry/CrisfieldIsometry.h | 1 + .../Frame/LinearFrameTransf.h | 17 +- .../Frame/LinearFrameTransf.tpp | 303 +++++++++--------- SRC/runtime/commands/modeling/element.cpp | 160 ++------- SRC/runtime/commands/modeling/element.hpp | 99 +++--- .../commands/modeling/element/frames.cpp | 12 - SRC/runtime/commands/modeling/geomTransf.cpp | 7 +- SRC/utility/Unroll.h | 62 ++++ 13 files changed, 587 insertions(+), 543 deletions(-) create mode 100644 SRC/utility/Unroll.h diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.h b/SRC/coordTransformation/Frame/BasicFrameTransf.h index 613aa41e3f..a546a07b32 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.h +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.h @@ -74,8 +74,9 @@ class BasicFrameTransf3d: public CrdTransf // Sensitivity // const Vector & getBasicTrialDispShapeSensitivity() final; - const Vector & getBasicDisplTotalGrad(int grad) final; - const Vector &getGlobalResistingForceShapeSensitivity(const Vector &basicForce, const Vector &p0, int grad) final; + const Vector & getBasicDisplSensitivity(int grad) final; + const Vector &getGlobalResistingForceShapeSensitivity(const Vector &basicForce, + const Vector &p0, int grad) final; bool isShapeSensitivity() final; double getdLdh() final; double getd1overLdh() final; @@ -85,7 +86,7 @@ class BasicFrameTransf3d: public CrdTransf int sendSelf(int tag, Channel &) final; int recvSelf(int tag, Channel &, FEM_ObjectBroker &) final; const char *getClassType() const final { - return "BasicFrameTransf3d"; + return "BasicFrameTransf3d"; } // TaggedObject diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index 0d59c30009..6d86744134 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -19,9 +19,28 @@ #include #include #include "FrameTransform.h" +#include namespace OpenSees { +namespace { + template + const Vector& + ShapeBasic(const VectorND<2*ndf>& ul) + { + static VectorND<6+(ndf-6)*2> ub; + static Vector wrapper(ub); + ub[0] = ul[1*ndf+0]; // Nj + ub[1] = ul[0*ndf+5]; + ub[2] = ul[1*ndf+5]; + ub[3] = ul[0*ndf+4]; + ub[4] = ul[1*ndf+4]; + ub[5] = ul[1*ndf+3] - ul[0*ndf+3]; + return wrapper; + } +} + + template BasicFrameTransf3d::BasicFrameTransf3d(FrameTransform<2,ndf> *t) : CrdTransf(t->getTag(), 0), @@ -41,7 +60,6 @@ template int BasicFrameTransf3d::commitState() { - // linear.commit(); return t.commit(); } @@ -49,7 +67,6 @@ template int BasicFrameTransf3d::revertToLastCommit() { - // linear.revertToLastCommit(); return t.revertToLastCommit(); } @@ -57,7 +74,6 @@ template int BasicFrameTransf3d::revertToStart() { - // linear.revertToStart(); return t.revertToStart(); } @@ -65,7 +81,6 @@ template int BasicFrameTransf3d::update() { - // linear.update(); return t.update(); } @@ -125,20 +140,12 @@ BasicFrameTransf3d::getBasicTrialDisp() return wrapper; } + template const Vector & BasicFrameTransf3d::getBasicIncrDeltaDisp() { - static VectorND<6> ub; - static Vector wrapper(ub); - VectorND ul = t.getStateVariation(); - ub[0] = ul[1*ndf+0]; // Nj - ub[1] = ul[0*ndf+5]; - ub[2] = ul[1*ndf+5]; - ub[3] = ul[0*ndf+4]; - ub[4] = ul[1*ndf+4]; - ub[5] = ul[1*ndf+3] - ul[0*ndf+3]; - return wrapper; + return ShapeBasic(t.getStateVariation()); } template @@ -170,35 +177,33 @@ BasicFrameTransf3d::getGlobalResistingForce(const Vector &q_pres, const Vec static constexpr int nwm = ndf - 6; // Number of warping DOFs + static constexpr double c = 1.0; + static VectorND pl{}; + static Vector wrapper(pl); // to return reference pl.zero(); + pl[0*NDF+0] = -q_pres[jnx] + p0[0]*c; // Ni + pl[0*NDF+1] = p0[1]*c; // + pl[0*NDF+2] = p0[3]*c; // + pl[0*NDF+3] = -q_pres[jmx]; // Ti pl[0*NDF+4] = q_pres[imy]; pl[0*NDF+5] = q_pres[imz]; - pl[1*NDF+0] = q_pres[jnx]; // Nj - pl[1*NDF+3] = q_pres[jmx]; // Tj + pl[1*NDF+0] = q_pres[jnx]; // Nj + pl[1*NDF+1] = p0[2]*c; + pl[1*NDF+2] = p0[4]*c; + pl[1*NDF+3] = q_pres[jmx]; // Tj pl[1*NDF+4] = q_pres[jmy]; pl[1*NDF+5] = q_pres[jmz]; - for (int i=0; i pf; - pf.zero(); - pf[0*NDF + 0] = p0[0]; - pf[0*NDF + 1] = p0[1]; - pf[0*NDF + 2] = p0[3]; - pf[1*NDF + 1] = p0[2]; - pf[1*NDF + 2] = p0[4]; + if constexpr (nwm > 0) // Warping DOFs + for (int i=0; i::getGlobalStiffMatrix(const Matrix &kb, const Vector &q_ pl[1*NDF+3] = q_pres[jmx]; // Tj pl[1*NDF+4] = q_pres[jmy]; pl[1*NDF+5] = q_pres[jmz]; - for (int i=0; i 0) // Warping DOFs + for (int i=0; i kl; static Matrix Wrapper(kl); - kl.zero(); - for (int i=0; i= NBV) - continue; - for (int j=0; j= NBV) - continue; + Repeat ([&](auto j_) { + constexpr static int j = j_.value; + constexpr int jj = iq[j] >= 0 ? iq[j] : -iq[j]; + + Repeat ([&](auto i_) { + constexpr static int i = i_.value; + constexpr int ii = iq[i] >= 0 ? iq[i] : -iq[i]; + if constexpr (ii >= NBV || jj >= NBV) { + kl(i,j) = 0.0; + return; + } kl(i,j) = kb(ii, jj); - } - } + }); + }); - for (int i = 0; i < 2*NDF; i++) { + Repeat ([&](auto i_) { + constexpr static int i = i_.value; kl(0*NDF+0, i) = kl(i, 0*NDF+0) = i==0? kl(NDF+0, NDF+0): (i==3? kl(NDF+0, NDF+3) : -kl( NDF+0, i)); kl(0*NDF+3, i) = kl(i, 0*NDF+3) = i==0? kl(NDF+3, NDF+0): (i==3? kl(NDF+3, NDF+3) : -kl( NDF+3, i)); - } + }); t.push(kl, pl, Operation::Total); @@ -263,6 +273,7 @@ BasicFrameTransf3d::getInitialGlobalStiffMatrix(const Matrix &KB) static double kb[6][6]; // Basic stiffness static MatrixND<2*ndf,2*ndf> kl; // Local stiffness + double tmp[6][12]{}; for (int i = 0; i < 6; i++) @@ -283,7 +294,6 @@ BasicFrameTransf3d::getInitialGlobalStiffMatrix(const Matrix &KB) } kl.zero(); - // TODO: // Now compute T'_{bl}*(kb*T_{bl}) for (int i = 0; i < 12; i++) { kl( 0, i) = -tmp[0][i]; @@ -385,15 +395,45 @@ BasicFrameTransf3d::getd1overLdh() template const Vector & -BasicFrameTransf3d::getGlobalResistingForceShapeSensitivity(const Vector &pb, +BasicFrameTransf3d::getGlobalResistingForceShapeSensitivity(const Vector &q_pres, const Vector &p0, int gradNumber) { // return t.getGlobalResistingForceShapeSensitivity(pb, p0, gradNumber); - static VectorND<6> dub; - static Vector wrapper(dub); - opserr << "WARNING unimplemented method\n"; + static constexpr int nwm = ndf - 6; // Number of warping DOFs + + static constexpr double c = 1.0; + + static VectorND pl{}; + pl.zero(); + pl[0*NDF+0] = -q_pres[jnx] + p0[0]*c; // Ni + pl[0*NDF+1] = p0[1]*c; // + pl[0*NDF+2] = p0[3]*c; // + pl[0*NDF+3] = -q_pres[jmx]; // Ti + pl[0*NDF+4] = q_pres[imy]; + pl[0*NDF+5] = q_pres[imz]; + pl[1*NDF+0] = q_pres[jnx]; // Nj + pl[1*NDF+1] = p0[2]*c; + pl[1*NDF+2] = p0[4]*c; + pl[1*NDF+3] = q_pres[jmx]; // Tj + pl[1*NDF+4] = q_pres[jmy]; + pl[1*NDF+5] = q_pres[jmz]; + + if constexpr (nwm > 0) // Warping DOFs + for (int i=0; i dp; + static Vector wrapper(dp); // to return reference + dp.zero(); + + t.pushGrad(dp, pl); + return wrapper; } @@ -402,20 +442,18 @@ template const Vector & BasicFrameTransf3d::getBasicTrialDispShapeSensitivity() { - static VectorND<6> dub; - static Vector wrapper(dub); - opserr << "WARNING unimplemented method\n"; - return wrapper; + static VectorND<2*ndf> du; + t.pullFixedGrad(du); + return ShapeBasic(du); } template const Vector & -BasicFrameTransf3d::getBasicDisplTotalGrad(int gradNumber) +BasicFrameTransf3d::getBasicDisplSensitivity(int gradNumber) { - static VectorND<6> dub; - static Vector wrapper(dub); - opserr << "WARNING unimplemented method\n"; - return wrapper; + static VectorND<2*ndf> du; + t.pullTotalGrad(du, gradNumber); + return ShapeBasic(du); } diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index 578a5e2cfa..cdb981d9f6 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -132,6 +132,13 @@ EuclidFrameTransf::initialize(std::array& new_nodes) } +template +FrameTransform * +EuclidFrameTransf::getCopy() const +{ + return new EuclidFrameTransf(this->getTag(), vz, offsets); +} + template int @@ -208,7 +215,6 @@ EuclidFrameTransf::getNodePosition(int node) Vector3D u = this->pullPosition<&Node::getTrialDisp>(node); u -= basis.getPosition(); u += basis.getRotationDelta()^(nodes[node]->getCrds()); - return u; } @@ -285,12 +291,11 @@ EuclidFrameTransf::getStateVariation() } // (5) Logarithm of rotations - if (1) { // !(offset_flags & LogIter)) { - for (int i=0; i::getStateVariation() // Push // template -// VectorND int EuclidFrameTransf::push(VectorND&p, Operation op) { VectorND& pa = p; // 1) Logarithm - if (1) { // !(offset_flags & LogIter)) { - for (int i=0; i::push(VectorND&p, Operation op) // 3,4) Rotate and joint offsets - // pa = this->FrameTransform::pushConstant(pa); Matrix3D R = basis.getRotation(); for (int i=0; i::push(MatrixND&kb, const VectorND& pb, Operation op) { - MatrixND Kb = kb; VectorND p = pb; + MatrixND Kb = kb; if (1) {//!(offset_flags & LogIter)) { for (int i=0; i::push(MatrixND&kb, } } - // Kb = kb; + // Kl = A ^ k * A MatrixND& Kl = kb; const MatrixND A = getProjection(); @@ -396,6 +397,7 @@ EuclidFrameTransf::push(MatrixND&kb, const VectorND Ap = A^p; + // Kl += Kw * A Kb.zero(); VectorND<12> qwx{}; for (int i=0; i::push(MatrixND&kb, } // - // Kl += -W'*Pn'*A + // Kl += -W'*Pn'*A - Pnm * W // Kb.zero(); for (int j=0; j::push(MatrixND&kb, } -template -FrameTransform * -EuclidFrameTransf::getCopy() const -{ - return new EuclidFrameTransf(this->getTag(), vz, offsets); -} - // // Sensitivity diff --git a/SRC/coordTransformation/Frame/FrameTransform.h b/SRC/coordTransformation/Frame/FrameTransform.h index 7ca2611212..e8bbe70b5d 100644 --- a/SRC/coordTransformation/Frame/FrameTransform.h +++ b/SRC/coordTransformation/Frame/FrameTransform.h @@ -18,17 +18,25 @@ #ifndef FrameTransform_h #define FrameTransform_h -#include -#include #include #include #include #include +using OpenSees::VectorND; +using OpenSees::MatrixND; +using OpenSees::Matrix3D; class Information; class Response; class Node; +enum { + CRDTR_TAG_CorotFrameTransfWarping3d, + CRDTR_TAG_CorotFrameTransf3d, + CRDTR_TAG_LinearFrameTransf3d, + CRDTR_TAG_PDeltaFrameTransf3d +}; + enum { OffsetGlobal = 0, // 1<<0, OffsetLocal = 1, // 1<<1, @@ -46,38 +54,47 @@ template class FrameTransform : public TaggedObject { public: - constexpr static int ndm = 3; - -public: - FrameTransform(int tag) : TaggedObject(tag) {} + explicit FrameTransform(int tag) : TaggedObject(tag) {} + + enum class Operation { + Total = 0, + Logarithm = 1<<0, + LocalOffset = 1<<1, + Isometry = 1<<2, + Rotation, + GlobalOffset, + Exponential + }; virtual FrameTransform *getCopy() const =0; + virtual int initialize(std::array& nodes)=0; virtual int update() =0; virtual int commit() =0; virtual int revertToLastCommit() =0; virtual int revertToStart() =0; - virtual Vector3D getNodePosition(int tag) =0; virtual Vector3D getNodeRotationLogarithm(int tag) =0; - virtual VectorND getStateVariation() =0; + virtual VectorND getStateVariation() =0; // pull + virtual int push(VectorND&pl, Operation=0) =0; + virtual int push(MatrixND& kl, const VectorND& pl, Operation=0) =0; virtual double getInitialLength() =0; virtual double getDeformedLength() =0; virtual const std::array *getRigidOffsets() const =0; - virtual VectorND pushResponse(VectorND&pl) =0; - virtual MatrixND pushResponse(MatrixND& kl, - const VectorND& pl) =0; - - VectorND pushConstant(const VectorND&pl); - MatrixND pushConstant(const MatrixND& kl); - // virtual int getLocalAxes(Vector3D &x, Vector3D &y, Vector3D &z) const =0; + Vector3D getNormalVector() const { + Vector3D x, y, z; + if (getLocalAxes(x, y, z) < 0) + return Vector3D{{0.0, 0.0, 1.0}}; + return z; + } + // Recorders virtual Response *setResponse(const char **argv, int argc, OPS_Stream &) { return nullptr; @@ -86,10 +103,39 @@ class FrameTransform : public TaggedObject return -1; } + // Sensitivity + virtual void pushGrad(VectorND& dp, VectorND& pl) {} + virtual void pullFixedGrad(VectorND&) {} + virtual void pullTotalGrad(VectorND&, int) {} virtual bool isShapeSensitivity() {return false;} virtual double getLengthGrad() {return 0.0;} virtual double getd1overLdh() {return 0.0;} + + // deprecatred API + virtual VectorND pushResponse(VectorND&pl) final { + VectorND pg{pl}; + push(pg, Operation::Total); + return pg; + } + + virtual MatrixND pushResponse(MatrixND& kl, + const VectorND& pl) final { + MatrixND kg{kl}; + push(kg, pl, Operation::Total); + return kg; + } + + + +protected: + constexpr static int ndm = 3; + static inline constexpr void + pushRotation(MatrixND& Kg, const Matrix3D& R); + + static inline constexpr void + pushOffsets(MatrixND& Kg, const std::array& offsets); + static int Orient(const Vector3D& dx, const Vector3D& vz, Matrix3D &R) { @@ -116,10 +162,12 @@ class FrameTransform : public TaggedObject } return 0; } -}; -} // namespace OpenSees + VectorND pushConstant(const VectorND&pl); + MatrixND pushConstant(const MatrixND& kl); +}; +} #include "FrameTransform.tpp" #endif // include guard diff --git a/SRC/coordTransformation/Frame/FrameTransform.tpp b/SRC/coordTransformation/Frame/FrameTransform.tpp index ce30bd1f82..6e19570bed 100644 --- a/SRC/coordTransformation/Frame/FrameTransform.tpp +++ b/SRC/coordTransformation/Frame/FrameTransform.tpp @@ -8,8 +8,8 @@ // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// [1] Perez, C.M., and Filippou F.C. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// @@ -17,42 +17,10 @@ #pragma once #include "FrameTransform.h" #include +#include namespace OpenSees { -template -static VectorND -pushLocal(const Vector& q, double L) -{ - - VectorND<12> pl; - - double q0 = q(0); - double q1 = q(1); - double q2 = q(2); - double q3 = q(3); - double q4 = q(4); - double q5 = q(5); - - double oneOverL = 1.0 / L; - - pl[0] = -q0; // Ni - pl[1] = oneOverL * (q1 + q2); // Viy - pl[2] = -oneOverL * (q3 + q4); // Viz - pl[3] = -q5; // Ti - pl[4] = q3; - pl[5] = q1; // Mzi - pl[6] = q0; // Nj - pl[7] = -pl[1]; // Vjy - pl[8] = -pl[2]; // Vjz - pl[9] = q5; // Tj - pl[10] = q4; - pl[11] = q2; // Mzj - - return pl; -} - - template VectorND FrameTransform::pushConstant(const VectorND& pl) @@ -67,7 +35,6 @@ FrameTransform::pushConstant(const VectorND& pl) } constexpr int N = nn * ndf; - const std::array *offset = this->getRigidOffsets(); // // Initialize @@ -76,29 +43,29 @@ FrameTransform::pushConstant(const VectorND& pl) // (A) First pass: just do the direct transformations for (int i=0; i= 6) - if (offset) { - const std::array& offsets = *offset; - for (int i=0; i *offset = this->getRigidOffsets(); + if (offset) { + const std::array& offsets = *offset; + for (int i=0; i::pushConstant(const MatrixND& kl) R(i,2) = z[i]; } + this->pushRotation(Kg, R); + + const std::array *offset = this->getRigidOffsets(); + if (offset) [[unlikely]] { + this->pushOffsets(Kg, *offset); + } + return Kg; +} + +template +constexpr void +FrameTransform::pushRotation(MatrixND& Kg, const Matrix3D& R) +{ + // + // Do diag(R)*M*diag(R)' + // const Matrix3D RT = R.transpose(); for (int i=0; i::pushConstant(const MatrixND& kl) } } } +} - const std::array *offset = this->getRigidOffsets(); - if (offset) [[unlikely]] { - const std::array& offsets = *offset; - for (int i=0; i(i*ndf+3, j*ndf), offsets[j], -1.0); - Kg.assemble(KmnW, i*ndf+3, j*ndf+3, 1.0); - } - { - Matrix3D WKnm{}; - WKnm.addSpinMatrixProduct(offsets[i], Kg.template extract<3,3>(i*ndf, j*ndf+3), 1.0); - Kg.assemble(WKnm, i*ndf+3, j*ndf+3, 1.0); - } +template +constexpr void +FrameTransform::pushOffsets(MatrixND& Kg, + const std::array& offsets) +{ + for (int i=0; i(i*ndf+3, j*ndf), offsets[j], -1.0); + Kg.assemble(KmnW, i*ndf+3, j*ndf+3, 1.0); + } + { + Matrix3D WKnm{}; + WKnm.addSpinMatrixProduct(offsets[i], Kg.template extract<3,3>(i*ndf, j*ndf+3), 1.0); + Kg.assemble(WKnm, i*ndf+3, j*ndf+3, 1.0); + } + { + Matrix3D WKnn{}; { - Matrix3D WKnn{}; + Matrix3D Knn = Kg.template extract<3,3>(i*ndf, j*ndf); { - Matrix3D Knn = Kg.template extract<3,3>(i*ndf, j*ndf); - { - Matrix3D KnnW{}; - KnnW.addMatrixSpinProduct(Knn, offsets[j], -1.0); - Kg.assemble(KnnW, i*ndf, j*ndf+3, 1.0); - } - WKnn.addSpinMatrixProduct(offsets[i], Knn, 1.0); - Kg.assemble(WKnn, i*ndf+3, j*ndf, 1.0); + Matrix3D KnnW{}; + KnnW.addMatrixSpinProduct(Knn, offsets[j], -1.0); + Kg.assemble(KnnW, i*ndf, j*ndf+3, 1.0); } - Matrix3D WKmmW{}; - WKmmW.addMatrixSpinProduct(WKnn, offsets[j], -1.0); - Kg.assemble(WKmmW, i*ndf+3, j*ndf+3, 1.0); + WKnn.addSpinMatrixProduct(offsets[i], Knn, 1.0); + Kg.assemble(WKnn, i*ndf+3, j*ndf, 1.0); } + Matrix3D WKmmW{}; + WKmmW.addMatrixSpinProduct(WKnn, offsets[j], -1.0); + Kg.assemble(WKmmW, i*ndf+3, j*ndf+3, 1.0); } } } - return Kg; } -} \ No newline at end of file + +} // namespace OpenSees \ No newline at end of file diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h index 931d00e1bb..1ff06efbf2 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h @@ -243,6 +243,7 @@ class CrisfieldIsometry : public AlignedIsometry { return G.template extract<0,3, 6,12>(); else return MatrixND<3,6>{}; + } // diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.h b/SRC/coordTransformation/Frame/LinearFrameTransf.h index 75cda8bf28..53e31daa76 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.h +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.h @@ -68,16 +68,13 @@ class LinearFrameTransf: public FrameTransform int push(VectorND&pl, Operation) final; int push(MatrixND& kl, const VectorND& pl, Operation) final; - // // method used to rotate consistent mass matrix - // const Matrix &getGlobalMatrixFromLocal(const Matrix &local); - // Sensitivity // - const Vector & getBasicDisplFixedGrad(); - const Vector & getBasicDisplTotalGrad(int gradNumber); - const Vector &getGlobalResistingForceShapeSensitivity (const Vector &basicForce, const Vector &p0, int grad); - bool isShapeSensitivity() final; + void pushGrad(VectorND& dp, VectorND& pl) override; + void pullFixedGrad(VectorND&) override; + void pullTotalGrad(VectorND&, int) override; + bool isShapeSensitivity() final; double getLengthGrad() final; double getd1overLdh() final; @@ -89,8 +86,8 @@ class LinearFrameTransf: public FrameTransform private: - inline VectorND - pullConstant(const VectorND& ug, + inline int + pull(VectorND& ug, const Matrix3D& R, const std::array *offset = nullptr, int offset_flags = 0); @@ -119,7 +116,7 @@ class LinearFrameTransf: public FrameTransform } std::array nodes; - Vector3D Du; + Vector3D Du, ur[nn]; std::array *offsets; int offset_flags; diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index 5a59044b7b..7ad9f37f6c 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -95,11 +95,13 @@ LinearFrameTransf::LinearFrameTransf(int tag, const std::array *offset, int offset_flags) : FrameTransform(tag), - Du{0}, - L(0), + Du{}, + ur{}, + L(0.0), offsets{nullptr}, offset_flags(offset_flags), - u_init{nullptr}, initialDispChecked(false) + u_init{nullptr}, + initialDispChecked(false) { R.zero(); @@ -258,23 +260,37 @@ template int LinearFrameTransf::update() { - Du = this->pullPosition<&Node::getTrialDisp>(nn-1) - this->pullPosition<&Node::getTrialDisp>(0); + constexpr Vector3D iv{1, 0, 0}; + + Du = this->pullPosition<&Node::getTrialDisp>(nn-1); + Du -= this->pullPosition<&Node::getTrialDisp>(0); + + for (int node =0 ; node < nn; node++) { + const Vector& u = nodes[node]->getTrialDisp(); + for (int i=0; i<3; i++) { + ur[node][i] = 0; + for (int j=0; j<3; j++) + ur[node][i] += R(j,i) * u[3+j]; + } + + ur[node].addCrossProduct(iv, Du, -1.0/L); + } return 0; } + template -VectorND -LinearFrameTransf::pullConstant(const VectorND& ug, - const Matrix3D& R, +int +LinearFrameTransf::pull(VectorND& ul, + const Matrix3D& R, const std::array *offset, int offset_flags) { - constexpr static int N = nn * ndf; - - VectorND ul = ug; - // (1) + + // (2) Global offsets + // // Do ui -= ri x wi if constexpr (ndf >= 6) if (offset && !(offset_flags&OffsetLocal)) [[unlikely]] { @@ -287,15 +303,16 @@ LinearFrameTransf::pullConstant(const VectorND& ug, ul.assemble(j, offsets[i].cross(w), -1.0); } } - - // (2) Rotations and translations + + // (3) Rotation for (int i=0; i= 6) if (offset && (offset_flags&OffsetLocal)) [[unlikely]] { const std::array& offsets = *offset; @@ -308,7 +325,7 @@ LinearFrameTransf::pullConstant(const VectorND& ug, } } - // (4) + // (5) Isometry // TODO (nn>2) constexpr static Vector3D iv {1,0,0}; Vector3D uI = ul.template extract<3>(0); @@ -324,7 +341,7 @@ LinearFrameTransf::pullConstant(const VectorND& ug, ul.assemble(i*ndf+3, ixDu, -1.0/L); } - return ul; + return 0; } template @@ -338,19 +355,18 @@ LinearFrameTransf::getStateVariation() ug[i*ndf+j] = ddu(j); } } - return LinearFrameTransf::pullConstant(ug, R, offsets, offset_flags); + LinearFrameTransf::pull(ug, R, offsets, offset_flags); + return ug; } + template Vector3D LinearFrameTransf::getNodePosition(int node) { Vector3D v{}; - if (node == 0) { - return v; - } else if (node == nn-1) { + if (node == nn-1) { v[0] = Du[0]; - return v; } // TODO(nn>2) return v; @@ -361,19 +377,7 @@ template Vector3D LinearFrameTransf::getNodeRotationLogarithm(int node) { - constexpr Vector3D iv{1, 0, 0}; - constexpr Matrix3D ix = Hat(iv); - - Vector3D w; - const Vector& u = nodes[node]->getTrialDisp(); - for (int i=0; i<3; i++) { - w[i] = u[3+i]; - } - - w = R^w; - - w.addMatrixVector(1, ix, Du, -1.0/L); - return w; + return ur[node]; } @@ -381,13 +385,11 @@ LinearFrameTransf::getNodeRotationLogarithm(int node) // Push // template -// VectorND int LinearFrameTransf::push(VectorND&p, Operation op) { - VectorND pa = p; + VectorND pa = p; // NOTE constexpr Vector3D iv{1, 0, 0}; - constexpr Matrix3D ix = Hat(iv); // 1.1) Sum of moments: m = sum_i mi + sum_i (xi x ni) Vector3D m{}; @@ -399,7 +401,7 @@ LinearFrameTransf::push(VectorND&p, Operation op) const Vector3D n = Vector3D{p[i*ndf+0], p[i*ndf+1], p[i*ndf+2]}; m.addVector(1, iv.cross(n), double(i)/double(nn-1)*L); } - const Vector3D ixm = ix*m; + const Vector3D ixm = iv.cross(m); // 1.2) Adjust force part for (int i=0; i::push(VectorND&p, Operation op) pa[i*ndf+3] += m[0]*(i? -1.0:1.0)*0.5; } + if (op == Operation::Isometry) + return 0; + // 2) Rotate and do joint offsets p = this->FrameTransform::pushConstant(pa); return 0; @@ -419,32 +424,46 @@ LinearFrameTransf::push(MatrixND&kb, Operation op) { + static constexpr Vector3D axis{1, 0, 0}; + static constexpr Matrix3D ix = Hat(Vector3D{1, 0, 0}); + static constexpr Matrix3D ioi = axis.bun(Vector3D{1, 0, 0}); + const Matrix3D RT = R.transpose(); + const Matrix3D ixRT = ix*RT; + MatrixND A{}; - A.addDiagonal(1.0); - constexpr Vector3D axis{1, 0, 0}; - constexpr Matrix3D ix = Hat(Vector3D{1, 0, 0}); - constexpr Matrix3D ioi = axis.bun(Vector3D{1, 0, 0}); - - MatrixND<3,ndf> Gb{}; - Gb.template insert<0, 3>(ioi, 0.5); - for (int a = 0; a2): Interpolate coordinate - if (b == 0) - Gb.template insert<0,0>(ix, -1/L); - else if (b == nn-1) - Gb.template insert<0,0>(ix, 1/L); - // TODO(nn>2): Interpolate coordinate - A.assemble(ix*Gb, a*ndf , b*ndf, double(a)/double(nn-1)*L); - A.assemble( Gb, a*ndf+3, b*ndf, -1.0); - } + if constexpr (ndf > 6) + A.addDiagonal(1.0); + + { + MatrixND<3,ndf> Gb{}; + Gb.template insert<0, 3>(ioi*RT, 0.5); + Repeat ([&](auto a_) { + constexpr static int a = a_.value; + A.template insert(RT); + A.template insert(RT); + Repeat ([&](auto b_) { + constexpr static int b = b_.value; + + // TODO(nn>2): Interpolate coordinate + if constexpr (b == 0) + Gb.template insert<0,0>(ixRT, -1/L); + else if constexpr (b == nn-1) + Gb.template insert<0,0>(ixRT, 1/L); + + // TODO(nn>2): Interpolate coordinate + A.assemble(ix*Gb, a*ndf , b*ndf, double(a)/double(nn-1)*L); + A.assemble( Gb, a*ndf+3, b*ndf, -1.0); + }); + }); } + // MatrixND kl = kb; + const MatrixND KA = kb*A; + kb.addMatrixTransposeProduct(0.0, A, KA, 1.0); + + if (offsets != nullptr) [[unlikely]] + this->pushOffsets(kb, *offsets); - MatrixND kl; - kl.addMatrixTripleProduct(0, A, kb, 1); - kb = this->FrameTransform::pushConstant(kl); - // this->pushRotation(kb, R); return 0; } @@ -513,14 +532,36 @@ LinearFrameTransf::getd1overLdh() } template -const Vector & -LinearFrameTransf::getGlobalResistingForceShapeSensitivity(const Vector &pb, - const Vector &p0, - int gradNumber) -{ - - static Vector pg(nn*ndf); - pg.Zero(); +void +LinearFrameTransf::pushGrad(VectorND& dp, + VectorND& pl) +{ + // + // dp += T_{gl} dpl + // + double dL = this->getLengthGrad(); + double doneOverL = -dL/(L*L); + + constexpr Vector3D iv{1, 0, 0}; + + // 1.1) Sum of moments: m = sum_i mi + sum_i (xi x ni) + Vector3D m{}; + for (int i=0; i::getGlobalResistingForceShapeSensitivity(const Vector int di = nodes[0]->getCrdsSensitivity(); int dj = nodes[1]->getCrdsSensitivity(); - VectorND pl = pushLocal(pb, L); - - pl[0] += p0[0]; - pl[1] += p0[1]; - pl[7] += p0[2]; - pl[2] += p0[3]; - pl[8] += p0[4]; + // Matrix3D R = this->getRotationMatrix(); + for (int i=0; ipush(pl, Operation::Isometry); Matrix3D dR = FrameOrientationGradient(xi, xj, vz, di, dj, dv); - for (int i=0; i<4; i++) - for (int j=0; j<3; j++) - pg(i*3+j) = dR(j,0) * pl(3*i) + dR(j,1) * pl(3*i+1) + dR(j,2) * pl(3*i+2); - - // - // dp += T_{gl} dpl - // - double dL = this->getLengthGrad(); - double doneOverL = -dL/(L*L); - VectorND dpl{0.0}; - dpl[1] = doneOverL * (pb[1] + pb[2]); // Viy - dpl[2] = -doneOverL * (pb[3] + pb[4]); // Viz - dpl[7] = -dpl[1]; // Vjy - dpl[8] = -dpl[2]; // Vjz + for (int i=0; i -const Vector & -LinearFrameTransf::getBasicDisplFixedGrad() +void +LinearFrameTransf::pullFixedGrad(VectorND& du) { - static VectorND<6> dub; - static Vector wrapper(dub); + // + // dub += (T_{bl}' T_{lg} + T_{bl} T_{lg}') * ug + // + // // Form ug // - // TODO(sensitivity) -#if 0 VectorND ug; for (int i = 0; i < nn; i++) { const Vector& u = nodes[i]->getTrialDisp(); @@ -581,19 +610,6 @@ LinearFrameTransf::getBasicDisplFixedGrad() } } - if (u_init[0] != 0) { - for (int j = 0; j < ndf; j++) - ug[j] -= (*u_init[0])[j]; - } - - if (u_init[nn-1] != 0) { - for (int j = 0; j < ndf; j++) - ug[j + 6] -= (*u_init[nn-1])[j]; - } - - // - // dub += (T_{bl}' T_{lg} + T_{bl} T_{lg}') * ug - // int dv = 0; // TODO(sensitivity) // TODO: Sensitivity @@ -601,48 +617,47 @@ LinearFrameTransf::getBasicDisplFixedGrad() int dj = nodes[1]->getCrdsSensitivity(); - // TODO(sensitivity) - // Matrix3D dR = FrameOrientationGradient(xi, xj, vz, di, dj, dv); - // dub = getBasic(ug, 1/L); // - // - VectorND ul = LinearFrameTransf::pullConstant(ug, R, offsets); - // - dub[0] += 0; - double dL = this->getLengthGrad(); - double doneOverL = -dL/(L*L); - double tmp = doneOverL * (ul[1] - ul[7]); - dub[1] += tmp; - dub[2] += tmp; - tmp = doneOverL * (ul[8] - ul[2]); - dub[3] += tmp; - dub[4] += tmp; -#endif - return wrapper; + // du = Tbl dR^ug + { + Matrix3D dR = FrameOrientationGradient(xi, xj, vz, di, dj, dv); + + VectorND u1 = ug; + LinearFrameTransf::pull(u1, dR, offsets, offset_flags); + du += u1; + } + + { + // double dL = this->getLengthGrad(); + // double doneOverL = -dL/(L*L); + // double length = L; + // L = 1/doneOverL; + // VectorND u2 = ug; + // LinearFrameTransf::pull(u2, R, offsets, offset_flags); + // L = length; // restore + // du += u2; + } + return; } + template -const Vector & -LinearFrameTransf::getBasicDisplTotalGrad(int gradNumber) +void +LinearFrameTransf::pullTotalGrad(VectorND& du, int gradNumber) { - - double dug[12]; - for (int i = 0; i < 6; i++) { - dug[i] = nodes[0]->getDispSensitivity((i + 1), gradNumber); - dug[i + 6] = nodes[1]->getDispSensitivity((i + 1), gradNumber); - } - - static VectorND<6> dub; - static Vector wrapper(dub); + for (int n=0; ngetDispSensitivity((i + 1), gradNumber); + } // dub = T_{bl} T_{lg} * ug' - // TODO - // dub = getBasic(dug, R, offsets[0], offsets[nn-1], 1/L); + LinearFrameTransf::pull(du, R, offsets, offset_flags); - wrapper += getBasicDisplFixedGrad(); + // dub += (T_{bl}' T_{lg} + T_{bl} T_{lg}') * ug + pullFixedGrad(du); - return wrapper; + return; } diff --git a/SRC/runtime/commands/modeling/element.cpp b/SRC/runtime/commands/modeling/element.cpp index d15c5f7ba2..2029e033d4 100644 --- a/SRC/runtime/commands/modeling/element.cpp +++ b/SRC/runtime/commands/modeling/element.cpp @@ -11,7 +11,7 @@ #include #include -#ifdef _MSC_VER +#ifdef _MSC_VER # include # define strcasecmp _stricmp #else @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -54,19 +53,9 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp *interp // THE PROTOTYPES OF THE FUNCTIONS INVOKED BY THE INTERPRETER // -#if 0 // cmp - commented out to eliminate use of TclBasicBuilder -extern int TclBasicBuilder_addFeapTruss(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, Domain *, TclBasicBuilder *, int argStart); -extern int Tcl_addWrapperElement(eleObj *, ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, Domain *, TclBuilder *); -// Added by Quan Gu and Yongdou Liu, et al. on 2018/10/31 (Xiamen University) -#endif static Tcl_CmdProc TclBasicBuilder_addWheelRail; - -extern OPS_Routine OPS_ElasticBeam3d; -extern void *OPS_ElasticBeam2d(G3_Runtime *, const ID &); - - // Frame Tcl_CmdProc TclBasicBuilder_addElasticBeam; Tcl_CmdProc TclBasicBuilder_addGradientInelasticBeamColumn; @@ -113,16 +102,7 @@ G3_TclElementCommand TclBasicBuilder_addBeamGT; // Shells -Element* TclDispatch_newASDShellQ4(ClientData, Tcl_Interp*, int, TCL_Char** const); Element* TclDispatch_newShellANDeS(ClientData, Tcl_Interp*, int, TCL_Char** const); -Element* TclDispatch_newShellDKGQ(ClientData, Tcl_Interp*, int, TCL_Char** const); -Element* TclDispatch_newShellDKGT(ClientData, Tcl_Interp*, int, TCL_Char** const); -Element* TclDispatch_newShellMITC4(ClientData, Tcl_Interp*, int, TCL_Char** const); -Element* TclDispatch_newShellMITC4Thermal(ClientData, Tcl_Interp*, int, TCL_Char** const); -Element* TclDispatch_newShellMITC9(ClientData, Tcl_Interp*, int, TCL_Char** const); -Element* TclDispatch_newShellNLDKGQ(ClientData, Tcl_Interp*, int, TCL_Char** const); -Element* TclDispatch_newShellNLDKGQThermal(ClientData, Tcl_Interp*, int, TCL_Char** const); -Element* TclDispatch_newShellNLDKGT(ClientData, Tcl_Interp*, int, TCL_Char** const); @@ -140,7 +120,7 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C // check at least two arguments so don't segemnt fault on strcmp if (argc < 2) { - opserr << G3_ERROR_PROMPT << "insufficient arguments, expected:\n"; + opserr << OpenSees::PromptValueError << "insufficient arguments, expected:\n"; opserr << " element eleType .. \n"; return TCL_ERROR; } @@ -160,14 +140,6 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C return (*tcl_cmd->second)(clientData, interp, argc, &argv[0]); } - if (strcasecmp(argv[1], "truss") == 0) { - theEle = OPS_TrussElement(rt, argc, argv); - - // for backward compatibility - if (theEle == nullptr) - theEle = OPS_TrussSectionElement(rt, argc, argv); - } - else if ((strcasecmp(argv[1], "elasticBeamColumn") == 0) || (strcasecmp(argv[1], "elasticBeam") == 0) || (strcasecmp(argv[1], "PrismFrame") == 0)) { @@ -233,14 +205,6 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C theEle = OPS_TFP_Bearing(rt, argc, argv); } - else if (strcasecmp(argv[1], "CorotTruss") == 0) { - theEle = OPS_CorotTrussElement(rt, argc, argv); - - // for backward compatibility - if (theEle == nullptr) - theEle = OPS_CorotTrussSectionElement(rt, argc, argv); - } - else if ((strcmp(argv[1], "MultiFP2d") == 0) || (strcmp(argv[1], "MultiFPB2d") == 0)) { @@ -282,10 +246,6 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C interp, argc, argv); -// if (ndm == 2) -// theEle = OPS_FlatSliderSimple2d(rt, argc, argv); -// else -// theEle = OPS_FlatSliderSimple3d(rt, argc, argv); } else if (strcmp(argv[1], "SingleFPBearing") == 0 || @@ -296,74 +256,19 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C interp, argc, argv); -// if (ndm == 2) -// theEle = OPS_SingleFPSimple2d(rt, argc, argv); -// else -// theEle = OPS_SingleFPSimple3d(rt, argc, argv); } - // Xinlong Du - else if ((strcmp(argv[1], "DispBeamColumnAsym") == 0) || - (strcmp(argv[1], "DispBeamAsym")) == 0) { - if (ndm == 3) - theEle = OPS_DispBeamColumnAsym3dTcl(rt, argc, argv); - } - - else if ((strcmp(argv[1], "MixedBeamColumnAsym") == 0) || - (strcmp(argv[1], "MixedBeamAsym") == 0)) { - - if (ndm == 3) - theEle = OPS_MixedBeamColumnAsym3dTcl(rt, argc, argv); - } - // Xinlong Du // // Shells // - else if ((strcmp(argv[1], "Shell") == 0) || - (strcmp(argv[1], "ShellMITC4") == 0)) { - theEle = TclDispatch_newShellMITC4(clientData, interp, argc, argv); - } - - else if (strcmp(argv[1], "ShellMITC4Thermal") == 0) { - theEle = TclDispatch_newShellMITC4Thermal(clientData, interp, argc, argv); - } - - else if (strcmp(argv[1], "ShellNLDKGQThermal") == 0) { - theEle = TclDispatch_newShellNLDKGQThermal(clientData, interp, argc, argv); - } - - else if ((strcmp(argv[1], "ShellNL") == 0) || - (strcmp(argv[1], "ShellMITC9") == 0)) { - theEle = TclDispatch_newShellMITC9(clientData, interp, argc, argv); - } - - else if ((strcmp(argv[1], "shellDKGQ") == 0) || - (strcmp(argv[1], "ShellDKGQ") == 0)) { - theEle = TclDispatch_newShellDKGQ(clientData, interp, argc, argv); - } - - else if (strcmp(argv[1], "ShellNLDKGQ") == 0) { - theEle = TclDispatch_newShellNLDKGQ(clientData, interp, argc, argv); - } - - else if (strcmp(argv[1], "ShellDKGT") == 0) { - theEle = TclDispatch_newShellDKGT(clientData, interp, argc, argv); - } - - else if (strcmp(argv[1], "ShellNLDKGT") == 0) { - theEle = TclDispatch_newShellNLDKGT(clientData, interp, argc, argv); - } - - else if (strcmp(argv[1], "ASDShellQ4") == 0) { - theEle = TclDispatch_newASDShellQ4(clientData, interp, argc, argv); - } else if (strcmp(argv[1], "ShellANDeS") == 0) { theEle = TclDispatch_newShellANDeS(clientData, interp, argc, argv); } + // if one of the above worked theElement = (Element*)theEle; @@ -400,26 +305,28 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C return TclBasicBuilder_addWheelRail(clientData, interp, argc, argv); } - else if (strcmp(argv[1], "DisplFrame") == 0 || - strcmp(argv[1], "CubicFrame") == 0 || - strcmp(argv[1], "ForceFrame") == 0 || - strcmp(argv[1], "ExactFrame") == 0 || - strcmp(argv[1], "ForceDeltaFrame") == 0 || - - strcmp(argv[1], "ForceBeamColumn") == 0 || - strcmp(argv[1], "DispBeamColumn") == 0 || - strcmp(argv[1], "DispBeamColumn") == 0 || - strcmp(argv[1], "TimoshenkoBeamColumn") == 0 || - strcmp(argv[1], "ForceBeamColumnCBDI") == 0 || - strcmp(argv[1], "ForceBeamColumnCSBDI") == 0 || - strcmp(argv[1], "ForceBeamColumnWarping") == 0 || - strcmp(argv[1], "ForceBeamColumnThermal") == 0 || - strcmp(argv[1], "ElasticForceBeamColumnWarping") == 0 || - strcmp(argv[1], "DispBeamColumnNL") == 0 || - strcmp(argv[1], "DispBeamColumnThermal") == 0 || - strcmp(argv[1], "ElasticForceBeamColumn") == 0 || - strcmp(argv[1], "NonlinearBeamColumn") == 0 || - strcmp(argv[1], "DispBeamColumnWithSensitivity") == 0) { + else if (strcasecmp(argv[1], "DisplFrame") == 0 || + strcasecmp(argv[1], "CubicFrame") == 0 || + strcasecmp(argv[1], "EulerFrame") == 0 || + strcasecmp(argv[1], "ForceFrame") == 0 || + strcasecmp(argv[1], "MixedFrame") == 0 || + strcasecmp(argv[1], "ExactFrame") == 0 || + strcasecmp(argv[1], "ForceDeltaFrame") == 0 || + + strcasecmp(argv[1], "ForceBeamColumn") == 0 || + strcasecmp(argv[1], "DispBeamColumn") == 0 || + strcasecmp(argv[1], "DispBeamColumn") == 0 || + strcasecmp(argv[1], "TimoshenkoBeamColumn") == 0 || + strcasecmp(argv[1], "ForceBeamColumnCBDI") == 0 || + strcasecmp(argv[1], "ForceBeamColumnCSBDI") == 0 || + strcasecmp(argv[1], "ForceBeamColumnWarping") == 0 || + strcasecmp(argv[1], "ForceBeamColumnThermal") == 0 || + strcasecmp(argv[1], "ElasticForceBeamColumnWarping") == 0 || + strcasecmp(argv[1], "DispBeamColumnNL") == 0 || + strcasecmp(argv[1], "DispBeamColumnThermal") == 0 || + strcasecmp(argv[1], "ElasticForceBeamColumn") == 0 || + strcasecmp(argv[1], "nonlinearBeamColumn") == 0 || + strcasecmp(argv[1], "DispBeamColumnWithSensitivity") == 0) { return TclBasicBuilder_addForceBeamColumn(clientData, interp, argc, argv); @@ -427,11 +334,7 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C (strcmp(argv[1], "BeamWithHinges") == 0)) { return TclBasicBuilder_addBeamWithHinges(clientData, interp, argc, argv); - // - // -// -// Brick -// + // // Zero-Length // @@ -442,11 +345,11 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C return TclCommand_addZeroLengthSection(clientData, interp, argc, argv); } else if (strcmp(argv[1], "zeroLengthRocking") == 0) { - int result = TclCommand_addZeroLengthRocking(clientData, interp, argc, argv); - return result; + return TclCommand_addZeroLengthRocking(clientData, interp, argc, argv); + } else if (strcmp(argv[1], "zeroLengthContact2D") == 0) { - int result = TclCommand_addZeroLengthContact2D(clientData, interp, argc, argv); - return result; + return TclCommand_addZeroLengthContact2D(clientData, interp, argc, argv); + } else if (strcmp(argv[1], "zeroLengthContact3D") == 0) { return TclCommand_addZeroLengthContact3D(clientData, interp, argc, argv); @@ -875,6 +778,7 @@ errDetected(bool ifNoError, const char *msg) return false; }; + int TclBasicBuilder_addMultipleNormalSpring(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, @@ -2030,7 +1934,7 @@ TclBasicBuilder_addWheelRail(ClientData clientData, Tcl_Interp *interp, int argc // -- End of a 2D wheel-rail element(By Quan Gu, Yongdou Liu, et al.) on 2018/10/29 else if (ndm == 3) { - opserr << G3_ERROR_PROMPT << "Unimplemented." << endln; + opserr << OpenSees::PromptValueError << "Unimplemented." << endln; return TCL_ERROR; } diff --git a/SRC/runtime/commands/modeling/element.hpp b/SRC/runtime/commands/modeling/element.hpp index 73f0ecd9a7..0f09aeda65 100644 --- a/SRC/runtime/commands/modeling/element.hpp +++ b/SRC/runtime/commands/modeling/element.hpp @@ -1,3 +1,9 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// #include #include @@ -6,11 +12,6 @@ typedef void *OPS_Routine(G3_Runtime* , int, const char** const); extern OPS_Routine OPS_ComponentElement2d; extern OPS_Routine OPS_ComponentElement3d; -// extern void *OPS_ComponentElementDamp2d(G3_Runtime*); -extern OPS_Routine OPS_TrussElement; -extern OPS_Routine OPS_TrussSectionElement; -extern OPS_Routine OPS_CorotTrussElement; -extern OPS_Routine OPS_CorotTrussSectionElement; extern OPS_Routine OPS_ElasticTubularJoint; extern OPS_Routine OPS_ZeroLength; extern OPS_Routine OPS_ZeroLengthContactNTS2D; @@ -31,10 +32,6 @@ extern OPS_Routine OPS_ElasticTimoshenkoBeam2d; extern OPS_Routine OPS_ElasticTimoshenkoBeam3d; extern OPS_Routine OPS_AxEqDispBeamColumn2d; extern OPS_Routine OPS_BeamGT; -// extern void* OPS_GradientInelasticBeamColumn2d(); -// extern void* OPS_GradientInelasticBeamColumn3d(); -extern OPS_Routine OPS_DispBeamColumnAsym3dTcl; // Xinlong Du -extern OPS_Routine OPS_MixedBeamColumnAsym3dTcl; // Xinlong Du #if defined(_HAVE_LHNMYS) || defined(OPSDEF_ELEMENT_LHNMYS) extern void *OPS_BeamColumn2DwLHNMYS(G3_Runtime*); extern void *OPS_Beam2dDamage(G3_Runtime*); @@ -43,6 +40,8 @@ extern OPS_Routine OPS_MixedBeamColumnAsym3dTcl; // Xinlong Du #endif extern OPS_Routine OPS_FourNodeTetrahedron; +extern OPS_Routine OPS_TenNodeTetrahedron; + extern OPS_Routine OPS_TPB1D; extern OPS_Routine OPS_TFP_Bearing; extern OPS_Routine OPS_FPBearingPTV; @@ -63,10 +62,11 @@ extern OPS_Routine OPS_PML2D; extern OPS_Routine OPS_CorotTruss2; extern OPS_Routine OPS_HDR; extern OPS_Routine OPS_LeadRubberX; +extern OPS_Routine OPS_LeadRubberY; extern OPS_Routine OPS_ElastomericX; extern OPS_Routine OPS_N4BiaxialTruss; extern OPS_Routine OPS_AC3D8HexWithSensitivity; -extern OPS_Routine OPS_VS3D4WuadWithSensitivity; +extern OPS_Routine OPS_VS3D4QuadWithSensitivity; extern OPS_Routine OPS_MVLEM; // Kristijan Kolozvari extern OPS_Routine OPS_SFI_MVLEM; // Kristijan Kolozvari extern OPS_Routine OPS_MVLEM_3D; // Kristijan Kolozvari @@ -86,6 +86,7 @@ extern OPS_Routine OPS_FSIFluidBoundaryElement2D; // Massimo Petracca (ASDEA) extern OPS_Routine OPS_FSIFluidElement2D; // Massimo Petracca (ASDEA) extern OPS_Routine OPS_ASDShellT3; extern OPS_Routine OPS_TwoNodeLink; +extern OPS_Routine OPS_TwoNodeLinkSection; extern OPS_Routine OPS_LinearElasticSpring; extern OPS_Routine OPS_Inerter; extern OPS_Routine OPS_Inno3DPnPJoint; @@ -105,6 +106,7 @@ extern OPS_Routine OPS_LehighJoint2d; extern OPS_Routine OPS_MasonPan12; extern OPS_Routine OPS_MasonPan3D; + #include #include static @@ -137,42 +139,20 @@ class CaseInsensitive } }; -#if 0 -// template static int -class BasicModelBuilder; -struct Tcl_Interp; -class Domain; -template static int -dispatch(BasicModelBuilder* builder, Tcl_Interp* interp, int argc, const char** const argv) -{ - int ndm = builder->getNDM(); - Domain* domain = builder->getDomain(); - G3_Runtime *rt = G3_getRuntime(interp); - - Element* theElement = (Element*)fn( rt, argc, argv ); - - if (domain->addElement(*theElement) == false) { - opserr << G3_ERROR_PROMPT << "Could not add element to the domain.\n"; - delete theElement; - return TCL_ERROR; - } - return TCL_OK; -} -#endif +Tcl_CmdProc TclCommand_addTruss; Tcl_CmdProc TclCommand_addTwoNodeLink; +Tcl_CmdProc TclCommand_addTwoNodeLinkSection; // Plane Tcl_CmdProc TclBasicBuilder_addFourNodeQuad; Tcl_CmdProc TclBasicBuilder_addFourNodeQuadWithSensitivity; -Tcl_CmdProc TclBasicBuilder_addEnhancedQuad; Tcl_CmdProc TclBasicBuilder_addConstantPressureVolumeQuad; Tcl_CmdProc TclBasicBuilder_addNineNodeMixedQuad; -Tcl_CmdProc TclBasicBuilder_addNineNodeQuad; Tcl_CmdProc TclBasicBuilder_addSixNodeTri; -Tcl_CmdProc TclBasicBuilder_addEightNodeQuad; Tcl_CmdProc TclBasicBuilder_addFourNodeQuadUP; Tcl_CmdProc TclBasicBuilder_addNineFourNodeQuadUP; Tcl_CmdProc TclBasicBuilder_addBBarFourNodeQuadUP; -Tcl_CmdProc TclDispatch_newTri31; +// Shell +Tcl_CmdProc TclBasicBuilder_addShell; // Brick Tcl_CmdProc TclBasicBuilder_addBrickUP; Tcl_CmdProc TclBasicBuilder_addBBarBrickUP; @@ -186,37 +166,56 @@ Tcl_CmdProc TclCommand_addActuatorCorot; Tcl_CmdProc TclCommand_addAdapter; Tcl_CmdProc TclBasicBuilder_addRJWatsonEqsBearing; -static +const static std::unordered_map element_dispatch_tcl = { {"twoNodeLink", TclCommand_addTwoNodeLink}, + {"twoNodeLinkSection", TclCommand_addTwoNodeLinkSection}, + {"Truss", TclCommand_addTruss}, + {"TrussSection", TclCommand_addTruss}, + {"CorotTruss", TclCommand_addTruss}, + {"CorotTrussSection", TclCommand_addTruss}, // // Plane // - {"Quad", TclBasicBuilder_addFourNodeQuad}, {"stdQuad", TclBasicBuilder_addFourNodeQuad}, + {"LagrangeQuad", TclBasicBuilder_addFourNodeQuad}, + {"enhancedQuad", TclBasicBuilder_addFourNodeQuad}, + {"quad", TclBasicBuilder_addFourNodeQuad}, + {"quad9n", TclBasicBuilder_addFourNodeQuad}, + {"quad8n", TclBasicBuilder_addFourNodeQuad}, {"quadWithSensitivity", TclBasicBuilder_addFourNodeQuadWithSensitivity}, - {"enhancedQuad", TclBasicBuilder_addEnhancedQuad}, - {"bbarQuad", TclBasicBuilder_addConstantPressureVolumeQuad}, {"mixedQuad", TclBasicBuilder_addConstantPressureVolumeQuad}, {"nineNodeMixedQuad", TclBasicBuilder_addNineNodeMixedQuad}, - {"nineNodeQuad", TclBasicBuilder_addNineNodeMixedQuad}, + {"nineNodeQuad", TclBasicBuilder_addNineNodeMixedQuad}, // ?? - {"quad9n", TclBasicBuilder_addNineNodeQuad}, + {"tri6n", TclBasicBuilder_addSixNodeTri}, + {"tri31", TclBasicBuilder_addFourNodeQuad}, - {"quad8n", TclBasicBuilder_addEightNodeQuad}, +// Shell + {"ASDShellQ4", TclBasicBuilder_addShell}, + {"ShellMITC4", TclBasicBuilder_addShell}, + {"ShellMITC9", TclBasicBuilder_addShell}, + {"ShellDKGQ", TclBasicBuilder_addShell}, + {"ShellDKGT", TclBasicBuilder_addShell}, + {"ShellNLDKGQ", TclBasicBuilder_addShell}, + {"ShellNLDKGT", TclBasicBuilder_addShell}, +// {"ShellANDeS", TclBasicBuilder_addShell}, + {"ShellMITC4Thermal", TclBasicBuilder_addShell}, + {"ShellNLDKGQThermal", TclBasicBuilder_addShell}, + +// U-P - {"tri6n", TclBasicBuilder_addSixNodeTri}, - {"tri31", TclDispatch_newTri31}, {"quadUP", TclBasicBuilder_addFourNodeQuadUP}, {"9_4_QuadUP", TclBasicBuilder_addNineFourNodeQuadUP}, {"bbarQuadUP", TclBasicBuilder_addBBarFourNodeQuadUP}, + // // Brick // @@ -252,8 +251,6 @@ static std::unordered_map element_dispatch = { // Truss - {"TrussSection", OPS_TrussSectionElement}, - {"CorotTrussSection", OPS_CorotTrussSectionElement}, {"N4BiaxialTruss", OPS_N4BiaxialTruss}, {"Truss2", OPS_Truss2}, {"CorotTruss2", OPS_CorotTruss2}, @@ -284,7 +281,8 @@ element_dispatch = { {"TripleFrictionPendulum", OPS_TripleFrictionPendulum}, {"TripleFrictionPendulumX", OPS_TripleFrictionPendulumX}, {"HDR", OPS_HDR}, - {"LeadRubberX", OPS_LeadRubberX}, +//{"LeadRubberX", OPS_LeadRubberX}, + {"LeadRubberX", OPS_LeadRubberY}, {"ElastomericX", OPS_ElastomericX}, {"AxEqDispBeamColumn2d", OPS_AxEqDispBeamColumn2d}, @@ -322,13 +320,16 @@ element_dispatch = { {"ASI3D8", OPS_ASID8QuadWithSensitivity}, {"AV3D4", OPS_AV3D4QuadWithSensitivity}, {"ElastomericBearingBoucWenMod", OPS_ElastomericBearingBoucWenMod3d}, - {"VS3D4", OPS_VS3D4WuadWithSensitivity}, + {"VS3D4", OPS_VS3D4QuadWithSensitivity}, {"CatenaryCable", OPS_CatenaryCableElement}, {"ASDEmbeddedNodeElement", OPS_ASDEmbeddedNodeElement}, {"LysmerTriangle", OPS_LysmerTriangle}, {"ASDAbsorbingBoundary2D", OPS_ASDAbsorbingBoundary2D}, {"ASDAbsorbingBoundary3D", OPS_ASDAbsorbingBoundary3D}, + {"FourNodeTetrahedron", OPS_FourNodeTetrahedron}, + {"TenNodeTetrahedron", OPS_TenNodeTetrahedron}, + {"LinearElasticSpring", OPS_LinearElasticSpring}, {"Inerter", OPS_Inerter}, {"Adapter", OPS_Adapter}, diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index d15920b7c1..2f0377148b 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -405,18 +405,6 @@ CreateFrame(BasicModelBuilder& builder, } -#if 0 -Element* -CreateInelasticFrame(std::string, std::vector& nodes, - std::vector&, - BeamIntegration&, - // FrameQuadrature&, - FrameTransform&, - Options&); -Element* -CreatePrismaticFrame(std::string); -#endif - // 0 1 2 3 4 // element beam 1 $i $j 0 1 2 // diff --git a/SRC/runtime/commands/modeling/geomTransf.cpp b/SRC/runtime/commands/modeling/geomTransf.cpp index 9cf79d8292..e1dff124e1 100644 --- a/SRC/runtime/commands/modeling/geomTransf.cpp +++ b/SRC/runtime/commands/modeling/geomTransf.cpp @@ -386,16 +386,17 @@ TclCommand_addGeomTransf(ClientData clientData, Tcl_Interp *interp, int argc, strcmp(argv[1], "LinearWithPDelta") == 0) crdTransf2d = new PDeltaCrdTransf2d(tag, jntOffsetI, jntOffsetJ); - else if (strcmp(argv[1], "Corotational") == 0 && ndf == 3) + else if ((strcmp(argv[1], "Corotational") == 0 || strcmp(argv[1], "Corotational02") == 0) && ndf == 3) crdTransf2d = new CorotCrdTransf2d(tag, jntOffsetI, jntOffsetJ); - else if (strcmp(argv[1], "Corotational") == 0 && ndf == 4) + else if ((strcmp(argv[1], "Corotational") == 0 || strcmp(argv[1], "Corotational02") == 0) && ndf == 4) crdTransf2d = new CorotCrdTransfWarping2d(tag, jntOffsetI, jntOffsetJ); else { opserr << OpenSees::PromptValueError - << "invalid Type: " << argv[1] << "\n"; + << "invalid Type: " << argv[1] + << "\n"; return TCL_ERROR; } diff --git a/SRC/utility/Unroll.h b/SRC/utility/Unroll.h new file mode 100644 index 0000000000..1be782bbb7 --- /dev/null +++ b/SRC/utility/Unroll.h @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//----------------------------------------------------------------------------// +#pragma once +#include +#include + +namespace OpenSees { +namespace +{ + template + struct num { static constexpr std::size_t value = N; }; + + // Helper that unpacks the index_sequence into calls to func + template + [[gnu::always_inline]] inline constexpr void + repeat_impl(F func, std::index_sequence) noexcept + { + (func(num{}), ...); + } + + // Helper that unpacks the index_sequence into calls to func, offset by Start + template + [[gnu::always_inline]] inline constexpr void + unroll_impl(F func, std::index_sequence) noexcept + { + (func(num{}), ...); + } +} + +#if 0 // __cplusplus >= 202002L +template +[[gnu::always_inline]] inline constexpr void +Repeat(F func) noexcept +{ + // Lambda with templated parameter pack (C++20 feature) + ([](F func, std::index_sequence){ + (func(num{}), ...); + })(func, std::make_index_sequence{}); +} +#else +template +[[gnu::always_inline]] inline constexpr void +Repeat(F func) noexcept +{ + repeat_impl(func, std::make_index_sequence{}); +} +#endif + +template +inline constexpr void +Unroll(F func) noexcept +{ + static_assert(Stop >= Start, "Stop must be greater than or equal to Start"); + constexpr std::size_t N = Stop - Start; + unroll_impl(func, std::make_index_sequence{}); +} + +} // namespace OpenSees \ No newline at end of file From 9cf6271721160a620eaa6167e80b571372a4456c Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Wed, 23 Jul 2025 10:39:51 -0700 Subject: [PATCH 190/261] purge commented out code --- .../Frame/LinearFrameTransf.tpp | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index 7ad9f37f6c..7d4f34a7c3 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -36,7 +36,8 @@ namespace OpenSees { static inline MatrixND<3,3> -FrameOrientationGradient(const Vector3D& xi, const Vector3D& xj, +FrameOrientationGradient(const Vector3D& xi, + const Vector3D& xj, const Vector3D& vz, int di, int dj, int dv) { @@ -47,8 +48,6 @@ FrameOrientationGradient(const Vector3D& xi, const Vector3D& xj, Vector3D v2 = vz.cross(e1); Vector3D e2 = v2 / v2.norm(); -// Vector3D v3 = e1.cross(e2); -// Vector3D e3 = v3 / v3.norm(); // Vector3D dvz{0.0}; @@ -570,7 +569,6 @@ LinearFrameTransf::pushGrad(VectorND& dp, int di = nodes[0]->getCrdsSensitivity(); int dj = nodes[1]->getCrdsSensitivity(); - // Matrix3D R = this->getRotationMatrix(); for (int i=0; i::pullFixedGrad(VectorND& du) int dv = 0; // TODO(sensitivity) - // TODO: Sensitivity int di = nodes[0]->getCrdsSensitivity(); int dj = nodes[1]->getCrdsSensitivity(); - - // // du = Tbl dR^ug { @@ -627,17 +622,6 @@ LinearFrameTransf::pullFixedGrad(VectorND& du) LinearFrameTransf::pull(u1, dR, offsets, offset_flags); du += u1; } - - { - // double dL = this->getLengthGrad(); - // double doneOverL = -dL/(L*L); - // double length = L; - // L = 1/doneOverL; - // VectorND u2 = ug; - // LinearFrameTransf::pull(u2, R, offsets, offset_flags); - // L = length; // restore - // du += u2; - } return; } From 29617a5fde402883748a14f38c7aead76c63a6e6 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Wed, 23 Jul 2025 10:40:44 -0700 Subject: [PATCH 191/261] Update SouzaFrameTransf.h --- SRC/coordTransformation/Frame/SouzaFrameTransf.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.h b/SRC/coordTransformation/Frame/SouzaFrameTransf.h index cad97523b5..738432ddaf 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.h +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.h @@ -97,8 +97,6 @@ class SouzaFrameTransf: public FrameTransform private: constexpr static int n = nn*ndf; - // compute the transformation matrix - // void compute_tangent(const Matrix3D&, const Versor*); int addTangent(MatrixND<12,12>& M, const VectorND<12>& pl, const VectorND<12>&ul); enum { From ef7e5aaa52a5de3e1c085211cb53fad1310e74ab Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Wed, 23 Jul 2025 10:46:13 -0700 Subject: [PATCH 192/261] add matrix inverse kernels --- SRC/matrix/routines/cmx.h | 8 + SRC/matrix/routines/invGL2.c | 50 + SRC/matrix/routines/invGL3.c | 61 + SRC/matrix/routines/invGL4.c | 102 + SRC/matrix/routines/invGL5.c | 350 +++ SRC/matrix/routines/invGL6.c | 5449 ++++++++++++++++++++++++++++++++++ 6 files changed, 6020 insertions(+) create mode 100644 SRC/matrix/routines/invGL2.c create mode 100644 SRC/matrix/routines/invGL3.c create mode 100644 SRC/matrix/routines/invGL4.c create mode 100644 SRC/matrix/routines/invGL5.c create mode 100644 SRC/matrix/routines/invGL6.c diff --git a/SRC/matrix/routines/cmx.h b/SRC/matrix/routines/cmx.h index c9cc19faa7..8d948772b1 100644 --- a/SRC/matrix/routines/cmx.h +++ b/SRC/matrix/routines/cmx.h @@ -1,3 +1,11 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// + #ifndef cmx_h #define cmx_h diff --git a/SRC/matrix/routines/invGL2.c b/SRC/matrix/routines/invGL2.c new file mode 100644 index 0000000000..0eef184872 --- /dev/null +++ b/SRC/matrix/routines/invGL2.c @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// adapted by CMP from code by David Simpson at +// https://caps.gsfc.nasa.gov/simpson/software/m22inv_f90.txt +// +#include + +int cmx_inv2(double *a, double *ainv, int *ok_flag__) +{ + /* **************************************************************************************** + * m22inv - compute the inverse of a 2x2 matrix. + * + * a : (input) 2x2 matrix to be inverted + * ainv : (output) 2x2 inverse of matrix a + * + * ok_flag: (output) 0 if the input matrix could be inverted, + * and -1 if the input matrix is singular. + * + * ****************************************************************************************/ + + /* Parameter adjustments */ + ainv -= 3; + a -= 3; + + const double eps = 1e-10; + const double det = a[3] * a[6] - a[5] * a[4]; + if (fabs(det) <= eps) { + *ok_flag__ = -1; + } + + double cofactor[4]; + + cofactor[0] = a[6]; + cofactor[2] = -a[4]; + cofactor[1] = -a[5]; + cofactor[3] = a[3]; + + for (int i__ = 1; i__ <= 2; ++i__) + for (int j = 1; j <= 2; ++j) + ainv[j + (i__ << 1)] = cofactor[i__ + (j << 1) - 3] / det; + + *ok_flag__ = 0; + return 0; +} diff --git a/SRC/matrix/routines/invGL3.c b/SRC/matrix/routines/invGL3.c new file mode 100644 index 0000000000..08da4b5845 --- /dev/null +++ b/SRC/matrix/routines/invGL3.c @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// adapted from https://caps.gsfc.nasa.gov/simpson/software/m33inv_f90.txt +// +#include + + +int cmx_inv3(double *a, double *ainv, int *ok_flag__) +{ +/* **************************************************************************************** */ +/* m33inv - compute the inverse of a 3x3 matrix. */ + +/* a = input 3x3 matrix to be inverted */ +/* ainv = output 3x3 inverse of matrix a */ +/* ok_flag = (output) .true. if the input matrix could be inverted, and */ +/* .false. if the input matrix is singular. */ +/* **************************************************************************************** */ + + + /* Parameter adjustments */ + ainv -= 4; + a -= 4; + + const double det = a[4]*a[8]*a[12] + - a[4]*a[11]*a[9] + - a[7]*a[5]*a[12] + + a[7]*a[11]*a[6] + + a[10]*a[5]*a[9] + - a[10]*a[8]*a[6]; + + const double eps=1e-10; + if (fabs(det) <= eps) { + *ok_flag__ = -1; + // return 0; + } + + double cofactor[9]; + cofactor[0] = a[8]*a[12] - a[11]*a[9]; + cofactor[3] = -(a[5]*a[12] - a[11]*a[6]); + cofactor[6] = a[5]*a[9] - a[8]*a[6]; + cofactor[1] = -(a[7]*a[12] - a[10]*a[9]); + cofactor[4] = a[4]*a[12] - a[10]*a[6]; + cofactor[7] = -(a[4]*a[9] - a[7]*a[6]); + cofactor[2] = a[7]*a[11] - a[10]*a[8]; + cofactor[5] = -(a[4]*a[11] - a[10]*a[5]); + cofactor[8] = a[4]*a[8] - a[7]*a[5]; + + for (int i__ = 1; i__ <= 3; ++i__) + for (int j = 1; j <= 3; ++j) + ainv[j + i__ * 3] = cofactor[i__ + j * 3 - 4] / det; + + *ok_flag__ = 0; + return 0; +} + diff --git a/SRC/matrix/routines/invGL4.c b/SRC/matrix/routines/invGL4.c new file mode 100644 index 0000000000..b6335342ca --- /dev/null +++ b/SRC/matrix/routines/invGL4.c @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// adapted from https://caps.gsfc.nasa.gov/simpson/software/m44inv_f90.txt +// +#include + +int cmx_inv4(double *a, double *ainv, int *ok_flag__) +{ +/* **************************************************************************************** + * m44inv - compute the inverse of a 4x4 matrix. + + * a = input 4x4 matrix to be inverted + * ainv = output 4x4 inverse of matrix a + * ok_flag = (output) .true. if the input matrix could be inverted, and .false. if the input matrix is singular. + * **************************************************************************************** */ + static double cofactor[16]; + static double eps=1e-10; + + /* Parameter adjustments */ + ainv -= 5; + a -= 5; + + const double det = a[ 5]*(a[10]*(a[15]*a[20] - a[19]*a[16]) + + a[14]*(a[19]*a[12] - a[11]*a[20]) + + a[18]*(a[11]*a[16] - a[15]*a[12])) + - a[ 9]*(a[ 6]*(a[15]*a[20] - a[19]*a[16]) + + a[14]*(a[19]*a[ 8] - a[ 7]*a[20]) + + a[18]*(a[ 7]*a[16] - a[15]*a[ 8])) + + a[13]*(a[ 6]*(a[11]*a[20] - a[19]*a[12]) + + a[10]*(a[19]*a[ 8] - a[ 7]*a[20]) + + a[18]*(a[ 7]*a[12] - a[11]*a[ 8])) + - a[17]*(a[ 6]*(a[11]*a[16] - a[15]*a[12]) + + a[10]*(a[15]*a[ 8] - a[ 7]*a[16]) + + a[14]*(a[ 7]*a[12] - a[11]*a[ 8])); + + if (fabs(det) <= eps) { + *ok_flag__ = -1; + } + + cofactor[ 0] = a[10]*(a[15]*a[20] - a[19]*a[16]) + + a[14]*(a[19]*a[12] - a[11]*a[20]) + + a[18]*(a[11]*a[16] - a[15]*a[12]); + cofactor[ 4] = a[ 6]*(a[19]*a[16] - a[15]*a[20]) + + a[14]*(a[ 7]*a[20] - a[19]*a[ 8]) + + a[18]*(a[15]*a[ 8] - a[ 7]*a[16]); + cofactor[ 8] = a[ 6]*(a[11]*a[20] - a[19]*a[12]) + + a[10]*(a[19]*a[ 8] - a[ 7]*a[20]) + + a[18]*(a[ 7]*a[12] - a[11]*a[ 8]); + cofactor[12] = a[ 6]*(a[15]*a[12] - a[11]*a[16]) + + a[10]*(a[ 7]*a[16] - a[15]*a[ 8]) + + a[14]*(a[11]*a[ 8] - a[ 7]*a[12]); + cofactor[ 1] = a[ 9]*(a[19]*a[16] - a[15]*a[20]) + + a[13]*(a[11]*a[20] - a[19]*a[12]) + + a[17]*(a[15]*a[12] - a[11]*a[16]); + cofactor[ 5] = a[ 5]*(a[15]*a[20] - a[19]*a[16]) + + a[13]*(a[19]*a[ 8] - a[ 7]*a[20]) + + a[17]*(a[ 7]*a[16] - a[15]*a[ 8]); + cofactor[ 9] = a[ 5]*(a[19]*a[12] - a[11]*a[20]) + + a[ 9]*(a[ 7]*a[20] - a[19]*a[ 8]) + + a[17]*(a[11]*a[ 8] - a[ 7]*a[12]); + cofactor[13] = a[ 5]*(a[11]*a[16] - a[15]*a[12]) + + a[ 9]*(a[15]*a[ 8] - a[ 7]*a[16]) + + a[13]*(a[ 7]*a[12] - a[11]*a[ 8]); + cofactor[ 2] = a[ 9]*(a[14]*a[20] - a[18]*a[16]) + + a[13]*(a[18]*a[12] - a[10]*a[20]) + + a[17]*(a[10]*a[16] - a[14]*a[12]); + cofactor[ 6] = a[ 5]*(a[18]*a[16] - a[14]*a[20]) + + a[13]*(a[ 6]*a[20] - a[18]*a[ 8]) + + a[17]*(a[14]*a[ 8] - a[ 6]*a[16]); + cofactor[10] = a[ 5]*(a[10]*a[20] - a[18]*a[12]) + + a[ 9]*(a[18]*a[ 8] - a[ 6]*a[20]) + + a[17]*(a[ 6]*a[12] - a[10]*a[ 8]); + cofactor[14] = a[ 5]*(a[14]*a[12] - a[10]*a[16]) + + a[ 9]*(a[ 6]*a[16] - a[14]*a[ 8]) + + a[13]*(a[10]*a[ 8] - a[ 6]*a[12]); + cofactor[ 3] = a[ 9]*(a[18]*a[15] - a[14]*a[19]) + + a[13]*(a[10]*a[19] - a[18]*a[11]) + + a[17]*(a[14]*a[11] - a[10]*a[15]); + cofactor[ 7] = a[ 5]*(a[14]*a[19] - a[18]*a[15]) + + a[13]*(a[18]*a[ 7] - a[ 6]*a[19]) + + a[17]*(a[ 6]*a[15] - a[14]*a[ 7]); + cofactor[11] = a[ 5]*(a[18]*a[11] - a[10]*a[19]) + + a[ 9]*(a[ 6]*a[19] - a[18]*a[ 7]) + + a[17]*(a[10]*a[ 7] - a[ 6]*a[11]); + cofactor[15] = a[ 5]*(a[10]*a[15] - a[14]*a[11]) + + a[ 9]*(a[14]*a[ 7] - a[ 6]*a[15]) + + a[13]*(a[ 6]*a[11] - a[10]*a[ 7]); + + for (int i__ = 1; i__ <= 4; ++i__) + for (int j = 1; j <= 4; ++j) + ainv[j + (i__ << 2)] = cofactor[i__ + (j << 2) - 5] / det; + + *ok_flag__ = 0; + return 0; +} + diff --git a/SRC/matrix/routines/invGL5.c b/SRC/matrix/routines/invGL5.c new file mode 100644 index 0000000000..2ca0d59409 --- /dev/null +++ b/SRC/matrix/routines/invGL5.c @@ -0,0 +1,350 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// adapted from https://caps.gsfc.nasa.gov/simpson/software/m55inv_f90.txt +// +#include + +int cmx_inv5(double *a, double *ainv, int *ok_flag__) +{ +/* **************************************************************************************** + * m55inv - compute the inverse of a 5x5 matrix. + + * a = input 5x5 matrix to be inverted + * ainv = output 5x5 inverse of matrix a + * ok_flag = (output) .true. if the input matrix could be inverted, and .false. if the input matrix is singular. + ***************************************************************************************** */ + static double cofactor[25]; + static double a11, a12, a13, a14, a15, a21, a22, a23, a24, a25, a31, + a32, a33, a34, a35, a41, a42, a43, a44, a45, a51, a52, a53, a54, + a55, det; + + const double eps = 1e-10; + + /* Parameter adjustments */ + ainv -= 6; + a -= 6; + + a11 = a[6]; + a12 = a[11]; + a13 = a[16]; + a14 = a[21]; + a15 = a[26]; + a21 = a[7]; + a22 = a[12]; + a23 = a[17]; + a24 = a[22]; + a25 = a[27]; + a31 = a[8]; + a32 = a[13]; + a33 = a[18]; + a34 = a[23]; + a35 = a[28]; + a41 = a[9]; + a42 = a[14]; + a43 = a[19]; + a44 = a[24]; + a45 = a[29]; + a51 = a[10]; + a52 = a[15]; + a53 = a[20]; + a54 = a[25]; + a55 = a[30]; + det = a15*a24*a33*a42*a51 - a14*a25*a33*a42*a51 - a15* + a23*a34*a42*a51 + a13*a25*a34*a42*a51 + a14*a23* + a35*a42*a51 - a13*a24*a35*a42*a51 - a15*a24*a32* + a43*a51 + a14*a25*a32*a43*a51 + a15*a22*a34*a43* + a51 - a12*a25*a34*a43*a51 - a14*a22*a35*a43*a51 + + a12*a24*a35*a43*a51 + a15*a23*a32*a44*a51 - a13* + a25*a32*a44*a51 - a15*a22*a33*a44*a51 + a12*a25* + a33*a44*a51 + a13*a22*a35*a44*a51 - a12*a23*a35* + a44*a51 - a14*a23*a32*a45*a51 + a13*a24*a32*a45* + a51 + a14*a22*a33*a45*a51 - a12*a24*a33*a45*a51 - + a13*a22*a34*a45*a51 + a12*a23*a34*a45*a51 - a15* + a24*a33*a41*a52 + a14*a25*a33*a41*a52 + a15*a23* + a34*a41*a52 - a13*a25*a34*a41*a52 - a14*a23*a35* + a41*a52 + a13*a24*a35*a41*a52 + a15*a24*a31*a43* + a52 - a14*a25*a31*a43*a52 - a15*a21*a34*a43*a52 + + a11*a25*a34*a43*a52 + a14*a21*a35*a43*a52 - a11* + a24*a35*a43*a52 - a15*a23*a31*a44*a52 + a13*a25* + a31*a44*a52 + a15*a21*a33*a44*a52 - a11*a25*a33* + a44*a52 - a13*a21*a35*a44*a52 + a11*a23*a35*a44* + a52 + a14*a23*a31*a45*a52 - a13*a24*a31*a45*a52 - + a14*a21*a33*a45*a52 + a11*a24*a33*a45*a52 + a13* + a21*a34*a45*a52 - a11*a23*a34*a45*a52 + a15*a24* + a32*a41*a53 - a14*a25*a32*a41*a53 - a15*a22*a34* + a41*a53 + a12*a25*a34*a41*a53 + a14*a22*a35*a41* + a53 - a12*a24*a35*a41*a53 - a15*a24*a31*a42*a53 + + a14*a25*a31*a42*a53 + a15*a21*a34*a42*a53 - a11* + a25*a34*a42*a53 - a14*a21*a35*a42*a53 + a11*a24* + a35*a42*a53 + a15*a22*a31*a44*a53 - a12*a25*a31* + a44*a53 - a15*a21*a32*a44*a53 + a11*a25*a32*a44* + a53 + a12*a21*a35*a44*a53 - a11*a22*a35*a44*a53 - + a14*a22*a31*a45*a53 + a12*a24*a31*a45*a53 + a14* + a21*a32*a45*a53 - a11*a24*a32*a45*a53 - a12*a21* + a34*a45*a53 + a11*a22*a34*a45*a53 - a15*a23*a32* + a41*a54 + a13*a25*a32*a41*a54 + a15*a22*a33*a41* + a54 - a12*a25*a33*a41*a54 - a13*a22*a35*a41*a54 + + a12*a23*a35*a41*a54 + a15*a23*a31*a42*a54 - a13* + a25*a31*a42*a54 - a15*a21*a33*a42*a54 + a11*a25* + a33*a42*a54 + a13*a21*a35*a42*a54 - a11*a23*a35* + a42*a54 - a15*a22*a31*a43*a54 + a12*a25*a31*a43* + a54 + a15*a21*a32*a43*a54 - a11*a25*a32*a43*a54 - + a12*a21*a35*a43*a54 + a11*a22*a35*a43*a54 + a13* + a22*a31*a45*a54 - a12*a23*a31*a45*a54 - a13*a21* + a32*a45*a54 + a11*a23*a32*a45*a54 + a12*a21*a33* + a45*a54 - a11*a22*a33*a45*a54 + a14*a23*a32*a41* + a55 - a13*a24*a32*a41*a55 - a14*a22*a33*a41*a55 + + a12*a24*a33*a41*a55 + a13*a22*a34*a41*a55 - a12* + a23*a34*a41*a55 - a14*a23*a31*a42*a55 + a13*a24* + a31*a42*a55 + a14*a21*a33*a42*a55 - a11*a24*a33* + a42*a55 - a13*a21*a34*a42*a55 + a11*a23*a34*a42* + a55 + a14*a22*a31*a43*a55 - a12*a24*a31*a43*a55 - + a14*a21*a32*a43*a55 + a11*a24*a32*a43*a55 + a12* + a21*a34*a43*a55 - a11*a22*a34*a43*a55 - a13*a22* + a31*a44*a55 + a12*a23*a31*a44*a55 + a13*a21*a32* + a44*a55 - a11*a23*a32*a44*a55 - a12*a21*a33*a44* + a55 + a11*a22*a33*a44*a55; + if (fabs(det) <= eps) { + *ok_flag__ = -1; + return 0; + } + cofactor[0] = a25*a34*a43*a52 - a24*a35*a43*a52 - a25*a33* + a44*a52 + a23*a35*a44*a52 + a24*a33*a45*a52 - a23* + a34*a45*a52 - a25*a34*a42*a53 + a24*a35*a42*a53 + + a25*a32*a44*a53 - a22*a35*a44*a53 - a24*a32*a45* + a53 + a22*a34*a45*a53 + a25*a33*a42*a54 - a23*a35* + a42*a54 - a25*a32*a43*a54 + a22*a35*a43*a54 + a23* + a32*a45*a54 - a22*a33*a45*a54 - a24*a33*a42*a55 + + a23*a34*a42*a55 + a24*a32*a43*a55 - a22*a34*a43* + a55 - a23*a32*a44*a55 + a22*a33*a44*a55; + cofactor[1] = -a15*a34*a43*a52 + a14*a35*a43*a52 + a15*a33 * + a44*a52 - a13*a35*a44*a52 - a14*a33*a45*a52 + a13 * + a34*a45*a52 + a15*a34*a42*a53 - a14*a35*a42*a53 + - a15*a32*a44*a53 + a12*a35*a44*a53 + a14*a32*a45 + *a53 - a12*a34*a45*a53 - a15*a33*a42*a54 + a13*a35 + *a42*a54 + a15*a32*a43*a54 - a12*a35*a43*a54 - a13 + *a32*a45*a54 + a12*a33*a45*a54 + a14*a33*a42*a55 + - a13*a34*a42*a55 - a14*a32*a43*a55 + a12*a34*a43 + *a55 + a13*a32*a44*a55 - a12*a33*a44*a55; + cofactor[2] = a15*a24*a43*a52 - a14*a25*a43*a52 - a15*a23* + a44*a52 + a13*a25*a44*a52 + a14*a23*a45*a52 - a13* + a24*a45*a52 - a15*a24*a42*a53 + a14*a25*a42*a53 + + a15*a22*a44*a53 - a12*a25*a44*a53 - a14*a22*a45* + a53 + a12*a24*a45*a53 + a15*a23*a42*a54 - a13*a25* + a42*a54 - a15*a22*a43*a54 + a12*a25*a43*a54 + a13* + a22*a45*a54 - a12*a23*a45*a54 - a14*a23*a42*a55 + + a13*a24*a42*a55 + a14*a22*a43*a55 - a12*a24*a43* + a55 - a13*a22*a44*a55 + a12*a23*a44*a55; + cofactor[3] = -a15*a24*a33*a52 + a14*a25*a33*a52 + a15*a23 * + a34*a52 - a13*a25*a34*a52 - a14*a23*a35*a52 + a13 * + a24*a35*a52 + a15*a24*a32*a53 - a14*a25*a32*a53 + - a15*a22*a34*a53 + a12*a25*a34*a53 + a14*a22*a35 + *a53 - a12*a24*a35*a53 - a15*a23*a32*a54 + a13*a25 + *a32*a54 + a15*a22*a33*a54 - a12*a25*a33*a54 - a13 + *a22*a35*a54 + a12*a23*a35*a54 + a14*a23*a32*a55 + - a13*a24*a32*a55 - a14*a22*a33*a55 + a12*a24*a33 + *a55 + a13*a22*a34*a55 - a12*a23*a34*a55; + cofactor[4] = a15*a24*a33*a42 - a14*a25*a33*a42 - a15*a23* + a34*a42 + a13*a25*a34*a42 + a14*a23*a35*a42 - a13* + a24*a35*a42 - a15*a24*a32*a43 + a14*a25*a32*a43 + + a15*a22*a34*a43 - a12*a25*a34*a43 - a14*a22*a35* + a43 + a12*a24*a35*a43 + a15*a23*a32*a44 - a13*a25* + a32*a44 - a15*a22*a33*a44 + a12*a25*a33*a44 + a13* + a22*a35*a44 - a12*a23*a35*a44 - a14*a23*a32*a45 + + a13*a24*a32*a45 + a14*a22*a33*a45 - a12*a24*a33* + a45 - a13*a22*a34*a45 + a12*a23*a34*a45; + cofactor[5] = -a25*a34*a43*a51 + a24*a35*a43*a51 + a25*a33 * + a44*a51 - a23*a35*a44*a51 - a24*a33*a45*a51 + a23 * + a34*a45*a51 + a25*a34*a41*a53 - a24*a35*a41*a53 + - a25*a31*a44*a53 + a21*a35*a44*a53 + a24*a31*a45 + *a53 - a21*a34*a45*a53 - a25*a33*a41*a54 + a23*a35 + *a41*a54 + a25*a31*a43*a54 - a21*a35*a43*a54 - a23 + *a31*a45*a54 + a21*a33*a45*a54 + a24*a33*a41*a55 + - a23*a34*a41*a55 - a24*a31*a43*a55 + a21*a34*a43 + *a55 + a23*a31*a44*a55 - a21*a33*a44*a55; + cofactor[6] = a15*a34*a43*a51 - a14*a35*a43*a51 - a15*a33* + a44*a51 + a13*a35*a44*a51 + a14*a33*a45*a51 - a13* + a34*a45*a51 - a15*a34*a41*a53 + a14*a35*a41*a53 + + a15*a31*a44*a53 - a11*a35*a44*a53 - a14*a31*a45* + a53 + a11*a34*a45*a53 + a15*a33*a41*a54 - a13*a35* + a41*a54 - a15*a31*a43*a54 + a11*a35*a43*a54 + a13* + a31*a45*a54 - a11*a33*a45*a54 - a14*a33*a41*a55 + + a13*a34*a41*a55 + a14*a31*a43*a55 - a11*a34*a43* + a55 - a13*a31*a44*a55 + a11*a33*a44*a55; + cofactor[7] = -a15*a24*a43*a51 + a14*a25*a43*a51 + a15*a23 * + a44*a51 - a13*a25*a44*a51 - a14*a23*a45*a51 + a13 * + a24*a45*a51 + a15*a24*a41*a53 - a14*a25*a41*a53 + - a15*a21*a44*a53 + a11*a25*a44*a53 + a14*a21*a45 + *a53 - a11*a24*a45*a53 - a15*a23*a41*a54 + a13*a25 + *a41*a54 + a15*a21*a43*a54 - a11*a25*a43*a54 - a13 + *a21*a45*a54 + a11*a23*a45*a54 + a14*a23*a41*a55 + - a13*a24*a41*a55 - a14*a21*a43*a55 + a11*a24*a43 + *a55 + a13*a21*a44*a55 - a11*a23*a44*a55; + cofactor[8] = a15*a24*a33*a51 - a14*a25*a33*a51 - a15*a23* + a34*a51 + a13*a25*a34*a51 + a14*a23*a35*a51 - a13* + a24*a35*a51 - a15*a24*a31*a53 + a14*a25*a31*a53 + + a15*a21*a34*a53 - a11*a25*a34*a53 - a14*a21*a35* + a53 + a11*a24*a35*a53 + a15*a23*a31*a54 - a13*a25* + a31*a54 - a15*a21*a33*a54 + a11*a25*a33*a54 + a13* + a21*a35*a54 - a11*a23*a35*a54 - a14*a23*a31*a55 + + a13*a24*a31*a55 + a14*a21*a33*a55 - a11*a24*a33* + a55 - a13*a21*a34*a55 + a11*a23*a34*a55; + cofactor[9] = -a15*a24*a33*a41 + a14*a25*a33*a41 + a15*a23 * + a34*a41 - a13*a25*a34*a41 - a14*a23*a35*a41 + a13 * + a24*a35*a41 + a15*a24*a31*a43 - a14*a25*a31*a43 + - a15*a21*a34*a43 + a11*a25*a34*a43 + a14*a21*a35 + *a43 - a11*a24*a35*a43 - a15*a23*a31*a44 + a13*a25 + *a31*a44 + a15*a21*a33*a44 - a11*a25*a33*a44 - a13 + *a21*a35*a44 + a11*a23*a35*a44 + a14*a23*a31*a45 + - a13*a24*a31*a45 - a14*a21*a33*a45 + a11*a24*a33 + *a45 + a13*a21*a34*a45 - a11*a23*a34*a45; + cofactor[10] = a25*a34*a42*a51 - a24*a35*a42*a51 - a25*a32 * + a44*a51 + a22*a35*a44*a51 + a24*a32*a45*a51 - a22 * + a34*a45*a51 - a25*a34*a41*a52 + a24*a35*a41*a52 + + a25*a31*a44*a52 - a21*a35*a44*a52 - a24*a31*a45 + *a52 + a21*a34*a45*a52 + a25*a32*a41*a54 - a22*a35 + *a41*a54 - a25*a31*a42*a54 + a21*a35*a42*a54 + a22 + *a31*a45*a54 - a21*a32*a45*a54 - a24*a32*a41*a55 + + a22*a34*a41*a55 + a24*a31*a42*a55 - a21*a34*a42 + *a55 - a22*a31*a44*a55 + a21*a32*a44*a55; + cofactor[11] = -a15*a34*a42*a51 + a14*a35*a42*a51 + a15*a32 + *a44*a51 - a12*a35*a44*a51 - a14*a32*a45*a51 + a12 + *a34*a45*a51 + a15*a34*a41*a52 - a14*a35*a41*a52 + - a15*a31*a44*a52 + a11*a35*a44*a52 + a14*a31*a45 + *a52 - a11*a34*a45*a52 - a15*a32*a41*a54 + a12*a35 + *a41*a54 + a15*a31*a42*a54 - a11*a35*a42*a54 - a12 + *a31*a45*a54 + a11*a32*a45*a54 + a14*a32*a41*a55 + - a12*a34*a41*a55 - a14*a31*a42*a55 + a11*a34*a42 + *a55 + a12*a31*a44*a55 - a11*a32*a44*a55; + cofactor[12] = a15*a24*a42*a51 - a14*a25*a42*a51 - a15*a22 * + a44*a51 + a12*a25*a44*a51 + a14*a22*a45*a51 - a12 * + a24*a45*a51 - a15*a24*a41*a52 + a14*a25*a41*a52 + + a15*a21*a44*a52 - a11*a25*a44*a52 - a14*a21*a45 + *a52 + a11*a24*a45*a52 + a15*a22*a41*a54 - a12*a25 + *a41*a54 - a15*a21*a42*a54 + a11*a25*a42*a54 + a12 + *a21*a45*a54 - a11*a22*a45*a54 - a14*a22*a41*a55 + + a12*a24*a41*a55 + a14*a21*a42*a55 - a11*a24*a42 + *a55 - a12*a21*a44*a55 + a11*a22*a44*a55; + cofactor[13] = -a15*a24*a32*a51 + a14*a25*a32*a51 + a15*a22 + *a34*a51 - a12*a25*a34*a51 - a14*a22*a35*a51 + a12 + *a24*a35*a51 + a15*a24*a31*a52 - a14*a25*a31*a52 + - a15*a21*a34*a52 + a11*a25*a34*a52 + a14*a21*a35 + *a52 - a11*a24*a35*a52 - a15*a22*a31*a54 + a12*a25 + *a31*a54 + a15*a21*a32*a54 - a11*a25*a32*a54 - a12 + *a21*a35*a54 + a11*a22*a35*a54 + a14*a22*a31*a55 + - a12*a24*a31*a55 - a14*a21*a32*a55 + a11*a24*a32 + *a55 + a12*a21*a34*a55 - a11*a22*a34*a55; + cofactor[14] = a15*a24*a32*a41 - a14*a25*a32*a41 - a15*a22 * + a34*a41 + a12*a25*a34*a41 + a14*a22*a35*a41 - a12 * + a24*a35*a41 - a15*a24*a31*a42 + a14*a25*a31*a42 + + a15*a21*a34*a42 - a11*a25*a34*a42 - a14*a21*a35 + *a42 + a11*a24*a35*a42 + a15*a22*a31*a44 - a12*a25 + *a31*a44 - a15*a21*a32*a44 + a11*a25*a32*a44 + a12 + *a21*a35*a44 - a11*a22*a35*a44 - a14*a22*a31*a45 + + a12*a24*a31*a45 + a14*a21*a32*a45 - a11*a24*a32 + *a45 - a12*a21*a34*a45 + a11*a22*a34*a45; + cofactor[15] = -a25*a33*a42*a51 + a23*a35*a42*a51 + a25*a32 + *a43*a51 - a22*a35*a43*a51 - a23*a32*a45*a51 + a22 + *a33*a45*a51 + a25*a33*a41*a52 - a23*a35*a41*a52 + - a25*a31*a43*a52 + a21*a35*a43*a52 + a23*a31*a45 + *a52 - a21*a33*a45*a52 - a25*a32*a41*a53 + a22*a35 + *a41*a53 + a25*a31*a42*a53 - a21*a35*a42*a53 - a22 + *a31*a45*a53 + a21*a32*a45*a53 + a23*a32*a41*a55 + - a22*a33*a41*a55 - a23*a31*a42*a55 + a21*a33*a42 + *a55 + a22*a31*a43*a55 - a21*a32*a43*a55; + cofactor[16] = a15*a33*a42*a51 - a13*a35*a42*a51 - a15*a32 * + a43*a51 + a12*a35*a43*a51 + a13*a32*a45*a51 - a12 * + a33*a45*a51 - a15*a33*a41*a52 + a13*a35*a41*a52 + + a15*a31*a43*a52 - a11*a35*a43*a52 - a13*a31*a45 + *a52 + a11*a33*a45*a52 + a15*a32*a41*a53 - a12*a35 + *a41*a53 - a15*a31*a42*a53 + a11*a35*a42*a53 + a12 + *a31*a45*a53 - a11*a32*a45*a53 - a13*a32*a41*a55 + + a12*a33*a41*a55 + a13*a31*a42*a55 - a11*a33*a42 + *a55 - a12*a31*a43*a55 + a11*a32*a43*a55; + cofactor[17] = -a15*a23*a42*a51 + a13*a25*a42*a51 + a15*a22 + *a43*a51 - a12*a25*a43*a51 - a13*a22*a45*a51 + a12 + *a23*a45*a51 + a15*a23*a41*a52 - a13*a25*a41*a52 + - a15*a21*a43*a52 + a11*a25*a43*a52 + a13*a21*a45 + *a52 - a11*a23*a45*a52 - a15*a22*a41*a53 + a12*a25 + *a41*a53 + a15*a21*a42*a53 - a11*a25*a42*a53 - a12 + *a21*a45*a53 + a11*a22*a45*a53 + a13*a22*a41*a55 + - a12*a23*a41*a55 - a13*a21*a42*a55 + a11*a23*a42 + *a55 + a12*a21*a43*a55 - a11*a22*a43*a55; + cofactor[18] = a15*a23*a32*a51 - a13*a25*a32*a51 - a15*a22 * + a33*a51 + a12*a25*a33*a51 + a13*a22*a35*a51 - a12 * + a23*a35*a51 - a15*a23*a31*a52 + a13*a25*a31*a52 + + a15*a21*a33*a52 - a11*a25*a33*a52 - a13*a21*a35 + *a52 + a11*a23*a35*a52 + a15*a22*a31*a53 - a12*a25 + *a31*a53 - a15*a21*a32*a53 + a11*a25*a32*a53 + a12 + *a21*a35*a53 - a11*a22*a35*a53 - a13*a22*a31*a55 + + a12*a23*a31*a55 + a13*a21*a32*a55 - a11*a23*a32 + *a55 - a12*a21*a33*a55 + a11*a22*a33*a55; + cofactor[19] = -a15*a23*a32*a41 + a13*a25*a32*a41 + a15*a22 + *a33*a41 - a12*a25*a33*a41 - a13*a22*a35*a41 + a12 + *a23*a35*a41 + a15*a23*a31*a42 - a13*a25*a31*a42 + - a15*a21*a33*a42 + a11*a25*a33*a42 + a13*a21*a35 + *a42 - a11*a23*a35*a42 - a15*a22*a31*a43 + a12*a25 + *a31*a43 + a15*a21*a32*a43 - a11*a25*a32*a43 - a12 + *a21*a35*a43 + a11*a22*a35*a43 + a13*a22*a31*a45 + - a12*a23*a31*a45 - a13*a21*a32*a45 + a11*a23*a32 + *a45 + a12*a21*a33*a45 - a11*a22*a33*a45; + cofactor[20] = a24*a33*a42*a51 - a23*a34*a42*a51 - a24*a32 * + a43*a51 + a22*a34*a43*a51 + a23*a32*a44*a51 - a22 * + a33*a44*a51 - a24*a33*a41*a52 + a23*a34*a41*a52 + + a24*a31*a43*a52 - a21*a34*a43*a52 - a23*a31*a44 + *a52 + a21*a33*a44*a52 + a24*a32*a41*a53 - a22*a34 + *a41*a53 - a24*a31*a42*a53 + a21*a34*a42*a53 + a22 + *a31*a44*a53 - a21*a32*a44*a53 - a23*a32*a41*a54 + + a22*a33*a41*a54 + a23*a31*a42*a54 - a21*a33*a42 + *a54 - a22*a31*a43*a54 + a21*a32*a43*a54; + cofactor[21] = -a14*a33*a42*a51 + a13*a34*a42*a51 + a14*a32 + *a43*a51 - a12*a34*a43*a51 - a13*a32*a44*a51 + a12 + *a33*a44*a51 + a14*a33*a41*a52 - a13*a34*a41*a52 + - a14*a31*a43*a52 + a11*a34*a43*a52 + a13*a31*a44 + *a52 - a11*a33*a44*a52 - a14*a32*a41*a53 + a12*a34 + *a41*a53 + a14*a31*a42*a53 - a11*a34*a42*a53 - a12 + *a31*a44*a53 + a11*a32*a44*a53 + a13*a32*a41*a54 + - a12*a33*a41*a54 - a13*a31*a42*a54 + a11*a33*a42 + *a54 + a12*a31*a43*a54 - a11*a32*a43*a54; + cofactor[22] = a14*a23*a42*a51 - a13*a24*a42*a51 - a14*a22 * + a43*a51 + a12*a24*a43*a51 + a13*a22*a44*a51 - a12 * + a23*a44*a51 - a14*a23*a41*a52 + a13*a24*a41*a52 + + a14*a21*a43*a52 - a11*a24*a43*a52 - a13*a21*a44 + *a52 + a11*a23*a44*a52 + a14*a22*a41*a53 - a12*a24 + *a41*a53 - a14*a21*a42*a53 + a11*a24*a42*a53 + a12 + *a21*a44*a53 - a11*a22*a44*a53 - a13*a22*a41*a54 + + a12*a23*a41*a54 + a13*a21*a42*a54 - a11*a23*a42 + *a54 - a12*a21*a43*a54 + a11*a22*a43*a54; + cofactor[23] = -a14*a23*a32*a51 + a13*a24*a32*a51 + a14*a22 + *a33*a51 - a12*a24*a33*a51 - a13*a22*a34*a51 + a12 + *a23*a34*a51 + a14*a23*a31*a52 - a13*a24*a31*a52 + - a14*a21*a33*a52 + a11*a24*a33*a52 + a13*a21*a34 + *a52 - a11*a23*a34*a52 - a14*a22*a31*a53 + a12*a24 + *a31*a53 + a14*a21*a32*a53 - a11*a24*a32*a53 - a12 + *a21*a34*a53 + a11*a22*a34*a53 + a13*a22*a31*a54 + - a12*a23*a31*a54 - a13*a21*a32*a54 + a11*a23*a32 + *a54 + a12*a21*a33*a54 - a11*a22*a33*a54; + cofactor[24] = a14*a23*a32*a41 - a13*a24*a32*a41 - a14*a22 * + a33*a41 + a12*a24*a33*a41 + a13*a22*a34*a41 - a12 * + a23*a34*a41 - a14*a23*a31*a42 + a13*a24*a31*a42 + + a14*a21*a33*a42 - a11*a24*a33*a42 - a13*a21*a34 + *a42 + a11*a23*a34*a42 + a14*a22*a31*a43 - a12*a24 + *a31*a43 - a14*a21*a32*a43 + a11*a24*a32*a43 + a12 + *a21*a34*a43 - a11*a22*a34*a43 - a13*a22*a31*a44 + + a12*a23*a31*a44 + a13*a21*a32*a44 - a11*a23*a32 + *a44 - a12*a21*a33*a44 + a11*a22*a33*a44; + + for (int i__ = 1; i__ <= 5; ++i__) + for (int j = 1; j <= 5; ++j) + ainv[j + i__*5] = cofactor[i__ + j*5 - 6] / det; + + *ok_flag__ = 0; + return 0; +} + diff --git a/SRC/matrix/routines/invGL6.c b/SRC/matrix/routines/invGL6.c new file mode 100644 index 0000000000..853f4e5aea --- /dev/null +++ b/SRC/matrix/routines/invGL6.c @@ -0,0 +1,5449 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// adapted from https://caps.gsfc.nasa.gov/simpson/software/m66inv_f90.txt +// +// +#include + + +#define a11 a[ 0] +#define a12 a[6] +#define a13 a[12] +#define a14 a[18] +#define a15 a[24] +#define a16 a[30] +#define a21 a[ 1] +#define a22 a[7] +#define a23 a[13] +#define a24 a[19] +#define a25 a[25] +#define a26 a[31] +#define a31 a[ 2] +#define a32 a[8] +#define a33 a[14] +#define a34 a[20] +#define a35 a[26] +#define a36 a[32] +#define a41 a[3] +#define a42 a[9] +#define a43 a[15] +#define a44 a[21] +#define a45 a[27] +#define a46 a[33] +#define a51 a[4] +#define a52 a[10] +#define a53 a[16] +#define a54 a[22] +#define a55 a[28] +#define a56 a[34] +#define a61 a[5] +#define a62 a[11] +#define a63 a[17] +#define a64 a[23] +#define a65 a[29] +#define a66 a[35] + +int cmx_inv6(const double a[36], double *ainv, int*ok_flag__) +{ + double cofactor[36]; + + /* Parameter adjustments */ + + /* Function Body */ + const double eps = 1e-10; + const double + det = - ( a16*a25*a34*a43*a52 + - a15*a26*a34*a43*a52 + - a16*a24*a35*a43*a52 + + a14*a26*a35*a43*a52 + + a15*a24*a36*a43*a52 + - a14*a25*a36*a43*a52 + - a16*a25*a33*a44*a52 + + a15*a26*a33*a44*a52 + + a16*a23*a35*a44*a52 + - a13*a26*a35*a44*a52 + - a15*a23*a36*a44*a52 + + a13*a25*a36*a44*a52 + + a16*a24*a33*a45*a52 + - a14*a26*a33*a45*a52 + - a16*a23*a34*a45*a52 + + a13*a26*a34*a45*a52 + + a14*a23*a36*a45*a52 + - a13*a24*a36*a45*a52 + - a15*a24*a33*a46*a52 + + a14*a25*a33*a46*a52 + + a15*a23*a34*a46*a52 + - a13*a25*a34*a46*a52 + - a14*a23*a35*a46*a52 + + a13*a24*a35*a46*a52 + - a16*a25*a34*a42*a53 + + a15*a26*a34*a42*a53 + + a16*a24*a35*a42*a53 + - a14*a26*a35*a42*a53 + - a15*a24*a36*a42*a53 + + a14*a25*a36*a42*a53 + + a16*a25*a32*a44*a53 + - a15*a26*a32*a44*a53 + - a16*a22*a35*a44*a53 + + + a12*a26*a35*a44*a53 + + a15*a22*a36*a44*a53 + - a12*a25*a36*a44*a53 + - a16*a24*a32*a45*a53 + + a14*a26*a32*a45*a53 + + a16*a22*a34*a45*a53 + - a12*a26*a34*a45*a53 + - a14*a22*a36*a45*a53 + + a12*a24*a36*a45*a53 + + a15*a24*a32*a46*a53 + - a14*a25*a32*a46*a53 + - + a15*a22*a34*a46*a53 + + a12*a25*a34*a46*a53 + + a14*a22*a35*a46*a53 + - a12*a24*a35*a46*a53 + + a16*a25*a33*a42*a54 + - a15*a26*a33*a42*a54 + - a16*a23*a35*a42*a54 + + a13*a26*a35*a42*a54 + + a15*a23*a36*a42*a54 + - a13*a25*a36*a42*a54 + - a16*a25*a32*a43*a54 + + + a15*a26*a32*a43*a54 + + a16*a22*a35*a43*a54 + - a12*a26*a35*a43*a54 + - a15*a22*a36*a43*a54 + + a12*a25*a36*a43*a54 + + a16*a23*a32*a45*a54 + - a13*a26*a32*a45*a54 + - a16*a22*a33*a45*a54 + + a12*a26*a33*a45*a54 + + a13*a22*a36*a45*a54 + - a12*a23*a36*a45*a54 + - + a15*a23*a32*a46*a54 + + a13*a25*a32*a46*a54 + + a15*a22*a33*a46*a54 + - a12*a25*a33*a46*a54 + - a13*a22*a35*a46*a54 + + a12*a23*a35*a46*a54 + - a16*a24*a33*a42*a55 + + a14*a26*a33*a42*a55 + + a16*a23*a34*a42*a55 + - a13*a26*a34*a42*a55 + - a14*a23*a36*a42*a55 + + a13*a24*a36*a42*a55 + + a16*a24*a32*a43*a55 + - a14*a26*a32*a43*a55 + - a16*a22*a34*a43*a55 + + a12*a26*a34*a43*a55 + + a14*a22*a36*a43*a55 + - a12*a24*a36*a43*a55 + - a16*a23*a32*a44*a55 + + a13*a26*a32*a44*a55 + + a16*a22*a33*a44*a55 + - a12*a26*a33*a44*a55 + - a13*a22*a36*a44*a55 + + a12*a23*a36*a44*a55 + + a14*a23*a32*a46*a55 + - a13*a24*a32*a46*a55 + - a14*a22*a33*a46*a55 + + a12*a24*a33*a46*a55 + + a13*a22*a34*a46*a55 + - a12*a23*a34*a46*a55 + + a15*a24*a33*a42*a56 + - a14*a25*a33*a42*a56 + - a15*a23*a34*a42*a56 + + a13*a25*a34*a42*a56 + + a14*a23*a35*a42*a56 + - a13*a24*a35*a42*a56 + - a15*a24*a32*a43*a56 + + a14*a25*a32*a43*a56 + + a15*a22*a34*a43*a56 + - a12*a25*a34*a43*a56 + - a14*a22*a35*a43*a56 + + a12*a24*a35*a43*a56 + + a15*a23*a32*a44*a56 + - a13*a25*a32*a44*a56 + - a15*a22*a33*a44*a56 + + a12*a25*a33*a44*a56 + + a13*a22*a35*a44*a56 + - a12*a23*a35*a44*a56 + - a14*a23*a32*a45*a56 + + a13*a24*a32*a45*a56 + + a14*a22*a33*a45*a56 + - a12*a24*a33*a45*a56 + - a13*a22*a34*a45*a56 + + a12*a23*a34*a45*a56)*a61 + + + (a16*a25*a34*a43*a51 + - a15*a26*a34*a43*a51 + - a16*a24*a35*a43*a51 + + a14*a26*a35*a43*a51 + + a15*a24*a36*a43*a51 + - a14*a25*a36*a43*a51 + - a16*a25*a33*a44*a51 + + a15*a26*a33*a44*a51 + + a16*a23*a35*a44*a51 + - a13*a26*a35*a44*a51 + - a15*a23*a36*a44*a51 + + a13*a25*a36*a44*a51 + + a16*a24*a33*a45*a51 + - a14*a26*a33*a45*a51 + - a16*a23*a34*a45*a51 + + a13*a26*a34*a45*a51 + + a14*a23*a36*a45*a51 + - a13*a24*a36*a45*a51 + - a15*a24*a33*a46*a51 + + a14*a25*a33*a46*a51 + + a15*a23*a34*a46*a51 + - a13*a25*a34*a46*a51 + - a14*a23*a35*a46*a51 + + a13*a24*a35*a46*a51 + - a16*a25*a34*a41*a53 + + a15*a26*a34*a41*a53 + + a16*a24*a35*a41*a53 + - a14*a26*a35*a41*a53 + - a15*a24*a36*a41*a53 + + a14*a25*a36*a41*a53 + + a16*a25*a31*a44*a53 + - a15*a26*a31*a44*a53 + - a16*a21*a35*a44*a53 + + a11*a26*a35*a44*a53 + + a15*a21*a36*a44*a53 + - a11*a25*a36*a44*a53 + - a16*a24*a31*a45*a53 + + a14*a26*a31*a45*a53 + + a16*a21*a34*a45*a53 + - a11*a26*a34*a45*a53 + - a14*a21*a36*a45*a53 + + a11*a24*a36*a45*a53 + + a15*a24*a31*a46*a53 + - a14*a25*a31*a46*a53 + - a15*a21*a34*a46*a53 + + a11*a25*a34*a46*a53 + + a14*a21*a35*a46*a53 + - a11*a24*a35*a46*a53 + + a16*a25*a33*a41*a54 + - a15*a26*a33*a41*a54 + - a16*a23*a35*a41*a54 + + a13*a26*a35*a41*a54 + + a15*a23*a36*a41*a54 + - a13*a25*a36*a41*a54 + - a16*a25*a31*a43*a54 + + a15*a26*a31*a43*a54 + + a16*a21*a35*a43*a54 + - a11*a26*a35*a43*a54 + - a15*a21*a36*a43*a54 + + a11*a25*a36*a43*a54 + + a16*a23*a31*a45*a54 + - a13*a26*a31*a45*a54 + - a16*a21*a33*a45*a54 + + a11*a26*a33*a45*a54 + + a13*a21*a36*a45*a54 + - a11*a23*a36*a45*a54 + - a15*a23*a31*a46*a54 + + a13*a25*a31*a46*a54 + + a15*a21*a33*a46*a54 + - a11*a25*a33*a46*a54 + - a13*a21*a35*a46*a54 + + a11*a23*a35*a46*a54 + - a16*a24*a33*a41*a55 + + a14*a26*a33*a41*a55 + + a16*a23*a34*a41*a55 + - a13*a26*a34*a41*a55 + - a14*a23*a36*a41*a55 + + a13*a24*a36*a41*a55 + + a16*a24*a31*a43*a55 + - a14*a26*a31*a43*a55 + - a16*a21*a34*a43*a55 + + a11*a26*a34*a43*a55 + + a14*a21*a36*a43*a55 + - a11*a24*a36*a43*a55 + - a16*a23*a31*a44*a55 + + a13*a26*a31*a44*a55 + + a16*a21*a33*a44*a55 + - a11*a26*a33*a44*a55 + - a13*a21*a36*a44*a55 + + a11*a23*a36*a44*a55 + + a14*a23*a31*a46*a55 + - a13*a24*a31*a46*a55 + - a14*a21*a33*a46*a55 + + a11*a24*a33*a46*a55 + + a13*a21*a34*a46*a55 + - a11*a23*a34*a46*a55 + + a15*a24*a33*a41*a56 + - a14*a25*a33*a41*a56 + - a15*a23*a34*a41*a56 + + a13*a25*a34*a41*a56 + + a14*a23*a35*a41*a56 + - a13*a24*a35*a41*a56 + - a15*a24*a31*a43*a56 + + a14*a25*a31*a43*a56 + + a15*a21*a34*a43*a56 + - a11*a25*a34*a43*a56 + - a14*a21*a35*a43*a56 + + a11*a24*a35*a43*a56 + + a15*a23*a31*a44*a56 + - a13*a25*a31*a44*a56 + - a15*a21*a33*a44*a56 + + a11*a25*a33*a44*a56 + + a13*a21*a35*a44*a56 + - a11*a23*a35*a44*a56 + - a14*a23*a31*a45*a56 + + a13*a24*a31*a45*a56 + + a14*a21*a33*a45*a56 + - a11*a24*a33*a45*a56 + - a13*a21*a34*a45*a56 + + a11*a23*a34*a45*a56)*a62 + - (a16*a25*a34*a42*a51 + - a15*a26*a34*a42*a51 + - a16*a24*a35*a42*a51 + + a14*a26*a35*a42*a51 + + a15*a24*a36*a42*a51 + - a14*a25*a36*a42*a51 + - a16*a25*a32*a44*a51 + + a15*a26*a32*a44*a51 + + + a16*a22*a35*a44*a51 + - a12*a26*a35*a44*a51 + - a15*a22*a36*a44*a51 + + a12*a25*a36*a44*a51 + + a16*a24*a32*a45*a51 + - a14*a26*a32*a45*a51 + - a16*a22*a34*a45*a51 + + a12*a26*a34*a45*a51 + + a14*a22*a36*a45*a51 + - a12*a24*a36*a45*a51 + - a15*a24*a32*a46*a51 + + + a14*a25*a32*a46*a51 + + a15*a22*a34*a46*a51 + - a12*a25*a34*a46*a51 + - a14*a22*a35*a46*a51 + + a12*a24*a35*a46*a51 + - a16*a25*a34*a41*a52 + + a15*a26*a34*a41*a52 + + a16*a24*a35*a41*a52 + - a14*a26*a35*a41*a52 + - a15*a24*a36*a41*a52 + + a14*a25*a36*a41*a52 + + + a16*a25*a31*a44*a52 + - a15*a26*a31*a44*a52 + - a16*a21*a35*a44*a52 + + a11*a26*a35*a44*a52 + + a15*a21*a36*a44*a52 + - a11*a25*a36*a44*a52 + - a16*a24*a31*a45*a52 + + a14*a26*a31*a45*a52 + + a16*a21*a34*a45*a52 + - a11*a26*a34*a45*a52 + - a14*a21*a36*a45*a52 + + + a11*a24*a36*a45*a52 + + a15*a24*a31*a46*a52 + - a14*a25*a31*a46*a52 + - a15*a21*a34*a46*a52 + + a11*a25*a34*a46*a52 + + a14*a21*a35*a46*a52 + - a11*a24*a35*a46*a52 + + a16*a25*a32*a41*a54 + - a15*a26*a32*a41*a54 + - a16*a22*a35*a41*a54 + + a12*a26*a35*a41*a54 + + + a15*a22*a36*a41*a54 + - a12*a25*a36*a41*a54 + - a16*a25*a31*a42*a54 + + a15*a26*a31*a42*a54 + + a16*a21*a35*a42*a54 + - a11*a26*a35*a42*a54 + - a15*a21*a36*a42*a54 + + a11*a25*a36*a42*a54 + + a16*a22*a31*a45*a54 + - a12*a26*a31*a45*a54 + - a16*a21*a32*a45*a54 + + + a11*a26*a32*a45*a54 + + a12*a21*a36*a45*a54 + - a11*a22*a36*a45*a54 + - a15*a22*a31*a46*a54 + + a12*a25*a31*a46*a54 + + a15*a21*a32*a46*a54 + - a11*a25*a32*a46*a54 + - a12*a21*a35*a46*a54 + + a11*a22*a35*a46*a54 + - a16*a24*a32*a41*a55 + + a14*a26*a32*a41*a55 + + + a16*a22*a34*a41*a55 + - a12*a26*a34*a41*a55 + - a14*a22*a36*a41*a55 + + a12*a24*a36*a41*a55 + + a16*a24*a31*a42*a55 + - a14*a26*a31*a42*a55 + - a16*a21*a34*a42*a55 + + a11*a26*a34*a42*a55 + + a14*a21*a36*a42*a55 + - a11*a24*a36*a42*a55 + - a16*a22*a31*a44*a55 + + + a12*a26*a31*a44*a55 + + a16*a21*a32*a44*a55 + - a11*a26*a32*a44*a55 + - a12*a21*a36*a44*a55 + + a11*a22*a36*a44*a55 + + a14*a22*a31*a46*a55 + - a12*a24*a31*a46*a55 + - a14*a21*a32*a46*a55 + + a11*a24*a32*a46*a55 + + a12*a21*a34*a46*a55 + - a11*a22*a34*a46*a55 + + + a15*a24*a32*a41*a56 + - a14*a25*a32*a41*a56 + - a15*a22*a34*a41*a56 + + a12*a25*a34*a41*a56 + + a14*a22*a35*a41*a56 + - a12*a24*a35*a41*a56 + - a15*a24*a31*a42*a56 + + a14*a25*a31*a42*a56 + + a15*a21*a34*a42*a56 + - a11*a25*a34*a42*a56 + - a14*a21*a35*a42*a56 + + + a11*a24*a35*a42*a56 + + a15*a22*a31*a44*a56 + - a12*a25*a31*a44*a56 + - a15*a21*a32*a44*a56 + + a11*a25*a32*a44*a56 + + a12*a21*a35*a44*a56 + - a11*a22*a35*a44*a56 + - a14*a22*a31*a45*a56 + + a12*a24*a31*a45*a56 + + a14*a21*a32*a45*a56 + - a11*a24*a32*a45*a56 + - + a12*a21*a34*a45*a56 + + a11*a22*a34*a45*a56)*a63 + + (a16*a25*a33*a42*a51 + - a15*a26*a33*a42*a51 + - + a16*a23*a35*a42*a51 + + a13*a26*a35*a42*a51 + + a15*a23*a36*a42*a51 + - a13*a25*a36*a42*a51 + - a16*a25*a32*a43*a51 + + a15*a26*a32*a43*a51 + + a16*a22*a35*a43*a51 + - a12*a26*a35*a43*a51 + - a15*a22*a36*a43*a51 + + a12*a25*a36*a43*a51 + + a16*a23*a32*a45*a51 + - + a13*a26*a32*a45*a51 + - a16*a22*a33*a45*a51 + + a12*a26*a33*a45*a51 + + a13*a22*a36*a45*a51 + - a12*a23*a36*a45*a51 + - a15*a23*a32*a46*a51 + + a13*a25*a32*a46*a51 + + a15*a22*a33*a46*a51 + - a12*a25*a33*a46*a51 + - a13*a22*a35*a46*a51 + + a12*a23*a35*a46*a51 + - + a16*a25*a33*a41*a52 + + a15*a26*a33*a41*a52 + + a16*a23*a35*a41*a52 + - a13*a26*a35*a41*a52 + - a15*a23*a36*a41*a52 + + a13*a25*a36*a41*a52 + + a16*a25*a31*a43*a52 + - a15*a26*a31*a43*a52 + - a16*a21*a35*a43*a52 + + a11*a26*a35*a43*a52 + + a15*a21*a36*a43*a52 + - a11*a25*a36*a43*a52 + - a16*a23*a31*a45*a52 + + a13*a26*a31*a45*a52 + + a16*a21*a33*a45*a52 + - a11*a26*a33*a45*a52 + - a13*a21*a36*a45*a52 + + a11*a23*a36*a45*a52 + + a15*a23*a31*a46*a52 + - a13*a25*a31*a46*a52 + - a15*a21*a33*a46*a52 + + a11*a25*a33*a46*a52 + + a13*a21*a35*a46*a52 + - a11*a23*a35*a46*a52 + + a16*a25*a32*a41*a53 + - a15*a26*a32*a41*a53 + - a16*a22*a35*a41*a53 + + a12*a26*a35*a41*a53 + + a15*a22*a36*a41*a53 + - a12*a25*a36*a41*a53 + - a16*a25*a31*a42*a53 + + a15*a26*a31*a42*a53 + + a16*a21*a35*a42*a53 + - a11*a26*a35*a42*a53 + - a15*a21*a36*a42*a53 + + a11*a25*a36*a42*a53 + + a16*a22*a31*a45*a53 + - a12*a26*a31*a45*a53 + - a16*a21*a32*a45*a53 + + a11*a26*a32*a45*a53 + + a12*a21*a36*a45*a53 + - a11*a22*a36*a45*a53 + - a15*a22*a31*a46*a53 + + a12*a25*a31*a46*a53 + + a15*a21*a32*a46*a53 + - a11*a25*a32*a46*a53 + - a12*a21*a35*a46*a53 + + a11*a22*a35*a46*a53 + - a16*a23*a32*a41*a55 + + a13*a26*a32*a41*a55 + + a16*a22*a33*a41*a55 + - a12*a26*a33*a41*a55 + - a13*a22*a36*a41*a55 + + a12*a23*a36*a41*a55 + + a16*a23*a31*a42*a55 + - a13*a26*a31*a42*a55 + - a16*a21*a33*a42*a55 + + a11*a26*a33*a42*a55 + + a13*a21*a36*a42*a55 + - a11*a23*a36*a42*a55 + - a16*a22*a31*a43*a55 + + a12*a26*a31*a43*a55 + + a16*a21*a32*a43*a55 + - a11*a26*a32*a43*a55 + - a12*a21*a36*a43*a55 + + a11*a22*a36*a43*a55 + + a13*a22*a31*a46*a55 + - a12*a23*a31*a46*a55 + - a13*a21*a32*a46*a55 + + a11*a23*a32*a46*a55 + + a12*a21*a33*a46*a55 + - a11*a22*a33*a46*a55 + + a15*a23*a32*a41*a56 + - a13*a25*a32*a41*a56 + - a15*a22*a33*a41*a56 + + a12*a25*a33*a41*a56 + + a13*a22*a35*a41*a56 + - a12*a23*a35*a41*a56 + - a15*a23*a31*a42*a56 + + a13*a25*a31*a42*a56 + + a15*a21*a33*a42*a56 + - a11*a25*a33*a42*a56 + - a13*a21*a35*a42*a56 + + a11*a23*a35*a42*a56 + + a15*a22*a31*a43*a56 + - a12*a25*a31*a43*a56 + - a15*a21*a32*a43*a56 + + a11*a25*a32*a43*a56 + + a12*a21*a35*a43*a56 + - a11*a22*a35*a43*a56 + - a13*a22*a31*a45*a56 + + a12*a23*a31*a45*a56 + + a13*a21*a32*a45*a56 + - a11*a23*a32*a45*a56 + - a12*a21*a33*a45*a56 + + a11*a22*a33*a45*a56)*a64 + + - (a16*a24*a33*a42*a51 + - a14*a26*a33*a42*a51 + - a16*a23*a34*a42*a51 + + a13*a26*a34*a42*a51 + + a14*a23*a36*a42*a51 + - a13*a24*a36*a42*a51 + - a16*a24*a32*a43*a51 + + a14*a26*a32*a43*a51 + + a16*a22*a34*a43*a51 + - a12*a26*a34*a43*a51 + - a14*a22*a36*a43*a51 + + a12*a24*a36*a43*a51 + + a16*a23*a32*a44*a51 + - a13*a26*a32*a44*a51 + - a16*a22*a33*a44*a51 + + a12*a26*a33*a44*a51 + + a13*a22*a36*a44*a51 + - a12*a23*a36*a44*a51 + - a14*a23*a32*a46*a51 + + a13*a24*a32*a46*a51 + + a14*a22*a33*a46*a51 + - a12*a24*a33*a46*a51 + - a13*a22*a34*a46*a51 + + a12*a23*a34*a46*a51 + - a16*a24*a33*a41*a52 + + a14*a26*a33*a41*a52 + + a16*a23*a34*a41*a52 + - a13*a26*a34*a41*a52 + - a14*a23*a36*a41*a52 + + a13*a24*a36*a41*a52 + + a16*a24*a31*a43*a52 + - a14*a26*a31*a43*a52 + - a16*a21*a34*a43*a52 + + a11*a26*a34*a43*a52 + + a14*a21*a36*a43*a52 + - a11*a24*a36*a43*a52 + - a16*a23*a31*a44*a52 + + a13*a26*a31*a44*a52 + + a16*a21*a33*a44*a52 + - a11*a26*a33*a44*a52 + - a13*a21*a36*a44*a52 + + a11*a23*a36*a44*a52 + + a14*a23*a31*a46*a52 + - a13*a24*a31*a46*a52 + - a14*a21*a33*a46*a52 + + a11*a24*a33*a46*a52 + + a13*a21*a34*a46*a52 + - a11*a23*a34*a46*a52 + + a16*a24*a32*a41*a53 + - a14*a26*a32*a41*a53 + - a16*a22*a34*a41*a53 + + a12*a26*a34*a41*a53 + + a14*a22*a36*a41*a53 + - a12*a24*a36*a41*a53 + - a16*a24*a31*a42*a53 + + a14*a26*a31*a42*a53 + + a16*a21*a34*a42*a53 + - a11*a26*a34*a42*a53 + - a14*a21*a36*a42*a53 + + a11*a24*a36*a42*a53 + + a16*a22*a31*a44*a53 + - a12*a26*a31*a44*a53 + - a16*a21*a32*a44*a53 + + a11*a26*a32*a44*a53 + + a12*a21*a36*a44*a53 + - a11*a22*a36*a44*a53 + - a14*a22*a31*a46*a53 + + a12*a24*a31*a46*a53 + + a14*a21*a32*a46*a53 + - a11*a24*a32*a46*a53 + - a12*a21*a34*a46*a53 + + a11*a22*a34*a46*a53 + - a16*a23*a32*a41*a54 + + a13*a26*a32*a41*a54 + + a16*a22*a33*a41*a54 + - a12*a26*a33*a41*a54 + - a13*a22*a36*a41*a54 + + a12*a23*a36*a41*a54 + + a16*a23*a31*a42*a54 + - a13*a26*a31*a42*a54 + - a16*a21*a33*a42*a54 + + a11*a26*a33*a42*a54 + + a13*a21*a36*a42*a54 + - a11*a23*a36*a42*a54 + - a16*a22*a31*a43*a54 + + a12*a26*a31*a43*a54 + + a16*a21*a32*a43*a54 + - a11*a26*a32*a43*a54 + - a12*a21*a36*a43*a54 + + a11*a22*a36*a43*a54 + + a13*a22*a31*a46*a54 + - a12*a23*a31*a46*a54 + - a13*a21*a32*a46*a54 + + a11*a23*a32*a46*a54 + + a12*a21*a33*a46*a54 + - a11*a22*a33*a46*a54 + + a14*a23*a32*a41*a56 + - a13*a24*a32*a41*a56 + - a14*a22*a33*a41*a56 + + a12*a24*a33*a41*a56 + + a13*a22*a34*a41*a56 + - a12*a23*a34*a41*a56 + - a14*a23*a31*a42*a56 + + a13*a24*a31*a42*a56 + + a14*a21*a33*a42*a56 + - a11*a24*a33*a42*a56 + - a13*a21*a34*a42*a56 + + a11*a23*a34*a42*a56 + + a14*a22*a31*a43*a56 + - a12*a24*a31*a43*a56 + - a14*a21*a32*a43*a56 + + a11*a24*a32*a43*a56 + + a12*a21*a34*a43*a56 + - a11*a22*a34*a43*a56 + - a13*a22*a31*a44*a56 + + a12*a23*a31*a44*a56 + + a13*a21*a32*a44*a56 + - a11*a23*a32*a44*a56 + - a12*a21*a33*a44*a56 + + a11*a22*a33*a44*a56)*a65 + + (a15*a24*a33*a42*a51 + - a14*a25*a33*a42*a51 + - a15*a23*a34*a42*a51 + + a13*a25*a34*a42*a51 + + a14*a23*a35*a42*a51 + - a13*a24*a35*a42*a51 + - a15*a24*a32*a43*a51 + + a14*a25*a32*a43*a51 + + a15*a22*a34*a43*a51 + - a12*a25*a34*a43*a51 + - a14*a22*a35*a43*a51 + + a12*a24*a35*a43*a51 + + a15*a23*a32*a44*a51 + - a13*a25*a32*a44*a51 + - a15*a22*a33*a44*a51 + + a12*a25*a33*a44*a51 + + a13*a22*a35*a44*a51 + - a12*a23*a35*a44*a51 + - a14*a23*a32*a45*a51 + + a13*a24*a32*a45*a51 + + a14*a22*a33*a45*a51 + - + a12*a24*a33*a45*a51 + - a13*a22*a34*a45*a51 + + a12*a23*a34*a45*a51 + - a15*a24*a33*a41*a52 + + a14*a25*a33*a41*a52 + + a15*a23*a34*a41*a52 + - a13*a25*a34*a41*a52 + - a14*a23*a35*a41*a52 + + a13*a24*a35*a41*a52 + + a15*a24*a31*a43*a52 + - a14*a25*a31*a43*a52 + - + a15*a21*a34*a43*a52 + + a11*a25*a34*a43*a52 + + a14*a21*a35*a43*a52 + - a11*a24*a35*a43*a52 + - a15*a23*a31*a44*a52 + + a13*a25*a31*a44*a52 + + a15*a21*a33*a44*a52 + - a11*a25*a33*a44*a52 + - a13*a21*a35*a44*a52 + + a11*a23*a35*a44*a52 + + a14*a23*a31*a45*a52 + - + a13*a24*a31*a45*a52 + - a14*a21*a33*a45*a52 + + a11*a24*a33*a45*a52 + + a13*a21*a34*a45*a52 + - a11*a23*a34*a45*a52 + + a15*a24*a32*a41*a53 + - a14*a25*a32*a41*a53 + - a15*a22*a34*a41*a53 + + a12*a25*a34*a41*a53 + + a14*a22*a35*a41*a53 + - a12*a24*a35*a41*a53 + - + a15*a24*a31*a42*a53 + + a14*a25*a31*a42*a53 + + a15*a21*a34*a42*a53 + - a11*a25*a34*a42*a53 + - a14*a21*a35*a42*a53 + + a11*a24*a35*a42*a53 + + a15*a22*a31*a44*a53 + - a12*a25*a31*a44*a53 + - a15*a21*a32*a44*a53 + + a11*a25*a32*a44*a53 + + a12*a21*a35*a44*a53 + - + a11*a22*a35*a44*a53 + - a14*a22*a31*a45*a53 + + a12*a24*a31*a45*a53 + + a14*a21*a32*a45*a53 + - a11*a24*a32*a45*a53 + - a12*a21*a34*a45*a53 + + a11*a22*a34*a45*a53 + - a15*a23*a32*a41*a54 + + a13*a25*a32*a41*a54 + + a15*a22*a33*a41*a54 + - a12*a25*a33*a41*a54 + - + a13*a22*a35*a41*a54 + + a12*a23*a35*a41*a54 + + a15*a23*a31*a42*a54 + - a13*a25*a31*a42*a54 + - a15*a21*a33*a42*a54 + + a11*a25*a33*a42*a54 + + a13*a21*a35*a42*a54 + - a11*a23*a35*a42*a54 + - a15*a22*a31*a43*a54 + + a12*a25*a31*a43*a54 + + a15*a21*a32*a43*a54 + - + a11*a25*a32*a43*a54 + - a12*a21*a35*a43*a54 + + a11*a22*a35*a43*a54 + + a13*a22*a31*a45*a54 + - a12*a23*a31*a45*a54 + - a13*a21*a32*a45*a54 + + a11*a23*a32*a45*a54 + + a12*a21*a33*a45*a54 + - a11*a22*a33*a45*a54 + + a14*a23*a32*a41*a55 + - a13*a24*a32*a41*a55 + - + a14*a22*a33*a41*a55 + + a12*a24*a33*a41*a55 + + a13*a22*a34*a41*a55 + - a12*a23*a34*a41*a55 + - a14*a23*a31*a42*a55 + + a13*a24*a31*a42*a55 + + a14*a21*a33*a42*a55 + - a11*a24*a33*a42*a55 + - a13*a21*a34*a42*a55 + + a11*a23*a34*a42*a55 + + a14*a22*a31*a43*a55 + - a12*a24*a31*a43*a55 + - a14*a21*a32*a43*a55 + + a11*a24*a32*a43*a55 + + a12*a21*a34*a43*a55 + - a11*a22*a34*a43*a55 + - a13*a22*a31*a44*a55 + + a12*a23*a31*a44*a55 + + a13*a21*a32*a44*a55 + - a11*a23*a32*a44*a55 + - a12*a21*a33*a44*a55 + + a11*a22*a33*a44*a55)*a66; + + if (fabs(det) <= eps) { + // printf("inv6: det = %lf\n", det); + *ok_flag__ = -1; + // return -1; + } + cofactor[0] = a26*a35*a44*a53*a62 + - a25*a36*a44*a53*a62 + - + a26*a34*a45*a53*a62 + + a24*a36*a45*a53*a62 + + a25* + a34*a46*a53*a62 + - a24*a35*a46*a53*a62 + - a26*a35* + a43*a54*a62 + + a25*a36*a43*a54*a62 + + a26*a33*a45* + a54*a62 + - a23*a36*a45*a54*a62 + - a25*a33*a46*a54* + a62 + + a23*a35*a46*a54*a62 + + a26*a34*a43*a55*a62 + - + a24*a36*a43*a55*a62 + - a26*a33*a44*a55*a62 + + a23* + a36*a44*a55*a62 + + a24*a33*a46*a55*a62 + - a23*a34* + a46*a55*a62 + - a25*a34*a43*a56*a62 + + a24*a35*a43* + a56*a62 + + a25*a33*a44*a56*a62 + - a23*a35*a44*a56* + a62 + - a24*a33*a45*a56*a62 + + a23*a34*a45*a56*a62 + - + a26*a35*a44*a52*a63 + + a25*a36*a44*a52*a63 + + a26* + a34*a45*a52*a63 + - a24*a36*a45*a52*a63 + - a25*a34* + a46*a52*a63 + + a24*a35*a46*a52*a63 + + a26*a35*a42* + a54*a63 + - a25*a36*a42*a54*a63 + - a26*a32*a45*a54* + a63 + + a22*a36*a45*a54*a63 + + a25*a32*a46*a54*a63 + - + a22*a35*a46*a54*a63 + - a26*a34*a42*a55*a63 + + a24* + a36*a42*a55*a63 + + a26*a32*a44*a55*a63 + - a22*a36* + a44*a55*a63 + - a24*a32*a46*a55*a63 + + a22*a34*a46* + a55*a63 + + a25*a34*a42*a56*a63 + - a24*a35*a42*a56* + a63 + - a25*a32*a44*a56*a63 + + a22*a35*a44*a56*a63 + + + a24*a32*a45*a56*a63 + - a22*a34*a45*a56*a63 + + a26* + a35*a43*a52*a64 + - a25*a36*a43*a52*a64 + - a26*a33* + a45*a52*a64 + + a23*a36*a45*a52*a64 + + a25*a33*a46* + a52*a64 + - a23*a35*a46*a52*a64 + - a26*a35*a42*a53* + a64 + + a25*a36*a42*a53*a64 + + a26*a32*a45*a53*a64 + - + a22*a36*a45*a53*a64 + - a25*a32*a46*a53*a64 + + a22* + a35*a46*a53*a64 + + a26*a33*a42*a55*a64 + - a23*a36* + a42*a55*a64 + - a26*a32*a43*a55*a64 + + a22*a36*a43* + a55*a64 + + a23*a32*a46*a55*a64 + - a22*a33*a46*a55* + a64 + - a25*a33*a42*a56*a64 + + a23*a35*a42*a56*a64 + + + a25*a32*a43*a56*a64 + - a22*a35*a43*a56*a64 + - a23* + a32*a45*a56*a64 + + a22*a33*a45*a56*a64 + - a26*a34* + a43*a52*a65 + + a24*a36*a43*a52*a65 + + a26*a33*a44* + a52*a65 + - a23*a36*a44*a52*a65 + - a24*a33*a46*a52* + a65 + + a23*a34*a46*a52*a65 + + a26*a34*a42*a53*a65 + - + a24*a36*a42*a53*a65 + - a26*a32*a44*a53*a65 + + a22* + a36*a44*a53*a65 + + a24*a32*a46*a53*a65 + - a22*a34* + a46*a53*a65 + - a26*a33*a42*a54*a65 + + a23*a36*a42* + a54*a65 + + a26*a32*a43*a54*a65 + - a22*a36*a43*a54* + a65 + - a23*a32*a46*a54*a65 + + a22*a33*a46*a54*a65 + + + a24*a33*a42*a56*a65 + - a23*a34*a42*a56*a65 + - a24* + a32*a43*a56*a65 + + a22*a34*a43*a56*a65 + + a23*a32* + a44*a56*a65 + - a22*a33*a44*a56*a65 + + a25*a34*a43* + a52*a66 + - a24*a35*a43*a52*a66 + - a25*a33*a44*a52* + a66 + + a23*a35*a44*a52*a66 + + a24*a33*a45*a52*a66 + - + a23*a34*a45*a52*a66 + - a25*a34*a42*a53*a66 + + a24* + a35*a42*a53*a66 + + a25*a32*a44*a53*a66 + - a22*a35* + a44*a53*a66 + - a24*a32*a45*a53*a66 + + a22*a34*a45* + a53*a66 + + a25*a33*a42*a54*a66 + - a23*a35*a42*a54* + a66 + - a25*a32*a43*a54*a66 + + a22*a35*a43*a54*a66 + + + a23*a32*a45*a54*a66 + - a22*a33*a45*a54*a66 + - a24* + a33*a42*a55*a66 + + a23*a34*a42*a55*a66 + + a24*a32* + a43*a55*a66 + - a22*a34*a43*a55*a66 + - a23*a32*a44* + a55*a66 + + a22*a33*a44*a55*a66; + cofactor[1] = -a16*a35*a44*a53*a62 + + a15*a36*a44*a53*a62 + + a16*a34*a45*a53*a62 + - a14*a36*a45*a53*a62 + - a15*a34*a46*a53*a62 + + a14*a35*a46*a53*a62 + + a16*a35*a43*a54*a62 + - a15*a36*a43*a54*a62 + - a16*a33*a45*a54*a62 + + a13*a36*a45*a54*a62 + + a15*a33*a46*a54*a62 + - a13*a35*a46*a54*a62 + - a16*a34*a43*a55*a62 + + a14*a36*a43*a55*a62 + + a16*a33*a44*a55*a62 + - a13*a36*a44*a55*a62 + - a14*a33*a46*a55*a62 + + a13*a34*a46*a55*a62 + + a15*a34*a43*a56*a62 + - a14*a35*a43*a56*a62 + - a15*a33*a44*a56*a62 + + a13*a35*a44*a56*a62 + + a14*a33*a45*a56*a62 + - a13*a34*a45*a56*a62 + + a16*a35*a44*a52*a63 + - a15*a36*a44*a52*a63 + - a16*a34*a45*a52*a63 + + a14*a36*a45*a52*a63 + + a15*a34*a46*a52*a63 + - a14*a35*a46*a52*a63 + - a16*a35*a42*a54*a63 + + a15*a36*a42*a54*a63 + + a16*a32*a45*a54*a63 + - a12*a36*a45*a54*a63 + - a15*a32*a46*a54*a63 + + a12*a35*a46*a54*a63 + + a16*a34*a42*a55*a63 + - a14*a36*a42*a55*a63 + - a16*a32*a44*a55*a63 + + a12*a36*a44*a55*a63 + + a14*a32*a46*a55*a63 + - a12*a34*a46*a55*a63 + - a15*a34*a42*a56*a63 + + a14*a35*a42*a56*a63 + + a15*a32*a44*a56*a63 + - a12*a35*a44*a56*a63 + - a14*a32*a45*a56*a63 + + a12*a34*a45*a56*a63 + - a16*a35*a43*a52*a64 + + a15*a36*a43*a52*a64 + + a16*a33*a45*a52*a64 + - a13*a36*a45*a52*a64 + - a15*a33*a46*a52*a64 + + a13*a35*a46*a52*a64 + + a16*a35*a42*a53*a64 + - a15*a36*a42*a53*a64 + - a16*a32*a45*a53*a64 + + a12*a36*a45*a53*a64 + + a15*a32*a46*a53*a64 + - a12*a35*a46*a53*a64 + - a16*a33*a42*a55*a64 + + a13*a36*a42*a55*a64 + + a16*a32*a43*a55*a64 + - a12*a36*a43*a55*a64 + - a13*a32*a46*a55*a64 + + a12*a33*a46*a55*a64 + + a15*a33*a42*a56*a64 + - a13*a35*a42*a56*a64 + - a15*a32*a43*a56*a64 + + a12*a35*a43*a56*a64 + + a13*a32*a45*a56*a64 + - a12*a33*a45*a56*a64 + + a16*a34*a43*a52*a65 + - a14*a36*a43*a52*a65 + - a16*a33*a44*a52*a65 + + a13*a36*a44*a52*a65 + + a14*a33*a46*a52*a65 + - a13*a34*a46*a52*a65 + - a16*a34*a42*a53*a65 + + a14*a36*a42*a53*a65 + + a16*a32*a44*a53*a65 + - a12*a36*a44*a53*a65 + - a14*a32*a46*a53*a65 + + a12*a34*a46*a53*a65 + + a16*a33*a42*a54*a65 + - a13*a36*a42*a54*a65 + - a16*a32*a43*a54*a65 + + a12*a36*a43*a54*a65 + + a13*a32*a46*a54*a65 + - a12*a33*a46*a54*a65 + - a14*a33*a42*a56*a65 + + a13*a34*a42*a56*a65 + + a14*a32*a43*a56*a65 + - a12*a34*a43*a56*a65 + - a13*a32*a44*a56*a65 + + a12*a33*a44*a56*a65 + - a15*a34*a43*a52*a66 + + a14*a35*a43*a52*a66 + + a15*a33*a44*a52*a66 + - a13*a35*a44*a52*a66 + - a14*a33*a45*a52*a66 + + a13*a34*a45*a52*a66 + + a15*a34*a42*a53*a66 + - a14*a35*a42*a53*a66 + - a15*a32*a44*a53*a66 + + a12*a35*a44*a53*a66 + + a14*a32*a45*a53*a66 + - a12*a34*a45*a53*a66 + - a15*a33*a42*a54*a66 + + a13*a35*a42*a54*a66 + + a15*a32*a43*a54*a66 + - a12*a35*a43*a54*a66 + - a13*a32*a45*a54*a66 + + a12*a33*a45*a54*a66 + + a14*a33*a42*a55*a66 + - a13*a34*a42*a55*a66 + - a14*a32*a43*a55*a66 + + a12*a34*a43*a55*a66 + + a13*a32*a44*a55*a66 + - a12*a33*a44*a55*a66; + cofactor[2] = a16*a25*a44*a53*a62 + - a15*a26*a44*a53*a62 + - + a16*a24*a45*a53*a62 + + a14*a26*a45*a53*a62 + + a15* + a24*a46*a53*a62 + - a14*a25*a46*a53*a62 + - a16*a25* + a43*a54*a62 + + a15*a26*a43*a54*a62 + + a16*a23*a45* + a54*a62 + - a13*a26*a45*a54*a62 + - a15*a23*a46*a54* + a62 + + a13*a25*a46*a54*a62 + + a16*a24*a43*a55*a62 + - + a14*a26*a43*a55*a62 + - a16*a23*a44*a55*a62 + + a13* + a26*a44*a55*a62 + + a14*a23*a46*a55*a62 + - a13*a24* + a46*a55*a62 + - a15*a24*a43*a56*a62 + + a14*a25*a43* + a56*a62 + + a15*a23*a44*a56*a62 + - a13*a25*a44*a56* + a62 + - a14*a23*a45*a56*a62 + + a13*a24*a45*a56*a62 + - + a16*a25*a44*a52*a63 + + a15*a26*a44*a52*a63 + + a16* + a24*a45*a52*a63 + - a14*a26*a45*a52*a63 + - a15*a24* + a46*a52*a63 + + a14*a25*a46*a52*a63 + + a16*a25*a42* + a54*a63 + - a15*a26*a42*a54*a63 + - a16*a22*a45*a54* + a63 + + a12*a26*a45*a54*a63 + + a15*a22*a46*a54*a63 + - + a12*a25*a46*a54*a63 + - a16*a24*a42*a55*a63 + + a14* + a26*a42*a55*a63 + + a16*a22*a44*a55*a63 + - a12*a26* + a44*a55*a63 + - a14*a22*a46*a55*a63 + + a12*a24*a46* + a55*a63 + + a15*a24*a42*a56*a63 + - a14*a25*a42*a56* + a63 + - a15*a22*a44*a56*a63 + + a12*a25*a44*a56*a63 + + + a14*a22*a45*a56*a63 + - a12*a24*a45*a56*a63 + + a16* + a25*a43*a52*a64 + - a15*a26*a43*a52*a64 + - a16*a23* + a45*a52*a64 + + a13*a26*a45*a52*a64 + + a15*a23*a46* + a52*a64 + - a13*a25*a46*a52*a64 + - a16*a25*a42*a53* + a64 + + a15*a26*a42*a53*a64 + + a16*a22*a45*a53*a64 + - + a12*a26*a45*a53*a64 + - a15*a22*a46*a53*a64 + + a12* + a25*a46*a53*a64 + + a16*a23*a42*a55*a64 + - a13*a26* + a42*a55*a64 + - a16*a22*a43*a55*a64 + + a12*a26*a43* + a55*a64 + + a13*a22*a46*a55*a64 + - a12*a23*a46*a55* + a64 + - a15*a23*a42*a56*a64 + + a13*a25*a42*a56*a64 + + + a15*a22*a43*a56*a64 + - a12*a25*a43*a56*a64 + - a13* + a22*a45*a56*a64 + + a12*a23*a45*a56*a64 + - a16*a24* + a43*a52*a65 + + a14*a26*a43*a52*a65 + + a16*a23*a44* + a52*a65 + - a13*a26*a44*a52*a65 + - a14*a23*a46*a52* + a65 + + a13*a24*a46*a52*a65 + + a16*a24*a42*a53*a65 + - + a14*a26*a42*a53*a65 + - a16*a22*a44*a53*a65 + + a12* + a26*a44*a53*a65 + + a14*a22*a46*a53*a65 + - a12*a24* + a46*a53*a65 + - a16*a23*a42*a54*a65 + + a13*a26*a42* + a54*a65 + + a16*a22*a43*a54*a65 + - a12*a26*a43*a54* + a65 + - a13*a22*a46*a54*a65 + + a12*a23*a46*a54*a65 + + + a14*a23*a42*a56*a65 + - a13*a24*a42*a56*a65 + - a14* + a22*a43*a56*a65 + + a12*a24*a43*a56*a65 + + a13*a22* + a44*a56*a65 + - a12*a23*a44*a56*a65 + + a15*a24*a43* + a52*a66 + - a14*a25*a43*a52*a66 + - a15*a23*a44*a52* + a66 + + a13*a25*a44*a52*a66 + + a14*a23*a45*a52*a66 + - + a13*a24*a45*a52*a66 + - a15*a24*a42*a53*a66 + + a14* + a25*a42*a53*a66 + + a15*a22*a44*a53*a66 + - a12*a25* + a44*a53*a66 + - a14*a22*a45*a53*a66 + + a12*a24*a45* + a53*a66 + + a15*a23*a42*a54*a66 + - a13*a25*a42*a54* + a66 + - a15*a22*a43*a54*a66 + + a12*a25*a43*a54*a66 + + + a13*a22*a45*a54*a66 + - a12*a23*a45*a54*a66 + - a14* + a23*a42*a55*a66 + + a13*a24*a42*a55*a66 + + a14*a22* + a43*a55*a66 + - a12*a24*a43*a55*a66 + - a13*a22*a44* + a55*a66 + + a12*a23*a44*a55*a66; + cofactor[3] = -a16*a25*a34*a53*a62 + + a15*a26*a34*a53*a62 + + a16*a24*a35*a53*a62 + - a14*a26*a35*a53*a62 + - a15*a24*a36*a53*a62 + + a14*a25*a36*a53*a62 + + a16*a25*a33*a54*a62 + - a15*a26*a33*a54*a62 + - a16*a23*a35*a54*a62 + + a13*a26*a35*a54*a62 + + a15*a23*a36*a54*a62 + - a13*a25*a36*a54*a62 + - a16*a24*a33*a55*a62 + + a14*a26*a33*a55*a62 + + a16*a23*a34*a55*a62 + - a13*a26*a34*a55*a62 + - a14*a23*a36*a55*a62 + + a13*a24*a36*a55*a62 + + a15*a24*a33*a56*a62 + - a14*a25*a33*a56*a62 + - a15*a23*a34*a56*a62 + + a13*a25*a34*a56*a62 + + a14*a23*a35*a56*a62 + - a13*a24*a35*a56*a62 + + a16*a25*a34*a52*a63 + - a15*a26*a34*a52*a63 + - a16*a24*a35*a52*a63 + + a14*a26*a35*a52*a63 + + a15*a24*a36*a52*a63 + - a14*a25*a36*a52*a63 + - a16*a25*a32*a54*a63 + + a15*a26*a32*a54*a63 + + a16*a22*a35*a54*a63 + - a12*a26*a35*a54*a63 + - a15*a22*a36*a54*a63 + + a12*a25*a36*a54*a63 + + a16*a24*a32*a55*a63 + - a14*a26*a32*a55*a63 + - a16*a22*a34*a55*a63 + + a12*a26*a34*a55*a63 + + a14*a22*a36*a55*a63 + - a12*a24*a36*a55*a63 + - a15*a24*a32*a56*a63 + + a14*a25*a32*a56*a63 + + a15*a22*a34*a56*a63 + - a12*a25*a34*a56*a63 + - a14*a22*a35*a56*a63 + + a12*a24*a35*a56*a63 + - a16*a25*a33*a52*a64 + + a15*a26*a33*a52*a64 + + a16*a23*a35*a52*a64 + - a13*a26*a35*a52*a64 + - a15*a23*a36*a52*a64 + + a13*a25*a36*a52*a64 + + a16*a25*a32*a53*a64 + - a15*a26*a32*a53*a64 + - a16*a22*a35*a53*a64 + + a12*a26*a35*a53*a64 + + a15*a22*a36*a53*a64 + - a12*a25*a36*a53*a64 + - a16*a23*a32*a55*a64 + + a13*a26*a32*a55*a64 + + a16*a22*a33*a55*a64 + - a12*a26*a33*a55*a64 + - a13*a22*a36*a55*a64 + + a12*a23*a36*a55*a64 + + a15*a23*a32*a56*a64 + - a13*a25*a32*a56*a64 + - a15*a22*a33*a56*a64 + + a12*a25*a33*a56*a64 + + a13*a22*a35*a56*a64 + - a12*a23*a35*a56*a64 + + a16*a24*a33*a52*a65 + - a14*a26*a33*a52*a65 + - a16*a23*a34*a52*a65 + + a13*a26*a34*a52*a65 + + a14*a23*a36*a52*a65 + - a13*a24*a36*a52*a65 + - a16*a24*a32*a53*a65 + + a14*a26*a32*a53*a65 + + a16*a22*a34*a53*a65 + - a12*a26*a34*a53*a65 + - a14*a22*a36*a53*a65 + + a12*a24*a36*a53*a65 + + a16*a23*a32*a54*a65 + - a13*a26*a32*a54*a65 + - a16*a22*a33*a54*a65 + + a12*a26*a33*a54*a65 + + a13*a22*a36*a54*a65 + - a12*a23*a36*a54*a65 + - a14*a23*a32*a56*a65 + + a13*a24*a32*a56*a65 + + a14*a22*a33*a56*a65 + - a12*a24*a33*a56*a65 + - a13*a22*a34*a56*a65 + + a12*a23*a34*a56*a65 + - a15*a24*a33*a52*a66 + + a14*a25*a33*a52*a66 + + a15*a23*a34*a52*a66 + - a13*a25*a34*a52*a66 + - a14*a23*a35*a52*a66 + + a13*a24*a35*a52*a66 + + a15*a24*a32*a53*a66 + - a14*a25*a32*a53*a66 + - a15*a22*a34*a53*a66 + + a12*a25*a34*a53*a66 + + a14*a22*a35*a53*a66 + - a12*a24*a35*a53*a66 + - a15*a23*a32*a54*a66 + + a13*a25*a32*a54*a66 + + a15*a22*a33*a54*a66 + - a12*a25*a33*a54*a66 + - a13*a22*a35*a54*a66 + + a12*a23*a35*a54*a66 + + a14*a23*a32*a55*a66 + - a13*a24*a32*a55*a66 + - a14*a22*a33*a55*a66 + + a12*a24*a33*a55*a66 + + a13*a22*a34*a55*a66 + - a12*a23*a34*a55*a66; + cofactor[4] = a16*a25*a34*a43*a62 + - a15*a26*a34*a43*a62 + - + a16*a24*a35*a43*a62 + + a14*a26*a35*a43*a62 + + a15* + a24*a36*a43*a62 + - a14*a25*a36*a43*a62 + - a16*a25* + a33*a44*a62 + + a15*a26*a33*a44*a62 + + a16*a23*a35* + a44*a62 + - a13*a26*a35*a44*a62 + - a15*a23*a36*a44* + a62 + + a13*a25*a36*a44*a62 + + a16*a24*a33*a45*a62 + - + a14*a26*a33*a45*a62 + - a16*a23*a34*a45*a62 + + a13* + a26*a34*a45*a62 + + a14*a23*a36*a45*a62 + - a13*a24* + a36*a45*a62 + - a15*a24*a33*a46*a62 + + a14*a25*a33* + a46*a62 + + a15*a23*a34*a46*a62 + - a13*a25*a34*a46* + a62 + - a14*a23*a35*a46*a62 + + a13*a24*a35*a46*a62 + - + a16*a25*a34*a42*a63 + + a15*a26*a34*a42*a63 + + a16* + a24*a35*a42*a63 + - a14*a26*a35*a42*a63 + - a15*a24* + a36*a42*a63 + + a14*a25*a36*a42*a63 + + a16*a25*a32* + a44*a63 + - a15*a26*a32*a44*a63 + - a16*a22*a35*a44* + a63 + + a12*a26*a35*a44*a63 + + a15*a22*a36*a44*a63 + - + a12*a25*a36*a44*a63 + - a16*a24*a32*a45*a63 + + a14* + a26*a32*a45*a63 + + a16*a22*a34*a45*a63 + - a12*a26* + a34*a45*a63 + - a14*a22*a36*a45*a63 + + a12*a24*a36* + a45*a63 + + a15*a24*a32*a46*a63 + - a14*a25*a32*a46* + a63 + - a15*a22*a34*a46*a63 + + a12*a25*a34*a46*a63 + + + a14*a22*a35*a46*a63 + - a12*a24*a35*a46*a63 + + a16* + a25*a33*a42*a64 + - a15*a26*a33*a42*a64 + - a16*a23* + a35*a42*a64 + + a13*a26*a35*a42*a64 + + a15*a23*a36* + a42*a64 + - a13*a25*a36*a42*a64 + - a16*a25*a32*a43* + a64 + + a15*a26*a32*a43*a64 + + a16*a22*a35*a43*a64 + - + a12*a26*a35*a43*a64 + - a15*a22*a36*a43*a64 + + a12* + a25*a36*a43*a64 + + a16*a23*a32*a45*a64 + - a13*a26* + a32*a45*a64 + - a16*a22*a33*a45*a64 + + a12*a26*a33* + a45*a64 + + a13*a22*a36*a45*a64 + - a12*a23*a36*a45* + a64 + - a15*a23*a32*a46*a64 + + a13*a25*a32*a46*a64 + + + a15*a22*a33*a46*a64 + - a12*a25*a33*a46*a64 + - a13* + a22*a35*a46*a64 + + a12*a23*a35*a46*a64 + - a16*a24* + a33*a42*a65 + + a14*a26*a33*a42*a65 + + a16*a23*a34* + a42*a65 + - a13*a26*a34*a42*a65 + - a14*a23*a36*a42* + a65 + + a13*a24*a36*a42*a65 + + a16*a24*a32*a43*a65 + - + a14*a26*a32*a43*a65 + - a16*a22*a34*a43*a65 + + a12* + a26*a34*a43*a65 + + a14*a22*a36*a43*a65 + - a12*a24* + a36*a43*a65 + - a16*a23*a32*a44*a65 + + a13*a26*a32* + a44*a65 + + a16*a22*a33*a44*a65 + - a12*a26*a33*a44* + a65 + - a13*a22*a36*a44*a65 + + a12*a23*a36*a44*a65 + + + a14*a23*a32*a46*a65 + - a13*a24*a32*a46*a65 + - a14* + a22*a33*a46*a65 + + a12*a24*a33*a46*a65 + + a13*a22* + a34*a46*a65 + - a12*a23*a34*a46*a65 + + a15*a24*a33* + a42*a66 + - a14*a25*a33*a42*a66 + - a15*a23*a34*a42* + a66 + + a13*a25*a34*a42*a66 + + a14*a23*a35*a42*a66 + - + a13*a24*a35*a42*a66 + - a15*a24*a32*a43*a66 + + a14* + a25*a32*a43*a66 + + a15*a22*a34*a43*a66 + - a12*a25* + a34*a43*a66 + - a14*a22*a35*a43*a66 + + a12*a24*a35* + a43*a66 + + a15*a23*a32*a44*a66 + - a13*a25*a32*a44* + a66 + - a15*a22*a33*a44*a66 + + a12*a25*a33*a44*a66 + + + a13*a22*a35*a44*a66 + - a12*a23*a35*a44*a66 + - a14* + a23*a32*a45*a66 + + a13*a24*a32*a45*a66 + + a14*a22* + a33*a45*a66 + - a12*a24*a33*a45*a66 + - a13*a22*a34* + a45*a66 + + a12*a23*a34*a45*a66; + cofactor[5] = -a16*a25*a34*a43*a52 + + a15*a26*a34*a43*a52 + + a16*a24*a35*a43*a52 + - a14*a26*a35*a43*a52 + - a15*a24*a36*a43*a52 + + a14*a25*a36*a43*a52 + + a16*a25*a33*a44*a52 + - a15*a26*a33*a44*a52 + - a16*a23*a35*a44*a52 + + a13*a26*a35*a44*a52 + + a15*a23*a36*a44*a52 + - a13*a25*a36*a44*a52 + - a16*a24*a33*a45*a52 + + a14*a26*a33*a45*a52 + + a16*a23*a34*a45*a52 + - a13*a26*a34*a45*a52 + - a14*a23*a36*a45*a52 + + a13*a24*a36*a45*a52 + + a15*a24*a33*a46*a52 + - a14*a25*a33*a46*a52 + - a15*a23*a34*a46*a52 + + a13*a25*a34*a46*a52 + + a14*a23*a35*a46*a52 + - a13*a24*a35*a46*a52 + + a16*a25*a34*a42*a53 + - a15*a26*a34*a42*a53 + - a16*a24*a35*a42*a53 + + a14*a26*a35*a42*a53 + + a15*a24*a36*a42*a53 + - a14*a25*a36*a42*a53 + - a16*a25*a32*a44*a53 + + a15*a26*a32*a44*a53 + + a16*a22*a35*a44*a53 + - a12*a26*a35*a44*a53 + - a15*a22*a36*a44*a53 + + a12*a25*a36*a44*a53 + + a16*a24*a32*a45*a53 + - a14*a26*a32*a45*a53 + - a16*a22*a34*a45*a53 + + a12*a26*a34*a45*a53 + + a14*a22*a36*a45*a53 + - a12*a24*a36*a45*a53 + - a15*a24*a32*a46*a53 + + a14*a25*a32*a46*a53 + + a15*a22*a34*a46*a53 + - a12*a25*a34*a46*a53 + - a14*a22*a35*a46*a53 + + a12*a24*a35*a46*a53 + - a16*a25*a33*a42*a54 + + a15*a26*a33*a42*a54 + + a16*a23*a35*a42*a54 + - a13*a26*a35*a42*a54 + - a15*a23*a36*a42*a54 + + a13*a25*a36*a42*a54 + + a16*a25*a32*a43*a54 + - a15*a26*a32*a43*a54 + - a16*a22*a35*a43*a54 + + a12*a26*a35*a43*a54 + + a15*a22*a36*a43*a54 + - a12*a25*a36*a43*a54 + - a16*a23*a32*a45*a54 + + a13*a26*a32*a45*a54 + + a16*a22*a33*a45*a54 + - a12*a26*a33*a45*a54 + - a13*a22*a36*a45*a54 + + a12*a23*a36*a45*a54 + + a15*a23*a32*a46*a54 + - a13*a25*a32*a46*a54 + - a15*a22*a33*a46*a54 + + a12*a25*a33*a46*a54 + + a13*a22*a35*a46*a54 + - a12*a23*a35*a46*a54 + + a16*a24*a33*a42*a55 + - a14*a26*a33*a42*a55 + - a16*a23*a34*a42*a55 + + a13*a26*a34*a42*a55 + + a14*a23*a36*a42*a55 + - a13*a24*a36*a42*a55 + - a16*a24*a32*a43*a55 + + a14*a26*a32*a43*a55 + + a16*a22*a34*a43*a55 + - a12*a26*a34*a43*a55 + - a14*a22*a36*a43*a55 + + a12*a24*a36*a43*a55 + + a16*a23*a32*a44*a55 + - a13*a26*a32*a44*a55 + - a16*a22*a33*a44*a55 + + a12*a26*a33*a44*a55 + + a13*a22*a36*a44*a55 + - a12*a23*a36*a44*a55 + - a14*a23*a32*a46*a55 + + a13*a24*a32*a46*a55 + + a14*a22*a33*a46*a55 + - a12*a24*a33*a46*a55 + - a13*a22*a34*a46*a55 + + a12*a23*a34*a46*a55 + - a15*a24*a33*a42*a56 + + a14*a25*a33*a42*a56 + + a15*a23*a34*a42*a56 + - a13*a25*a34*a42*a56 + - a14*a23*a35*a42*a56 + + a13*a24*a35*a42*a56 + + a15*a24*a32*a43*a56 + - a14*a25*a32*a43*a56 + - a15*a22*a34*a43*a56 + + a12*a25*a34*a43*a56 + + a14*a22*a35*a43*a56 + - a12*a24*a35*a43*a56 + - a15*a23*a32*a44*a56 + + a13*a25*a32*a44*a56 + + a15*a22*a33*a44*a56 + - a12*a25*a33*a44*a56 + - a13*a22*a35*a44*a56 + + a12*a23*a35*a44*a56 + + a14*a23*a32*a45*a56 + - a13*a24*a32*a45*a56 + - a14*a22*a33*a45*a56 + + a12*a24*a33*a45*a56 + + a13*a22*a34*a45*a56 + - a12*a23*a34*a45*a56; + cofactor[6] = -a26*a35*a44*a53*a61 + + a25*a36*a44*a53*a61 + + a26*a34*a45*a53*a61 + - a24*a36*a45*a53*a61 + - a25*a34*a46*a53*a61 + + a24*a35*a46*a53*a61 + + a26*a35*a43*a54*a61 + - a25*a36*a43*a54*a61 + - a26*a33*a45*a54*a61 + + a23*a36*a45*a54*a61 + + a25*a33*a46*a54*a61 + - a23*a35*a46*a54*a61 + - a26*a34*a43*a55*a61 + + a24*a36*a43*a55*a61 + + a26*a33*a44*a55*a61 + - a23*a36*a44*a55*a61 + - a24*a33*a46*a55*a61 + + a23*a34*a46*a55*a61 + + a25*a34*a43*a56*a61 + - a24*a35*a43*a56*a61 + - a25*a33*a44*a56*a61 + + a23*a35*a44*a56*a61 + + a24*a33*a45*a56*a61 + - a23*a34*a45*a56*a61 + + a26*a35*a44*a51*a63 + - a25*a36*a44*a51*a63 + - a26*a34*a45*a51*a63 + + a24*a36*a45*a51*a63 + + a25*a34*a46*a51*a63 + - a24*a35*a46*a51*a63 + - a26*a35*a41*a54*a63 + + a25*a36*a41*a54*a63 + + a26*a31*a45*a54*a63 + - a21*a36*a45*a54*a63 + - a25*a31*a46*a54*a63 + + a21*a35*a46*a54*a63 + + a26*a34*a41*a55*a63 + - a24*a36*a41*a55*a63 + - a26*a31*a44*a55*a63 + + a21*a36*a44*a55*a63 + + a24*a31*a46*a55*a63 + - a21*a34*a46*a55*a63 + - a25*a34*a41*a56*a63 + + a24*a35*a41*a56*a63 + + a25*a31*a44*a56*a63 + - a21*a35*a44*a56*a63 + - a24*a31*a45*a56*a63 + + a21*a34*a45*a56*a63 + - a26*a35*a43*a51*a64 + + a25*a36*a43*a51*a64 + + a26*a33*a45*a51*a64 + - a23*a36*a45*a51*a64 + - a25*a33*a46*a51*a64 + + a23*a35*a46*a51*a64 + + a26*a35*a41*a53*a64 + - a25*a36*a41*a53*a64 + - a26*a31*a45*a53*a64 + + a21*a36*a45*a53*a64 + + a25*a31*a46*a53*a64 + - a21*a35*a46*a53*a64 + - a26*a33*a41*a55*a64 + + a23*a36*a41*a55*a64 + + a26*a31*a43*a55*a64 + - a21*a36*a43*a55*a64 + - a23*a31*a46*a55*a64 + + a21*a33*a46*a55*a64 + + a25*a33*a41*a56*a64 + - a23*a35*a41*a56*a64 + - a25*a31*a43*a56*a64 + + a21*a35*a43*a56*a64 + + a23*a31*a45*a56*a64 + - a21*a33*a45*a56*a64 + + a26*a34*a43*a51*a65 + - a24*a36*a43*a51*a65 + - a26*a33*a44*a51*a65 + + a23*a36*a44*a51*a65 + + a24*a33*a46*a51*a65 + - a23*a34*a46*a51*a65 + - a26*a34*a41*a53*a65 + + a24*a36*a41*a53*a65 + + a26*a31*a44*a53*a65 + - a21*a36*a44*a53*a65 + - a24*a31*a46*a53*a65 + + a21*a34*a46*a53*a65 + + a26*a33*a41*a54*a65 + - a23*a36*a41*a54*a65 + - a26*a31*a43*a54*a65 + + a21*a36*a43*a54*a65 + + a23*a31*a46*a54*a65 + - a21*a33*a46*a54*a65 + - a24*a33*a41*a56*a65 + + a23*a34*a41*a56*a65 + + a24*a31*a43*a56*a65 + - a21*a34*a43*a56*a65 + - a23*a31*a44*a56*a65 + + a21*a33*a44*a56*a65 + - a25*a34*a43*a51*a66 + + a24*a35*a43*a51*a66 + + a25*a33*a44*a51*a66 + - a23*a35*a44*a51*a66 + - a24*a33*a45*a51*a66 + + a23*a34*a45*a51*a66 + + a25*a34*a41*a53*a66 + - a24*a35*a41*a53*a66 + - a25*a31*a44*a53*a66 + + a21*a35*a44*a53*a66 + + a24*a31*a45*a53*a66 + - a21*a34*a45*a53*a66 + - a25*a33*a41*a54*a66 + + a23*a35*a41*a54*a66 + + a25*a31*a43*a54*a66 + - a21*a35*a43*a54*a66 + - a23*a31*a45*a54*a66 + + a21*a33*a45*a54*a66 + + a24*a33*a41*a55*a66 + - a23*a34*a41*a55*a66 + - a24*a31*a43*a55*a66 + + a21*a34*a43*a55*a66 + + a23*a31*a44*a55*a66 + - a21*a33*a44*a55*a66; + cofactor[7] = a16*a35*a44*a53*a61 + - a15*a36*a44*a53*a61 + - + a16*a34*a45*a53*a61 + + a14*a36*a45*a53*a61 + + a15* + a34*a46*a53*a61 + - a14*a35*a46*a53*a61 + - a16*a35* + a43*a54*a61 + + a15*a36*a43*a54*a61 + + a16*a33*a45* + a54*a61 + - a13*a36*a45*a54*a61 + - a15*a33*a46*a54* + a61 + + a13*a35*a46*a54*a61 + + a16*a34*a43*a55*a61 + - + a14*a36*a43*a55*a61 + - a16*a33*a44*a55*a61 + + a13* + a36*a44*a55*a61 + + a14*a33*a46*a55*a61 + - a13*a34* + a46*a55*a61 + - a15*a34*a43*a56*a61 + + a14*a35*a43* + a56*a61 + + a15*a33*a44*a56*a61 + - a13*a35*a44*a56* + a61 + - a14*a33*a45*a56*a61 + + a13*a34*a45*a56*a61 + - + a16*a35*a44*a51*a63 + + a15*a36*a44*a51*a63 + + a16* + a34*a45*a51*a63 + - a14*a36*a45*a51*a63 + - a15*a34* + a46*a51*a63 + + a14*a35*a46*a51*a63 + + a16*a35*a41* + a54*a63 + - a15*a36*a41*a54*a63 + - a16*a31*a45*a54* + a63 + + a11*a36*a45*a54*a63 + + a15*a31*a46*a54*a63 + - + a11*a35*a46*a54*a63 + - a16*a34*a41*a55*a63 + + a14* + a36*a41*a55*a63 + + a16*a31*a44*a55*a63 + - a11*a36* + a44*a55*a63 + - a14*a31*a46*a55*a63 + + a11*a34*a46* + a55*a63 + + a15*a34*a41*a56*a63 + - a14*a35*a41*a56* + a63 + - a15*a31*a44*a56*a63 + + a11*a35*a44*a56*a63 + + + a14*a31*a45*a56*a63 + - a11*a34*a45*a56*a63 + + a16* + a35*a43*a51*a64 + - a15*a36*a43*a51*a64 + - a16*a33* + a45*a51*a64 + + a13*a36*a45*a51*a64 + + a15*a33*a46* + a51*a64 + - a13*a35*a46*a51*a64 + - a16*a35*a41*a53* + a64 + + a15*a36*a41*a53*a64 + + a16*a31*a45*a53*a64 + - + a11*a36*a45*a53*a64 + - a15*a31*a46*a53*a64 + + a11* + a35*a46*a53*a64 + + a16*a33*a41*a55*a64 + - a13*a36* + a41*a55*a64 + - a16*a31*a43*a55*a64 + + a11*a36*a43* + a55*a64 + + a13*a31*a46*a55*a64 + - a11*a33*a46*a55* + a64 + - a15*a33*a41*a56*a64 + + a13*a35*a41*a56*a64 + + + a15*a31*a43*a56*a64 + - a11*a35*a43*a56*a64 + - a13* + a31*a45*a56*a64 + + a11*a33*a45*a56*a64 + - a16*a34* + a43*a51*a65 + + a14*a36*a43*a51*a65 + + a16*a33*a44* + a51*a65 + - a13*a36*a44*a51*a65 + - a14*a33*a46*a51* + a65 + + a13*a34*a46*a51*a65 + + a16*a34*a41*a53*a65 + - + a14*a36*a41*a53*a65 + - a16*a31*a44*a53*a65 + + a11* + a36*a44*a53*a65 + + a14*a31*a46*a53*a65 + - a11*a34* + a46*a53*a65 + - a16*a33*a41*a54*a65 + + a13*a36*a41* + a54*a65 + + a16*a31*a43*a54*a65 + - a11*a36*a43*a54* + a65 + - a13*a31*a46*a54*a65 + + a11*a33*a46*a54*a65 + + + a14*a33*a41*a56*a65 + - a13*a34*a41*a56*a65 + - a14* + a31*a43*a56*a65 + + a11*a34*a43*a56*a65 + + a13*a31* + a44*a56*a65 + - a11*a33*a44*a56*a65 + + a15*a34*a43* + a51*a66 + - a14*a35*a43*a51*a66 + - a15*a33*a44*a51* + a66 + + a13*a35*a44*a51*a66 + + a14*a33*a45*a51*a66 + - + a13*a34*a45*a51*a66 + - a15*a34*a41*a53*a66 + + a14* + a35*a41*a53*a66 + + a15*a31*a44*a53*a66 + - a11*a35* + a44*a53*a66 + - a14*a31*a45*a53*a66 + + a11*a34*a45* + a53*a66 + + a15*a33*a41*a54*a66 + - a13*a35*a41*a54* + a66 + - a15*a31*a43*a54*a66 + + a11*a35*a43*a54*a66 + + + a13*a31*a45*a54*a66 + - a11*a33*a45*a54*a66 + - a14* + a33*a41*a55*a66 + + a13*a34*a41*a55*a66 + + a14*a31* + a43*a55*a66 + - a11*a34*a43*a55*a66 + - a13*a31*a44* + a55*a66 + + a11*a33*a44*a55*a66; + cofactor[8] = -a16*a25*a44*a53*a61 + + a15*a26*a44*a53*a61 + + a16*a24*a45*a53*a61 + - a14*a26*a45*a53*a61 + - a15*a24*a46*a53*a61 + + a14*a25*a46*a53*a61 + + a16*a25*a43*a54*a61 + - a15*a26*a43*a54*a61 + - a16*a23*a45*a54*a61 + + a13*a26*a45*a54*a61 + + a15*a23*a46*a54*a61 + - a13*a25*a46*a54*a61 + - a16*a24*a43*a55*a61 + + a14*a26*a43*a55*a61 + + a16*a23*a44*a55*a61 + - a13*a26*a44*a55*a61 + - a14*a23*a46*a55*a61 + + a13*a24*a46*a55*a61 + + a15*a24*a43*a56*a61 + - a14*a25*a43*a56*a61 + - a15*a23*a44*a56*a61 + + a13*a25*a44*a56*a61 + + a14*a23*a45*a56*a61 + - a13*a24*a45*a56*a61 + + a16*a25*a44*a51*a63 + - a15*a26*a44*a51*a63 + - a16*a24*a45*a51*a63 + + a14*a26*a45*a51*a63 + + a15*a24*a46*a51*a63 + - a14*a25*a46*a51*a63 + - a16*a25*a41*a54*a63 + + a15*a26*a41*a54*a63 + + a16*a21*a45*a54*a63 + - a11*a26*a45*a54*a63 + - a15*a21*a46*a54*a63 + + a11*a25*a46*a54*a63 + + a16*a24*a41*a55*a63 + - a14*a26*a41*a55*a63 + - a16*a21*a44*a55*a63 + + a11*a26*a44*a55*a63 + + a14*a21*a46*a55*a63 + - a11*a24*a46*a55*a63 + - a15*a24*a41*a56*a63 + + a14*a25*a41*a56*a63 + + a15*a21*a44*a56*a63 + - a11*a25*a44*a56*a63 + - a14*a21*a45*a56*a63 + + a11*a24*a45*a56*a63 + - a16*a25*a43*a51*a64 + + a15*a26*a43*a51*a64 + + a16*a23*a45*a51*a64 + - a13*a26*a45*a51*a64 + - a15*a23*a46*a51*a64 + + a13*a25*a46*a51*a64 + + a16*a25*a41*a53*a64 + - a15*a26*a41*a53*a64 + - a16*a21*a45*a53*a64 + + a11*a26*a45*a53*a64 + + a15*a21*a46*a53*a64 + - a11*a25*a46*a53*a64 + - a16*a23*a41*a55*a64 + + a13*a26*a41*a55*a64 + + a16*a21*a43*a55*a64 + - a11*a26*a43*a55*a64 + - a13*a21*a46*a55*a64 + + a11*a23*a46*a55*a64 + + a15*a23*a41*a56*a64 + - a13*a25*a41*a56*a64 + - a15*a21*a43*a56*a64 + + a11*a25*a43*a56*a64 + + a13*a21*a45*a56*a64 + - a11*a23*a45*a56*a64 + + a16*a24*a43*a51*a65 + - a14*a26*a43*a51*a65 + - a16*a23*a44*a51*a65 + + a13*a26*a44*a51*a65 + + a14*a23*a46*a51*a65 + - a13*a24*a46*a51*a65 + - a16*a24*a41*a53*a65 + + a14*a26*a41*a53*a65 + + a16*a21*a44*a53*a65 + - a11*a26*a44*a53*a65 + - a14*a21*a46*a53*a65 + + a11*a24*a46*a53*a65 + + a16*a23*a41*a54*a65 + - a13*a26*a41*a54*a65 + - a16*a21*a43*a54*a65 + + a11*a26*a43*a54*a65 + + a13*a21*a46*a54*a65 + - a11*a23*a46*a54*a65 + - a14*a23*a41*a56*a65 + + a13*a24*a41*a56*a65 + + a14*a21*a43*a56*a65 + - a11*a24*a43*a56*a65 + - a13*a21*a44*a56*a65 + + a11*a23*a44*a56*a65 + - a15*a24*a43*a51*a66 + + a14*a25*a43*a51*a66 + + a15*a23*a44*a51*a66 + - a13*a25*a44*a51*a66 + - a14*a23*a45*a51*a66 + + a13*a24*a45*a51*a66 + + a15*a24*a41*a53*a66 + - a14*a25*a41*a53*a66 + - a15*a21*a44*a53*a66 + + a11*a25*a44*a53*a66 + + a14*a21*a45*a53*a66 + - a11*a24*a45*a53*a66 + - a15*a23*a41*a54*a66 + + a13*a25*a41*a54*a66 + + a15*a21*a43*a54*a66 + - a11*a25*a43*a54*a66 + - a13*a21*a45*a54*a66 + + a11*a23*a45*a54*a66 + + a14*a23*a41*a55*a66 + - a13*a24*a41*a55*a66 + - a14*a21*a43*a55*a66 + + a11*a24*a43*a55*a66 + + a13*a21*a44*a55*a66 + - a11*a23*a44*a55*a66; + cofactor[9] = a16*a25*a34*a53*a61 + - a15*a26*a34*a53*a61 + - + a16*a24*a35*a53*a61 + + a14*a26*a35*a53*a61 + + a15* + a24*a36*a53*a61 + - a14*a25*a36*a53*a61 + - a16*a25* + a33*a54*a61 + + a15*a26*a33*a54*a61 + + a16*a23*a35* + a54*a61 + - a13*a26*a35*a54*a61 + - a15*a23*a36*a54* + a61 + + a13*a25*a36*a54*a61 + + a16*a24*a33*a55*a61 + - + a14*a26*a33*a55*a61 + - a16*a23*a34*a55*a61 + + a13* + a26*a34*a55*a61 + + a14*a23*a36*a55*a61 + - a13*a24* + a36*a55*a61 + - a15*a24*a33*a56*a61 + + a14*a25*a33* + a56*a61 + + a15*a23*a34*a56*a61 + - a13*a25*a34*a56* + a61 + - a14*a23*a35*a56*a61 + + a13*a24*a35*a56*a61 + - + a16*a25*a34*a51*a63 + + a15*a26*a34*a51*a63 + + a16* + a24*a35*a51*a63 + - a14*a26*a35*a51*a63 + - a15*a24* + a36*a51*a63 + + a14*a25*a36*a51*a63 + + a16*a25*a31* + a54*a63 + - a15*a26*a31*a54*a63 + - a16*a21*a35*a54* + a63 + + a11*a26*a35*a54*a63 + + a15*a21*a36*a54*a63 + - + a11*a25*a36*a54*a63 + - a16*a24*a31*a55*a63 + + a14* + a26*a31*a55*a63 + + a16*a21*a34*a55*a63 + - a11*a26* + a34*a55*a63 + - a14*a21*a36*a55*a63 + + a11*a24*a36* + a55*a63 + + a15*a24*a31*a56*a63 + - a14*a25*a31*a56* + a63 + - a15*a21*a34*a56*a63 + + a11*a25*a34*a56*a63 + + + a14*a21*a35*a56*a63 + - a11*a24*a35*a56*a63 + + a16* + a25*a33*a51*a64 + - a15*a26*a33*a51*a64 + - a16*a23* + a35*a51*a64 + + a13*a26*a35*a51*a64 + + a15*a23*a36* + a51*a64 + - a13*a25*a36*a51*a64 + - a16*a25*a31*a53* + a64 + + a15*a26*a31*a53*a64 + + a16*a21*a35*a53*a64 + - + a11*a26*a35*a53*a64 + - a15*a21*a36*a53*a64 + + a11* + a25*a36*a53*a64 + + a16*a23*a31*a55*a64 + - a13*a26* + a31*a55*a64 + - a16*a21*a33*a55*a64 + + a11*a26*a33* + a55*a64 + + a13*a21*a36*a55*a64 + - a11*a23*a36*a55* + a64 + - a15*a23*a31*a56*a64 + + a13*a25*a31*a56*a64 + + + a15*a21*a33*a56*a64 + - a11*a25*a33*a56*a64 + - a13* + a21*a35*a56*a64 + + a11*a23*a35*a56*a64 + - a16*a24* + a33*a51*a65 + + a14*a26*a33*a51*a65 + + a16*a23*a34* + a51*a65 + - a13*a26*a34*a51*a65 + - a14*a23*a36*a51* + a65 + + a13*a24*a36*a51*a65 + + a16*a24*a31*a53*a65 + - + a14*a26*a31*a53*a65 + - a16*a21*a34*a53*a65 + + a11* + a26*a34*a53*a65 + + a14*a21*a36*a53*a65 + - a11*a24* + a36*a53*a65 + - a16*a23*a31*a54*a65 + + a13*a26*a31* + a54*a65 + + a16*a21*a33*a54*a65 + - a11*a26*a33*a54* + a65 + - a13*a21*a36*a54*a65 + + a11*a23*a36*a54*a65 + + + a14*a23*a31*a56*a65 + - a13*a24*a31*a56*a65 + - a14* + a21*a33*a56*a65 + + a11*a24*a33*a56*a65 + + a13*a21* + a34*a56*a65 + - a11*a23*a34*a56*a65 + + a15*a24*a33* + a51*a66 + - a14*a25*a33*a51*a66 + - a15*a23*a34*a51* + a66 + + a13*a25*a34*a51*a66 + + a14*a23*a35*a51*a66 + - + a13*a24*a35*a51*a66 + - a15*a24*a31*a53*a66 + + a14* + a25*a31*a53*a66 + + a15*a21*a34*a53*a66 + - a11*a25* + a34*a53*a66 + - a14*a21*a35*a53*a66 + + a11*a24*a35* + a53*a66 + + a15*a23*a31*a54*a66 + - a13*a25*a31*a54* + a66 + - a15*a21*a33*a54*a66 + + a11*a25*a33*a54*a66 + + + a13*a21*a35*a54*a66 + - a11*a23*a35*a54*a66 + - a14* + a23*a31*a55*a66 + + a13*a24*a31*a55*a66 + + a14*a21* + a33*a55*a66 + - a11*a24*a33*a55*a66 + - a13*a21*a34* + a55*a66 + + a11*a23*a34*a55*a66; + cofactor[10] = -a16*a25*a34*a43*a61 + + a15*a26*a34*a43*a61 + + a16*a24*a35*a43*a61 + - a14*a26*a35*a43*a61 + - a15*a24*a36*a43*a61 + + a14*a25*a36*a43*a61 + + a16*a25*a33*a44*a61 + - a15*a26*a33*a44*a61 + - a16*a23*a35*a44*a61 + + a13*a26*a35*a44*a61 + + a15*a23*a36*a44*a61 + - a13*a25*a36*a44*a61 + - a16*a24*a33*a45*a61 + + a14*a26*a33*a45*a61 + + a16*a23*a34*a45*a61 + - a13*a26*a34*a45*a61 + - a14*a23*a36*a45*a61 + + a13*a24*a36*a45*a61 + + a15*a24*a33*a46*a61 + - a14*a25*a33*a46*a61 + - a15*a23*a34*a46*a61 + + a13*a25*a34*a46*a61 + + a14*a23*a35*a46*a61 + - a13*a24*a35*a46*a61 + + a16*a25*a34*a41*a63 + - a15*a26*a34*a41*a63 + - a16*a24*a35*a41*a63 + + a14*a26*a35*a41*a63 + + a15*a24*a36*a41*a63 + - a14*a25*a36*a41*a63 + - a16*a25*a31*a44*a63 + + a15*a26*a31*a44*a63 + + a16*a21*a35*a44*a63 + - a11*a26*a35*a44*a63 + - a15*a21*a36*a44*a63 + + a11*a25*a36*a44*a63 + + a16*a24*a31*a45*a63 + - a14*a26*a31*a45*a63 + - a16*a21*a34*a45*a63 + + a11*a26*a34*a45*a63 + + a14*a21*a36*a45*a63 + - a11*a24*a36*a45*a63 + - a15*a24*a31*a46*a63 + + a14*a25*a31*a46*a63 + + a15*a21*a34*a46*a63 + - a11*a25*a34*a46*a63 + - a14*a21*a35*a46*a63 + + a11*a24*a35*a46*a63 + - a16*a25*a33*a41*a64 + + a15*a26*a33*a41*a64 + + a16*a23*a35*a41*a64 + - a13*a26*a35*a41*a64 + - a15*a23*a36*a41*a64 + + a13*a25*a36*a41*a64 + + a16*a25*a31*a43*a64 + - a15*a26*a31*a43*a64 + - a16*a21*a35*a43*a64 + + a11*a26*a35*a43*a64 + + a15*a21*a36*a43*a64 + - a11*a25*a36*a43*a64 + - a16*a23*a31*a45*a64 + + a13*a26*a31*a45*a64 + + a16*a21*a33*a45*a64 + - a11*a26*a33*a45*a64 + - a13*a21*a36*a45*a64 + + a11*a23*a36*a45*a64 + + a15*a23*a31*a46*a64 + - a13*a25*a31*a46*a64 + - a15*a21*a33*a46*a64 + + a11*a25*a33*a46*a64 + + a13*a21*a35*a46*a64 + - a11*a23*a35*a46*a64 + + a16*a24*a33*a41*a65 + - a14*a26*a33*a41*a65 + - a16*a23*a34*a41*a65 + + a13*a26*a34*a41*a65 + + a14*a23*a36*a41*a65 + - a13*a24*a36*a41*a65 + - a16*a24*a31*a43*a65 + + a14*a26*a31*a43*a65 + + a16*a21*a34*a43*a65 + - a11*a26*a34*a43*a65 + - a14*a21*a36*a43*a65 + + a11*a24*a36*a43*a65 + + a16*a23*a31*a44*a65 + - a13*a26*a31*a44*a65 + - a16*a21*a33*a44*a65 + + a11*a26*a33*a44*a65 + + a13*a21*a36*a44*a65 + - a11*a23*a36*a44*a65 + - a14*a23*a31*a46*a65 + + a13*a24*a31*a46*a65 + + a14*a21*a33*a46*a65 + - a11*a24*a33*a46*a65 + - a13*a21*a34*a46*a65 + + a11*a23*a34*a46*a65 + - a15*a24*a33*a41*a66 + + a14*a25*a33*a41*a66 + + a15*a23*a34*a41*a66 + - a13*a25*a34*a41*a66 + - a14*a23*a35*a41*a66 + + a13*a24*a35*a41*a66 + + a15*a24*a31*a43*a66 + - a14*a25*a31*a43*a66 + - a15*a21*a34*a43*a66 + + a11*a25*a34*a43*a66 + + a14*a21*a35*a43*a66 + - a11*a24*a35*a43*a66 + - a15*a23*a31*a44*a66 + + a13*a25*a31*a44*a66 + + a15*a21*a33*a44*a66 + - a11*a25*a33*a44*a66 + - a13*a21*a35*a44*a66 + + a11*a23*a35*a44*a66 + + a14*a23*a31*a45*a66 + - a13*a24*a31*a45*a66 + - a14*a21*a33*a45*a66 + + a11*a24*a33*a45*a66 + + a13*a21*a34*a45*a66 + - a11*a23*a34*a45*a66; + cofactor[11] = a16*a25*a34*a43*a51 + - a15*a26*a34*a43*a51 + - a16*a24*a35*a43*a51 + + a14*a26*a35*a43*a51 + + a15*a24*a36*a43*a51 + - a14*a25*a36*a43*a51 + - a16*a25*a33*a44*a51 + + a15*a26*a33*a44*a51 + + a16*a23*a35*a44*a51 + - a13*a26*a35*a44*a51 + - a15*a23*a36*a44*a51 + + a13*a25*a36*a44*a51 + + a16*a24*a33*a45*a51 + - a14*a26*a33*a45*a51 + - a16*a23*a34*a45*a51 + + a13*a26*a34*a45*a51 + + a14*a23*a36*a45*a51 + - a13*a24*a36*a45*a51 + - a15*a24*a33*a46*a51 + + a14*a25*a33*a46*a51 + + a15*a23*a34*a46*a51 + - a13*a25*a34*a46*a51 + - a14*a23*a35*a46*a51 + + a13*a24*a35*a46*a51 + - a16*a25*a34*a41*a53 + + a15*a26*a34*a41*a53 + + a16*a24*a35*a41*a53 + - a14*a26*a35*a41*a53 + - a15*a24*a36*a41*a53 + + a14*a25*a36*a41*a53 + + a16*a25*a31*a44*a53 + - a15*a26*a31*a44*a53 + - a16*a21*a35*a44*a53 + + a11*a26*a35*a44*a53 + + a15*a21*a36*a44*a53 + - a11*a25*a36*a44*a53 + - a16*a24*a31*a45*a53 + + a14*a26*a31*a45*a53 + + a16*a21*a34*a45*a53 + - a11*a26*a34*a45*a53 + - a14*a21*a36*a45*a53 + + a11*a24*a36*a45*a53 + + a15*a24*a31*a46*a53 + - a14*a25*a31*a46*a53 + - a15*a21*a34*a46*a53 + + a11*a25*a34*a46*a53 + + a14*a21*a35*a46*a53 + - a11*a24*a35*a46*a53 + + a16*a25*a33*a41*a54 + - a15*a26*a33*a41*a54 + - a16*a23*a35*a41*a54 + + a13*a26*a35*a41*a54 + + a15*a23*a36*a41*a54 + - a13*a25*a36*a41*a54 + - a16*a25*a31*a43*a54 + + a15*a26*a31*a43*a54 + + a16*a21*a35*a43*a54 + - a11*a26*a35*a43*a54 + - a15*a21*a36*a43*a54 + + a11*a25*a36*a43*a54 + + a16*a23*a31*a45*a54 + - a13*a26*a31*a45*a54 + - a16*a21*a33*a45*a54 + + a11*a26*a33*a45*a54 + + a13*a21*a36*a45*a54 + - a11*a23*a36*a45*a54 + - a15*a23*a31*a46*a54 + + a13*a25*a31*a46*a54 + + a15*a21*a33*a46*a54 + - a11*a25*a33*a46*a54 + - a13*a21*a35*a46*a54 + + a11*a23*a35*a46*a54 + - a16*a24*a33*a41*a55 + + a14*a26*a33*a41*a55 + + a16*a23*a34*a41*a55 + - a13*a26*a34*a41*a55 + - a14*a23*a36*a41*a55 + + a13*a24*a36*a41*a55 + + a16*a24*a31*a43*a55 + - a14*a26*a31*a43*a55 + - a16*a21*a34*a43*a55 + + a11*a26*a34*a43*a55 + + a14*a21*a36*a43*a55 + - a11*a24*a36*a43*a55 + - a16*a23*a31*a44*a55 + + a13*a26*a31*a44*a55 + + a16*a21*a33*a44*a55 + - a11*a26*a33*a44*a55 + - a13*a21*a36*a44*a55 + + a11*a23*a36*a44*a55 + + a14*a23*a31*a46*a55 + - a13*a24*a31*a46*a55 + - a14*a21*a33*a46*a55 + + a11*a24*a33*a46*a55 + + a13*a21*a34*a46*a55 + - a11*a23*a34*a46*a55 + + a15*a24*a33*a41*a56 + - a14*a25*a33*a41*a56 + - a15*a23*a34*a41*a56 + + a13*a25*a34*a41*a56 + + a14*a23*a35*a41*a56 + - a13*a24*a35*a41*a56 + - a15*a24*a31*a43*a56 + + a14*a25*a31*a43*a56 + + a15*a21*a34*a43*a56 + - a11*a25*a34*a43*a56 + - a14*a21*a35*a43*a56 + + a11*a24*a35*a43*a56 + + a15*a23*a31*a44*a56 + - a13*a25*a31*a44*a56 + - a15*a21*a33*a44*a56 + + a11*a25*a33*a44*a56 + + a13*a21*a35*a44*a56 + - a11*a23*a35*a44*a56 + - a14*a23*a31*a45*a56 + + a13*a24*a31*a45*a56 + + a14*a21*a33*a45*a56 + - a11*a24*a33*a45*a56 + - a13*a21*a34*a45*a56 + + a11*a23*a34*a45*a56; + cofactor[12] = a26*a35*a44*a52*a61 + - a25*a36*a44*a52*a61 + - a26*a34*a45*a52*a61 + + a24*a36*a45*a52*a61 + + a25*a34*a46*a52*a61 + - a24*a35*a46*a52*a61 + - a26*a35*a42*a54*a61 + + a25*a36*a42*a54*a61 + + a26*a32*a45*a54*a61 + - a22*a36*a45*a54*a61 + - a25*a32*a46*a54*a61 + + a22*a35*a46*a54*a61 + + a26*a34*a42*a55*a61 + - a24*a36*a42*a55*a61 + - a26*a32*a44*a55*a61 + + a22*a36*a44*a55*a61 + + a24*a32*a46*a55*a61 + - a22*a34*a46*a55*a61 + - a25*a34*a42*a56*a61 + + a24*a35*a42*a56*a61 + + a25*a32*a44*a56*a61 + - a22*a35*a44*a56*a61 + - a24*a32*a45*a56*a61 + + a22*a34*a45*a56*a61 + - a26*a35*a44*a51*a62 + + a25*a36*a44*a51*a62 + + a26*a34*a45*a51*a62 + - a24*a36*a45*a51*a62 + - a25*a34*a46*a51*a62 + + a24*a35*a46*a51*a62 + + a26*a35*a41*a54*a62 + - a25*a36*a41*a54*a62 + - a26*a31*a45*a54*a62 + + a21*a36*a45*a54*a62 + + a25*a31*a46*a54*a62 + - a21*a35*a46*a54*a62 + - a26*a34*a41*a55*a62 + + a24*a36*a41*a55*a62 + + a26*a31*a44*a55*a62 + - a21*a36*a44*a55*a62 + - a24*a31*a46*a55*a62 + + a21*a34*a46*a55*a62 + + a25*a34*a41*a56*a62 + - a24*a35*a41*a56*a62 + - a25*a31*a44*a56*a62 + + a21*a35*a44*a56*a62 + + a24*a31*a45*a56*a62 + - a21*a34*a45*a56*a62 + + a26*a35*a42*a51*a64 + - a25*a36*a42*a51*a64 + - a26*a32*a45*a51*a64 + + a22*a36*a45*a51*a64 + + a25*a32*a46*a51*a64 + - a22*a35*a46*a51*a64 + - a26*a35*a41*a52*a64 + + a25*a36*a41*a52*a64 + + a26*a31*a45*a52*a64 + - a21*a36*a45*a52*a64 + - a25*a31*a46*a52*a64 + + a21*a35*a46*a52*a64 + + a26*a32*a41*a55*a64 + - a22*a36*a41*a55*a64 + - a26*a31*a42*a55*a64 + + a21*a36*a42*a55*a64 + + a22*a31*a46*a55*a64 + - a21*a32*a46*a55*a64 + - a25*a32*a41*a56*a64 + + a22*a35*a41*a56*a64 + + a25*a31*a42*a56*a64 + - a21*a35*a42*a56*a64 + - a22*a31*a45*a56*a64 + + a21*a32*a45*a56*a64 + - a26*a34*a42*a51*a65 + + a24*a36*a42*a51*a65 + + a26*a32*a44*a51*a65 + - a22*a36*a44*a51*a65 + - a24*a32*a46*a51*a65 + + a22*a34*a46*a51*a65 + + a26*a34*a41*a52*a65 + - a24*a36*a41*a52*a65 + - a26*a31*a44*a52*a65 + + a21*a36*a44*a52*a65 + + a24*a31*a46*a52*a65 + - a21*a34*a46*a52*a65 + - a26*a32*a41*a54*a65 + + a22*a36*a41*a54*a65 + + a26*a31*a42*a54*a65 + - a21*a36*a42*a54*a65 + - a22*a31*a46*a54*a65 + + a21*a32*a46*a54*a65 + + a24*a32*a41*a56*a65 + - a22*a34*a41*a56*a65 + - a24*a31*a42*a56*a65 + + a21*a34*a42*a56*a65 + + a22*a31*a44*a56*a65 + - a21*a32*a44*a56*a65 + + a25*a34*a42*a51*a66 + - a24*a35*a42*a51*a66 + - a25*a32*a44*a51*a66 + + a22*a35*a44*a51*a66 + + a24*a32*a45*a51*a66 + - a22*a34*a45*a51*a66 + - a25*a34*a41*a52*a66 + + a24*a35*a41*a52*a66 + + a25*a31*a44*a52*a66 + - a21*a35*a44*a52*a66 + - a24*a31*a45*a52*a66 + + a21*a34*a45*a52*a66 + + a25*a32*a41*a54*a66 + - a22*a35*a41*a54*a66 + - a25*a31*a42*a54*a66 + + a21*a35*a42*a54*a66 + + a22*a31*a45*a54*a66 + - a21*a32*a45*a54*a66 + - a24*a32*a41*a55*a66 + + a22*a34*a41*a55*a66 + + a24*a31*a42*a55*a66 + - a21*a34*a42*a55*a66 + - a22*a31*a44*a55*a66 + + a21*a32*a44*a55*a66; + cofactor[13] = -a16*a35*a44*a52*a61 + + a15*a36*a44*a52*a61 + + a16*a34*a45*a52*a61 + - a14*a36*a45*a52*a61 + - a15*a34*a46*a52*a61 + + a14*a35*a46*a52*a61 + + a16*a35*a42*a54*a61 + - a15*a36*a42*a54*a61 + - a16*a32*a45*a54*a61 + + a12*a36*a45*a54*a61 + + a15*a32*a46*a54*a61 + - a12*a35*a46*a54*a61 + - a16*a34*a42*a55*a61 + + a14*a36*a42*a55*a61 + + a16*a32*a44*a55*a61 + - a12*a36*a44*a55*a61 + - a14*a32*a46*a55*a61 + + a12*a34*a46*a55*a61 + + a15*a34*a42*a56*a61 + - a14*a35*a42*a56*a61 + - a15*a32*a44*a56*a61 + + a12*a35*a44*a56*a61 + + a14*a32*a45*a56*a61 + - a12*a34*a45*a56*a61 + + a16*a35*a44*a51*a62 + - a15*a36*a44*a51*a62 + - a16*a34*a45*a51*a62 + + a14*a36*a45*a51*a62 + + a15*a34*a46*a51*a62 + - a14*a35*a46*a51*a62 + - a16*a35*a41*a54*a62 + + a15*a36*a41*a54*a62 + + a16*a31*a45*a54*a62 + - a11*a36*a45*a54*a62 + - a15*a31*a46*a54*a62 + + a11*a35*a46*a54*a62 + + a16*a34*a41*a55*a62 + - a14*a36*a41*a55*a62 + - a16*a31*a44*a55*a62 + + a11*a36*a44*a55*a62 + + a14*a31*a46*a55*a62 + - a11*a34*a46*a55*a62 + - a15*a34*a41*a56*a62 + + a14*a35*a41*a56*a62 + + a15*a31*a44*a56*a62 + - a11*a35*a44*a56*a62 + - a14*a31*a45*a56*a62 + + a11*a34*a45*a56*a62 + - a16*a35*a42*a51*a64 + + a15*a36*a42*a51*a64 + + a16*a32*a45*a51*a64 + - a12*a36*a45*a51*a64 + - a15*a32*a46*a51*a64 + + a12*a35*a46*a51*a64 + + a16*a35*a41*a52*a64 + - a15*a36*a41*a52*a64 + - a16*a31*a45*a52*a64 + + a11*a36*a45*a52*a64 + + a15*a31*a46*a52*a64 + - a11*a35*a46*a52*a64 + - a16*a32*a41*a55*a64 + + a12*a36*a41*a55*a64 + + a16*a31*a42*a55*a64 + - a11*a36*a42*a55*a64 + - a12*a31*a46*a55*a64 + + a11*a32*a46*a55*a64 + + a15*a32*a41*a56*a64 + - a12*a35*a41*a56*a64 + - a15*a31*a42*a56*a64 + + a11*a35*a42*a56*a64 + + a12*a31*a45*a56*a64 + - a11*a32*a45*a56*a64 + + a16*a34*a42*a51*a65 + - a14*a36*a42*a51*a65 + - a16*a32*a44*a51*a65 + + a12*a36*a44*a51*a65 + + a14*a32*a46*a51*a65 + - a12*a34*a46*a51*a65 + - a16*a34*a41*a52*a65 + + a14*a36*a41*a52*a65 + + a16*a31*a44*a52*a65 + - a11*a36*a44*a52*a65 + - a14*a31*a46*a52*a65 + + a11*a34*a46*a52*a65 + + a16*a32*a41*a54*a65 + - a12*a36*a41*a54*a65 + - a16*a31*a42*a54*a65 + + a11*a36*a42*a54*a65 + + a12*a31*a46*a54*a65 + - a11*a32*a46*a54*a65 + - a14*a32*a41*a56*a65 + + a12*a34*a41*a56*a65 + + a14*a31*a42*a56*a65 + - a11*a34*a42*a56*a65 + - a12*a31*a44*a56*a65 + + a11*a32*a44*a56*a65 + - a15*a34*a42*a51*a66 + + a14*a35*a42*a51*a66 + + a15*a32*a44*a51*a66 + - a12*a35*a44*a51*a66 + - a14*a32*a45*a51*a66 + + a12*a34*a45*a51*a66 + + a15*a34*a41*a52*a66 + - a14*a35*a41*a52*a66 + - a15*a31*a44*a52*a66 + + a11*a35*a44*a52*a66 + + a14*a31*a45*a52*a66 + - a11*a34*a45*a52*a66 + - a15*a32*a41*a54*a66 + + a12*a35*a41*a54*a66 + + a15*a31*a42*a54*a66 + - a11*a35*a42*a54*a66 + - a12*a31*a45*a54*a66 + + a11*a32*a45*a54*a66 + + a14*a32*a41*a55*a66 + - a12*a34*a41*a55*a66 + - a14*a31*a42*a55*a66 + + a11*a34*a42*a55*a66 + + a12*a31*a44*a55*a66 + - a11*a32*a44*a55*a66; + cofactor[14] = a16*a25*a44*a52*a61 + - a15*a26*a44*a52*a61 + - a16*a24*a45*a52*a61 + + a14*a26*a45*a52*a61 + + a15*a24*a46*a52*a61 + - a14*a25*a46*a52*a61 + - a16*a25*a42*a54*a61 + + a15*a26*a42*a54*a61 + + a16*a22*a45*a54*a61 + - a12*a26*a45*a54*a61 + - a15*a22*a46*a54*a61 + + a12*a25*a46*a54*a61 + + a16*a24*a42*a55*a61 + - a14*a26*a42*a55*a61 + - a16*a22*a44*a55*a61 + + a12*a26*a44*a55*a61 + + a14*a22*a46*a55*a61 + - a12*a24*a46*a55*a61 + - a15*a24*a42*a56*a61 + + a14*a25*a42*a56*a61 + + a15*a22*a44*a56*a61 + - a12*a25*a44*a56*a61 + - a14*a22*a45*a56*a61 + + a12*a24*a45*a56*a61 + - a16*a25*a44*a51*a62 + + a15*a26*a44*a51*a62 + + a16*a24*a45*a51*a62 + - a14*a26*a45*a51*a62 + - a15*a24*a46*a51*a62 + + a14*a25*a46*a51*a62 + + a16*a25*a41*a54*a62 + - a15*a26*a41*a54*a62 + - a16*a21*a45*a54*a62 + + a11*a26*a45*a54*a62 + + a15*a21*a46*a54*a62 + - a11*a25*a46*a54*a62 + - a16*a24*a41*a55*a62 + + a14*a26*a41*a55*a62 + + a16*a21*a44*a55*a62 + - a11*a26*a44*a55*a62 + - a14*a21*a46*a55*a62 + + a11*a24*a46*a55*a62 + + a15*a24*a41*a56*a62 + - a14*a25*a41*a56*a62 + - a15*a21*a44*a56*a62 + + a11*a25*a44*a56*a62 + + a14*a21*a45*a56*a62 + - a11*a24*a45*a56*a62 + + a16*a25*a42*a51*a64 + - a15*a26*a42*a51*a64 + - a16*a22*a45*a51*a64 + + a12*a26*a45*a51*a64 + + a15*a22*a46*a51*a64 + - a12*a25*a46*a51*a64 + - a16*a25*a41*a52*a64 + + a15*a26*a41*a52*a64 + + a16*a21*a45*a52*a64 + - a11*a26*a45*a52*a64 + - a15*a21*a46*a52*a64 + + a11*a25*a46*a52*a64 + + a16*a22*a41*a55*a64 + - a12*a26*a41*a55*a64 + - a16*a21*a42*a55*a64 + + a11*a26*a42*a55*a64 + + a12*a21*a46*a55*a64 + - a11*a22*a46*a55*a64 + - a15*a22*a41*a56*a64 + + a12*a25*a41*a56*a64 + + a15*a21*a42*a56*a64 + - a11*a25*a42*a56*a64 + - a12*a21*a45*a56*a64 + + a11*a22*a45*a56*a64 + - a16*a24*a42*a51*a65 + + a14*a26*a42*a51*a65 + + a16*a22*a44*a51*a65 + - a12*a26*a44*a51*a65 + - a14*a22*a46*a51*a65 + + a12*a24*a46*a51*a65 + + a16*a24*a41*a52*a65 + - a14*a26*a41*a52*a65 + - a16*a21*a44*a52*a65 + + a11*a26*a44*a52*a65 + + a14*a21*a46*a52*a65 + - a11*a24*a46*a52*a65 + - a16*a22*a41*a54*a65 + + a12*a26*a41*a54*a65 + + a16*a21*a42*a54*a65 + - a11*a26*a42*a54*a65 + - a12*a21*a46*a54*a65 + + a11*a22*a46*a54*a65 + + a14*a22*a41*a56*a65 + - a12*a24*a41*a56*a65 + - a14*a21*a42*a56*a65 + + a11*a24*a42*a56*a65 + + a12*a21*a44*a56*a65 + - a11*a22*a44*a56*a65 + + a15*a24*a42*a51*a66 + - a14*a25*a42*a51*a66 + - a15*a22*a44*a51*a66 + + a12*a25*a44*a51*a66 + + a14*a22*a45*a51*a66 + - a12*a24*a45*a51*a66 + - a15*a24*a41*a52*a66 + + a14*a25*a41*a52*a66 + + a15*a21*a44*a52*a66 + - a11*a25*a44*a52*a66 + - a14*a21*a45*a52*a66 + + a11*a24*a45*a52*a66 + + a15*a22*a41*a54*a66 + - a12*a25*a41*a54*a66 + - a15*a21*a42*a54*a66 + + a11*a25*a42*a54*a66 + + a12*a21*a45*a54*a66 + - a11*a22*a45*a54*a66 + - a14*a22*a41*a55*a66 + + a12*a24*a41*a55*a66 + + a14*a21*a42*a55*a66 + - a11*a24*a42*a55*a66 + - a12*a21*a44*a55*a66 + + a11*a22*a44*a55*a66; + cofactor[15] = -a16*a25*a34*a52*a61 + + a15*a26*a34*a52*a61 + + a16*a24*a35*a52*a61 + - a14*a26*a35*a52*a61 + - a15*a24*a36*a52*a61 + + a14*a25*a36*a52*a61 + + a16*a25*a32*a54*a61 + - a15*a26*a32*a54*a61 + - a16*a22*a35*a54*a61 + + a12*a26*a35*a54*a61 + + a15*a22*a36*a54*a61 + - a12*a25*a36*a54*a61 + - a16*a24*a32*a55*a61 + + a14*a26*a32*a55*a61 + + a16*a22*a34*a55*a61 + - a12*a26*a34*a55*a61 + - a14*a22*a36*a55*a61 + + a12*a24*a36*a55*a61 + + a15*a24*a32*a56*a61 + - a14*a25*a32*a56*a61 + - a15*a22*a34*a56*a61 + + a12*a25*a34*a56*a61 + + a14*a22*a35*a56*a61 + - a12*a24*a35*a56*a61 + + a16*a25*a34*a51*a62 + - a15*a26*a34*a51*a62 + - a16*a24*a35*a51*a62 + + a14*a26*a35*a51*a62 + + a15*a24*a36*a51*a62 + - a14*a25*a36*a51*a62 + - a16*a25*a31*a54*a62 + + a15*a26*a31*a54*a62 + + a16*a21*a35*a54*a62 + - a11*a26*a35*a54*a62 + - a15*a21*a36*a54*a62 + + a11*a25*a36*a54*a62 + + a16*a24*a31*a55*a62 + - a14*a26*a31*a55*a62 + - a16*a21*a34*a55*a62 + + a11*a26*a34*a55*a62 + + a14*a21*a36*a55*a62 + - a11*a24*a36*a55*a62 + - a15*a24*a31*a56*a62 + + a14*a25*a31*a56*a62 + + a15*a21*a34*a56*a62 + - a11*a25*a34*a56*a62 + - a14*a21*a35*a56*a62 + + a11*a24*a35*a56*a62 + - a16*a25*a32*a51*a64 + + a15*a26*a32*a51*a64 + + a16*a22*a35*a51*a64 + - a12*a26*a35*a51*a64 + - a15*a22*a36*a51*a64 + + a12*a25*a36*a51*a64 + + a16*a25*a31*a52*a64 + - a15*a26*a31*a52*a64 + - a16*a21*a35*a52*a64 + + a11*a26*a35*a52*a64 + + a15*a21*a36*a52*a64 + - a11*a25*a36*a52*a64 + - a16*a22*a31*a55*a64 + + a12*a26*a31*a55*a64 + + a16*a21*a32*a55*a64 + - a11*a26*a32*a55*a64 + - a12*a21*a36*a55*a64 + + a11*a22*a36*a55*a64 + + a15*a22*a31*a56*a64 + - a12*a25*a31*a56*a64 + - a15*a21*a32*a56*a64 + + a11*a25*a32*a56*a64 + + a12*a21*a35*a56*a64 + - a11*a22*a35*a56*a64 + + a16*a24*a32*a51*a65 + - a14*a26*a32*a51*a65 + - a16*a22*a34*a51*a65 + + a12*a26*a34*a51*a65 + + a14*a22*a36*a51*a65 + - a12*a24*a36*a51*a65 + - a16*a24*a31*a52*a65 + + a14*a26*a31*a52*a65 + + a16*a21*a34*a52*a65 + - a11*a26*a34*a52*a65 + - a14*a21*a36*a52*a65 + + a11*a24*a36*a52*a65 + + a16*a22*a31*a54*a65 + - a12*a26*a31*a54*a65 + - a16*a21*a32*a54*a65 + + a11*a26*a32*a54*a65 + + a12*a21*a36*a54*a65 + - a11*a22*a36*a54*a65 + - a14*a22*a31*a56*a65 + + a12*a24*a31*a56*a65 + + a14*a21*a32*a56*a65 + - a11*a24*a32*a56*a65 + - a12*a21*a34*a56*a65 + + a11*a22*a34*a56*a65 + - a15*a24*a32*a51*a66 + + a14*a25*a32*a51*a66 + + a15*a22*a34*a51*a66 + - a12*a25*a34*a51*a66 + - a14*a22*a35*a51*a66 + + a12*a24*a35*a51*a66 + + a15*a24*a31*a52*a66 + - a14*a25*a31*a52*a66 + - a15*a21*a34*a52*a66 + + a11*a25*a34*a52*a66 + + a14*a21*a35*a52*a66 + - a11*a24*a35*a52*a66 + - a15*a22*a31*a54*a66 + + a12*a25*a31*a54*a66 + + a15*a21*a32*a54*a66 + - a11*a25*a32*a54*a66 + - a12*a21*a35*a54*a66 + + a11*a22*a35*a54*a66 + + a14*a22*a31*a55*a66 + - a12*a24*a31*a55*a66 + - a14*a21*a32*a55*a66 + + a11*a24*a32*a55*a66 + + a12*a21*a34*a55*a66 + - a11*a22*a34*a55*a66; + cofactor[16] = a16*a25*a34*a42*a61 + - a15*a26*a34*a42*a61 + - a16*a24*a35*a42*a61 + + a14*a26*a35*a42*a61 + + a15*a24*a36*a42*a61 + - a14*a25*a36*a42*a61 + - a16*a25*a32*a44*a61 + + a15*a26*a32*a44*a61 + + a16*a22*a35*a44*a61 + - a12*a26*a35*a44*a61 + - a15*a22*a36*a44*a61 + + a12*a25*a36*a44*a61 + + a16*a24*a32*a45*a61 + - a14*a26*a32*a45*a61 + - a16*a22*a34*a45*a61 + + a12*a26*a34*a45*a61 + + a14*a22*a36*a45*a61 + - a12*a24*a36*a45*a61 + - a15*a24*a32*a46*a61 + + a14*a25*a32*a46*a61 + + a15*a22*a34*a46*a61 + - a12*a25*a34*a46*a61 + - a14*a22*a35*a46*a61 + + a12*a24*a35*a46*a61 + - a16*a25*a34*a41*a62 + + a15*a26*a34*a41*a62 + + a16*a24*a35*a41*a62 + - a14*a26*a35*a41*a62 + - a15*a24*a36*a41*a62 + + a14*a25*a36*a41*a62 + + a16*a25*a31*a44*a62 + - a15*a26*a31*a44*a62 + - a16*a21*a35*a44*a62 + + a11*a26*a35*a44*a62 + + a15*a21*a36*a44*a62 + - a11*a25*a36*a44*a62 + - a16*a24*a31*a45*a62 + + a14*a26*a31*a45*a62 + + a16*a21*a34*a45*a62 + - a11*a26*a34*a45*a62 + - a14*a21*a36*a45*a62 + + a11*a24*a36*a45*a62 + + a15*a24*a31*a46*a62 + - a14*a25*a31*a46*a62 + - a15*a21*a34*a46*a62 + + a11*a25*a34*a46*a62 + + a14*a21*a35*a46*a62 + - a11*a24*a35*a46*a62 + + a16*a25*a32*a41*a64 + - a15*a26*a32*a41*a64 + - a16*a22*a35*a41*a64 + + a12*a26*a35*a41*a64 + + a15*a22*a36*a41*a64 + - a12*a25*a36*a41*a64 + - a16*a25*a31*a42*a64 + + a15*a26*a31*a42*a64 + + a16*a21*a35*a42*a64 + - a11*a26*a35*a42*a64 + - a15*a21*a36*a42*a64 + + a11*a25*a36*a42*a64 + + a16*a22*a31*a45*a64 + - a12*a26*a31*a45*a64 + - a16*a21*a32*a45*a64 + + a11*a26*a32*a45*a64 + + a12*a21*a36*a45*a64 + - a11*a22*a36*a45*a64 + - a15*a22*a31*a46*a64 + + a12*a25*a31*a46*a64 + + a15*a21*a32*a46*a64 + - a11*a25*a32*a46*a64 + - a12*a21*a35*a46*a64 + + a11*a22*a35*a46*a64 + - a16*a24*a32*a41*a65 + + a14*a26*a32*a41*a65 + + a16*a22*a34*a41*a65 + - a12*a26*a34*a41*a65 + - a14*a22*a36*a41*a65 + + a12*a24*a36*a41*a65 + + a16*a24*a31*a42*a65 + - a14*a26*a31*a42*a65 + - a16*a21*a34*a42*a65 + + a11*a26*a34*a42*a65 + + a14*a21*a36*a42*a65 + - a11*a24*a36*a42*a65 + - a16*a22*a31*a44*a65 + + a12*a26*a31*a44*a65 + + a16*a21*a32*a44*a65 + - a11*a26*a32*a44*a65 + - a12*a21*a36*a44*a65 + + a11*a22*a36*a44*a65 + + a14*a22*a31*a46*a65 + - a12*a24*a31*a46*a65 + - a14*a21*a32*a46*a65 + + a11*a24*a32*a46*a65 + + a12*a21*a34*a46*a65 + - a11*a22*a34*a46*a65 + + a15*a24*a32*a41*a66 + - a14*a25*a32*a41*a66 + - a15*a22*a34*a41*a66 + + a12*a25*a34*a41*a66 + + a14*a22*a35*a41*a66 + - a12*a24*a35*a41*a66 + - a15*a24*a31*a42*a66 + + a14*a25*a31*a42*a66 + + a15*a21*a34*a42*a66 + - a11*a25*a34*a42*a66 + - a14*a21*a35*a42*a66 + + a11*a24*a35*a42*a66 + + a15*a22*a31*a44*a66 + - a12*a25*a31*a44*a66 + - a15*a21*a32*a44*a66 + + a11*a25*a32*a44*a66 + + a12*a21*a35*a44*a66 + - a11*a22*a35*a44*a66 + - a14*a22*a31*a45*a66 + + a12*a24*a31*a45*a66 + + a14*a21*a32*a45*a66 + - a11*a24*a32*a45*a66 + - a12*a21*a34*a45*a66 + + a11*a22*a34*a45*a66; + cofactor[17] = -a16*a25*a34*a42*a51 + + a15*a26*a34*a42*a51 + + a16*a24*a35*a42*a51 + - a14*a26*a35*a42*a51 + - a15*a24*a36*a42*a51 + + a14*a25*a36*a42*a51 + + a16*a25*a32*a44*a51 + - a15*a26*a32*a44*a51 + - a16*a22*a35*a44*a51 + + a12*a26*a35*a44*a51 + + a15*a22*a36*a44*a51 + - a12*a25*a36*a44*a51 + - a16*a24*a32*a45*a51 + + a14*a26*a32*a45*a51 + + a16*a22*a34*a45*a51 + - a12*a26*a34*a45*a51 + - a14*a22*a36*a45*a51 + + a12*a24*a36*a45*a51 + + a15*a24*a32*a46*a51 + - a14*a25*a32*a46*a51 + - a15*a22*a34*a46*a51 + + a12*a25*a34*a46*a51 + + a14*a22*a35*a46*a51 + - a12*a24*a35*a46*a51 + + a16*a25*a34*a41*a52 + - a15*a26*a34*a41*a52 + - a16*a24*a35*a41*a52 + + a14*a26*a35*a41*a52 + + a15*a24*a36*a41*a52 + - a14*a25*a36*a41*a52 + - a16*a25*a31*a44*a52 + + a15*a26*a31*a44*a52 + + a16*a21*a35*a44*a52 + - a11*a26*a35*a44*a52 + - a15*a21*a36*a44*a52 + + a11*a25*a36*a44*a52 + + a16*a24*a31*a45*a52 + - a14*a26*a31*a45*a52 + - a16*a21*a34*a45*a52 + + a11*a26*a34*a45*a52 + + a14*a21*a36*a45*a52 + - a11*a24*a36*a45*a52 + - a15*a24*a31*a46*a52 + + a14*a25*a31*a46*a52 + + a15*a21*a34*a46*a52 + - a11*a25*a34*a46*a52 + - a14*a21*a35*a46*a52 + + a11*a24*a35*a46*a52 + - a16*a25*a32*a41*a54 + + a15*a26*a32*a41*a54 + + a16*a22*a35*a41*a54 + - a12*a26*a35*a41*a54 + - a15*a22*a36*a41*a54 + + a12*a25*a36*a41*a54 + + a16*a25*a31*a42*a54 + - a15*a26*a31*a42*a54 + - a16*a21*a35*a42*a54 + + a11*a26*a35*a42*a54 + + a15*a21*a36*a42*a54 + - a11*a25*a36*a42*a54 + - a16*a22*a31*a45*a54 + + a12*a26*a31*a45*a54 + + a16*a21*a32*a45*a54 + - a11*a26*a32*a45*a54 + - a12*a21*a36*a45*a54 + + a11*a22*a36*a45*a54 + + a15*a22*a31*a46*a54 + - a12*a25*a31*a46*a54 + - a15*a21*a32*a46*a54 + + a11*a25*a32*a46*a54 + + a12*a21*a35*a46*a54 + - a11*a22*a35*a46*a54 + + a16*a24*a32*a41*a55 + - a14*a26*a32*a41*a55 + - a16*a22*a34*a41*a55 + + a12*a26*a34*a41*a55 + + a14*a22*a36*a41*a55 + - a12*a24*a36*a41*a55 + - a16*a24*a31*a42*a55 + + a14*a26*a31*a42*a55 + + a16*a21*a34*a42*a55 + - a11*a26*a34*a42*a55 + - a14*a21*a36*a42*a55 + + a11*a24*a36*a42*a55 + + a16*a22*a31*a44*a55 + - a12*a26*a31*a44*a55 + - a16*a21*a32*a44*a55 + + a11*a26*a32*a44*a55 + + a12*a21*a36*a44*a55 + - a11*a22*a36*a44*a55 + - a14*a22*a31*a46*a55 + + a12*a24*a31*a46*a55 + + a14*a21*a32*a46*a55 + - a11*a24*a32*a46*a55 + - a12*a21*a34*a46*a55 + + a11*a22*a34*a46*a55 + - a15*a24*a32*a41*a56 + + a14*a25*a32*a41*a56 + + a15*a22*a34*a41*a56 + - a12*a25*a34*a41*a56 + - a14*a22*a35*a41*a56 + + a12*a24*a35*a41*a56 + + a15*a24*a31*a42*a56 + - a14*a25*a31*a42*a56 + - a15*a21*a34*a42*a56 + + a11*a25*a34*a42*a56 + + a14*a21*a35*a42*a56 + - a11*a24*a35*a42*a56 + - a15*a22*a31*a44*a56 + + a12*a25*a31*a44*a56 + + a15*a21*a32*a44*a56 + - a11*a25*a32*a44*a56 + - a12*a21*a35*a44*a56 + + a11*a22*a35*a44*a56 + + a14*a22*a31*a45*a56 + - a12*a24*a31*a45*a56 + - a14*a21*a32*a45*a56 + + a11*a24*a32*a45*a56 + + a12*a21*a34*a45*a56 + - a11*a22*a34*a45*a56; + cofactor[18] = -a26*a35*a43*a52*a61 + + a25*a36*a43*a52*a61 + + a26*a33*a45*a52*a61 + - a23*a36*a45*a52*a61 + - a25*a33*a46*a52*a61 + + a23*a35*a46*a52*a61 + + a26*a35*a42*a53*a61 + - a25*a36*a42*a53*a61 + - a26*a32*a45*a53*a61 + + a22*a36*a45*a53*a61 + + a25*a32*a46*a53*a61 + - a22*a35*a46*a53*a61 + - a26*a33*a42*a55*a61 + + a23*a36*a42*a55*a61 + + a26*a32*a43*a55*a61 + - a22*a36*a43*a55*a61 + - a23*a32*a46*a55*a61 + + a22*a33*a46*a55*a61 + + a25*a33*a42*a56*a61 + - a23*a35*a42*a56*a61 + - a25*a32*a43*a56*a61 + + a22*a35*a43*a56*a61 + + a23*a32*a45*a56*a61 + - a22*a33*a45*a56*a61 + + a26*a35*a43*a51*a62 + - a25*a36*a43*a51*a62 + - a26*a33*a45*a51*a62 + + a23*a36*a45*a51*a62 + + a25*a33*a46*a51*a62 + - a23*a35*a46*a51*a62 + - a26*a35*a41*a53*a62 + + a25*a36*a41*a53*a62 + + a26*a31*a45*a53*a62 + - a21*a36*a45*a53*a62 + - a25*a31*a46*a53*a62 + + a21*a35*a46*a53*a62 + + a26*a33*a41*a55*a62 + - a23*a36*a41*a55*a62 + - a26*a31*a43*a55*a62 + + a21*a36*a43*a55*a62 + + a23*a31*a46*a55*a62 + - a21*a33*a46*a55*a62 + - a25*a33*a41*a56*a62 + + a23*a35*a41*a56*a62 + + a25*a31*a43*a56*a62 + - a21*a35*a43*a56*a62 + - a23*a31*a45*a56*a62 + + a21*a33*a45*a56*a62 + - a26*a35*a42*a51*a63 + + a25*a36*a42*a51*a63 + + a26*a32*a45*a51*a63 + - a22*a36*a45*a51*a63 + - a25*a32*a46*a51*a63 + + a22*a35*a46*a51*a63 + + a26*a35*a41*a52*a63 + - a25*a36*a41*a52*a63 + - a26*a31*a45*a52*a63 + + a21*a36*a45*a52*a63 + + a25*a31*a46*a52*a63 + - a21*a35*a46*a52*a63 + - a26*a32*a41*a55*a63 + + a22*a36*a41*a55*a63 + + a26*a31*a42*a55*a63 + - a21*a36*a42*a55*a63 + - a22*a31*a46*a55*a63 + + a21*a32*a46*a55*a63 + + a25*a32*a41*a56*a63 + - a22*a35*a41*a56*a63 + - a25*a31*a42*a56*a63 + + a21*a35*a42*a56*a63 + + a22*a31*a45*a56*a63 + - a21*a32*a45*a56*a63 + + a26*a33*a42*a51*a65 + - a23*a36*a42*a51*a65 + - a26*a32*a43*a51*a65 + + a22*a36*a43*a51*a65 + + a23*a32*a46*a51*a65 + - a22*a33*a46*a51*a65 + - a26*a33*a41*a52*a65 + + a23*a36*a41*a52*a65 + + a26*a31*a43*a52*a65 + - a21*a36*a43*a52*a65 + - a23*a31*a46*a52*a65 + + a21*a33*a46*a52*a65 + + a26*a32*a41*a53*a65 + - a22*a36*a41*a53*a65 + - a26*a31*a42*a53*a65 + + a21*a36*a42*a53*a65 + + a22*a31*a46*a53*a65 + - a21*a32*a46*a53*a65 + - a23*a32*a41*a56*a65 + + a22*a33*a41*a56*a65 + + a23*a31*a42*a56*a65 + - a21*a33*a42*a56*a65 + - a22*a31*a43*a56*a65 + + a21*a32*a43*a56*a65 + - a25*a33*a42*a51*a66 + + a23*a35*a42*a51*a66 + + a25*a32*a43*a51*a66 + - a22*a35*a43*a51*a66 + - a23*a32*a45*a51*a66 + + a22*a33*a45*a51*a66 + + a25*a33*a41*a52*a66 + - a23*a35*a41*a52*a66 + - a25*a31*a43*a52*a66 + + a21*a35*a43*a52*a66 + + a23*a31*a45*a52*a66 + - a21*a33*a45*a52*a66 + - a25*a32*a41*a53*a66 + + a22*a35*a41*a53*a66 + + a25*a31*a42*a53*a66 + - a21*a35*a42*a53*a66 + - a22*a31*a45*a53*a66 + + a21*a32*a45*a53*a66 + + a23*a32*a41*a55*a66 + - a22*a33*a41*a55*a66 + - a23*a31*a42*a55*a66 + + a21*a33*a42*a55*a66 + + a22*a31*a43*a55*a66 + - a21*a32*a43*a55*a66; + cofactor[19] = a16*a35*a43*a52*a61 + - a15*a36*a43*a52*a61 + - a16*a33*a45*a52*a61 + + a13*a36*a45*a52*a61 + + a15*a33*a46*a52*a61 + - a13*a35*a46*a52*a61 + - a16*a35*a42*a53*a61 + + a15*a36*a42*a53*a61 + + a16*a32*a45*a53*a61 + - a12*a36*a45*a53*a61 + - a15*a32*a46*a53*a61 + + a12*a35*a46*a53*a61 + + a16*a33*a42*a55*a61 + - a13*a36*a42*a55*a61 + - a16*a32*a43*a55*a61 + + a12*a36*a43*a55*a61 + + a13*a32*a46*a55*a61 + - a12*a33*a46*a55*a61 + - a15*a33*a42*a56*a61 + + a13*a35*a42*a56*a61 + + a15*a32*a43*a56*a61 + - a12*a35*a43*a56*a61 + - a13*a32*a45*a56*a61 + + a12*a33*a45*a56*a61 + - a16*a35*a43*a51*a62 + + a15*a36*a43*a51*a62 + + a16*a33*a45*a51*a62 + - a13*a36*a45*a51*a62 + - a15*a33*a46*a51*a62 + + a13*a35*a46*a51*a62 + + a16*a35*a41*a53*a62 + - a15*a36*a41*a53*a62 + - a16*a31*a45*a53*a62 + + a11*a36*a45*a53*a62 + + a15*a31*a46*a53*a62 + - a11*a35*a46*a53*a62 + - a16*a33*a41*a55*a62 + + a13*a36*a41*a55*a62 + + a16*a31*a43*a55*a62 + - a11*a36*a43*a55*a62 + - a13*a31*a46*a55*a62 + + a11*a33*a46*a55*a62 + + a15*a33*a41*a56*a62 + - a13*a35*a41*a56*a62 + - a15*a31*a43*a56*a62 + + a11*a35*a43*a56*a62 + + a13*a31*a45*a56*a62 + - a11*a33*a45*a56*a62 + + a16*a35*a42*a51*a63 + - a15*a36*a42*a51*a63 + - a16*a32*a45*a51*a63 + + a12*a36*a45*a51*a63 + + a15*a32*a46*a51*a63 + - a12*a35*a46*a51*a63 + - a16*a35*a41*a52*a63 + + a15*a36*a41*a52*a63 + + a16*a31*a45*a52*a63 + - a11*a36*a45*a52*a63 + - a15*a31*a46*a52*a63 + + a11*a35*a46*a52*a63 + + a16*a32*a41*a55*a63 + - a12*a36*a41*a55*a63 + - a16*a31*a42*a55*a63 + + a11*a36*a42*a55*a63 + + a12*a31*a46*a55*a63 + - a11*a32*a46*a55*a63 + - a15*a32*a41*a56*a63 + + a12*a35*a41*a56*a63 + + a15*a31*a42*a56*a63 + - a11*a35*a42*a56*a63 + - a12*a31*a45*a56*a63 + + a11*a32*a45*a56*a63 + - a16*a33*a42*a51*a65 + + a13*a36*a42*a51*a65 + + a16*a32*a43*a51*a65 + - a12*a36*a43*a51*a65 + - a13*a32*a46*a51*a65 + + a12*a33*a46*a51*a65 + + a16*a33*a41*a52*a65 + - a13*a36*a41*a52*a65 + - a16*a31*a43*a52*a65 + + a11*a36*a43*a52*a65 + + a13*a31*a46*a52*a65 + - a11*a33*a46*a52*a65 + - a16*a32*a41*a53*a65 + + a12*a36*a41*a53*a65 + + a16*a31*a42*a53*a65 + - a11*a36*a42*a53*a65 + - a12*a31*a46*a53*a65 + + a11*a32*a46*a53*a65 + + a13*a32*a41*a56*a65 + - a12*a33*a41*a56*a65 + - a13*a31*a42*a56*a65 + + a11*a33*a42*a56*a65 + + a12*a31*a43*a56*a65 + - a11*a32*a43*a56*a65 + + a15*a33*a42*a51*a66 + - a13*a35*a42*a51*a66 + - a15*a32*a43*a51*a66 + + a12*a35*a43*a51*a66 + + a13*a32*a45*a51*a66 + - a12*a33*a45*a51*a66 + - a15*a33*a41*a52*a66 + + a13*a35*a41*a52*a66 + + a15*a31*a43*a52*a66 + - a11*a35*a43*a52*a66 + - a13*a31*a45*a52*a66 + + a11*a33*a45*a52*a66 + + a15*a32*a41*a53*a66 + - a12*a35*a41*a53*a66 + - a15*a31*a42*a53*a66 + + a11*a35*a42*a53*a66 + + a12*a31*a45*a53*a66 + - a11*a32*a45*a53*a66 + - a13*a32*a41*a55*a66 + + a12*a33*a41*a55*a66 + + a13*a31*a42*a55*a66 + - a11*a33*a42*a55*a66 + - a12*a31*a43*a55*a66 + + a11*a32*a43*a55*a66; + cofactor[20] = -a16*a25*a43*a52*a61 + + a15*a26*a43*a52*a61 + + a16*a23*a45*a52*a61 + - a13*a26*a45*a52*a61 + - a15*a23*a46*a52*a61 + + a13*a25*a46*a52*a61 + + a16*a25*a42*a53*a61 + - a15*a26*a42*a53*a61 + - a16*a22*a45*a53*a61 + + a12*a26*a45*a53*a61 + + a15*a22*a46*a53*a61 + - a12*a25*a46*a53*a61 + - a16*a23*a42*a55*a61 + + a13*a26*a42*a55*a61 + + a16*a22*a43*a55*a61 + - a12*a26*a43*a55*a61 + - a13*a22*a46*a55*a61 + + a12*a23*a46*a55*a61 + + a15*a23*a42*a56*a61 + - a13*a25*a42*a56*a61 + - a15*a22*a43*a56*a61 + + a12*a25*a43*a56*a61 + + a13*a22*a45*a56*a61 + - a12*a23*a45*a56*a61 + + a16*a25*a43*a51*a62 + - a15*a26*a43*a51*a62 + - a16*a23*a45*a51*a62 + + a13*a26*a45*a51*a62 + + a15*a23*a46*a51*a62 + - a13*a25*a46*a51*a62 + - a16*a25*a41*a53*a62 + + a15*a26*a41*a53*a62 + + a16*a21*a45*a53*a62 + - a11*a26*a45*a53*a62 + - a15*a21*a46*a53*a62 + + a11*a25*a46*a53*a62 + + a16*a23*a41*a55*a62 + - a13*a26*a41*a55*a62 + - a16*a21*a43*a55*a62 + + a11*a26*a43*a55*a62 + + a13*a21*a46*a55*a62 + - a11*a23*a46*a55*a62 + - a15*a23*a41*a56*a62 + + a13*a25*a41*a56*a62 + + a15*a21*a43*a56*a62 + - a11*a25*a43*a56*a62 + - a13*a21*a45*a56*a62 + + a11*a23*a45*a56*a62 + - a16*a25*a42*a51*a63 + + a15*a26*a42*a51*a63 + + a16*a22*a45*a51*a63 + - a12*a26*a45*a51*a63 + - a15*a22*a46*a51*a63 + + a12*a25*a46*a51*a63 + + a16*a25*a41*a52*a63 + - a15*a26*a41*a52*a63 + - a16*a21*a45*a52*a63 + + a11*a26*a45*a52*a63 + + a15*a21*a46*a52*a63 + - a11*a25*a46*a52*a63 + - a16*a22*a41*a55*a63 + + a12*a26*a41*a55*a63 + + a16*a21*a42*a55*a63 + - a11*a26*a42*a55*a63 + - a12*a21*a46*a55*a63 + + a11*a22*a46*a55*a63 + + a15*a22*a41*a56*a63 + - a12*a25*a41*a56*a63 + - a15*a21*a42*a56*a63 + + a11*a25*a42*a56*a63 + + a12*a21*a45*a56*a63 + - a11*a22*a45*a56*a63 + + a16*a23*a42*a51*a65 + - a13*a26*a42*a51*a65 + - a16*a22*a43*a51*a65 + + a12*a26*a43*a51*a65 + + a13*a22*a46*a51*a65 + - a12*a23*a46*a51*a65 + - a16*a23*a41*a52*a65 + + a13*a26*a41*a52*a65 + + a16*a21*a43*a52*a65 + - a11*a26*a43*a52*a65 + - a13*a21*a46*a52*a65 + + a11*a23*a46*a52*a65 + + a16*a22*a41*a53*a65 + - a12*a26*a41*a53*a65 + - a16*a21*a42*a53*a65 + + a11*a26*a42*a53*a65 + + a12*a21*a46*a53*a65 + - a11*a22*a46*a53*a65 + - a13*a22*a41*a56*a65 + + a12*a23*a41*a56*a65 + + a13*a21*a42*a56*a65 + - a11*a23*a42*a56*a65 + - a12*a21*a43*a56*a65 + + a11*a22*a43*a56*a65 + - a15*a23*a42*a51*a66 + + a13*a25*a42*a51*a66 + + a15*a22*a43*a51*a66 + - a12*a25*a43*a51*a66 + - a13*a22*a45*a51*a66 + + a12*a23*a45*a51*a66 + + a15*a23*a41*a52*a66 + - a13*a25*a41*a52*a66 + - a15*a21*a43*a52*a66 + + a11*a25*a43*a52*a66 + + a13*a21*a45*a52*a66 + - a11*a23*a45*a52*a66 + - a15*a22*a41*a53*a66 + + a12*a25*a41*a53*a66 + + a15*a21*a42*a53*a66 + - a11*a25*a42*a53*a66 + - a12*a21*a45*a53*a66 + + a11*a22*a45*a53*a66 + + a13*a22*a41*a55*a66 + - a12*a23*a41*a55*a66 + - a13*a21*a42*a55*a66 + + a11*a23*a42*a55*a66 + + a12*a21*a43*a55*a66 + - a11*a22*a43*a55*a66; + cofactor[21] = a16*a25*a33*a52*a61 + - a15*a26*a33*a52*a61 + - a16*a23*a35*a52*a61 + + a13*a26*a35*a52*a61 + + a15*a23*a36*a52*a61 + - a13*a25*a36*a52*a61 + - a16*a25*a32*a53*a61 + + a15*a26*a32*a53*a61 + + a16*a22*a35*a53*a61 + - a12*a26*a35*a53*a61 + - a15*a22*a36*a53*a61 + + a12*a25*a36*a53*a61 + + a16*a23*a32*a55*a61 + - a13*a26*a32*a55*a61 + - a16*a22*a33*a55*a61 + + a12*a26*a33*a55*a61 + + a13*a22*a36*a55*a61 + - a12*a23*a36*a55*a61 + - a15*a23*a32*a56*a61 + + a13*a25*a32*a56*a61 + + a15*a22*a33*a56*a61 + - a12*a25*a33*a56*a61 + - a13*a22*a35*a56*a61 + + a12*a23*a35*a56*a61 + - a16*a25*a33*a51*a62 + + a15*a26*a33*a51*a62 + + a16*a23*a35*a51*a62 + - a13*a26*a35*a51*a62 + - a15*a23*a36*a51*a62 + + a13*a25*a36*a51*a62 + + a16*a25*a31*a53*a62 + - a15*a26*a31*a53*a62 + - a16*a21*a35*a53*a62 + + a11*a26*a35*a53*a62 + + a15*a21*a36*a53*a62 + - a11*a25*a36*a53*a62 + - a16*a23*a31*a55*a62 + + a13*a26*a31*a55*a62 + + a16*a21*a33*a55*a62 + - a11*a26*a33*a55*a62 + - a13*a21*a36*a55*a62 + + a11*a23*a36*a55*a62 + + a15*a23*a31*a56*a62 + - a13*a25*a31*a56*a62 + - a15*a21*a33*a56*a62 + + a11*a25*a33*a56*a62 + + a13*a21*a35*a56*a62 + - a11*a23*a35*a56*a62 + + a16*a25*a32*a51*a63 + - a15*a26*a32*a51*a63 + - a16*a22*a35*a51*a63 + + a12*a26*a35*a51*a63 + + a15*a22*a36*a51*a63 + - a12*a25*a36*a51*a63 + - a16*a25*a31*a52*a63 + + a15*a26*a31*a52*a63 + + a16*a21*a35*a52*a63 + - a11*a26*a35*a52*a63 + - a15*a21*a36*a52*a63 + + a11*a25*a36*a52*a63 + + a16*a22*a31*a55*a63 + - a12*a26*a31*a55*a63 + - a16*a21*a32*a55*a63 + + a11*a26*a32*a55*a63 + + a12*a21*a36*a55*a63 + - a11*a22*a36*a55*a63 + - a15*a22*a31*a56*a63 + + a12*a25*a31*a56*a63 + + a15*a21*a32*a56*a63 + - a11*a25*a32*a56*a63 + - a12*a21*a35*a56*a63 + + a11*a22*a35*a56*a63 + - a16*a23*a32*a51*a65 + + a13*a26*a32*a51*a65 + + a16*a22*a33*a51*a65 + - a12*a26*a33*a51*a65 + - a13*a22*a36*a51*a65 + + a12*a23*a36*a51*a65 + + a16*a23*a31*a52*a65 + - a13*a26*a31*a52*a65 + - a16*a21*a33*a52*a65 + + a11*a26*a33*a52*a65 + + a13*a21*a36*a52*a65 + - a11*a23*a36*a52*a65 + - a16*a22*a31*a53*a65 + + a12*a26*a31*a53*a65 + + a16*a21*a32*a53*a65 + - a11*a26*a32*a53*a65 + - a12*a21*a36*a53*a65 + + a11*a22*a36*a53*a65 + + a13*a22*a31*a56*a65 + - a12*a23*a31*a56*a65 + - a13*a21*a32*a56*a65 + + a11*a23*a32*a56*a65 + + a12*a21*a33*a56*a65 + - a11*a22*a33*a56*a65 + + a15*a23*a32*a51*a66 + - a13*a25*a32*a51*a66 + - a15*a22*a33*a51*a66 + + a12*a25*a33*a51*a66 + + a13*a22*a35*a51*a66 + - a12*a23*a35*a51*a66 + - a15*a23*a31*a52*a66 + + a13*a25*a31*a52*a66 + + a15*a21*a33*a52*a66 + - a11*a25*a33*a52*a66 + - a13*a21*a35*a52*a66 + + a11*a23*a35*a52*a66 + + a15*a22*a31*a53*a66 + - a12*a25*a31*a53*a66 + - a15*a21*a32*a53*a66 + + a11*a25*a32*a53*a66 + + a12*a21*a35*a53*a66 + - a11*a22*a35*a53*a66 + - a13*a22*a31*a55*a66 + + a12*a23*a31*a55*a66 + + a13*a21*a32*a55*a66 + - a11*a23*a32*a55*a66 + - a12*a21*a33*a55*a66 + + a11*a22*a33*a55*a66; + cofactor[22] = -a16*a25*a33*a42*a61 + + a15*a26*a33*a42*a61 + + a16*a23*a35*a42*a61 + - a13*a26*a35*a42*a61 + - a15*a23*a36*a42*a61 + + a13*a25*a36*a42*a61 + + a16*a25*a32*a43*a61 + - a15*a26*a32*a43*a61 + - a16*a22*a35*a43*a61 + + a12*a26*a35*a43*a61 + + a15*a22*a36*a43*a61 + - a12*a25*a36*a43*a61 + - a16*a23*a32*a45*a61 + + a13*a26*a32*a45*a61 + + a16*a22*a33*a45*a61 + - a12*a26*a33*a45*a61 + - a13*a22*a36*a45*a61 + + a12*a23*a36*a45*a61 + + a15*a23*a32*a46*a61 + - a13*a25*a32*a46*a61 + - a15*a22*a33*a46*a61 + + a12*a25*a33*a46*a61 + + a13*a22*a35*a46*a61 + - a12*a23*a35*a46*a61 + + a16*a25*a33*a41*a62 + - a15*a26*a33*a41*a62 + - a16*a23*a35*a41*a62 + + a13*a26*a35*a41*a62 + + a15*a23*a36*a41*a62 + - a13*a25*a36*a41*a62 + - a16*a25*a31*a43*a62 + + a15*a26*a31*a43*a62 + + a16*a21*a35*a43*a62 + - a11*a26*a35*a43*a62 + - a15*a21*a36*a43*a62 + + a11*a25*a36*a43*a62 + + a16*a23*a31*a45*a62 + - a13*a26*a31*a45*a62 + - a16*a21*a33*a45*a62 + + a11*a26*a33*a45*a62 + + a13*a21*a36*a45*a62 + - a11*a23*a36*a45*a62 + - a15*a23*a31*a46*a62 + + a13*a25*a31*a46*a62 + + a15*a21*a33*a46*a62 + - a11*a25*a33*a46*a62 + - a13*a21*a35*a46*a62 + + a11*a23*a35*a46*a62 + - a16*a25*a32*a41*a63 + + a15*a26*a32*a41*a63 + + a16*a22*a35*a41*a63 + - a12*a26*a35*a41*a63 + - a15*a22*a36*a41*a63 + + a12*a25*a36*a41*a63 + + a16*a25*a31*a42*a63 + - a15*a26*a31*a42*a63 + - a16*a21*a35*a42*a63 + + a11*a26*a35*a42*a63 + + a15*a21*a36*a42*a63 + - a11*a25*a36*a42*a63 + - a16*a22*a31*a45*a63 + + a12*a26*a31*a45*a63 + + a16*a21*a32*a45*a63 + - a11*a26*a32*a45*a63 + - a12*a21*a36*a45*a63 + + a11*a22*a36*a45*a63 + + a15*a22*a31*a46*a63 + - a12*a25*a31*a46*a63 + - a15*a21*a32*a46*a63 + + a11*a25*a32*a46*a63 + + a12*a21*a35*a46*a63 + - a11*a22*a35*a46*a63 + + a16*a23*a32*a41*a65 + - a13*a26*a32*a41*a65 + - a16*a22*a33*a41*a65 + + a12*a26*a33*a41*a65 + + a13*a22*a36*a41*a65 + - a12*a23*a36*a41*a65 + - a16*a23*a31*a42*a65 + + a13*a26*a31*a42*a65 + + a16*a21*a33*a42*a65 + - a11*a26*a33*a42*a65 + - a13*a21*a36*a42*a65 + + a11*a23*a36*a42*a65 + + a16*a22*a31*a43*a65 + - a12*a26*a31*a43*a65 + - a16*a21*a32*a43*a65 + + a11*a26*a32*a43*a65 + + a12*a21*a36*a43*a65 + - a11*a22*a36*a43*a65 + - a13*a22*a31*a46*a65 + + a12*a23*a31*a46*a65 + + a13*a21*a32*a46*a65 + - a11*a23*a32*a46*a65 + - a12*a21*a33*a46*a65 + + a11*a22*a33*a46*a65 + - a15*a23*a32*a41*a66 + + a13*a25*a32*a41*a66 + + a15*a22*a33*a41*a66 + - a12*a25*a33*a41*a66 + - a13*a22*a35*a41*a66 + + a12*a23*a35*a41*a66 + + a15*a23*a31*a42*a66 + - a13*a25*a31*a42*a66 + - a15*a21*a33*a42*a66 + + a11*a25*a33*a42*a66 + + a13*a21*a35*a42*a66 + - a11*a23*a35*a42*a66 + - a15*a22*a31*a43*a66 + + a12*a25*a31*a43*a66 + + a15*a21*a32*a43*a66 + - a11*a25*a32*a43*a66 + - a12*a21*a35*a43*a66 + + a11*a22*a35*a43*a66 + + a13*a22*a31*a45*a66 + - a12*a23*a31*a45*a66 + - a13*a21*a32*a45*a66 + + a11*a23*a32*a45*a66 + + a12*a21*a33*a45*a66 + - a11*a22*a33*a45*a66; + cofactor[23] = a16*a25*a33*a42*a51 + - a15*a26*a33*a42*a51 + - a16*a23*a35*a42*a51 + + a13*a26*a35*a42*a51 + + a15*a23*a36*a42*a51 + - a13*a25*a36*a42*a51 + - a16*a25*a32*a43*a51 + + a15*a26*a32*a43*a51 + + a16*a22*a35*a43*a51 + - a12*a26*a35*a43*a51 + - a15*a22*a36*a43*a51 + + a12*a25*a36*a43*a51 + + a16*a23*a32*a45*a51 + - a13*a26*a32*a45*a51 + - a16*a22*a33*a45*a51 + + a12*a26*a33*a45*a51 + + a13*a22*a36*a45*a51 + - a12*a23*a36*a45*a51 + - a15*a23*a32*a46*a51 + + a13*a25*a32*a46*a51 + + a15*a22*a33*a46*a51 + - a12*a25*a33*a46*a51 + - a13*a22*a35*a46*a51 + + a12*a23*a35*a46*a51 + - a16*a25*a33*a41*a52 + + a15*a26*a33*a41*a52 + + a16*a23*a35*a41*a52 + - a13*a26*a35*a41*a52 + - a15*a23*a36*a41*a52 + + a13*a25*a36*a41*a52 + + a16*a25*a31*a43*a52 + - a15*a26*a31*a43*a52 + - a16*a21*a35*a43*a52 + + a11*a26*a35*a43*a52 + + a15*a21*a36*a43*a52 + - a11*a25*a36*a43*a52 + - a16*a23*a31*a45*a52 + + a13*a26*a31*a45*a52 + + a16*a21*a33*a45*a52 + - a11*a26*a33*a45*a52 + - a13*a21*a36*a45*a52 + + a11*a23*a36*a45*a52 + + a15*a23*a31*a46*a52 + - a13*a25*a31*a46*a52 + - a15*a21*a33*a46*a52 + + a11*a25*a33*a46*a52 + + a13*a21*a35*a46*a52 + - a11*a23*a35*a46*a52 + + a16*a25*a32*a41*a53 + - a15*a26*a32*a41*a53 + - a16*a22*a35*a41*a53 + + a12*a26*a35*a41*a53 + + a15*a22*a36*a41*a53 + - a12*a25*a36*a41*a53 + - a16*a25*a31*a42*a53 + + a15*a26*a31*a42*a53 + + a16*a21*a35*a42*a53 + - a11*a26*a35*a42*a53 + - a15*a21*a36*a42*a53 + + a11*a25*a36*a42*a53 + + a16*a22*a31*a45*a53 + - a12*a26*a31*a45*a53 + - a16*a21*a32*a45*a53 + + a11*a26*a32*a45*a53 + + a12*a21*a36*a45*a53 + - a11*a22*a36*a45*a53 + - a15*a22*a31*a46*a53 + + a12*a25*a31*a46*a53 + + a15*a21*a32*a46*a53 + - a11*a25*a32*a46*a53 + - a12*a21*a35*a46*a53 + + a11*a22*a35*a46*a53 + - a16*a23*a32*a41*a55 + + a13*a26*a32*a41*a55 + + a16*a22*a33*a41*a55 + - a12*a26*a33*a41*a55 + - a13*a22*a36*a41*a55 + + a12*a23*a36*a41*a55 + + a16*a23*a31*a42*a55 + - a13*a26*a31*a42*a55 + - a16*a21*a33*a42*a55 + + a11*a26*a33*a42*a55 + + a13*a21*a36*a42*a55 + - a11*a23*a36*a42*a55 + - a16*a22*a31*a43*a55 + + a12*a26*a31*a43*a55 + + a16*a21*a32*a43*a55 + - a11*a26*a32*a43*a55 + - a12*a21*a36*a43*a55 + + a11*a22*a36*a43*a55 + + a13*a22*a31*a46*a55 + - a12*a23*a31*a46*a55 + - a13*a21*a32*a46*a55 + + a11*a23*a32*a46*a55 + + a12*a21*a33*a46*a55 + - a11*a22*a33*a46*a55 + + a15*a23*a32*a41*a56 + - a13*a25*a32*a41*a56 + - a15*a22*a33*a41*a56 + + a12*a25*a33*a41*a56 + + a13*a22*a35*a41*a56 + - a12*a23*a35*a41*a56 + - a15*a23*a31*a42*a56 + + a13*a25*a31*a42*a56 + + a15*a21*a33*a42*a56 + - a11*a25*a33*a42*a56 + - a13*a21*a35*a42*a56 + + a11*a23*a35*a42*a56 + + a15*a22*a31*a43*a56 + - a12*a25*a31*a43*a56 + - a15*a21*a32*a43*a56 + + a11*a25*a32*a43*a56 + + a12*a21*a35*a43*a56 + - a11*a22*a35*a43*a56 + - a13*a22*a31*a45*a56 + + a12*a23*a31*a45*a56 + + a13*a21*a32*a45*a56 + - a11*a23*a32*a45*a56 + - a12*a21*a33*a45*a56 + + a11*a22*a33*a45*a56; + cofactor[24] = a26*a34*a43*a52*a61 + - a24*a36*a43*a52*a61 + - a26*a33*a44*a52*a61 + + a23*a36*a44*a52*a61 + + a24*a33*a46*a52*a61 + - a23*a34*a46*a52*a61 + - a26*a34*a42*a53*a61 + + a24*a36*a42*a53*a61 + + a26*a32*a44*a53*a61 + - a22*a36*a44*a53*a61 + - a24*a32*a46*a53*a61 + + a22*a34*a46*a53*a61 + + a26*a33*a42*a54*a61 + - a23*a36*a42*a54*a61 + - a26*a32*a43*a54*a61 + + a22*a36*a43*a54*a61 + + a23*a32*a46*a54*a61 + - a22*a33*a46*a54*a61 + - a24*a33*a42*a56*a61 + + a23*a34*a42*a56*a61 + + a24*a32*a43*a56*a61 + - a22*a34*a43*a56*a61 + - a23*a32*a44*a56*a61 + + a22*a33*a44*a56*a61 + - a26*a34*a43*a51*a62 + + a24*a36*a43*a51*a62 + + a26*a33*a44*a51*a62 + - a23*a36*a44*a51*a62 + - a24*a33*a46*a51*a62 + + a23*a34*a46*a51*a62 + + a26*a34*a41*a53*a62 + - a24*a36*a41*a53*a62 + - a26*a31*a44*a53*a62 + + a21*a36*a44*a53*a62 + + a24*a31*a46*a53*a62 + - a21*a34*a46*a53*a62 + - a26*a33*a41*a54*a62 + + a23*a36*a41*a54*a62 + + a26*a31*a43*a54*a62 + - a21*a36*a43*a54*a62 + - a23*a31*a46*a54*a62 + + a21*a33*a46*a54*a62 + + a24*a33*a41*a56*a62 + - a23*a34*a41*a56*a62 + - a24*a31*a43*a56*a62 + + a21*a34*a43*a56*a62 + + a23*a31*a44*a56*a62 + - a21*a33*a44*a56*a62 + + a26*a34*a42*a51*a63 + - a24*a36*a42*a51*a63 + - a26*a32*a44*a51*a63 + + a22*a36*a44*a51*a63 + + a24*a32*a46*a51*a63 + - a22*a34*a46*a51*a63 + - a26*a34*a41*a52*a63 + + a24*a36*a41*a52*a63 + + a26*a31*a44*a52*a63 + - a21*a36*a44*a52*a63 + - a24*a31*a46*a52*a63 + + a21*a34*a46*a52*a63 + + a26*a32*a41*a54*a63 + - a22*a36*a41*a54*a63 + - a26*a31*a42*a54*a63 + + a21*a36*a42*a54*a63 + + a22*a31*a46*a54*a63 + - a21*a32*a46*a54*a63 + - a24*a32*a41*a56*a63 + + a22*a34*a41*a56*a63 + + a24*a31*a42*a56*a63 + - a21*a34*a42*a56*a63 + - a22*a31*a44*a56*a63 + + a21*a32*a44*a56*a63 + - a26*a33*a42*a51*a64 + + a23*a36*a42*a51*a64 + + a26*a32*a43*a51*a64 + - a22*a36*a43*a51*a64 + - a23*a32*a46*a51*a64 + + a22*a33*a46*a51*a64 + + a26*a33*a41*a52*a64 + - a23*a36*a41*a52*a64 + - a26*a31*a43*a52*a64 + + a21*a36*a43*a52*a64 + + a23*a31*a46*a52*a64 + - a21*a33*a46*a52*a64 + - a26*a32*a41*a53*a64 + + a22*a36*a41*a53*a64 + + a26*a31*a42*a53*a64 + - a21*a36*a42*a53*a64 + - a22*a31*a46*a53*a64 + + a21*a32*a46*a53*a64 + + a23*a32*a41*a56*a64 + - a22*a33*a41*a56*a64 + - a23*a31*a42*a56*a64 + + a21*a33*a42*a56*a64 + + a22*a31*a43*a56*a64 + - a21*a32*a43*a56*a64 + + a24*a33*a42*a51*a66 + - a23*a34*a42*a51*a66 + - a24*a32*a43*a51*a66 + + a22*a34*a43*a51*a66 + + a23*a32*a44*a51*a66 + - a22*a33*a44*a51*a66 + - a24*a33*a41*a52*a66 + + a23*a34*a41*a52*a66 + + a24*a31*a43*a52*a66 + - a21*a34*a43*a52*a66 + - a23*a31*a44*a52*a66 + + a21*a33*a44*a52*a66 + + a24*a32*a41*a53*a66 + - a22*a34*a41*a53*a66 + - a24*a31*a42*a53*a66 + + a21*a34*a42*a53*a66 + + a22*a31*a44*a53*a66 + - a21*a32*a44*a53*a66 + - a23*a32*a41*a54*a66 + + a22*a33*a41*a54*a66 + + a23*a31*a42*a54*a66 + - a21*a33*a42*a54*a66 + - a22*a31*a43*a54*a66 + + a21*a32*a43*a54*a66; + cofactor[25] = -a16*a34*a43*a52*a61 + + a14*a36*a43*a52*a61 + + a16*a33*a44*a52*a61 + - a13*a36*a44*a52*a61 + - a14*a33*a46*a52*a61 + + a13*a34*a46*a52*a61 + + a16*a34*a42*a53*a61 + - a14*a36*a42*a53*a61 + - a16*a32*a44*a53*a61 + + a12*a36*a44*a53*a61 + + a14*a32*a46*a53*a61 + - a12*a34*a46*a53*a61 + - a16*a33*a42*a54*a61 + + a13*a36*a42*a54*a61 + + a16*a32*a43*a54*a61 + - a12*a36*a43*a54*a61 + - a13*a32*a46*a54*a61 + + a12*a33*a46*a54*a61 + + a14*a33*a42*a56*a61 + - a13*a34*a42*a56*a61 + - a14*a32*a43*a56*a61 + + a12*a34*a43*a56*a61 + + a13*a32*a44*a56*a61 + - a12*a33*a44*a56*a61 + + a16*a34*a43*a51*a62 + - a14*a36*a43*a51*a62 + - a16*a33*a44*a51*a62 + + a13*a36*a44*a51*a62 + + a14*a33*a46*a51*a62 + - a13*a34*a46*a51*a62 + - a16*a34*a41*a53*a62 + + a14*a36*a41*a53*a62 + + a16*a31*a44*a53*a62 + - a11*a36*a44*a53*a62 + - a14*a31*a46*a53*a62 + + a11*a34*a46*a53*a62 + + a16*a33*a41*a54*a62 + - a13*a36*a41*a54*a62 + - a16*a31*a43*a54*a62 + + a11*a36*a43*a54*a62 + + a13*a31*a46*a54*a62 + - a11*a33*a46*a54*a62 + - a14*a33*a41*a56*a62 + + a13*a34*a41*a56*a62 + + a14*a31*a43*a56*a62 + - a11*a34*a43*a56*a62 + - a13*a31*a44*a56*a62 + + a11*a33*a44*a56*a62 + - a16*a34*a42*a51*a63 + + a14*a36*a42*a51*a63 + + a16*a32*a44*a51*a63 + - a12*a36*a44*a51*a63 + - a14*a32*a46*a51*a63 + + a12*a34*a46*a51*a63 + + a16*a34*a41*a52*a63 + - a14*a36*a41*a52*a63 + - a16*a31*a44*a52*a63 + + a11*a36*a44*a52*a63 + + a14*a31*a46*a52*a63 + - a11*a34*a46*a52*a63 + - a16*a32*a41*a54*a63 + + a12*a36*a41*a54*a63 + + a16*a31*a42*a54*a63 + - a11*a36*a42*a54*a63 + - a12*a31*a46*a54*a63 + + a11*a32*a46*a54*a63 + + a14*a32*a41*a56*a63 + - a12*a34*a41*a56*a63 + - a14*a31*a42*a56*a63 + + a11*a34*a42*a56*a63 + + a12*a31*a44*a56*a63 + - a11*a32*a44*a56*a63 + + a16*a33*a42*a51*a64 + - a13*a36*a42*a51*a64 + - a16*a32*a43*a51*a64 + + a12*a36*a43*a51*a64 + + a13*a32*a46*a51*a64 + - a12*a33*a46*a51*a64 + - a16*a33*a41*a52*a64 + + a13*a36*a41*a52*a64 + + a16*a31*a43*a52*a64 + - a11*a36*a43*a52*a64 + - a13*a31*a46*a52*a64 + + a11*a33*a46*a52*a64 + + a16*a32*a41*a53*a64 + - a12*a36*a41*a53*a64 + - a16*a31*a42*a53*a64 + + a11*a36*a42*a53*a64 + + a12*a31*a46*a53*a64 + - a11*a32*a46*a53*a64 + - a13*a32*a41*a56*a64 + + a12*a33*a41*a56*a64 + + a13*a31*a42*a56*a64 + - a11*a33*a42*a56*a64 + - a12*a31*a43*a56*a64 + + a11*a32*a43*a56*a64 + - a14*a33*a42*a51*a66 + + a13*a34*a42*a51*a66 + + a14*a32*a43*a51*a66 + - a12*a34*a43*a51*a66 + - a13*a32*a44*a51*a66 + + a12*a33*a44*a51*a66 + + a14*a33*a41*a52*a66 + - a13*a34*a41*a52*a66 + - a14*a31*a43*a52*a66 + + a11*a34*a43*a52*a66 + + a13*a31*a44*a52*a66 + - a11*a33*a44*a52*a66 + - a14*a32*a41*a53*a66 + + a12*a34*a41*a53*a66 + + a14*a31*a42*a53*a66 + - a11*a34*a42*a53*a66 + - a12*a31*a44*a53*a66 + + a11*a32*a44*a53*a66 + + a13*a32*a41*a54*a66 + - a12*a33*a41*a54*a66 + - a13*a31*a42*a54*a66 + + a11*a33*a42*a54*a66 + + a12*a31*a43*a54*a66 + - a11*a32*a43*a54*a66; + cofactor[26] = a16*a24*a43*a52*a61 + - a14*a26*a43*a52*a61 + - a16*a23*a44*a52*a61 + + a13*a26*a44*a52*a61 + + a14*a23*a46*a52*a61 + - a13*a24*a46*a52*a61 + - a16*a24*a42*a53*a61 + + a14*a26*a42*a53*a61 + + a16*a22*a44*a53*a61 + - a12*a26*a44*a53*a61 + - a14*a22*a46*a53*a61 + + a12*a24*a46*a53*a61 + + a16*a23*a42*a54*a61 + - a13*a26*a42*a54*a61 + - a16*a22*a43*a54*a61 + + a12*a26*a43*a54*a61 + + a13*a22*a46*a54*a61 + - a12*a23*a46*a54*a61 + - a14*a23*a42*a56*a61 + + a13*a24*a42*a56*a61 + + a14*a22*a43*a56*a61 + - a12*a24*a43*a56*a61 + - a13*a22*a44*a56*a61 + + a12*a23*a44*a56*a61 + - a16*a24*a43*a51*a62 + + a14*a26*a43*a51*a62 + + a16*a23*a44*a51*a62 + - a13*a26*a44*a51*a62 + - a14*a23*a46*a51*a62 + + a13*a24*a46*a51*a62 + + a16*a24*a41*a53*a62 + - a14*a26*a41*a53*a62 + - a16*a21*a44*a53*a62 + + a11*a26*a44*a53*a62 + + a14*a21*a46*a53*a62 + - a11*a24*a46*a53*a62 + - a16*a23*a41*a54*a62 + + a13*a26*a41*a54*a62 + + a16*a21*a43*a54*a62 + - a11*a26*a43*a54*a62 + - a13*a21*a46*a54*a62 + + a11*a23*a46*a54*a62 + + a14*a23*a41*a56*a62 + - a13*a24*a41*a56*a62 + - a14*a21*a43*a56*a62 + + a11*a24*a43*a56*a62 + + a13*a21*a44*a56*a62 + - a11*a23*a44*a56*a62 + + a16*a24*a42*a51*a63 + - a14*a26*a42*a51*a63 + - a16*a22*a44*a51*a63 + + a12*a26*a44*a51*a63 + + a14*a22*a46*a51*a63 + - a12*a24*a46*a51*a63 + - a16*a24*a41*a52*a63 + + a14*a26*a41*a52*a63 + + a16*a21*a44*a52*a63 + - a11*a26*a44*a52*a63 + - a14*a21*a46*a52*a63 + + a11*a24*a46*a52*a63 + + a16*a22*a41*a54*a63 + - a12*a26*a41*a54*a63 + - a16*a21*a42*a54*a63 + + a11*a26*a42*a54*a63 + + a12*a21*a46*a54*a63 + - a11*a22*a46*a54*a63 + - a14*a22*a41*a56*a63 + + a12*a24*a41*a56*a63 + + a14*a21*a42*a56*a63 + - a11*a24*a42*a56*a63 + - a12*a21*a44*a56*a63 + + a11*a22*a44*a56*a63 + - a16*a23*a42*a51*a64 + + a13*a26*a42*a51*a64 + + a16*a22*a43*a51*a64 + - a12*a26*a43*a51*a64 + - a13*a22*a46*a51*a64 + + a12*a23*a46*a51*a64 + + a16*a23*a41*a52*a64 + - a13*a26*a41*a52*a64 + - a16*a21*a43*a52*a64 + + a11*a26*a43*a52*a64 + + a13*a21*a46*a52*a64 + - a11*a23*a46*a52*a64 + - a16*a22*a41*a53*a64 + + a12*a26*a41*a53*a64 + + a16*a21*a42*a53*a64 + - a11*a26*a42*a53*a64 + - a12*a21*a46*a53*a64 + + a11*a22*a46*a53*a64 + + a13*a22*a41*a56*a64 + - a12*a23*a41*a56*a64 + - a13*a21*a42*a56*a64 + + a11*a23*a42*a56*a64 + + a12*a21*a43*a56*a64 + - a11*a22*a43*a56*a64 + + a14*a23*a42*a51*a66 + - a13*a24*a42*a51*a66 + - a14*a22*a43*a51*a66 + + a12*a24*a43*a51*a66 + + a13*a22*a44*a51*a66 + - a12*a23*a44*a51*a66 + - a14*a23*a41*a52*a66 + + a13*a24*a41*a52*a66 + + a14*a21*a43*a52*a66 + - a11*a24*a43*a52*a66 + - a13*a21*a44*a52*a66 + + a11*a23*a44*a52*a66 + + a14*a22*a41*a53*a66 + - a12*a24*a41*a53*a66 + - a14*a21*a42*a53*a66 + + a11*a24*a42*a53*a66 + + a12*a21*a44*a53*a66 + - a11*a22*a44*a53*a66 + - a13*a22*a41*a54*a66 + + a12*a23*a41*a54*a66 + + a13*a21*a42*a54*a66 + - a11*a23*a42*a54*a66 + - a12*a21*a43*a54*a66 + + a11*a22*a43*a54*a66; + cofactor[27] = -a16*a24*a33*a52*a61 + + a14*a26*a33*a52*a61 + + a16*a23*a34*a52*a61 + - a13*a26*a34*a52*a61 + - a14*a23*a36*a52*a61 + + a13*a24*a36*a52*a61 + + a16*a24*a32*a53*a61 + - a14*a26*a32*a53*a61 + - a16*a22*a34*a53*a61 + + a12*a26*a34*a53*a61 + + a14*a22*a36*a53*a61 + - a12*a24*a36*a53*a61 + - a16*a23*a32*a54*a61 + + a13*a26*a32*a54*a61 + + a16*a22*a33*a54*a61 + - a12*a26*a33*a54*a61 + - a13*a22*a36*a54*a61 + + a12*a23*a36*a54*a61 + + a14*a23*a32*a56*a61 + - a13*a24*a32*a56*a61 + - a14*a22*a33*a56*a61 + + a12*a24*a33*a56*a61 + + a13*a22*a34*a56*a61 + - a12*a23*a34*a56*a61 + + a16*a24*a33*a51*a62 + - a14*a26*a33*a51*a62 + - a16*a23*a34*a51*a62 + + a13*a26*a34*a51*a62 + + a14*a23*a36*a51*a62 + - a13*a24*a36*a51*a62 + - a16*a24*a31*a53*a62 + + a14*a26*a31*a53*a62 + + a16*a21*a34*a53*a62 + - a11*a26*a34*a53*a62 + - a14*a21*a36*a53*a62 + + a11*a24*a36*a53*a62 + + a16*a23*a31*a54*a62 + - a13*a26*a31*a54*a62 + - a16*a21*a33*a54*a62 + + a11*a26*a33*a54*a62 + + a13*a21*a36*a54*a62 + - a11*a23*a36*a54*a62 + - a14*a23*a31*a56*a62 + + a13*a24*a31*a56*a62 + + a14*a21*a33*a56*a62 + - a11*a24*a33*a56*a62 + - a13*a21*a34*a56*a62 + + a11*a23*a34*a56*a62 + - a16*a24*a32*a51*a63 + + a14*a26*a32*a51*a63 + + a16*a22*a34*a51*a63 + - a12*a26*a34*a51*a63 + - a14*a22*a36*a51*a63 + + a12*a24*a36*a51*a63 + + a16*a24*a31*a52*a63 + - a14*a26*a31*a52*a63 + - a16*a21*a34*a52*a63 + + a11*a26*a34*a52*a63 + + a14*a21*a36*a52*a63 + - a11*a24*a36*a52*a63 + - a16*a22*a31*a54*a63 + + a12*a26*a31*a54*a63 + + a16*a21*a32*a54*a63 + - a11*a26*a32*a54*a63 + - a12*a21*a36*a54*a63 + + a11*a22*a36*a54*a63 + + a14*a22*a31*a56*a63 + - a12*a24*a31*a56*a63 + - a14*a21*a32*a56*a63 + + a11*a24*a32*a56*a63 + + a12*a21*a34*a56*a63 + - a11*a22*a34*a56*a63 + + a16*a23*a32*a51*a64 + - a13*a26*a32*a51*a64 + - a16*a22*a33*a51*a64 + + a12*a26*a33*a51*a64 + + a13*a22*a36*a51*a64 + - a12*a23*a36*a51*a64 + - a16*a23*a31*a52*a64 + + a13*a26*a31*a52*a64 + + a16*a21*a33*a52*a64 + - a11*a26*a33*a52*a64 + - a13*a21*a36*a52*a64 + + a11*a23*a36*a52*a64 + + a16*a22*a31*a53*a64 + - a12*a26*a31*a53*a64 + - a16*a21*a32*a53*a64 + + a11*a26*a32*a53*a64 + + a12*a21*a36*a53*a64 + - a11*a22*a36*a53*a64 + - a13*a22*a31*a56*a64 + + a12*a23*a31*a56*a64 + + a13*a21*a32*a56*a64 + - a11*a23*a32*a56*a64 + - a12*a21*a33*a56*a64 + + a11*a22*a33*a56*a64 + - a14*a23*a32*a51*a66 + + a13*a24*a32*a51*a66 + + a14*a22*a33*a51*a66 + - a12*a24*a33*a51*a66 + - a13*a22*a34*a51*a66 + + a12*a23*a34*a51*a66 + + a14*a23*a31*a52*a66 + - a13*a24*a31*a52*a66 + - a14*a21*a33*a52*a66 + + a11*a24*a33*a52*a66 + + a13*a21*a34*a52*a66 + - a11*a23*a34*a52*a66 + - a14*a22*a31*a53*a66 + + a12*a24*a31*a53*a66 + + a14*a21*a32*a53*a66 + - a11*a24*a32*a53*a66 + - a12*a21*a34*a53*a66 + + a11*a22*a34*a53*a66 + + a13*a22*a31*a54*a66 + - a12*a23*a31*a54*a66 + - a13*a21*a32*a54*a66 + + a11*a23*a32*a54*a66 + + a12*a21*a33*a54*a66 + - a11*a22*a33*a54*a66; + cofactor[28] = a16*a24*a33*a42*a61 + - a14*a26*a33*a42*a61 + - a16*a23*a34*a42*a61 + + a13*a26*a34*a42*a61 + + a14*a23*a36*a42*a61 + - a13*a24*a36*a42*a61 + - a16*a24*a32*a43*a61 + + a14*a26*a32*a43*a61 + + a16*a22*a34*a43*a61 + - a12*a26*a34*a43*a61 + - a14*a22*a36*a43*a61 + + a12*a24*a36*a43*a61 + + a16*a23*a32*a44*a61 + - a13*a26*a32*a44*a61 + - a16*a22*a33*a44*a61 + + a12*a26*a33*a44*a61 + + a13*a22*a36*a44*a61 + - a12*a23*a36*a44*a61 + - a14*a23*a32*a46*a61 + + a13*a24*a32*a46*a61 + + a14*a22*a33*a46*a61 + - a12*a24*a33*a46*a61 + - a13*a22*a34*a46*a61 + + a12*a23*a34*a46*a61 + - a16*a24*a33*a41*a62 + + a14*a26*a33*a41*a62 + + a16*a23*a34*a41*a62 + - a13*a26*a34*a41*a62 + - a14*a23*a36*a41*a62 + + a13*a24*a36*a41*a62 + + a16*a24*a31*a43*a62 + - a14*a26*a31*a43*a62 + - a16*a21*a34*a43*a62 + + a11*a26*a34*a43*a62 + + a14*a21*a36*a43*a62 + - a11*a24*a36*a43*a62 + - a16*a23*a31*a44*a62 + + a13*a26*a31*a44*a62 + + a16*a21*a33*a44*a62 + - a11*a26*a33*a44*a62 + - a13*a21*a36*a44*a62 + + a11*a23*a36*a44*a62 + + a14*a23*a31*a46*a62 + - a13*a24*a31*a46*a62 + - a14*a21*a33*a46*a62 + + a11*a24*a33*a46*a62 + + a13*a21*a34*a46*a62 + - a11*a23*a34*a46*a62 + + a16*a24*a32*a41*a63 + - a14*a26*a32*a41*a63 + - a16*a22*a34*a41*a63 + + a12*a26*a34*a41*a63 + + a14*a22*a36*a41*a63 + - a12*a24*a36*a41*a63 + - a16*a24*a31*a42*a63 + + a14*a26*a31*a42*a63 + + a16*a21*a34*a42*a63 + - a11*a26*a34*a42*a63 + - a14*a21*a36*a42*a63 + + a11*a24*a36*a42*a63 + + a16*a22*a31*a44*a63 + - a12*a26*a31*a44*a63 + - a16*a21*a32*a44*a63 + + a11*a26*a32*a44*a63 + + a12*a21*a36*a44*a63 + - a11*a22*a36*a44*a63 + - a14*a22*a31*a46*a63 + + a12*a24*a31*a46*a63 + + a14*a21*a32*a46*a63 + - a11*a24*a32*a46*a63 + - a12*a21*a34*a46*a63 + + a11*a22*a34*a46*a63 + - a16*a23*a32*a41*a64 + + a13*a26*a32*a41*a64 + + a16*a22*a33*a41*a64 + - a12*a26*a33*a41*a64 + - a13*a22*a36*a41*a64 + + a12*a23*a36*a41*a64 + + a16*a23*a31*a42*a64 + - a13*a26*a31*a42*a64 + - a16*a21*a33*a42*a64 + + a11*a26*a33*a42*a64 + + a13*a21*a36*a42*a64 + - a11*a23*a36*a42*a64 + - a16*a22*a31*a43*a64 + + a12*a26*a31*a43*a64 + + a16*a21*a32*a43*a64 + - a11*a26*a32*a43*a64 + - a12*a21*a36*a43*a64 + + a11*a22*a36*a43*a64 + + a13*a22*a31*a46*a64 + - a12*a23*a31*a46*a64 + - a13*a21*a32*a46*a64 + + a11*a23*a32*a46*a64 + + a12*a21*a33*a46*a64 + - a11*a22*a33*a46*a64 + + a14*a23*a32*a41*a66 + - a13*a24*a32*a41*a66 + - a14*a22*a33*a41*a66 + + a12*a24*a33*a41*a66 + + a13*a22*a34*a41*a66 + - a12*a23*a34*a41*a66 + - a14*a23*a31*a42*a66 + + a13*a24*a31*a42*a66 + + a14*a21*a33*a42*a66 + - a11*a24*a33*a42*a66 + - a13*a21*a34*a42*a66 + + a11*a23*a34*a42*a66 + + a14*a22*a31*a43*a66 + - a12*a24*a31*a43*a66 + - a14*a21*a32*a43*a66 + + a11*a24*a32*a43*a66 + + a12*a21*a34*a43*a66 + - a11*a22*a34*a43*a66 + - a13*a22*a31*a44*a66 + + a12*a23*a31*a44*a66 + + a13*a21*a32*a44*a66 + - a11*a23*a32*a44*a66 + - a12*a21*a33*a44*a66 + + a11*a22*a33*a44*a66; + cofactor[29] = -a16*a24*a33*a42*a51 + + a14*a26*a33*a42*a51 + + a16*a23*a34*a42*a51 + - a13*a26*a34*a42*a51 + - a14*a23*a36*a42*a51 + + a13*a24*a36*a42*a51 + + a16*a24*a32*a43*a51 + - a14*a26*a32*a43*a51 + - a16*a22*a34*a43*a51 + + a12*a26*a34*a43*a51 + + a14*a22*a36*a43*a51 + - a12*a24*a36*a43*a51 + - a16*a23*a32*a44*a51 + + a13*a26*a32*a44*a51 + + a16*a22*a33*a44*a51 + - a12*a26*a33*a44*a51 + - a13*a22*a36*a44*a51 + + a12*a23*a36*a44*a51 + + a14*a23*a32*a46*a51 + - a13*a24*a32*a46*a51 + - a14*a22*a33*a46*a51 + + a12*a24*a33*a46*a51 + + a13*a22*a34*a46*a51 + - a12*a23*a34*a46*a51 + + a16*a24*a33*a41*a52 + - a14*a26*a33*a41*a52 + - a16*a23*a34*a41*a52 + + a13*a26*a34*a41*a52 + + a14*a23*a36*a41*a52 + - a13*a24*a36*a41*a52 + - a16*a24*a31*a43*a52 + + a14*a26*a31*a43*a52 + + a16*a21*a34*a43*a52 + - a11*a26*a34*a43*a52 + - a14*a21*a36*a43*a52 + + a11*a24*a36*a43*a52 + + a16*a23*a31*a44*a52 + - a13*a26*a31*a44*a52 + - a16*a21*a33*a44*a52 + + a11*a26*a33*a44*a52 + + a13*a21*a36*a44*a52 + - a11*a23*a36*a44*a52 + - a14*a23*a31*a46*a52 + + a13*a24*a31*a46*a52 + + a14*a21*a33*a46*a52 + - a11*a24*a33*a46*a52 + - a13*a21*a34*a46*a52 + + a11*a23*a34*a46*a52 + - a16*a24*a32*a41*a53 + + a14*a26*a32*a41*a53 + + a16*a22*a34*a41*a53 + - a12*a26*a34*a41*a53 + - a14*a22*a36*a41*a53 + + a12*a24*a36*a41*a53 + + a16*a24*a31*a42*a53 + - a14*a26*a31*a42*a53 + - a16*a21*a34*a42*a53 + + a11*a26*a34*a42*a53 + + a14*a21*a36*a42*a53 + - a11*a24*a36*a42*a53 + - a16*a22*a31*a44*a53 + + a12*a26*a31*a44*a53 + + a16*a21*a32*a44*a53 + - a11*a26*a32*a44*a53 + - a12*a21*a36*a44*a53 + + a11*a22*a36*a44*a53 + + a14*a22*a31*a46*a53 + - a12*a24*a31*a46*a53 + - a14*a21*a32*a46*a53 + + a11*a24*a32*a46*a53 + + a12*a21*a34*a46*a53 + - a11*a22*a34*a46*a53 + + a16*a23*a32*a41*a54 + - a13*a26*a32*a41*a54 + - a16*a22*a33*a41*a54 + + a12*a26*a33*a41*a54 + + a13*a22*a36*a41*a54 + - a12*a23*a36*a41*a54 + - a16*a23*a31*a42*a54 + + a13*a26*a31*a42*a54 + + a16*a21*a33*a42*a54 + - a11*a26*a33*a42*a54 + - a13*a21*a36*a42*a54 + + a11*a23*a36*a42*a54 + + a16*a22*a31*a43*a54 + - a12*a26*a31*a43*a54 + - a16*a21*a32*a43*a54 + + a11*a26*a32*a43*a54 + + a12*a21*a36*a43*a54 + - a11*a22*a36*a43*a54 + - a13*a22*a31*a46*a54 + + a12*a23*a31*a46*a54 + + a13*a21*a32*a46*a54 + - a11*a23*a32*a46*a54 + - a12*a21*a33*a46*a54 + + a11*a22*a33*a46*a54 + - a14*a23*a32*a41*a56 + + a13*a24*a32*a41*a56 + + a14*a22*a33*a41*a56 + - a12*a24*a33*a41*a56 + - a13*a22*a34*a41*a56 + + a12*a23*a34*a41*a56 + + a14*a23*a31*a42*a56 + - a13*a24*a31*a42*a56 + - a14*a21*a33*a42*a56 + + a11*a24*a33*a42*a56 + + a13*a21*a34*a42*a56 + - a11*a23*a34*a42*a56 + - a14*a22*a31*a43*a56 + + a12*a24*a31*a43*a56 + + a14*a21*a32*a43*a56 + - a11*a24*a32*a43*a56 + - a12*a21*a34*a43*a56 + + a11*a22*a34*a43*a56 + + a13*a22*a31*a44*a56 + - a12*a23*a31*a44*a56 + - a13*a21*a32*a44*a56 + + a11*a23*a32*a44*a56 + + a12*a21*a33*a44*a56 + - a11*a22*a33*a44*a56; + cofactor[30] = -a25*a34*a43*a52*a61 + + a24*a35*a43*a52*a61 + + a25*a33*a44*a52*a61 + - a23*a35*a44*a52*a61 + - a24*a33*a45*a52*a61 + + a23*a34*a45*a52*a61 + + a25*a34*a42*a53*a61 + - a24*a35*a42*a53*a61 + - a25*a32*a44*a53*a61 + + a22*a35*a44*a53*a61 + + a24*a32*a45*a53*a61 + - a22*a34*a45*a53*a61 + - a25*a33*a42*a54*a61 + + a23*a35*a42*a54*a61 + + a25*a32*a43*a54*a61 + - a22*a35*a43*a54*a61 + - a23*a32*a45*a54*a61 + + a22*a33*a45*a54*a61 + + a24*a33*a42*a55*a61 + - a23*a34*a42*a55*a61 + - a24*a32*a43*a55*a61 + + a22*a34*a43*a55*a61 + + a23*a32*a44*a55*a61 + - a22*a33*a44*a55*a61 + + a25*a34*a43*a51*a62 + - a24*a35*a43*a51*a62 + - a25*a33*a44*a51*a62 + + a23*a35*a44*a51*a62 + + a24*a33*a45*a51*a62 + - a23*a34*a45*a51*a62 + - a25*a34*a41*a53*a62 + + a24*a35*a41*a53*a62 + + a25*a31*a44*a53*a62 + - a21*a35*a44*a53*a62 + - a24*a31*a45*a53*a62 + + a21*a34*a45*a53*a62 + + a25*a33*a41*a54*a62 + - a23*a35*a41*a54*a62 + - a25*a31*a43*a54*a62 + + a21*a35*a43*a54*a62 + + a23*a31*a45*a54*a62 + - a21*a33*a45*a54*a62 + - a24*a33*a41*a55*a62 + + a23*a34*a41*a55*a62 + + a24*a31*a43*a55*a62 + - a21*a34*a43*a55*a62 + - a23*a31*a44*a55*a62 + + a21*a33*a44*a55*a62 + - a25*a34*a42*a51*a63 + + a24*a35*a42*a51*a63 + + a25*a32*a44*a51*a63 + - a22*a35*a44*a51*a63 + - a24*a32*a45*a51*a63 + + a22*a34*a45*a51*a63 + + a25*a34*a41*a52*a63 + - a24*a35*a41*a52*a63 + - a25*a31*a44*a52*a63 + + a21*a35*a44*a52*a63 + + a24*a31*a45*a52*a63 + - a21*a34*a45*a52*a63 + - a25*a32*a41*a54*a63 + + a22*a35*a41*a54*a63 + + a25*a31*a42*a54*a63 + - a21*a35*a42*a54*a63 + - a22*a31*a45*a54*a63 + + a21*a32*a45*a54*a63 + + a24*a32*a41*a55*a63 + - a22*a34*a41*a55*a63 + - a24*a31*a42*a55*a63 + + a21*a34*a42*a55*a63 + + a22*a31*a44*a55*a63 + - a21*a32*a44*a55*a63 + + a25*a33*a42*a51*a64 + - a23*a35*a42*a51*a64 + - a25*a32*a43*a51*a64 + + a22*a35*a43*a51*a64 + + a23*a32*a45*a51*a64 + - a22*a33*a45*a51*a64 + - a25*a33*a41*a52*a64 + + a23*a35*a41*a52*a64 + + a25*a31*a43*a52*a64 + - a21*a35*a43*a52*a64 + - a23*a31*a45*a52*a64 + + a21*a33*a45*a52*a64 + + a25*a32*a41*a53*a64 + - a22*a35*a41*a53*a64 + - a25*a31*a42*a53*a64 + + a21*a35*a42*a53*a64 + + a22*a31*a45*a53*a64 + - a21*a32*a45*a53*a64 + - a23*a32*a41*a55*a64 + + a22*a33*a41*a55*a64 + + a23*a31*a42*a55*a64 + - a21*a33*a42*a55*a64 + - a22*a31*a43*a55*a64 + + a21*a32*a43*a55*a64 + - a24*a33*a42*a51*a65 + + a23*a34*a42*a51*a65 + + a24*a32*a43*a51*a65 + - a22*a34*a43*a51*a65 + - a23*a32*a44*a51*a65 + + a22*a33*a44*a51*a65 + + a24*a33*a41*a52*a65 + - a23*a34*a41*a52*a65 + - a24*a31*a43*a52*a65 + + a21*a34*a43*a52*a65 + + a23*a31*a44*a52*a65 + - a21*a33*a44*a52*a65 + - a24*a32*a41*a53*a65 + + a22*a34*a41*a53*a65 + + a24*a31*a42*a53*a65 + - a21*a34*a42*a53*a65 + - a22*a31*a44*a53*a65 + + a21*a32*a44*a53*a65 + + a23*a32*a41*a54*a65 + - a22*a33*a41*a54*a65 + - a23*a31*a42*a54*a65 + + a21*a33*a42*a54*a65 + + a22*a31*a43*a54*a65 + - a21*a32*a43*a54*a65; + cofactor[31] = a15*a34*a43*a52*a61 + - a14*a35*a43*a52*a61 + - a15*a33*a44*a52*a61 + + a13*a35*a44*a52*a61 + + a14*a33*a45*a52*a61 + - a13*a34*a45*a52*a61 + - a15*a34*a42*a53*a61 + + a14*a35*a42*a53*a61 + + a15*a32*a44*a53*a61 + - a12*a35*a44*a53*a61 + - a14*a32*a45*a53*a61 + + a12*a34*a45*a53*a61 + + a15*a33*a42*a54*a61 + - a13*a35*a42*a54*a61 + - a15*a32*a43*a54*a61 + + a12*a35*a43*a54*a61 + + a13*a32*a45*a54*a61 + - a12*a33*a45*a54*a61 + - a14*a33*a42*a55*a61 + + a13*a34*a42*a55*a61 + + a14*a32*a43*a55*a61 + - a12*a34*a43*a55*a61 + - a13*a32*a44*a55*a61 + + a12*a33*a44*a55*a61 + - a15*a34*a43*a51*a62 + + a14*a35*a43*a51*a62 + + a15*a33*a44*a51*a62 + - a13*a35*a44*a51*a62 + - a14*a33*a45*a51*a62 + + a13*a34*a45*a51*a62 + + a15*a34*a41*a53*a62 + - a14*a35*a41*a53*a62 + - a15*a31*a44*a53*a62 + + a11*a35*a44*a53*a62 + + a14*a31*a45*a53*a62 + - a11*a34*a45*a53*a62 + - a15*a33*a41*a54*a62 + + a13*a35*a41*a54*a62 + + a15*a31*a43*a54*a62 + - a11*a35*a43*a54*a62 + - a13*a31*a45*a54*a62 + + a11*a33*a45*a54*a62 + + a14*a33*a41*a55*a62 + - a13*a34*a41*a55*a62 + - a14*a31*a43*a55*a62 + + a11*a34*a43*a55*a62 + + a13*a31*a44*a55*a62 + - a11*a33*a44*a55*a62 + + a15*a34*a42*a51*a63 + - a14*a35*a42*a51*a63 + - a15*a32*a44*a51*a63 + + a12*a35*a44*a51*a63 + + a14*a32*a45*a51*a63 + - a12*a34*a45*a51*a63 + - a15*a34*a41*a52*a63 + + a14*a35*a41*a52*a63 + + a15*a31*a44*a52*a63 + - a11*a35*a44*a52*a63 + - a14*a31*a45*a52*a63 + + a11*a34*a45*a52*a63 + + a15*a32*a41*a54*a63 + - a12*a35*a41*a54*a63 + - a15*a31*a42*a54*a63 + + a11*a35*a42*a54*a63 + + a12*a31*a45*a54*a63 + - a11*a32*a45*a54*a63 + - a14*a32*a41*a55*a63 + + a12*a34*a41*a55*a63 + + a14*a31*a42*a55*a63 + - a11*a34*a42*a55*a63 + - a12*a31*a44*a55*a63 + + a11*a32*a44*a55*a63 + - a15*a33*a42*a51*a64 + + a13*a35*a42*a51*a64 + + a15*a32*a43*a51*a64 + - a12*a35*a43*a51*a64 + - a13*a32*a45*a51*a64 + + a12*a33*a45*a51*a64 + + a15*a33*a41*a52*a64 + - a13*a35*a41*a52*a64 + - a15*a31*a43*a52*a64 + + a11*a35*a43*a52*a64 + + a13*a31*a45*a52*a64 + - a11*a33*a45*a52*a64 + - a15*a32*a41*a53*a64 + + a12*a35*a41*a53*a64 + + a15*a31*a42*a53*a64 + - a11*a35*a42*a53*a64 + - a12*a31*a45*a53*a64 + + a11*a32*a45*a53*a64 + + a13*a32*a41*a55*a64 + - a12*a33*a41*a55*a64 + - a13*a31*a42*a55*a64 + + a11*a33*a42*a55*a64 + + a12*a31*a43*a55*a64 + - a11*a32*a43*a55*a64 + + a14*a33*a42*a51*a65 + - a13*a34*a42*a51*a65 + - a14*a32*a43*a51*a65 + + a12*a34*a43*a51*a65 + + a13*a32*a44*a51*a65 + - a12*a33*a44*a51*a65 + - a14*a33*a41*a52*a65 + + a13*a34*a41*a52*a65 + + a14*a31*a43*a52*a65 + - a11*a34*a43*a52*a65 + - a13*a31*a44*a52*a65 + + a11*a33*a44*a52*a65 + + a14*a32*a41*a53*a65 + - a12*a34*a41*a53*a65 + - a14*a31*a42*a53*a65 + + a11*a34*a42*a53*a65 + + a12*a31*a44*a53*a65 + - a11*a32*a44*a53*a65 + - a13*a32*a41*a54*a65 + + a12*a33*a41*a54*a65 + + a13*a31*a42*a54*a65 + - a11*a33*a42*a54*a65 + - a12*a31*a43*a54*a65 + + a11*a32*a43*a54*a65; + + cofactor[32] = -a15*a24*a43*a52*a61 + + a14*a25*a43*a52*a61 + + a15*a23*a44*a52*a61 + - a13*a25*a44*a52*a61 + - a14*a23*a45*a52*a61 + + a13*a24*a45*a52*a61 + + a15*a24*a42*a53*a61 + - a14*a25*a42*a53*a61 + - a15*a22*a44*a53*a61 + + a12*a25*a44*a53*a61 + + a14*a22*a45*a53*a61 + - a12*a24*a45*a53*a61 + - a15*a23*a42*a54*a61 + + a13*a25*a42*a54*a61 + + a15*a22*a43*a54*a61 + - a12*a25*a43*a54*a61 + - a13*a22*a45*a54*a61 + + a12*a23*a45*a54*a61 + + a14*a23*a42*a55*a61 + - a13*a24*a42*a55*a61 + - a14*a22*a43*a55*a61 + + a12*a24*a43*a55*a61 + + a13*a22*a44*a55*a61 + - a12*a23*a44*a55*a61 + + a15*a24*a43*a51*a62 + - a14*a25*a43*a51*a62 + - a15*a23*a44*a51*a62 + + a13*a25*a44*a51*a62 + + a14*a23*a45*a51*a62 + - a13*a24*a45*a51*a62 + - a15*a24*a41*a53*a62 + + a14*a25*a41*a53*a62 + + a15*a21*a44*a53*a62 + - a11*a25*a44*a53*a62 + - a14*a21*a45*a53*a62 + + a11*a24*a45*a53*a62 + + a15*a23*a41*a54*a62 + - a13*a25*a41*a54*a62 + - a15*a21*a43*a54*a62 + + a11*a25*a43*a54*a62 + + a13*a21*a45*a54*a62 + - a11*a23*a45*a54*a62 + - a14*a23*a41*a55*a62 + + a13*a24*a41*a55*a62 + + a14*a21*a43*a55*a62 + - a11*a24*a43*a55*a62 + - a13*a21*a44*a55*a62 + + a11*a23*a44*a55*a62 + - a15*a24*a42*a51*a63 + + a14*a25*a42*a51*a63 + + a15*a22*a44*a51*a63 + - a12*a25*a44*a51*a63 + - a14*a22*a45*a51*a63 + + a12*a24*a45*a51*a63 + + a15*a24*a41*a52*a63 + - a14*a25*a41*a52*a63 + - a15*a21*a44*a52*a63 + + a11*a25*a44*a52*a63 + + a14*a21*a45*a52*a63 + - a11*a24*a45*a52*a63 + - a15*a22*a41*a54*a63 + + a12*a25*a41*a54*a63 + + a15*a21*a42*a54*a63 + - a11*a25*a42*a54*a63 + - a12*a21*a45*a54*a63 + + a11*a22*a45*a54*a63 + + a14*a22*a41*a55*a63 + - a12*a24*a41*a55*a63 + - a14*a21*a42*a55*a63 + + a11*a24*a42*a55*a63 + + a12*a21*a44*a55*a63 + - a11*a22*a44*a55*a63 + + a15*a23*a42*a51*a64 + - a13*a25*a42*a51*a64 + - a15*a22*a43*a51*a64 + + a12*a25*a43*a51*a64 + + a13*a22*a45*a51*a64 + - a12*a23*a45*a51*a64 + - a15*a23*a41*a52*a64 + + a13*a25*a41*a52*a64 + + a15*a21*a43*a52*a64 + - a11*a25*a43*a52*a64 + - a13*a21*a45*a52*a64 + + a11*a23*a45*a52*a64 + + a15*a22*a41*a53*a64 + - a12*a25*a41*a53*a64 + - a15*a21*a42*a53*a64 + + a11*a25*a42*a53*a64 + + a12*a21*a45*a53*a64 + - a11*a22*a45*a53*a64 + - a13*a22*a41*a55*a64 + + a12*a23*a41*a55*a64 + + a13*a21*a42*a55*a64 + - a11*a23*a42*a55*a64 + - a12*a21*a43*a55*a64 + + a11*a22*a43*a55*a64 + + - a14*a23*a42*a51*a65 + + a13*a24*a42*a51*a65 + + a14*a22*a43*a51*a65 + - a12*a24*a43*a51*a65 + - a13*a22*a44*a51*a65 + + a12*a23*a44*a51*a65 + + a14*a23*a41*a52*a65 + - a13*a24*a41*a52*a65 + - a14*a21*a43*a52*a65 + + a11*a24*a43*a52*a65 + + a13*a21*a44*a52*a65 + - a11*a23*a44*a52*a65 + - a14*a22*a41*a53*a65 + + a12*a24*a41*a53*a65 + + a14*a21*a42*a53*a65 + - a11*a24*a42*a53*a65 + - a12*a21*a44*a53*a65 + + a11*a22*a44*a53*a65 + + a13*a22*a41*a54*a65 + - a12*a23*a41*a54*a65 + - a13*a21*a42*a54*a65 + + a11*a23*a42*a54*a65 + + a12*a21*a43*a54*a65 + - a11*a22*a43*a54*a65; + cofactor[33] = a15*a24*a33*a52*a61 + - a14*a25*a33*a52*a61 + - a15*a23*a34*a52*a61 + + a13*a25*a34*a52*a61 + + a14*a23*a35*a52*a61 + - a13*a24*a35*a52*a61 + - a15*a24*a32*a53*a61 + + a14*a25*a32*a53*a61 + + a15*a22*a34*a53*a61 + - a12*a25*a34*a53*a61 + - a14*a22*a35*a53*a61 + + a12*a24*a35*a53*a61 + + a15*a23*a32*a54*a61 + - a13*a25*a32*a54*a61 + - a15*a22*a33*a54*a61 + + a12*a25*a33*a54*a61 + + a13*a22*a35*a54*a61 + - a12*a23*a35*a54*a61 + - a14*a23*a32*a55*a61 + + a13*a24*a32*a55*a61 + + a14*a22*a33*a55*a61 + - a12*a24*a33*a55*a61 + - a13*a22*a34*a55*a61 + + a12*a23*a34*a55*a61 + - a15*a24*a33*a51*a62 + + a14*a25*a33*a51*a62 + + a15*a23*a34*a51*a62 + - a13*a25*a34*a51*a62 + - a14*a23*a35*a51*a62 + + a13*a24*a35*a51*a62 + + a15*a24*a31*a53*a62 + - a14*a25*a31*a53*a62 + - a15*a21*a34*a53*a62 + + a11*a25*a34*a53*a62 + + a14*a21*a35*a53*a62 + - a11*a24*a35*a53*a62 + - a15*a23*a31*a54*a62 + + a13*a25*a31*a54*a62 + + a15*a21*a33*a54*a62 + - a11*a25*a33*a54*a62 + - a13*a21*a35*a54*a62 + + a11*a23*a35*a54*a62 + + a14*a23*a31*a55*a62 + - a13*a24*a31*a55*a62 + - a14*a21*a33*a55*a62 + + a11*a24*a33*a55*a62 + + a13*a21*a34*a55*a62 + - a11*a23*a34*a55*a62 + + a15*a24*a32*a51*a63 + - a14*a25*a32*a51*a63 + - a15*a22*a34*a51*a63 + + a12*a25*a34*a51*a63 + + a14*a22*a35*a51*a63 + - a12*a24*a35*a51*a63 + - a15*a24*a31*a52*a63 + + a14*a25*a31*a52*a63 + + a15*a21*a34*a52*a63 + - a11*a25*a34*a52*a63 + - a14*a21*a35*a52*a63 + + a11*a24*a35*a52*a63 + + a15*a22*a31*a54*a63 + - a12*a25*a31*a54*a63 + - a15*a21*a32*a54*a63 + + a11*a25*a32*a54*a63 + + a12*a21*a35*a54*a63 + - a11*a22*a35*a54*a63 + - a14*a22*a31*a55*a63 + + a12*a24*a31*a55*a63 + + a14*a21*a32*a55*a63 + - a11*a24*a32*a55*a63 + - a12*a21*a34*a55*a63 + + a11*a22*a34*a55*a63 + - a15*a23*a32*a51*a64 + + a13*a25*a32*a51*a64 + + a15*a22*a33*a51*a64 + - a12*a25*a33*a51*a64 + - a13*a22*a35*a51*a64 + + a12*a23*a35*a51*a64 + + a15*a23*a31*a52*a64 + - a13*a25*a31*a52*a64 + - a15*a21*a33*a52*a64 + + a11*a25*a33*a52*a64 + + a13*a21*a35*a52*a64 + - a11*a23*a35*a52*a64 + - a15*a22*a31*a53*a64 + + a12*a25*a31*a53*a64 + + a15*a21*a32*a53*a64 + - a11*a25*a32*a53*a64 + - a12*a21*a35*a53*a64 + + a11*a22*a35*a53*a64 + + a13*a22*a31*a55*a64 + - a12*a23*a31*a55*a64 + - a13*a21*a32*a55*a64 + + a11*a23*a32*a55*a64 + + a12*a21*a33*a55*a64 + - a11*a22*a33*a55*a64 + + a14*a23*a32*a51*a65 + - a13*a24*a32*a51*a65 + - a14*a22*a33*a51*a65 + + a12*a24*a33*a51*a65 + + a13*a22*a34*a51*a65 + - a12*a23*a34*a51*a65 + - a14*a23*a31*a52*a65 + + a13*a24*a31*a52*a65 + + a14*a21*a33*a52*a65 + - a11*a24*a33*a52*a65 + - a13*a21*a34*a52*a65 + + a11*a23*a34*a52*a65 + + a14*a22*a31*a53*a65 + - a12*a24*a31*a53*a65 + - a14*a21*a32*a53*a65 + + a11*a24*a32*a53*a65 + + a12*a21*a34*a53*a65 + - a11*a22*a34*a53*a65 + - a13*a22*a31*a54*a65 + + a12*a23*a31*a54*a65 + + a13*a21*a32*a54*a65 + - a11*a23*a32*a54*a65 + - a12*a21*a33*a54*a65 + + a11*a22*a33*a54*a65; + cofactor[34] = -a15*a24*a33*a42*a61 + + a14*a25*a33*a42*a61 + + a15*a23*a34*a42*a61 + - a13*a25*a34*a42*a61 + - a14*a23*a35*a42*a61 + + a13*a24*a35*a42*a61 + + a15*a24*a32*a43*a61 + - a14*a25*a32*a43*a61 + - a15*a22*a34*a43*a61 + + a12*a25*a34*a43*a61 + + a14*a22*a35*a43*a61 + - a12*a24*a35*a43*a61 + - a15*a23*a32*a44*a61 + + a13*a25*a32*a44*a61 + + a15*a22*a33*a44*a61 + - a12*a25*a33*a44*a61 + - a13*a22*a35*a44*a61 + + a12*a23*a35*a44*a61 + + a14*a23*a32*a45*a61 + - a13*a24*a32*a45*a61 + - a14*a22*a33*a45*a61 + + a12*a24*a33*a45*a61 + + a13*a22*a34*a45*a61 + - a12*a23*a34*a45*a61 + + a15*a24*a33*a41*a62 + - a14*a25*a33*a41*a62 + - a15*a23*a34*a41*a62 + + a13*a25*a34*a41*a62 + + a14*a23*a35*a41*a62 + - a13*a24*a35*a41*a62 + - a15*a24*a31*a43*a62 + + a14*a25*a31*a43*a62 + + a15*a21*a34*a43*a62 + - a11*a25*a34*a43*a62 + - a14*a21*a35*a43*a62 + + a11*a24*a35*a43*a62 + + a15*a23*a31*a44*a62 + - a13*a25*a31*a44*a62 + - a15*a21*a33*a44*a62 + + a11*a25*a33*a44*a62 + + a13*a21*a35*a44*a62 + - a11*a23*a35*a44*a62 + - a14*a23*a31*a45*a62 + + a13*a24*a31*a45*a62 + + a14*a21*a33*a45*a62 + - a11*a24*a33*a45*a62 + - a13*a21*a34*a45*a62 + + a11*a23*a34*a45*a62 + - a15*a24*a32*a41*a63 + + a14*a25*a32*a41*a63 + + a15*a22*a34*a41*a63 + - a12*a25*a34*a41*a63 + - a14*a22*a35*a41*a63 + + a12*a24*a35*a41*a63 + + a15*a24*a31*a42*a63 + - a14*a25*a31*a42*a63 + - a15*a21*a34*a42*a63 + + a11*a25*a34*a42*a63 + + a14*a21*a35*a42*a63 + - a11*a24*a35*a42*a63 + - a15*a22*a31*a44*a63 + + a12*a25*a31*a44*a63 + + a15*a21*a32*a44*a63 + - a11*a25*a32*a44*a63 + - a12*a21*a35*a44*a63 + + a11*a22*a35*a44*a63 + + a14*a22*a31*a45*a63 + - a12*a24*a31*a45*a63 + - a14*a21*a32*a45*a63 + + a11*a24*a32*a45*a63 + + a12*a21*a34*a45*a63 + - a11*a22*a34*a45*a63 + + a15*a23*a32*a41*a64 + - a13*a25*a32*a41*a64 + - a15*a22*a33*a41*a64 + + a12*a25*a33*a41*a64 + + a13*a22*a35*a41*a64 + - a12*a23*a35*a41*a64 + - a15*a23*a31*a42*a64 + + a13*a25*a31*a42*a64 + + a15*a21*a33*a42*a64 + - a11*a25*a33*a42*a64 + - a13*a21*a35*a42*a64 + + a11*a23*a35*a42*a64 + + a15*a22*a31*a43*a64 + - a12*a25*a31*a43*a64 + - a15*a21*a32*a43*a64 + + a11*a25*a32*a43*a64 + + a12*a21*a35*a43*a64 + - a11*a22*a35*a43*a64 + - a13*a22*a31*a45*a64 + + a12*a23*a31*a45*a64 + + a13*a21*a32*a45*a64 + - a11*a23*a32*a45*a64 + - a12*a21*a33*a45*a64 + + a11*a22*a33*a45*a64 + - a14*a23*a32*a41*a65 + + a13*a24*a32*a41*a65 + + a14*a22*a33*a41*a65 + - a12*a24*a33*a41*a65 + - a13*a22*a34*a41*a65 + + a12*a23*a34*a41*a65 + + a14*a23*a31*a42*a65 + - a13*a24*a31*a42*a65 + - a14*a21*a33*a42*a65 + + a11*a24*a33*a42*a65 + + a13*a21*a34*a42*a65 + - a11*a23*a34*a42*a65 + - a14*a22*a31*a43*a65 + + a12*a24*a31*a43*a65 + + a14*a21*a32*a43*a65 + - a11*a24*a32*a43*a65 + - a12*a21*a34*a43*a65 + + a11*a22*a34*a43*a65 + + a13*a22*a31*a44*a65 + - a12*a23*a31*a44*a65 + - a13*a21*a32*a44*a65 + + a11*a23*a32*a44*a65 + + a12*a21*a33*a44*a65 + - a11*a22*a33*a44*a65; + cofactor[35] = a15*a24*a33*a42*a51 + - a14*a25*a33*a42*a51 + - a15*a23*a34*a42*a51 + + a13*a25*a34*a42*a51 + + a14*a23*a35*a42*a51 + - a13*a24*a35*a42*a51 + - a15*a24*a32*a43*a51 + + a14*a25*a32*a43*a51 + + a15*a22*a34*a43*a51 + - a12*a25*a34*a43*a51 + - a14*a22*a35*a43*a51 + + a12*a24*a35*a43*a51 + + a15*a23*a32*a44*a51 + - a13*a25*a32*a44*a51 + - a15*a22*a33*a44*a51 + + a12*a25*a33*a44*a51 + + a13*a22*a35*a44*a51 + - a12*a23*a35*a44*a51 + - a14*a23*a32*a45*a51 + + a13*a24*a32*a45*a51 + + a14*a22*a33*a45*a51 + - a12*a24*a33*a45*a51 + - a13*a22*a34*a45*a51 + + a12*a23*a34*a45*a51 + - a15*a24*a33*a41*a52 + + a14*a25*a33*a41*a52 + + a15*a23*a34*a41*a52 + - a13*a25*a34*a41*a52 + - a14*a23*a35*a41*a52 + + a13*a24*a35*a41*a52 + + a15*a24*a31*a43*a52 + - a14*a25*a31*a43*a52 + - a15*a21*a34*a43*a52 + + a11*a25*a34*a43*a52 + + a14*a21*a35*a43*a52 + - a11*a24*a35*a43*a52 + - a15*a23*a31*a44*a52 + + a13*a25*a31*a44*a52 + + a15*a21*a33*a44*a52 + - a11*a25*a33*a44*a52 + - a13*a21*a35*a44*a52 + + a11*a23*a35*a44*a52 + + a14*a23*a31*a45*a52 + - a13*a24*a31*a45*a52 + - a14*a21*a33*a45*a52 + + a11*a24*a33*a45*a52 + + a13*a21*a34*a45*a52 + - a11*a23*a34*a45*a52 + + a15*a24*a32*a41*a53 + - a14*a25*a32*a41*a53 + - a15*a22*a34*a41*a53 + + a12*a25*a34*a41*a53 + + a14*a22*a35*a41*a53 + - a12*a24*a35*a41*a53 + - a15*a24*a31*a42*a53 + + a14*a25*a31*a42*a53 + + a15*a21*a34*a42*a53 + - a11*a25*a34*a42*a53 + - a14*a21*a35*a42*a53 + + a11*a24*a35*a42*a53 + + a15*a22*a31*a44*a53 + - a12*a25*a31*a44*a53 + - a15*a21*a32*a44*a53 + + a11*a25*a32*a44*a53 + + a12*a21*a35*a44*a53 + - a11*a22*a35*a44*a53 + - a14*a22*a31*a45*a53 + + a12*a24*a31*a45*a53 + + a14*a21*a32*a45*a53 + - a11*a24*a32*a45*a53 + - a12*a21*a34*a45*a53 + + a11*a22*a34*a45*a53 + - a15*a23*a32*a41*a54 + + a13*a25*a32*a41*a54 + + a15*a22*a33*a41*a54 + - a12*a25*a33*a41*a54 + - a13*a22*a35*a41*a54 + + a12*a23*a35*a41*a54 + + a15*a23*a31*a42*a54 + - a13*a25*a31*a42*a54 + - a15*a21*a33*a42*a54 + + a11*a25*a33*a42*a54 + + a13*a21*a35*a42*a54 + - a11*a23*a35*a42*a54 + - a15*a22*a31*a43*a54 + + a12*a25*a31*a43*a54 + + a15*a21*a32*a43*a54 + - a11*a25*a32*a43*a54 + - a12*a21*a35*a43*a54 + + a11*a22*a35*a43*a54 + + a13*a22*a31*a45*a54 + - a12*a23*a31*a45*a54 + - a13*a21*a32*a45*a54 + + a11*a23*a32*a45*a54 + + a12*a21*a33*a45*a54 + - a11*a22*a33*a45*a54 + + a14*a23*a32*a41*a55 + - a13*a24*a32*a41*a55 + - a14*a22*a33*a41*a55 + + a12*a24*a33*a41*a55 + + a13*a22*a34*a41*a55 + - a12*a23*a34*a41*a55 + - a14*a23*a31*a42*a55 + + a13*a24*a31*a42*a55 + + a14*a21*a33*a42*a55 + - a11*a24*a33*a42*a55 + - a13*a21*a34*a42*a55 + + a11*a23*a34*a42*a55 + + a14*a22*a31*a43*a55 + - a12*a24*a31*a43*a55 + - a14*a21*a32*a43*a55 + + a11*a24*a32*a43*a55 + + a12*a21*a34*a43*a55 + - a11*a22*a34*a43*a55 + - a13*a22*a31*a44*a55 + + a12*a23*a31*a44*a55 + + a13*a21*a32*a44*a55 + - a11*a23*a32*a44*a55 + - a12*a21*a33*a44*a55 + + a11*a22*a33*a44*a55; + +/* ainv = transpose(cofactor) ! / det */ + const double jinv = 1/det; + ainv[0] = cofactor[0]*jinv; + ainv[1] = cofactor[6]*jinv; + ainv[2] = cofactor[12]*jinv; + ainv[3] = cofactor[18]*jinv; + ainv[4] = cofactor[24]*jinv; + ainv[5] = cofactor[30]*jinv; + ainv[6] = cofactor[1]*jinv; + ainv[7] = cofactor[7]*jinv; + ainv[8] = cofactor[13]*jinv; + ainv[9] = cofactor[19]*jinv; + ainv[10] = cofactor[25]*jinv; + ainv[11] = cofactor[31]*jinv; + ainv[12] = cofactor[2]*jinv; + ainv[13] = cofactor[8]*jinv; + ainv[14] = cofactor[14]*jinv; + ainv[15] = cofactor[20]*jinv; + ainv[16] = cofactor[26]*jinv; + ainv[17] = cofactor[32]*jinv; + ainv[18] = cofactor[3]*jinv; + ainv[19] = cofactor[9]*jinv; + ainv[20] = cofactor[15]*jinv; + ainv[21] = cofactor[21]*jinv; + ainv[22] = cofactor[27]*jinv; + ainv[23] = cofactor[33]*jinv; + ainv[24] = cofactor[4]*jinv; + ainv[25] = cofactor[10]*jinv; + ainv[26] = cofactor[16]*jinv; + ainv[27] = cofactor[22]*jinv; + ainv[28] = cofactor[28]*jinv; + ainv[29] = cofactor[34]*jinv; + ainv[30] = cofactor[5]*jinv; + ainv[31] = cofactor[11]*jinv; + ainv[32] = cofactor[17]*jinv; + ainv[33] = cofactor[23]*jinv; + ainv[34] = cofactor[29]*jinv; + ainv[35] = cofactor[35]*jinv; + + *ok_flag__ = 0; + return 0; +} From 24fbdbc278f7b3dd6d5df76f6bd53f2138f7b005 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:07:26 -0700 Subject: [PATCH 193/261] add copyright/license in headers --- .../Frame/BasicFrameTransf.h | 12 +++- .../Frame/BasicFrameTransf.tpp | 12 +++- .../Frame/EuclidFrameTransf.h | 11 +++- .../Frame/EuclidFrameTransf.tpp | 12 +++- .../Frame/FrameTransform.h | 8 ++- .../Frame/FrameTransform.tpp | 13 ++-- .../Frame/LinearFrameTransf.h | 28 ++++++++- .../Frame/LinearFrameTransf.tpp | 16 +++-- .../Frame/PDeltaFrameTransf3d.h | 15 +++++ .../Frame/PDeltaFrameTransf3d.tpp | 14 +++++ .../Frame/SouzaFrameTransf.h | 54 +++++++++++++++- .../Frame/SouzaFrameTransf.tpp | 61 ++++++++++++++++--- SRC/matrix/GroupSO3.h | 20 ++++-- SRC/matrix/Matrix3D.h | 11 +++- SRC/matrix/MatrixND.h | 11 +++- SRC/matrix/MatrixND.tpp | 12 ++-- SRC/matrix/Vector3D.h | 9 ++- SRC/matrix/VectorND.h | 9 ++- SRC/matrix/VectorND.tpp | 9 ++- SRC/matrix/routines/cmx.h | 9 ++- SRC/matrix/routines/invGL2.c | 9 ++- SRC/matrix/routines/invGL3.c | 9 ++- SRC/matrix/routines/invGL4.c | 9 ++- SRC/matrix/routines/invGL5.c | 9 ++- SRC/matrix/routines/invGL6.c | 9 ++- 25 files changed, 334 insertions(+), 57 deletions(-) diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.h b/SRC/coordTransformation/Frame/BasicFrameTransf.h index a546a07b32..18a23dc1c7 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.h +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.h @@ -3,11 +3,17 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // @@ -18,7 +24,6 @@ // templates to reproduce the legacy CrdTransf classes that were derived // for elements in a "basic" coordinate system. // -// // Written: Claudio M. Perez // #ifndef BasicFrameTransf3d_h @@ -27,6 +32,7 @@ #include #include #include + class Vector; class Matrix; diff --git a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp index 6d86744134..82425ba438 100644 --- a/SRC/coordTransformation/Frame/BasicFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/BasicFrameTransf.tpp @@ -3,11 +3,17 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C. "On Nonlinear Geometric Transformations +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // @@ -16,7 +22,7 @@ #include #include #include -#include +#include #include #include "FrameTransform.h" #include diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.h b/SRC/coordTransformation/Frame/EuclidFrameTransf.h index 3e8d8898a6..9d128c8b54 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.h +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.h @@ -3,11 +3,17 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // @@ -75,7 +81,6 @@ class EuclidFrameTransf: public FrameTransform int push(MatrixND& kl, const VectorND& pl, Operation) final; // Sensitivity - // bool isShapeSensitivity() final; double getLengthGrad() final; double getd1overLdh() final; diff --git a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp index cdb981d9f6..d02edd381d 100644 --- a/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/EuclidFrameTransf.tpp @@ -3,11 +3,17 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // @@ -23,7 +29,7 @@ #include #include #include -#include +#include #include #include #include "EuclidFrameTransf.h" diff --git a/SRC/coordTransformation/Frame/FrameTransform.h b/SRC/coordTransformation/Frame/FrameTransform.h index e8bbe70b5d..7d59cca1a1 100644 --- a/SRC/coordTransformation/Frame/FrameTransform.h +++ b/SRC/coordTransformation/Frame/FrameTransform.h @@ -5,9 +5,15 @@ // //===----------------------------------------------------------------------===// // +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // diff --git a/SRC/coordTransformation/Frame/FrameTransform.tpp b/SRC/coordTransformation/Frame/FrameTransform.tpp index 6e19570bed..f491979bbb 100644 --- a/SRC/coordTransformation/Frame/FrameTransform.tpp +++ b/SRC/coordTransformation/Frame/FrameTransform.tpp @@ -1,15 +1,20 @@ //===----------------------------------------------------------------------===// // // xara -// -//===----------------------------------------------------------------------===// // https://xara.so +// //===----------------------------------------------------------------------===// // +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.h b/SRC/coordTransformation/Frame/LinearFrameTransf.h index 53e31daa76..b2d845366f 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.h +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.h @@ -3,11 +3,17 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. // -// Please cite the following resource in any derivative works: +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// Please cite the following resources in any derivative works: +// +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // @@ -19,6 +25,22 @@ // // Written: Claudio Perez // +// References: +// +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +// Haukaas, Terje, and Michael H. Scott. +// “Shape Sensitivities in the Reliability Analysis of Nonlinear Frame Structures.” +// Computers & Structures 84, nos. 15–16 (2006): 964–77. +// https://doi.org/10.1016/j.compstruc.2006.02.014. +// +// Scott, Michael H., Paolo Franchin, Gregory L. Fenves, and Filip C. Filippou. +// “Response Sensitivity for Nonlinear Beam–Column Elements.” +// Journal of Structural Engineering 130, no. 9 (2004): 1281–88. +// https://doi.org/10.1061/(asce)0733-9445(2004)130:9(1281). +// #ifndef LinearFrameTransf_hpp #define LinearFrameTransf_hpp diff --git a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp index 7d4f34a7c3..72650b7d5c 100644 --- a/SRC/coordTransformation/Frame/LinearFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/LinearFrameTransf.tpp @@ -3,24 +3,28 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// // -// Description: This file contains the implementation for the -// LinearFrameTransf class. LinearFrameTransf is a linear +// Description: LinearFrameTransf is a linear // transformation for a space frame between the global // and basic coordinate systems // // Written: Claudio M. Perez -// Adapted: Remo Magalhaes de Souza // #pragma once #include @@ -29,7 +33,7 @@ #include #include #include -#include +#include #include #include "LinearFrameTransf.h" diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h index ae82e3f1fc..113ea44b07 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.h @@ -2,6 +2,21 @@ // // xara // https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +// Please cite the following resource in any derivative works: +// +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// //===----------------------------------------------------------------------===// // // OpenSees - Open System for Earthquake Engineering Simulation diff --git a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp index 0b3d9ec9c5..6063424799 100644 --- a/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp +++ b/SRC/coordTransformation/Frame/PDeltaFrameTransf3d.tpp @@ -5,6 +5,20 @@ // //===----------------------------------------------------------------------===// // +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +// Please cite the following resource in any derivative works: +// +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// +//===----------------------------------------------------------------------===// +// // OpenSees - Open System for Earthquake Engineering Simulation // //===----------------------------------------------------------------------===// diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.h b/SRC/coordTransformation/Frame/SouzaFrameTransf.h index 738432ddaf..a41f84ba39 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.h +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.h @@ -9,14 +9,62 @@ // //===----------------------------------------------------------------------===// // +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// +// +// Copyright @ 1999-2020 The Regents of the University of California (The Regents). +// All Rights Reserved. +// +// The Regents grants permission, without fee and without a written license +// agreement, for (a) use, reproduction, modification, and distribution of this +// software and its documentation by educational, research, and non-profit +// entities for noncommercial purposes only; and (b) use, reproduction and +// modification of this software by other entities for internal purposes only. +// The above copyright notice, this paragraph and the following three +// paragraphs must appear in all copies and modifications of the software +// and/or documentation. +// +// Permission to incorporate this software into products for commercial +// distribution may be obtained by contacting the University of California +// Office of Technology Licensing +// 2150 Shattuck Avenue #510, +// Berkeley, CA 94720-1620, +// (510) 643-7201. +// +// This software program and documentation are copyrighted by The Regents of +// the University of California. The Regents does not warrant that the +// operation of the program will be uninterrupted or error-free. The end-user +// understands that the program was developed for research purposes and is +// advised not to rely exclusively on the program for any reason. +// +// IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, +// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, +// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF +// REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. REGENTS GRANTS +// NO EXPRESS OR IMPLIED LICENSE IN ANY PATENT RIGHTS OF REGENTS BUT HAS +// IMPLEMENTED AN INDIVIDUAL CONTRIBUTOR LICENSE AGREEMENT FOR THE OPENSEES +// PROJECT AT THE UNIVERISTY OF CALIFORNIA, BERKELEY TO BENEFIT THE END USER. +// +// REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED +// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED +// HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE +// MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +// +//===----------------------------------------------------------------------===// + // // Description: SouzaFrameTransf implements the formulation // of Crisfield (1990) with the objective of maintaining the @@ -28,6 +76,10 @@ // // Adapted from work by: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) // +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// // [2] Crisfield, M.A. (1990) "A consistent co-rotational formulation for // non-linear, three-dimensional, beam-elements", Computer Methods in Applied // Mechanics and Engineering, 81(2), pp. 131–150. Available at: diff --git a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp index 8a5d9a4f42..1a79fffbc8 100644 --- a/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp +++ b/SRC/coordTransformation/Frame/SouzaFrameTransf.tpp @@ -3,19 +3,62 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. // -//===----------------------------------------------------------------------===// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations -// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// +// +// Copyright @ 1999-2020 The Regents of the University of California (The Regents). +// All Rights Reserved. +// +// The Regents grants permission, without fee and without a written license +// agreement, for (a) use, reproduction, modification, and distribution of this +// software and its documentation by educational, research, and non-profit +// entities for noncommercial purposes only; and (b) use, reproduction and +// modification of this software by other entities for internal purposes only. +// The above copyright notice, this paragraph and the following three +// paragraphs must appear in all copies and modifications of the software +// and/or documentation. +// +// Permission to incorporate this software into products for commercial +// distribution may be obtained by contacting the University of California +// Office of Technology Licensing +// 2150 Shattuck Avenue #510, +// Berkeley, CA 94720-1620, +// (510) 643-7201. +// +// This software program and documentation are copyrighted by The Regents of +// the University of California. The Regents does not warrant that the +// operation of the program will be uninterrupted or error-free. The end-user +// understands that the program was developed for research purposes and is +// advised not to rely exclusively on the program for any reason. +// +// IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, +// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, +// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF +// REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. REGENTS GRANTS +// NO EXPRESS OR IMPLIED LICENSE IN ANY PATENT RIGHTS OF REGENTS BUT HAS +// IMPLEMENTED AN INDIVIDUAL CONTRIBUTOR LICENSE AGREEMENT FOR THE OPENSEES +// PROJECT AT THE UNIVERISTY OF CALIFORNIA, BERKELEY TO BENEFIT THE END USER. +// +// REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED +// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED +// HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE +// MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +// +//===----------------------------------------------------------------------===// // // Description: SouzaFrameTransf implements a Corotational @@ -27,6 +70,10 @@ // // Adapted from: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) // +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 +// // [2] Crisfield, M.A. (1990) "A consistent co-rotational formulation for // non-linear, three-dimensional, beam-elements", Computer Methods in Applied // Mechanics and Engineering, 81(2), pp. 131–150. Available at: @@ -34,7 +81,7 @@ // #include #include -#include +#include #include "SouzaFrameTransf.h" #include @@ -542,4 +589,4 @@ SouzaFrameTransf::Print(OPS_Stream &s, int flag) } } -} // namespace OpenSees \ No newline at end of file +} // namespace OpenSees diff --git a/SRC/matrix/GroupSO3.h b/SRC/matrix/GroupSO3.h index 2c694f8072..a2d82f57ec 100755 --- a/SRC/matrix/GroupSO3.h +++ b/SRC/matrix/GroupSO3.h @@ -3,16 +3,28 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // -// The following resource should be cited in derivative works: +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +// Please cite the following resource in any derivative works: +// +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // +//===----------------------------------------------------------------------===// + +// +// References: // -// Additional References: +// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 // // [2] Ritto-Corrêa, M. and Camotim, D. (2002) "On the differentiation of the // Rodrigues formula and its significance for the vector-like parameterization diff --git a/SRC/matrix/Matrix3D.h b/SRC/matrix/Matrix3D.h index cb5c55b98f..f8a6a57fc9 100644 --- a/SRC/matrix/Matrix3D.h +++ b/SRC/matrix/Matrix3D.h @@ -1,13 +1,18 @@ //===----------------------------------------------------------------------===// // // xara -// -//===----------------------------------------------------------------------===// // https://xara.so +// //===----------------------------------------------------------------------===// // -// Claudio Perez +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. // +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// + #ifndef Matrix3D_H #define Matrix3D_H diff --git a/SRC/matrix/MatrixND.h b/SRC/matrix/MatrixND.h index bf1bb8ca8a..f078b862a8 100644 --- a/SRC/matrix/MatrixND.h +++ b/SRC/matrix/MatrixND.h @@ -1,16 +1,21 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Desctiption: MatrixND is a fixed-size matrix class that is suitable for // stack-allocation. // -//===----------------------------------------------------------------------===// -// // Claudio Perez // #pragma once diff --git a/SRC/matrix/MatrixND.tpp b/SRC/matrix/MatrixND.tpp index 16ac15ab3a..68f9a67342 100644 --- a/SRC/matrix/MatrixND.tpp +++ b/SRC/matrix/MatrixND.tpp @@ -1,12 +1,17 @@ //===----------------------------------------------------------------------===// // // xara -// -//===----------------------------------------------------------------------===// // https://xara.so +// //===----------------------------------------------------------------------===// // -// Claudio Perez +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// // #pragma once #include "MatrixND.h" @@ -310,7 +315,6 @@ MatrixND::addMatrixTripleProduct( const MatrixND &T, const MatrixND &B, double otherFact) - //requires(nr == nc) { if (otherFact == 0.0 && thisFact == 1.0) return 0; diff --git a/SRC/matrix/Vector3D.h b/SRC/matrix/Vector3D.h index 876c04929a..8c3c76f38d 100644 --- a/SRC/matrix/Vector3D.h +++ b/SRC/matrix/Vector3D.h @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Implementation of a 3D Vector. The purpose of this file is to ensure that diff --git a/SRC/matrix/VectorND.h b/SRC/matrix/VectorND.h index 043aecac41..d1f3fd9a6f 100644 --- a/SRC/matrix/VectorND.h +++ b/SRC/matrix/VectorND.h @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Claudio Perez diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index 0ee9b84b8f..0fd76b4e5c 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // #include diff --git a/SRC/matrix/routines/cmx.h b/SRC/matrix/routines/cmx.h index 8d948772b1..9e53a83def 100644 --- a/SRC/matrix/routines/cmx.h +++ b/SRC/matrix/routines/cmx.h @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// #ifndef cmx_h diff --git a/SRC/matrix/routines/invGL2.c b/SRC/matrix/routines/invGL2.c index 0eef184872..de0c58543b 100644 --- a/SRC/matrix/routines/invGL2.c +++ b/SRC/matrix/routines/invGL2.c @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // adapted by CMP from code by David Simpson at diff --git a/SRC/matrix/routines/invGL3.c b/SRC/matrix/routines/invGL3.c index 08da4b5845..bc31f2836c 100644 --- a/SRC/matrix/routines/invGL3.c +++ b/SRC/matrix/routines/invGL3.c @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // adapted from https://caps.gsfc.nasa.gov/simpson/software/m33inv_f90.txt diff --git a/SRC/matrix/routines/invGL4.c b/SRC/matrix/routines/invGL4.c index b6335342ca..477d1ce896 100644 --- a/SRC/matrix/routines/invGL4.c +++ b/SRC/matrix/routines/invGL4.c @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // adapted from https://caps.gsfc.nasa.gov/simpson/software/m44inv_f90.txt diff --git a/SRC/matrix/routines/invGL5.c b/SRC/matrix/routines/invGL5.c index 2ca0d59409..1cfbdbfa35 100644 --- a/SRC/matrix/routines/invGL5.c +++ b/SRC/matrix/routines/invGL5.c @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // adapted from https://caps.gsfc.nasa.gov/simpson/software/m55inv_f90.txt diff --git a/SRC/matrix/routines/invGL6.c b/SRC/matrix/routines/invGL6.c index 853f4e5aea..3f800b5fe3 100644 --- a/SRC/matrix/routines/invGL6.c +++ b/SRC/matrix/routines/invGL6.c @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // adapted from https://caps.gsfc.nasa.gov/simpson/software/m66inv_f90.txt From 888a0fac50133e0052b047c37a36d2be8f128bb1 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:16:08 -0700 Subject: [PATCH 194/261] Update headers --- .../Frame/Isometry/CrisfieldIsometry.h | 17 ++-- .../Frame/Isometry/EuclidIsometry.h | 11 ++- .../Frame/Isometry/LinearIsometry.h | 18 +++- .../Frame/Isometry/RankinIsometry.h | 18 +++- .../Frame/Isometry/SphericalIsometry.h | 19 +++- SRC/matrix/GroupSO3.h | 1 - SRC/matrix/Versor.h | 93 ++---------------- SRC/matrix/Versor.tpp | 95 ++++++++++++++++++- 8 files changed, 166 insertions(+), 106 deletions(-) diff --git a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h index 1ff06efbf2..a4429f4abc 100644 --- a/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/CrisfieldIsometry.h @@ -3,14 +3,19 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // -// The following resource should be cited in derivative works: +// Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C. (2024) -// "On Nonlinear Geometric Transformations of Finite Elements" -// Int. J. Numer. Meth. Engrg.; -// Available at: https://doi.org/10.1002/nme.7506 +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// diff --git a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h index 14f23f1e3f..733cfc9392 100644 --- a/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/EuclidIsometry.h @@ -3,16 +3,21 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations // of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; // https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// - // // Written: Claudio M. Perez // diff --git a/SRC/coordTransformation/Frame/Isometry/LinearIsometry.h b/SRC/coordTransformation/Frame/Isometry/LinearIsometry.h index a2646f4c32..bf37ad2e22 100644 --- a/SRC/coordTransformation/Frame/Isometry/LinearIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/LinearIsometry.h @@ -3,13 +3,19 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C. (2024) -// "On Nonlinear Geometric Transformations of Finite Elements" -// Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// @@ -22,6 +28,10 @@ // // References: // +// [1] Perez, C.M., and Filippou F.C. (2024) +// "On Nonlinear Geometric Transformations of Finite Elements" +// Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 +// // [2] Filippou, F.C. (1998) // "FEDEASLab: Finite Elements for Design Evaluation and Analysis of Structures" // diff --git a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h index 96bfcdfed3..5bfe8bab5f 100644 --- a/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/RankinIsometry.h @@ -3,13 +3,19 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C. (2024) -// "On Nonlinear Geometric Transformations of Finite Elements" -// Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// @@ -22,6 +28,10 @@ // // References: // +// [1] Perez, C.M., and Filippou F.C. (2024) +// "On Nonlinear Geometric Transformations of Finite Elements" +// Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 +// // [2] Filippou, F.C. (1998) // "FEDEASLab: Finite Elements for Design Evaluation and Analysis of Structures" // diff --git a/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h b/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h index 1a10102e83..bb704a7757 100644 --- a/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/SphericalIsometry.h @@ -2,13 +2,20 @@ // // xara // https://xara.so -//----------------------------------------------------------------------------// +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // // Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. (2024) -// "On Nonlinear Geometric Transformations of Finite Elements" -// Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// @@ -21,6 +28,10 @@ // // References: // +// [1] Perez, C.M., and Filippou F.C.. (2024) +// "On Nonlinear Geometric Transformations of Finite Elements" +// Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 +// // [2] Filippou, F.C. (1998) // "FEDEASLab: Finite Elements for Design Evaluation and Analysis of Structures" // diff --git a/SRC/matrix/GroupSO3.h b/SRC/matrix/GroupSO3.h index a2d82f57ec..4d3d79a0b3 100755 --- a/SRC/matrix/GroupSO3.h +++ b/SRC/matrix/GroupSO3.h @@ -59,7 +59,6 @@ #include "Versor.h" #include "Matrix3D.h" #include "Vector3D.h" -#include using OpenSees::Matrix3D; using OpenSees::Versor; diff --git a/SRC/matrix/Versor.h b/SRC/matrix/Versor.h index ea838d2ccf..5e920b0602 100644 --- a/SRC/matrix/Versor.h +++ b/SRC/matrix/Versor.h @@ -1,16 +1,22 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Description: Versor implements a unit-normalized quaternion. // #pragma once #include -#include #include #include @@ -100,86 +106,7 @@ struct Versor { } }; -static_assert(std::is_trivially_copyable::value, "Versor must be trivially copyable"); - -inline Versor -Versor::from_matrix(const Matrix3D &R) -{ - //===--------------------------------------------------------------------===// - // Form a normalized quaternion (Versor) from a proper orthogonal matrix - // using Spurrier's algorithm - //===--------------------------------------------------------------------===// - Versor q; - - // Trace of the rotation R - const double trR = R(0,0) + R(1,1) + R(2,2); - - // a = max([trR R(0,0) R(1,1) R(2,2)]); - double a = trR; - for (int i = 0; i < 3; i++) - if (R(i,i) > a) - a = R(i,i); - - if (a == trR) { - q.scalar = std::sqrt(1.0 + a)*0.5; - - for (int i = 0; i < 3; i++) { - int j = (i+1)%3; - int k = (i+2)%3; - q.vector[i] = (R(k,j) - R(j,k))/(4.0*q.scalar); - } - } - else { - for (int i = 0; i < 3; i++) - if (a == R(i,i)) { - int j = (i+1)%3; - int k = (i+2)%3; - - q.vector[i] = std::sqrt(std::max(a*0.5 + (1.0 - trR)/4.0, 0.0)); - q.scalar = (R(k,j) - R(j,k))/(4.0*q.vector[i]); - q.vector[j] = (R(j,i) + R(i,j))/(4.0*q.vector[i]); - q.vector[k] = (R(k,i) + R(i,k))/(4.0*q.vector[i]); - } - } - return q; -} - -template -inline Versor -Versor::from_vector(const Vec3T &theta) -{ - double angle2 = 0.0; - for (int i=0; i<3; i++) - angle2 += theta[i]*theta[i]; - - double angle = std::sqrt(angle2); - - Versor q; - double sc, cs; - if (angle2 < 1e-12) { - sc = 0.5 - angle2 / 48.0; // + angle2*angle2 / 3840.0 - angle2*angle2*angle2 / 362880.0; - cs = 1.0 - angle2 / 8.0; // + angle2*angle2 / 384.0 - angle2*angle2*angle2 / 40320.0; - } - else { - sc = std::sin(angle*0.5) / angle; - cs = std::cos(angle*0.5); - } - - for (int i = 0; i < 3; i++) - q.vector[i] = theta[i] * sc; - - q.scalar = cs; - return q; -} - - } // namespace OpenSees -inline OpenSees::Versor -operator*(const OpenSees::Versor &qa, const OpenSees::Versor &qb) -{ - OpenSees::Versor q12; - q12.scalar = qa.scalar * qb.scalar - qa.vector.dot(qb.vector); - q12.vector = (qb.vector * qa.scalar) + (qa.vector * qb.scalar) + qa.vector.cross(qb.vector); - return q12; -} +#include "Versor.tpp" + diff --git a/SRC/matrix/Versor.tpp b/SRC/matrix/Versor.tpp index 4e7244123f..741207f9e7 100644 --- a/SRC/matrix/Versor.tpp +++ b/SRC/matrix/Versor.tpp @@ -1,9 +1,102 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // +#include "Versor.h" +#include + +namespace OpenSees { + +static_assert(std::is_trivially_copyable::value, "Versor must be trivially copyable"); + +inline Versor +Versor::from_matrix(const Matrix3D &R) +{ + //===--------------------------------------------------------------------===// + // Form a normalized quaternion (Versor) from a proper orthogonal matrix + // using Spurrier's algorithm + //===--------------------------------------------------------------------===// + Versor q; + + // Trace of the rotation R + const double trR = R(0,0) + R(1,1) + R(2,2); + + // a = max([trR R(0,0) R(1,1) R(2,2)]); + double a = trR; + for (int i = 0; i < 3; i++) + if (R(i,i) > a) + a = R(i,i); + + if (a == trR) { + q.scalar = std::sqrt(1.0 + a)*0.5; + + for (int i = 0; i < 3; i++) { + int j = (i+1)%3; + int k = (i+2)%3; + q.vector[i] = (R(k,j) - R(j,k))/(4.0*q.scalar); + } + } + else { + for (int i = 0; i < 3; i++) + if (a == R(i,i)) { + int j = (i+1)%3; + int k = (i+2)%3; + + q.vector[i] = std::sqrt(std::max(a*0.5 + (1.0 - trR)/4.0, 0.0)); + q.scalar = (R(k,j) - R(j,k))/(4.0*q.vector[i]); + q.vector[j] = (R(j,i) + R(i,j))/(4.0*q.vector[i]); + q.vector[k] = (R(k,i) + R(i,k))/(4.0*q.vector[i]); + } + } + return q; +} + +template +inline Versor +Versor::from_vector(const Vec3T &theta) +{ + double angle2 = 0.0; + for (int i=0; i<3; i++) + angle2 += theta[i]*theta[i]; + + double angle = std::sqrt(angle2); + + Versor q; + double sc, cs; + if (angle2 < 1e-12) { + sc = 0.5 - angle2 / 48.0; // + angle2*angle2 / 3840.0 - angle2*angle2*angle2 / 362880.0; + cs = 1.0 - angle2 / 8.0; // + angle2*angle2 / 384.0 - angle2*angle2*angle2 / 40320.0; + } + else { + sc = std::sin(angle*0.5) / angle; + cs = std::cos(angle*0.5); + } + + for (int i = 0; i < 3; i++) + q.vector[i] = theta[i] * sc; + + q.scalar = cs; + return q; +} +} // namespace OpenSees + +inline OpenSees::Versor +operator*(const OpenSees::Versor &qa, const OpenSees::Versor &qb) +{ + OpenSees::Versor q12; + q12.scalar = qa.scalar * qb.scalar - qa.vector.dot(qb.vector); + q12.vector = (qb.vector * qa.scalar) + (qa.vector * qb.scalar) + qa.vector.cross(qb.vector); + return q12; +} \ No newline at end of file From 011e6d542484bc9fdf6f9373dd8730368d854ef6 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:17:05 -0700 Subject: [PATCH 195/261] Update FrameTransformBuilder.hpp --- .../modeling/transform/FrameTransformBuilder.hpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp index a862357443..5fdd5f10e3 100644 --- a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp +++ b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // -// xara +// xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Written: Claudio M. Perez @@ -31,9 +38,7 @@ class FrameTransformBuilder : public TaggedObject { : ndm(ndm), TaggedObject(t), vz{{0, 0, 0}}, offsets{}, offset_flags(0) { - // strncpy(name, n, 128); snprintf(name, sizeof(name), "%s", n); - // offset_flags |= LogIter; } virtual ~FrameTransformBuilder() {} From b452821233127bf558276897e008f736e7eb5610 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:17:59 -0700 Subject: [PATCH 196/261] Update Unroll.h --- SRC/utility/Unroll.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/SRC/utility/Unroll.h b/SRC/utility/Unroll.h index 1be782bbb7..d7aecb2c8c 100644 --- a/SRC/utility/Unroll.h +++ b/SRC/utility/Unroll.h @@ -3,7 +3,15 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// #pragma once #include #include From 0014ea654868f0aba9f8fad237061d85ace9ae32 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:25:15 -0700 Subject: [PATCH 197/261] update headers --- .../Frame/Isometry/BattiniIsometry.h | 17 +++++++---- SRC/runtime/commands/domain/element.cpp | 24 +++++++++++---- SRC/runtime/commands/modeling/element.hpp | 11 ++++++- .../commands/modeling/element/frames.cpp | 9 +++++- SRC/runtime/commands/modeling/geomTransf.cpp | 30 ++++++++++++++++++- 5 files changed, 78 insertions(+), 13 deletions(-) diff --git a/SRC/coordTransformation/Frame/Isometry/BattiniIsometry.h b/SRC/coordTransformation/Frame/Isometry/BattiniIsometry.h index 17bf1c540a..c8e0cd66c3 100644 --- a/SRC/coordTransformation/Frame/Isometry/BattiniIsometry.h +++ b/SRC/coordTransformation/Frame/Isometry/BattiniIsometry.h @@ -2,13 +2,20 @@ // // xara // https://xara.so -//----------------------------------------------------------------------------// // -// The following resource should be cited in derivative works: +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +// Please cite the following resource in any derivative works: // -// [1] Perez, C.M., and Filippou F.C.. (2024) -// "On Nonlinear Geometric Transformations of Finite Elements" -// Int. J. Numer. Meth. Engrg.; https://doi.org/10.1002/nme.7506 +// Perez, C.M., and Filippou F.C.. "On Nonlinear Geometric Transformations +// of Finite Elements" Int. J. Numer. Meth. Engrg. 2024; +// https://doi.org/10.1002/nme.7506 // //===----------------------------------------------------------------------===// diff --git a/SRC/runtime/commands/domain/element.cpp b/SRC/runtime/commands/domain/element.cpp index 59dc1cc431..4912b8a29b 100644 --- a/SRC/runtime/commands/domain/element.cpp +++ b/SRC/runtime/commands/domain/element.cpp @@ -1,8 +1,22 @@ -//===----------------------------------------------------------------------===// -// -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ // // #include diff --git a/SRC/runtime/commands/modeling/element.hpp b/SRC/runtime/commands/modeling/element.hpp index 0f09aeda65..5f7ec2cc02 100644 --- a/SRC/runtime/commands/modeling/element.hpp +++ b/SRC/runtime/commands/modeling/element.hpp @@ -1,6 +1,15 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // //===----------------------------------------------------------------------===// // diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index 2f0377148b..797a981446 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Written: cmp, mhs, rms, fmk diff --git a/SRC/runtime/commands/modeling/geomTransf.cpp b/SRC/runtime/commands/modeling/geomTransf.cpp index e1dff124e1..d5e49fe360 100644 --- a/SRC/runtime/commands/modeling/geomTransf.cpp +++ b/SRC/runtime/commands/modeling/geomTransf.cpp @@ -1,10 +1,38 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// + +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + // // Description: Geometric transformation command // From 202e1cf1613586e169f446d095f7bd0d13807cdf Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:29:56 -0700 Subject: [PATCH 198/261] Update AxisAngle.h --- SRC/matrix/AxisAngle.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/SRC/matrix/AxisAngle.h b/SRC/matrix/AxisAngle.h index ebfc92521c..daa19832f4 100644 --- a/SRC/matrix/AxisAngle.h +++ b/SRC/matrix/AxisAngle.h @@ -1,3 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// #pragma once #include "Vector3D.h" #include "VectorND.h" @@ -29,7 +43,7 @@ class AxisAngle { explicit AxisAngle(const Vector3D& v) : angle(v.norm()), - vector(v) //Utility::RescaleVector(v, angle)) + vector(v) { Utility::dLogConst(angle, eta, mu); } From 3e49c8e8bff6dccdef9ef1cad8d522d9acd62baa Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 24 Jul 2025 13:31:37 -0700 Subject: [PATCH 199/261] Update xblas.h --- SRC/matrix/routines/xblas.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SRC/matrix/routines/xblas.h b/SRC/matrix/routines/xblas.h index 0384677984..a55aa90a4d 100644 --- a/SRC/matrix/routines/xblas.h +++ b/SRC/matrix/routines/xblas.h @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // #ifndef blasdecl_H From e74fa04681bc28e27611b2ed963f8695630cda60 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 24 Jul 2025 13:34:51 -0700 Subject: [PATCH 200/261] Update VectorND.tpp --- SRC/matrix/VectorND.tpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/SRC/matrix/VectorND.tpp b/SRC/matrix/VectorND.tpp index 0fd76b4e5c..c33b06761e 100644 --- a/SRC/matrix/VectorND.tpp +++ b/SRC/matrix/VectorND.tpp @@ -13,6 +13,26 @@ // //===----------------------------------------------------------------------===// // +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// #include #include "VectorND.h" #include "routines/xblas.h" From c17443aa9ff0c14629b2a1536ec87730f0ca9768 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 24 Jul 2025 13:34:57 -0700 Subject: [PATCH 201/261] Update nodes.cpp --- SRC/runtime/commands/domain/nodes.cpp | 29 ++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/SRC/runtime/commands/domain/nodes.cpp b/SRC/runtime/commands/domain/nodes.cpp index 401b6268c8..99f01f1699 100644 --- a/SRC/runtime/commands/domain/nodes.cpp +++ b/SRC/runtime/commands/domain/nodes.cpp @@ -1,10 +1,23 @@ -//===----------------------------------------------------------------------===// +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ // -// xara -// -//===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// // Description: This file implements commands for interacting with nodes // in the domain. // @@ -37,7 +50,9 @@ static int resDataSize = 0; int -getNodeTags(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, +getNodeTags(ClientData clientData, + Tcl_Interp *interp, + Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); From cdf5dd9731814be8fa80c4ed8087fa5da30f4f71 Mon Sep 17 00:00:00 2001 From: gaaraujo Date: Thu, 31 Jul 2025 20:24:06 -0700 Subject: [PATCH 202/261] add adaptive convergence to Itpack --- .../linearSOE/itpack/ItpackLinSolver.cpp | 27 ++++++++++++++----- .../linearSOE/itpack/ItpackLinSolver.h | 5 +++- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp index 588474abb1..ee125909c6 100644 --- a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp +++ b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.cpp @@ -53,6 +53,7 @@ void* OPS_ItpackLinSolver() int iter = 100; double omega = 1.0; bool symmetric = true; + double zeta = 5e-6; while (OPS_GetNumRemainingInputArgs() > 1) { const char *arg = OPS_GetString(); if (strcmp(arg,"-iter") == 0) { @@ -69,17 +70,21 @@ void* OPS_ItpackLinSolver() return 0; symmetric = (symm != 0) ? true : false; } + if (strcmp(arg,"-zeta") == 0) { + if (OPS_GetDoubleInput(&numData,&zeta) < 0) + return 0; + } } - ItpackLinSolver *theSolver = new ItpackLinSolver(method, iter, omega); + ItpackLinSolver *theSolver = new ItpackLinSolver(method, iter, omega, zeta); return new ItpackLinSOE(*theSolver, symmetric); } -ItpackLinSolver::ItpackLinSolver(int meth, int iter, double om) +ItpackLinSolver::ItpackLinSolver(int meth, int iter, double om, double z) :LinearSOESolver(SOLVER_TAGS_Itpack), theSOE(0), IA(0), JA(0), n(0), iwksp(0), wksp(0), nwksp(0), maxIter(iter), - method(meth), omega(om) + method(meth), omega(om), zeta(z) { } @@ -88,7 +93,7 @@ ItpackLinSolver::ItpackLinSolver() :LinearSOESolver(SOLVER_TAGS_Itpack), theSOE(0), IA(0), JA(0), n(0), iwksp(0), wksp(0), nwksp(0), maxIter(0), - method(0), omega(0.0) + method(0), omega(0.0), zeta(0.0) { } @@ -328,12 +333,22 @@ ItpackLinSolver::solve(void) // Overwrite default max number of iterations iparm[0] = maxIter; + /* Set convergence tolerance for inexact Newton methods. + * ITPACK stopping criterion: ||Ax-b|| / ||x|| * C < rparm[0] + * For (1+p)-order convergence: rparm[0] < ||b||^(1+p) + * Reference: Dembo et al. (1982) Inexact Newton Methods. + * SIAM Journal on Numerical Analysis, 19(2), 400–408. + * https://doi.org/10.1137/0719025 + */ + double norm_b = theSOE->normRHS(); + double norm_b_squared = norm_b * norm_b; + rparm[0] = (zeta < norm_b_squared) ? zeta : norm_b_squared; + // Print flag iparm[1] = 0; // Sparse matrix storage scheme (0 = symmetric, 1 = nonsymmetric) - iparm[4] = 1; - iparm[4] = 0; + iparm[4] = theSOE->symmetric ? 0 : 1; double *aPtr = theSOE->A; double *xPtr = theSOE->X; diff --git a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.h b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.h index e2e0a7a87b..4ec76b5e64 100644 --- a/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.h +++ b/SRC/system_of_eqn/linearSOE/itpack/ItpackLinSolver.h @@ -55,7 +55,7 @@ class ItpackLinSOE; class ItpackLinSolver : public LinearSOESolver { public: - ItpackLinSolver(int method, int maxIter = 100, double omega = 1.0); + ItpackLinSolver(int method, int maxIter = 100, double omega = 1.0, double zeta = 5e-6); ItpackLinSolver(); virtual ~ItpackLinSolver(); @@ -96,6 +96,9 @@ class ItpackLinSolver : public LinearSOESolver // Parameter for SOR and SSOR fixed omega methods double omega; + + // Parameter for convergence criteria + double zeta; }; #endif From 7fb4b7fb589beec4110649cc80210b5d834a11aa Mon Sep 17 00:00:00 2001 From: Angshuman Deb Date: Wed, 6 Aug 2025 09:30:08 -0700 Subject: [PATCH 203/261] fixed dereferencing of optionally empty Vectors in HystereticSMMaterial.cpp --- SRC/material/uniaxial/HystereticSMMaterial.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SRC/material/uniaxial/HystereticSMMaterial.cpp b/SRC/material/uniaxial/HystereticSMMaterial.cpp index ee14873632..61cffbdeeb 100644 --- a/SRC/material/uniaxial/HystereticSMMaterial.cpp +++ b/SRC/material/uniaxial/HystereticSMMaterial.cpp @@ -324,8 +324,9 @@ OPS_HystereticSMMaterial(void) Vector thepinchArray(&pinchArray[0], (int)pinchArray.size()); Vector thedamageArray(&damageArray[0], (int)damageArray.size()); Vector thedegEnvArray(°EnvArray[0], (int)degEnvArray.size()); - Vector theLSforce(&forceLimitStates[0], (int)forceLimitStates.size()); - Vector theLSdefo(&defoLimitStates[0], (int)defoLimitStates.size()); + // Not dereferencing optionally empty forceLimitStates and/or defoLimitStates + Vector theLSforce = forceLimitStates.size() > 0 ? Vector(&forceLimitStates[0], (int)forceLimitStates.size()) : Vector(); + Vector theLSdefo = defoLimitStates.size() > 0 ? Vector(&defoLimitStates[0], (int)defoLimitStates.size()) : Vector(); double tmp = 0; if (YXorder == -1) { From 983305d9e7a6f35a755979e6acfa4b9aec40ea2c Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 8 Aug 2025 10:48:51 -0700 Subject: [PATCH 204/261] Update SingleFPSimple3d.cpp --- SRC/element/frictionBearing/SingleFPSimple3d.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SRC/element/frictionBearing/SingleFPSimple3d.cpp b/SRC/element/frictionBearing/SingleFPSimple3d.cpp index 95c8c93ffe..d13758cc90 100755 --- a/SRC/element/frictionBearing/SingleFPSimple3d.cpp +++ b/SRC/element/frictionBearing/SingleFPSimple3d.cpp @@ -221,7 +221,7 @@ void* OPS_SingleFPSimple3d() opserr<<"WARNING: invalid tol\n"; return 0; } - } else if (strcmp(type,"-inclVertdisp") == 0) { + } else if (strcmp(type,"-inclVertDisp") == 0) { inclVertDisp = 1; } else if (strcmp(type,"-kFactUplift") == 0) { if (OPS_GetNumRemainingInputArgs() < 1) { @@ -1338,3 +1338,4 @@ SingleFPSimple3d::updateParameter(int parameterID, Information &info) return -1; } } + From 8a8cd7d08b65cabefedf9f02291f94e96d865424 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 8 Aug 2025 10:51:23 -0700 Subject: [PATCH 205/261] Update SingleFPSimple2d.cpp --- SRC/element/frictionBearing/SingleFPSimple2d.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SRC/element/frictionBearing/SingleFPSimple2d.cpp b/SRC/element/frictionBearing/SingleFPSimple2d.cpp index 519f0c580a..669e822961 100755 --- a/SRC/element/frictionBearing/SingleFPSimple2d.cpp +++ b/SRC/element/frictionBearing/SingleFPSimple2d.cpp @@ -182,7 +182,7 @@ void* OPS_SingleFPSimple2d() opserr<<"WARNING: invalid tol\n"; return 0; } - } else if (strcmp(type,"-inclVertdisp") == 0) { + } else if (strcmp(type,"-inclVertDisp") == 0) { inclVertDisp = 1; } else if (strcmp(type,"-kFactUplift") == 0) { if (OPS_GetNumRemainingInputArgs() < 1) { @@ -1190,3 +1190,4 @@ SingleFPSimple2d::updateParameter(int parameterID, Information &info) return -1; } } + From 02d3354fad2bfda905d45726847df94cf7eed80b Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Wed, 13 Aug 2025 15:37:32 -0700 Subject: [PATCH 206/261] Adding class for beam uniform moment as eleLoad --- SRC/domain/load/BeamUniformMoment.cpp | 120 ++++++++++++++++++++++++++ SRC/domain/load/BeamUniformMoment.h | 58 +++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 SRC/domain/load/BeamUniformMoment.cpp create mode 100644 SRC/domain/load/BeamUniformMoment.h diff --git a/SRC/domain/load/BeamUniformMoment.cpp b/SRC/domain/load/BeamUniformMoment.cpp new file mode 100644 index 0000000000..ffd4858707 --- /dev/null +++ b/SRC/domain/load/BeamUniformMoment.cpp @@ -0,0 +1,120 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.4 $ +// $Date: 2007-10-17 22:11:35 $ +// $Source: /usr/local/cvs/OpenSees/SRC/domain/load/BeamUniformMoment.cpp,v $ + + +// Written: fmk +// +// Purpose: This file contains the class implementation of BeamUniformMoment. + +#include +#include +#include +#include + +Vector BeamUniformMoment::data(3); + +BeamUniformMoment::BeamUniformMoment(int tag, double x, double y, double z, + int theElementTag) + :ElementalLoad(tag, LOAD_TAG_BeamUniformMoment, theElementTag), + mx(x), my(y), mz(z) +{ + +} + +BeamUniformMoment::BeamUniformMoment() + :ElementalLoad(LOAD_TAG_BeamUniformMoment), + mx(0.0), my(0.0), mz(0.0) +{ + +} + +BeamUniformMoment::~BeamUniformMoment() +{ + +} + +const Vector & +BeamUniformMoment::getData(int &type, double loadFactor) +{ + type = LOAD_TAG_BeamUniformMoment; + data(0) = mx; + data(1) = my; + data(2) = mz; + return data; +} + + +int +BeamUniformMoment::sendSelf(int commitTag, Channel &theChannel) +{ + int dbTag = this->getDbTag(); + + static Vector vectData(5); + vectData(4) = this->getTag(); + vectData(0) = mx; + vectData(1) = my; + vectData(2) = mz; + vectData(3) = eleTag; + + int result = theChannel.sendVector(dbTag, commitTag, vectData); + if (result < 0) { + opserr << "BeamUniformMoment::sendSelf - failed to send data\n"; + return result; + } + + return 0; +} + +int +BeamUniformMoment::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int dbTag = this->getDbTag(); + + static Vector vectData(5); + + int result = theChannel.recvVector(dbTag, commitTag, vectData); + if (result < 0) { + opserr << "BeamUniformMoment::recvSelf - failed to recv data\n"; + return result; + } + + mx = vectData(0);; + my = vectData(1);; + mz = vectData(2);; + eleTag = (int)vectData(3); + this->setTag(vectData(4)); + + return 0; +} + +void +BeamUniformMoment::Print(OPS_Stream &s, int flag) +{ + s << "BeamUniformMoment - Reference load: " << this->getTag() << endln; + s << " Torque (x): " << mx << endln; + s << " About y: " << my << endln; + s << " About z: " << mz << endln; + s << " Element: " << eleTag << endln; +} diff --git a/SRC/domain/load/BeamUniformMoment.h b/SRC/domain/load/BeamUniformMoment.h new file mode 100644 index 0000000000..477d091161 --- /dev/null +++ b/SRC/domain/load/BeamUniformMoment.h @@ -0,0 +1,58 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.3 $ +// $Date: 2007-10-17 22:11:35 $ +// $Source: /usr/local/cvs/OpenSees/SRC/domain/load/BeamUniformMoment.h,v $ + +#ifndef BeamUniformMoment_h +#define BeamUniformMoment_h + +// Written: fmk + +// Purpose: This file contains the class definition for BeamUniformMoment. + +#include + +class BeamUniformMoment : public ElementalLoad +{ + public: + BeamUniformMoment(int tag, double mx, double my, double mz, int eleTag); + + BeamUniformMoment(); + ~BeamUniformMoment(); + + const Vector &getData(int &type, double loadFactor); + + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + void Print(OPS_Stream &s, int flag =0); + + protected: + + private: + double mx; // Twist + double my; // About y + double mz; // About z + static Vector data; +}; + +#endif + From 30cc727df3241ece4b425b2de9cc18a9c30b422e Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 15 Aug 2025 11:47:52 -0700 Subject: [PATCH 207/261] Adding class tag for uniform moment --- SRC/classTags.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SRC/classTags.h b/SRC/classTags.h index a9e1b1efc2..8dcf509b0c 100644 --- a/SRC/classTags.h +++ b/SRC/classTags.h @@ -608,7 +608,7 @@ #define PATTERN_TAG_LoadPattern 1 #define PATTERN_TAG_MultiSupportPattern 3 #define PATTERN_TAG_UniformExcitation 2 -#define PATTERN_TAG_FirePattern 3 +#define PATTERN_TAG_FirePattern 7 #define PATTERN_TAG_PBowlLoading 4 #define PATTERN_TAG_DRMLoadPattern 5 #define PATTERN_TAG_H5DRM 6 @@ -617,6 +617,7 @@ #define LOAD_TAG_Beam2dPointLoad 4 #define LOAD_TAG_Beam3dUniformLoad 5 #define LOAD_TAG_Beam3dPointLoad 6 +#define LOAD_TAG_BeamUniformMoment 60 #define LOAD_TAG_BrickSelfWeight 7 #define LOAD_TAG_Beam2dTempLoad 8 #define LOAD_TAG_SurfaceLoader 9 // C.McGann, U.W. From 3359b32a98a41cdb48efeb725b0b514f3a6325f2 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 15 Aug 2025 11:50:04 -0700 Subject: [PATCH 208/261] Adding OPS command for beamUniformMoment --- SRC/interpreter/OpenSeesPatternCommands.cpp | 48 +++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/SRC/interpreter/OpenSeesPatternCommands.cpp b/SRC/interpreter/OpenSeesPatternCommands.cpp index da44743298..10c6c2bd09 100644 --- a/SRC/interpreter/OpenSeesPatternCommands.cpp +++ b/SRC/interpreter/OpenSeesPatternCommands.cpp @@ -41,6 +41,7 @@ UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #include #include #include +#include #include #include #include @@ -366,6 +367,53 @@ int OPS_ElementalLoad() return -1; } + } else if (strncmp(type,"-beamUniformMoment",80) == 0 || strncmp(type,"beamUniformMoment",80) == 0) { + double data[3] = {0.0,0.0,0.0}; + int numdata = OPS_GetNumRemainingInputArgs(); + if (ndm == 2) { + if (numdata < 1) { + opserr << "WARNING eleLoad - beamUniformMoment want mz" << endln; + return -1; + } + if (numdata > 1) numdata = 1; + if (OPS_GetDoubleInput(&numdata, &data[2]) < 0) { + opserr<<"WARNING eleLoad - invalid value for beamUniformMoment\n"; + return -1; + } + } + if (ndm == 3) { + if (numdata < 3) { + opserr << "WARNING eleLoad - beamUniformMoment want mx my mz" << endln; + return -1; + } + if (numdata > 3) numdata = 3; + if (OPS_GetDoubleInput(&numdata, data) < 0) { + opserr<<"WARNING eleLoad - invalid value for beamUniformMoment\n"; + return -1; + } + } + for (int i=0; igetTag(); + + // add the load to the domain + if (theDomain->addElementalLoad(theLoad, loadPatternTag) == false) { + opserr << "WARNING eleLoad - could not add following load to domain:\n "; + opserr << theLoad; + delete theLoad; + return -1; + } + eleLoadTag++; + } + + return 0; } else if (strcmp(type,"-beamPoint") == 0 || strcmp(type,"beamPoint") == 0 ) { From cfa8a7877a6171d739e762b5230157ff4976114f Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 15 Aug 2025 11:52:13 -0700 Subject: [PATCH 209/261] Adding BeamUniformMoment to make/cmake --- SRC/domain/load/CMakeLists.txt | 2 ++ SRC/domain/load/Makefile | 1 + 2 files changed, 3 insertions(+) diff --git a/SRC/domain/load/CMakeLists.txt b/SRC/domain/load/CMakeLists.txt index 29ede24e18..1c694290ba 100644 --- a/SRC/domain/load/CMakeLists.txt +++ b/SRC/domain/load/CMakeLists.txt @@ -17,6 +17,7 @@ target_sources(OPS_Domain Beam3dUniformLoad.cpp Beam3dPointLoad.cpp Beam3dPartialUniformLoad.cpp + BeamUniformMoment.cpp BrickSelfWeight.cpp SurfaceLoader.cpp SelfWeight.cpp @@ -32,6 +33,7 @@ target_sources(OPS_Domain Beam3dUniformLoad.h Beam3dPointLoad.h Beam3dPartialUniformLoad.h + BeamUniformMoment.h BrickSelfWeight.h SurfaceLoader.h SelfWeight.h diff --git a/SRC/domain/load/Makefile b/SRC/domain/load/Makefile index 4c3a92c857..ab8ae80880 100644 --- a/SRC/domain/load/Makefile +++ b/SRC/domain/load/Makefile @@ -12,6 +12,7 @@ OBJS = Load.o \ BrickSelfWeight.o \ Beam2dTempLoad.o \ Beam2dThermalAction.o \ + BeamUniformMoment.o \ NodalThermalAction.o \ ThermalActionWrapper.o \ Beam3dThermalAction.o \ From 8d64955ea643313fb59e510d57ee7d0985f7bd38 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 15 Aug 2025 11:52:51 -0700 Subject: [PATCH 210/261] Adding beam uniform moment --- .../forceBeamColumn/ForceBeamColumn2d.cpp | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/SRC/element/forceBeamColumn/ForceBeamColumn2d.cpp b/SRC/element/forceBeamColumn/ForceBeamColumn2d.cpp index 8a5074d8eb..b2293b9be7 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumn2d.cpp +++ b/SRC/element/forceBeamColumn/ForceBeamColumn2d.cpp @@ -1084,6 +1084,12 @@ ForceBeamColumn2d::computeReactions(double *p0) p0[1] -= V; p0[2] -= V; } + if (type == LOAD_TAG_BeamUniformMoment) { + double mz = data(2)*loadFactor; // About z + + p0[1] += mz; + p0[2] -= mz; + } else if (type == LOAD_TAG_Beam2dPartialUniformLoad) { double waa = data(2)*loadFactor; // Axial double wab = data(3)*loadFactor; // Axial @@ -1735,6 +1741,24 @@ ForceBeamColumn2d::computeSectionForces(Vector &sp, int isec) } } } + else if (type == LOAD_TAG_BeamUniformMoment) { + double mz = data(2)*loadFactor; // About z + + for (int ii = 0; ii < order; ii++) { + + switch(code(ii)) { + case SECTION_RESPONSE_P: + break; + case SECTION_RESPONSE_MZ: + break; + case SECTION_RESPONSE_VY: + sp(ii) += mz; + break; + default: + break; + } + } + } else if (type == LOAD_TAG_Beam2dPartialUniformLoad) { double waa = data(2)*loadFactor; // Axial double wab = data(3)*loadFactor; // Axial From 7386c14776aaf07262fddcaba3356cabefbcb3e5 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 15 Aug 2025 11:53:17 -0700 Subject: [PATCH 211/261] Adding beam uniform moment --- SRC/element/dispBeamColumn/DispBeamColumn2d.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/SRC/element/dispBeamColumn/DispBeamColumn2d.cpp b/SRC/element/dispBeamColumn/DispBeamColumn2d.cpp index a321830d41..ac80ae70eb 100644 --- a/SRC/element/dispBeamColumn/DispBeamColumn2d.cpp +++ b/SRC/element/dispBeamColumn/DispBeamColumn2d.cpp @@ -907,6 +907,17 @@ DispBeamColumn2d::addLoad(ElementalLoad *theLoad, double loadFactor) q0[1] -= M; q0[2] += M; } + else if (type == LOAD_TAG_BeamUniformMoment) { + double mz = data(2)*loadFactor; // About z + + // Reactions in basic system + p0[1] += mz; + p0[2] -= mz; + + // Fixed end forces in basic system + //q0[1] -= 0.0; + //q0[2] += 0.0; + } else if (type == LOAD_TAG_Beam2dPointLoad) { double P = data(0)*loadFactor; double N = data(1)*loadFactor; From 7551cc89df3622ea93e2455df33e64fcff05967e Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 15 Aug 2025 11:53:36 -0700 Subject: [PATCH 212/261] Adding beam uniform moment --- SRC/element/elasticBeamColumn/ElasticBeam2d.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/SRC/element/elasticBeamColumn/ElasticBeam2d.cpp b/SRC/element/elasticBeamColumn/ElasticBeam2d.cpp index 43eaf9d232..e3b3486da5 100644 --- a/SRC/element/elasticBeamColumn/ElasticBeam2d.cpp +++ b/SRC/element/elasticBeamColumn/ElasticBeam2d.cpp @@ -827,7 +827,17 @@ ElasticBeam2d::addLoad(ElementalLoad *theLoad, double loadFactor) // Nothing to do } } + else if (type == LOAD_TAG_BeamUniformMoment) { + double mz = data(2)*loadFactor; // About z + // Reactions in basic system + p0[1] += mz; + p0[2] -= mz; + + // Fixed end forces in basic system + //q0[1] -= 0.0; + //q0[2] += 0.0; + } else if (type == LOAD_TAG_Beam2dPartialUniformLoad) { // These equations should works for partial trapezoidal load double waa = data(2)*loadFactor; // Axial From eebb4c41c786aa302461a2c267c2cbdb8eac46dc Mon Sep 17 00:00:00 2001 From: Michael Scott Date: Fri, 15 Aug 2025 15:12:53 -0700 Subject: [PATCH 213/261] Adding uniform moment to object broker --- SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp index 65cb73fe09..8876d8e1c0 100644 --- a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp +++ b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp @@ -589,6 +589,7 @@ #include "Beam2dPointLoad.h" #include "Beam3dUniformLoad.h" #include "Beam3dPointLoad.h" +#include "BeamUniformMoment.h" #include "BrickSelfWeight.h" #include "SelfWeight.h" #include "SurfaceLoader.h" @@ -1362,6 +1363,9 @@ FEM_ObjectBrokerAllClasses::getNewElementalLoad(int classTag) case LOAD_TAG_Beam3dPointLoad: return new Beam3dPointLoad(); + + case LOAD_TAG_BeamUniformMoment: + return new BeamUniformMoment(); case LOAD_TAG_BrickSelfWeight: return new BrickSelfWeight(); From 908e04ef09e136efba74368262175a141e400dcf Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Fri, 15 Aug 2025 17:40:52 -0700 Subject: [PATCH 214/261] Add check to skip nodes with more than 6 DOF in node_matching_BruteForce --- SRC/domain/pattern/drm/H5DRMLoadPattern.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/SRC/domain/pattern/drm/H5DRMLoadPattern.cpp b/SRC/domain/pattern/drm/H5DRMLoadPattern.cpp index a2320d2a78..739fc3450c 100644 --- a/SRC/domain/pattern/drm/H5DRMLoadPattern.cpp +++ b/SRC/domain/pattern/drm/H5DRMLoadPattern.cpp @@ -1629,6 +1629,17 @@ void H5DRMLoadPattern::node_matching_BruteForce(double d_tol, const ID & interna while ((node_ptr = node_iter()) != 0) { int tag = node_ptr->getTag(); + + // Skip nodes with more than 6 DOF + int numDOF = node_ptr->getNumberDOF(); + if (numDOF > 6) { + if (DEBUG_NODE_MATCHING) + { + fprintf(fptrdrm, "Node # %05d skipped - has %d DOF (>6)\n", tag, numDOF); + } + continue; + } + const Vector& node_xyz = node_ptr->getCrds(); double dmin = std::numeric_limits::infinity(); int ii_station_min = 0; From 0a5daa4f60bb9d6b804e536f998a0998583478ce Mon Sep 17 00:00:00 2001 From: Amin Pakzad Date: Fri, 15 Aug 2025 17:41:06 -0700 Subject: [PATCH 215/261] Add support for custom starting tag in TclCommand_GenerateInterfacePoints --- .../Tcl_generateInterfacePoints.cpp | 56 +++++++++++++++++-- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/SRC/element/UWelements/Tcl_generateInterfacePoints.cpp b/SRC/element/UWelements/Tcl_generateInterfacePoints.cpp index 6119d2894d..f0cf17ccd8 100644 --- a/SRC/element/UWelements/Tcl_generateInterfacePoints.cpp +++ b/SRC/element/UWelements/Tcl_generateInterfacePoints.cpp @@ -63,8 +63,10 @@ TclCommand_GenerateInterfacePoints(ClientData clientData, Tcl_Interp *interp, in bool readingBeamEleTag = false; bool readingSolidEleTag = false; bool readingConBeamEleTag = false; + bool startTagSet = false; int lagrangeTag = 8; // 0 = local penalty, 1 = local Augmented Lagrangian, 2 = global Lagrange, 3 = global embedded lagrange, 4 = global penalty + int interfaceStartTag = 0; const char * crdsFN; const char * connectivityFN; @@ -380,6 +382,18 @@ TclCommand_GenerateInterfacePoints(ClientData clientData, Tcl_Interp *interp, in baseNodeTag = strtol(argv[curArgPos], NULL, 10); numArgsRemaining--; curArgPos++; } + else if ((strcmp(argv[curArgPos], "-startTag") == 0) && (numArgsRemaining >= 2)) + { + // This sets the starting tag for interface elements + readingSolidEleTag = false; + readingConBeamEleTag = false; + readingBeamEleTag = false; + startTagSet = true; + + numArgsRemaining--; curArgPos++; + interfaceStartTag = strtol(argv[curArgPos], NULL, 10); + numArgsRemaining--; curArgPos++; + } else { if (readingSolidEleTag) { @@ -437,7 +451,13 @@ TclCommand_GenerateInterfacePoints(ClientData clientData, Tcl_Interp *interp, in if (theElement->getTag() > maxTag) maxTag = theElement->getTag(); } - int startTag = maxTag + 1; + + // Use the provided startTag if set, otherwise use maxTag + 1 + int startTag; + if (startTagSet) + startTag = interfaceStartTag; + else + startTag = maxTag + 1; FileStream crdsFile, quadNodes, quadElems; if (writeCoords) @@ -451,6 +471,9 @@ TclCommand_GenerateInterfacePoints(ClientData clientData, Tcl_Interp *interp, in // Define variables needed int contactElemCount = 0, contactPointCount = 0; double area; + + // Initialize maxTag to startTag for interface element creation + maxTag = startTag; // Loop over beam elements for (int beamCount = 0; beamCount < beamEleTags.size(); beamCount++) @@ -700,8 +723,10 @@ TclCommand_GenerateInterfacePoints(ClientData clientData, Tcl_Interp *interp, in // 0 = local penalty, 1 = local Augmented Lagrangian, 2 = global Lagrange, 3 = global embedded lagrange if (lagrangeTag > 1) { - if (lagrangeTag == 2) + if (lagrangeTag == 2) { theElement = new EmbeddedBeamInterfaceL(maxTag, beamEleTagsInContact, solidEleTagsInContact, transfTag, contactPt_rho, contactPt_theta, contactPt_xi, contactPt_eta, contactPt_zeta, radius, contactPt_area, contactPt_length, writeConnectivity, connectivityFN); + opserr << "Creating EmbeddedBeamInterfaceL" << endln; + } else if (lagrangeTag == 3) { // if (beamConnected) @@ -709,8 +734,10 @@ TclCommand_GenerateInterfacePoints(ClientData clientData, Tcl_Interp *interp, in // else // theElement = new EmbeddedBeamInterfaceAL2(maxTag, beamEleTagsInContact, solidEleTagsInContact, transfTag, contactPt_rho, contactPt_theta, contactPt_xi, contactPt_eta, contactPt_zeta, radius, contactPt_area, writeConnectivity, connectivityFN); } - else if (lagrangeTag == 4) + else if (lagrangeTag == 4) { theElement = new EmbeddedBeamInterfaceP(maxTag, beamEleTagsInContact, solidEleTagsInContact, transfTag, contactPt_rho, contactPt_theta, contactPt_xi, contactPt_eta, contactPt_zeta, radius, contactPt_area, contactPt_length, penaltyParam, writeConnectivity, connectivityFN); + opserr << "Creating EmbeddedBeamInterfaceP " << endln; + } else if (lagrangeTag == 5) { // theElement = new EmbeddedBeamInterfaceAL2(maxTag, beamTag, solidEleTagsInContact, transfTag, contactPt_rho, contactPt_theta, contactPt_xi, contactPt_eta, contactPt_zeta, radius, area); @@ -832,7 +859,9 @@ TclCommand_GenerateToeInterfacePoints(ClientData clientData, Tcl_Interp *interp, bool solidEleSetDefined = false; bool debugFlag = false; bool writeCoords = false; + bool startTagSet = false; int lagrangeTag = 3; // 0 = local penalty, 1 = local Augmented Lagrangian, 2 = global Lagrange, 3 = global embedded lagrange + int interfaceStartTag = 0; const char * crdsFN; std::vector solidEleTags; @@ -991,6 +1020,16 @@ TclCommand_GenerateToeInterfacePoints(ClientData clientData, Tcl_Interp *interp, lagrangeTag = 4; numArgsRemaining--; curArgPos++; } + else if ((strcmp(argv[curArgPos], "-startTag") == 0) && (numArgsRemaining >= 2)) + { + // This sets the starting tag for interface elements + readingSolidEleTag = false; + startTagSet = true; + + numArgsRemaining--; curArgPos++; + interfaceStartTag = strtol(argv[curArgPos], NULL, 10); + numArgsRemaining--; curArgPos++; + } else { if (readingSolidEleTag) @@ -1042,7 +1081,16 @@ TclCommand_GenerateToeInterfacePoints(ClientData clientData, Tcl_Interp *interp, if (theElement->getTag() > maxTag) maxTag = theElement->getTag(); } - int startTag = maxTag + 1; + + // Use the provided startTag if set, otherwise use maxTag + 1 + int startTag; + if (startTagSet) + startTag = interfaceStartTag; + else + startTag = maxTag + 1; + + // Initialize maxTag to startTag for interface element creation + maxTag = startTag; From bbde8fea3ff0696c40bba59d01942997c50aeea3 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Sun, 17 Aug 2025 12:21:13 -0700 Subject: [PATCH 216/261] Updating VS projects for uniform moment --- Win64/proj/domain/domain.vcxproj | 4 +++- Win64/proj/domain/domain.vcxproj.filters | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Win64/proj/domain/domain.vcxproj b/Win64/proj/domain/domain.vcxproj index c22b57615a..b6bae2e71e 100644 --- a/Win64/proj/domain/domain.vcxproj +++ b/Win64/proj/domain/domain.vcxproj @@ -245,6 +245,7 @@ + @@ -345,6 +346,7 @@ + @@ -392,4 +394,4 @@ - \ No newline at end of file + diff --git a/Win64/proj/domain/domain.vcxproj.filters b/Win64/proj/domain/domain.vcxproj.filters index d73fba6d18..a14984f79e 100644 --- a/Win64/proj/domain/domain.vcxproj.filters +++ b/Win64/proj/domain/domain.vcxproj.filters @@ -141,6 +141,9 @@ load\beam + + load\beam + load\beam @@ -440,6 +443,9 @@ load\beam + + load\beam + load\beam @@ -615,4 +621,4 @@ timeSeries - \ No newline at end of file + From e5c60c6867715bf6c03279d87b60d71542d95ba6 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 18 Aug 2025 13:38:20 -0700 Subject: [PATCH 217/261] Update Makefile --- SRC/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SRC/Makefile b/SRC/Makefile index 2c7be55ba7..231789d90f 100644 --- a/SRC/Makefile +++ b/SRC/Makefile @@ -432,8 +432,7 @@ RECORDER_LIBS = $(FE)/recorder/Recorder.o \ $(FE)/recorder/ElementRecorderRMS.o \ $(FE)/recorder/NodeRecorderRMS.o \ $(FE)/recorder/MPCORecorder.o \ - $(FE)/recorder/VTK_Recorder.o \ - $(FE)/recorder/VTKHDF_Recorder.o \ + $(FE)/recorder/VTK_Recorder.o DATABASE_LIBS = $(FE)/database/FileDatastore.o \ From 19a6f8bce36b1bf38b3dd44e431ffa18d92126a5 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 18 Aug 2025 13:50:14 -0700 Subject: [PATCH 218/261] Update Makefile --- SRC/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/SRC/Makefile b/SRC/Makefile index 231789d90f..5d387c8e22 100644 --- a/SRC/Makefile +++ b/SRC/Makefile @@ -1326,6 +1326,7 @@ DOMAIN_LIBS = $(FE)/domain/component/DomainComponent.o \ $(FE)/domain/load/Beam2dPointLoad.o \ $(FE)/domain/load/Beam2dTempLoad.o \ $(FE)/domain/load/Beam2dThermalAction.o \ + $(FE)/domain/load/BeamUniformMoment.o \ $(FE)/domain/load/NodalThermalAction.o \ $(FE)/domain/load/ThermalActionWrapper.o \ $(FE)/domain/load/Beam3dThermalAction.o \ From 8bc9b084d28f5b4eb6eeef3b0a8619febf5501cb Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Thu, 28 Aug 2025 10:06:30 -0700 Subject: [PATCH 219/261] Fixing sign error on internal shear for point load in local z --- SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp b/SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp index 51add0480c..61d21c1ac2 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp +++ b/SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp @@ -1697,7 +1697,7 @@ ForceBeamColumn3d::computeSectionForces(Vector &sp, int isec) sp(ii) += x*Vz1; break; case SECTION_RESPONSE_VZ: - sp(ii) -= Vz1; + sp(ii) += Vz1; break; default: break; @@ -1715,7 +1715,7 @@ ForceBeamColumn3d::computeSectionForces(Vector &sp, int isec) sp(ii) += (L-x)*Vz2; break; case SECTION_RESPONSE_VZ: - sp(ii) += Vz2; + sp(ii) -= Vz2; break; default: break; From f67c37c8ba5bb6a464819026d4fd237b771b9895 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 28 Aug 2025 21:28:21 -0700 Subject: [PATCH 220/261] merge runtime updates --- SRC/runtime/CMakeLists.txt | 55 +- SRC/runtime/OpenSeesRT.cpp | 16 +- SRC/runtime/commands/CMakeLists.txt | 27 +- SRC/runtime/commands/analysis/algorithm.cpp | 813 ++++----- SRC/runtime/commands/analysis/analysis.cpp | 278 ++- SRC/runtime/commands/analysis/analysis.h | 21 +- SRC/runtime/commands/analysis/ctest.cpp | 62 +- SRC/runtime/commands/analysis/integrator.cpp | 223 ++- SRC/runtime/commands/analysis/integrator.h | 175 +- .../commands/analysis/modal/CMakeLists.txt | 8 + .../analysis/modal/DomainModalProperties.cpp | 859 +++++++++ .../analysis/modal/DomainModalProperties.h | 102 ++ .../modal/ResponseSpectrumAnalysis.cpp | 317 ++++ .../analysis/modal/ResponseSpectrumAnalysis.h | 78 + SRC/runtime/commands/analysis/modal/modal.cpp | 352 ++++ SRC/runtime/commands/analysis/numberer.cpp | 9 +- SRC/runtime/commands/analysis/sensitivity.cpp | 144 +- SRC/runtime/commands/analysis/solver.cpp | 46 +- SRC/runtime/commands/analysis/solver.hpp | 33 +- SRC/runtime/commands/analysis/spectrum.cpp | 77 + SRC/runtime/commands/analysis/transient.cpp | 37 +- .../domain/TclUpdateMaterialCommand.cpp | 5 +- .../domain/TclUpdateMaterialStageCommand.cpp | 35 +- SRC/runtime/commands/domain/commands.cpp | 250 ++- SRC/runtime/commands/domain/commands.h | 163 +- .../domain/database/TclBerkeleyDB.cpp | 5 +- SRC/runtime/commands/domain/domain.cpp | 74 +- SRC/runtime/commands/domain/element.cpp | 157 +- .../loading/TclSeriesIntegratorCommand.cpp | 5 +- .../domain/loading/drm/TclPatternCommand.cpp | 6 +- .../commands/domain/loading/element_load.cpp | 373 +++- .../domain/loading/groundExcitation.cpp | 5 +- .../commands/domain/loading/groundMotion.cpp | 25 +- .../commands/domain/loading/pattern.cpp | 47 +- .../commands/domain/loading/series.cpp | 154 +- SRC/runtime/commands/domain/nodes.cpp | 352 +++- SRC/runtime/commands/domain/parameter.cpp | 114 +- SRC/runtime/commands/domain/recorder.cpp | 237 +-- SRC/runtime/commands/domain/region.cpp | 13 +- SRC/runtime/commands/domain/response.cpp | 95 +- SRC/runtime/commands/domain/rigid_links.cpp | 91 +- SRC/runtime/commands/domain/runtime.cpp | 22 +- SRC/runtime/commands/domain/sensitivity.cpp | 180 +- SRC/runtime/commands/domain/staging.cpp | 5 +- SRC/runtime/commands/interpreter.cpp | 67 +- SRC/runtime/commands/interpreter.h | 26 + SRC/runtime/commands/modeling/CMakeLists.txt | 2 + SRC/runtime/commands/modeling/commands.h | 25 +- SRC/runtime/commands/modeling/constraint.cpp | 228 ++- SRC/runtime/commands/modeling/element.cpp | 111 +- SRC/runtime/commands/modeling/element.hpp | 11 +- .../commands/modeling/element/brick.cpp | 676 +++++++ .../commands/modeling/element/frames.cpp | 30 +- .../commands/modeling/element/plane.cpp | 1598 +++++++++++++++++ .../commands/modeling/element/shells.cpp | 682 +++++++ .../commands/modeling/element/truss.cpp | 407 +++++ SRC/runtime/commands/modeling/geomTransf.cpp | 38 +- .../commands/modeling/invoking/invoke.cpp | 7 +- .../modeling/invoking/invoke_material.cpp | 8 + .../modeling/invoking/invoke_section.cpp | 46 +- .../modeling/invoking/invoke_stress.cpp | 9 +- .../modeling/invoking/invoke_uniaxial.cpp | 45 +- .../commands/modeling/material/CMakeLists.txt | 16 + .../commands/modeling/material/boucwen.cpp | 640 +++++++ .../commands/modeling/material/concrete.cpp | 408 +++++ .../commands/modeling/material/elastic.cpp | 598 ++++++ .../commands/modeling/material/fedeas.cpp | 1244 +++++++++++++ .../commands/modeling/material/isotropy.cpp | 426 +++++ .../commands/modeling/material/isotropy.h | 58 + .../commands/modeling/material/legacy.cpp | 617 +++++++ .../commands/modeling/material/material.cpp | 846 +++++++++ .../commands/modeling/material/material.hpp | 291 +++ .../commands/modeling/material/nDMaterial.cpp | 1286 +++++++++++++ .../commands/modeling/material/plastic.cpp | 1009 +++++++++++ .../commands/modeling/material/shell.cpp | 252 +++ .../commands/modeling/material/wrapper.cpp | 476 +++++ SRC/runtime/commands/modeling/mesh.cpp | 2 - SRC/runtime/commands/modeling/model.cpp | 73 +- SRC/runtime/commands/modeling/nodes.cpp | 129 +- SRC/runtime/commands/modeling/printing.cpp | 207 ++- SRC/runtime/commands/modeling/section.cpp | 1204 ++++++------- .../commands/modeling/section/PlaneSection.h | 48 + .../commands/modeling/section/frame.cpp | 641 +++++++ .../commands/modeling/section/plane.cpp | 141 ++ .../commands/modeling/section/truss.cpp | 202 +++ .../transform/FrameTransformBuilder.hpp | 9 + SRC/runtime/commands/modeling/uniaxial.cpp | 886 +-------- SRC/runtime/commands/modeling/uniaxial.hpp | 372 ++-- .../commands/modeling/uniaxialMaterial.cpp | 127 +- .../commands/modeling/utilities/Block2D.cpp | 236 +++ .../commands/modeling/utilities/Block2D.h | 64 + .../commands/modeling/utilities/Block3D.cpp | 336 ++++ .../commands/modeling/utilities/Block3D.h | 64 + .../commands/modeling/utilities/blockND.cpp | 442 +++++ SRC/runtime/commands/packages.cpp | 104 -- SRC/runtime/commands/packages.h | 5 +- SRC/runtime/commands/parallel/CMakeLists.txt | 101 +- SRC/runtime/commands/parallel/communicate.cpp | 154 ++ SRC/runtime/commands/parallel/machine.cpp | 53 + SRC/runtime/commands/parallel/partition.cpp | 184 ++ SRC/runtime/commands/parallel/sequential.cpp | 5 +- SRC/runtime/commands/pragma.cpp | 31 +- SRC/runtime/commands/strings.cpp | 5 +- SRC/runtime/commands/utilities/formats.cpp | 8 +- SRC/runtime/commands/utilities/linalg.hh | 36 +- SRC/runtime/commands/utilities/progress.cpp | 5 +- .../commands/utilities/sdofResponse.cpp | 5 +- SRC/runtime/parsing/CMakeLists.txt | 9 + SRC/runtime/parsing/InputAPI.h | 2 +- SRC/runtime/parsing/InterpreterAPI.cpp | 222 +-- SRC/runtime/parsing/Parsing.h | 21 +- SRC/runtime/python/OpenSeesPyRT.cpp | 11 +- SRC/runtime/runtime/BasicAnalysisBuilder.cpp | 460 +++-- SRC/runtime/runtime/BasicAnalysisBuilder.h | 37 +- SRC/runtime/runtime/BasicModelBuilder.cpp | 110 +- SRC/runtime/runtime/BasicModelBuilder.h | 41 +- SRC/runtime/runtime/CMakeLists.txt | 4 +- SRC/runtime/runtime/G3_Runtime.h | 26 +- SRC/runtime/runtime/Notes.md | 91 + SRC/runtime/runtime/TclPackageClassBroker.cpp | 188 +- SRC/runtime/runtime/TclPackageClassBroker.h | 5 +- .../runtime/modeling/section/CMakeLists.txt | 14 + .../modeling/section/FiberSectionBuilder.h | 150 ++ .../modeling/section/cell/CMakeLists.txt | 18 + .../runtime/modeling/section/cell/Cell.h | 51 + .../modeling/section/cell/CircSectionCell.cpp | 46 + .../modeling/section/cell/CircSectionCell.h | 38 + .../modeling/section/cell/QuadCell.cpp | 92 + .../runtime/modeling/section/cell/QuadCell.h | 45 + .../modeling/section/patch/CMakeLists.txt | 18 + .../modeling/section/patch/CircPatch.cpp | 89 + .../modeling/section/patch/CircPatch.h | 45 + .../runtime/modeling/section/patch/Patch.h | 29 + .../modeling/section/patch/QuadPatch.cpp | 120 ++ .../modeling/section/patch/QuadPatch.h | 54 + .../section/reinfLayer/CMakeLists.txt | 18 + .../section/reinfLayer/CircReinfLayer.cpp | 98 + .../section/reinfLayer/CircReinfLayer.h | 60 + .../modeling/section/reinfLayer/ReinfLayer.h | 52 + .../section/reinfLayer/StraightReinfLayer.cpp | 87 + .../section/reinfLayer/StraightReinfLayer.h | 51 + 141 files changed, 21845 insertions(+), 4764 deletions(-) create mode 100644 SRC/runtime/commands/analysis/modal/CMakeLists.txt create mode 100644 SRC/runtime/commands/analysis/modal/DomainModalProperties.cpp create mode 100644 SRC/runtime/commands/analysis/modal/DomainModalProperties.h create mode 100644 SRC/runtime/commands/analysis/modal/ResponseSpectrumAnalysis.cpp create mode 100644 SRC/runtime/commands/analysis/modal/ResponseSpectrumAnalysis.h create mode 100644 SRC/runtime/commands/analysis/modal/modal.cpp create mode 100644 SRC/runtime/commands/analysis/spectrum.cpp create mode 100644 SRC/runtime/commands/interpreter.h create mode 100644 SRC/runtime/commands/modeling/CMakeLists.txt create mode 100644 SRC/runtime/commands/modeling/element/brick.cpp create mode 100644 SRC/runtime/commands/modeling/element/plane.cpp create mode 100644 SRC/runtime/commands/modeling/element/shells.cpp create mode 100644 SRC/runtime/commands/modeling/element/truss.cpp create mode 100644 SRC/runtime/commands/modeling/material/CMakeLists.txt create mode 100644 SRC/runtime/commands/modeling/material/boucwen.cpp create mode 100644 SRC/runtime/commands/modeling/material/concrete.cpp create mode 100644 SRC/runtime/commands/modeling/material/elastic.cpp create mode 100644 SRC/runtime/commands/modeling/material/fedeas.cpp create mode 100644 SRC/runtime/commands/modeling/material/isotropy.cpp create mode 100644 SRC/runtime/commands/modeling/material/isotropy.h create mode 100644 SRC/runtime/commands/modeling/material/legacy.cpp create mode 100644 SRC/runtime/commands/modeling/material/material.cpp create mode 100644 SRC/runtime/commands/modeling/material/material.hpp create mode 100644 SRC/runtime/commands/modeling/material/nDMaterial.cpp create mode 100644 SRC/runtime/commands/modeling/material/plastic.cpp create mode 100644 SRC/runtime/commands/modeling/material/shell.cpp create mode 100644 SRC/runtime/commands/modeling/material/wrapper.cpp create mode 100644 SRC/runtime/commands/modeling/section/PlaneSection.h create mode 100644 SRC/runtime/commands/modeling/section/frame.cpp create mode 100644 SRC/runtime/commands/modeling/section/plane.cpp create mode 100644 SRC/runtime/commands/modeling/section/truss.cpp create mode 100644 SRC/runtime/commands/modeling/utilities/Block2D.cpp create mode 100644 SRC/runtime/commands/modeling/utilities/Block2D.h create mode 100644 SRC/runtime/commands/modeling/utilities/Block3D.cpp create mode 100644 SRC/runtime/commands/modeling/utilities/Block3D.h create mode 100644 SRC/runtime/commands/modeling/utilities/blockND.cpp create mode 100644 SRC/runtime/commands/parallel/communicate.cpp create mode 100644 SRC/runtime/commands/parallel/machine.cpp create mode 100644 SRC/runtime/commands/parallel/partition.cpp create mode 100644 SRC/runtime/parsing/CMakeLists.txt create mode 100644 SRC/runtime/runtime/Notes.md create mode 100644 SRC/runtime/runtime/modeling/section/CMakeLists.txt create mode 100644 SRC/runtime/runtime/modeling/section/FiberSectionBuilder.h create mode 100644 SRC/runtime/runtime/modeling/section/cell/CMakeLists.txt create mode 100644 SRC/runtime/runtime/modeling/section/cell/Cell.h create mode 100644 SRC/runtime/runtime/modeling/section/cell/CircSectionCell.cpp create mode 100644 SRC/runtime/runtime/modeling/section/cell/CircSectionCell.h create mode 100644 SRC/runtime/runtime/modeling/section/cell/QuadCell.cpp create mode 100644 SRC/runtime/runtime/modeling/section/cell/QuadCell.h create mode 100644 SRC/runtime/runtime/modeling/section/patch/CMakeLists.txt create mode 100644 SRC/runtime/runtime/modeling/section/patch/CircPatch.cpp create mode 100644 SRC/runtime/runtime/modeling/section/patch/CircPatch.h create mode 100644 SRC/runtime/runtime/modeling/section/patch/Patch.h create mode 100644 SRC/runtime/runtime/modeling/section/patch/QuadPatch.cpp create mode 100644 SRC/runtime/runtime/modeling/section/patch/QuadPatch.h create mode 100644 SRC/runtime/runtime/modeling/section/reinfLayer/CMakeLists.txt create mode 100644 SRC/runtime/runtime/modeling/section/reinfLayer/CircReinfLayer.cpp create mode 100644 SRC/runtime/runtime/modeling/section/reinfLayer/CircReinfLayer.h create mode 100644 SRC/runtime/runtime/modeling/section/reinfLayer/ReinfLayer.h create mode 100644 SRC/runtime/runtime/modeling/section/reinfLayer/StraightReinfLayer.cpp create mode 100644 SRC/runtime/runtime/modeling/section/reinfLayer/StraightReinfLayer.h diff --git a/SRC/runtime/CMakeLists.txt b/SRC/runtime/CMakeLists.txt index c45463de26..a9e9f06592 100644 --- a/SRC/runtime/CMakeLists.txt +++ b/SRC/runtime/CMakeLists.txt @@ -6,18 +6,23 @@ #============================================================================== add_library(OpenSeesRT SHARED) +add_library(OpenSeesRT_Static STATIC) + target_sources(OpenSeesRT PRIVATE "OpenSeesRT.cpp") +target_sources(OpenSeesRT_Static PRIVATE "OpenSeesRT.cpp") target_compile_definitions(OpenSeesRT PUBLIC USE_TCL_STUBS _TCL85) -set_property(TARGET OpenSeesRT PROPERTY POSITION_INDEPENDENT_CODE 1) +set_property(TARGET OpenSeesRT PROPERTY POSITION_INDEPENDENT_CODE 1) target_compile_options(OPS_Runtime PRIVATE - "$<$>:-Wextra>" - "$<$>:-Wpedantic>" - "$<$:/W4>" +# "$<$>:-Wextra>" +# "$<$>:-Wpedantic>" + "$<$>:-Wno-unused-parameter>" + "$<$:/W3>" + "$<$:/bigobj>" + "$<$:/wd4100>" ) -target_include_directories(OPS_Runtime PUBLIC - ./api/ +target_include_directories(OPS_Runtime PUBLIC ${OPS_SRC_DIR}/runtime/commands ${OPS_SRC_DIR}/runtime/parsing/ ${OPS_SRC_DIR}/runtime/commands/modeling @@ -27,11 +32,8 @@ target_link_libraries(OPS_Runtime PRIVATE G3 OPS_Algorithm) add_subdirectory(commands) add_subdirectory(runtime) +add_subdirectory(parsing) -target_sources(OPS_Runtime PRIVATE - "runtime/G3_Runtime.cpp" - "parsing/InterpreterAPI.cpp" -) if (DEFINED OPENSEESRT_VERSION) set_property( @@ -50,27 +52,20 @@ if (${TCL_INCLUDE_PATH}) target_include_directories(OPS_Runtime PUBLIC ${TCL_INCLUDE_PATH}) endif() -target_link_libraries(OpenSeesRT PRIVATE OPS_Runtime OPS_Renderer OPS_Algorithm ${TCL_STUB_LIBRARY}) - -# -# Python -# -find_package(Python COMPONENTS Interpreter Development) -find_package(pybind11 CONFIG) -if (${pybind11_FOUND} AND NOT DEFINED NoOpenSeesPyRT) - message(" :: Configuring Pyton extension") - add_subdirectory(python) -endif() - -# -# Parallel -# -if (FALSE) # (MPI_FOUND) - add_library(OpenSeesRT_Parallel SHARED) - add_subdirectory(commands/parallel) - target_sources(OpenSeesRT_Parallel PRIVATE OpenSeesPRT.cpp) -endif() +target_link_libraries(OpenSeesRT + PRIVATE + OPS_Runtime + OPS_Renderer + OPS_Algorithm + ${TCL_STUB_LIBRARY} +) +target_link_libraries(OpenSeesRT_Static + PUBLIC + OPS_Runtime + OPS_Renderer + OPS_Algorithm +) if (EXISTS ${CMAKE_CURRENT_LIST_DIR}/packages/UCSD_CompGeoMech/CMakeLists.txt) add_subdirectory(packages/UCSD_CompGeoMech) diff --git a/SRC/runtime/OpenSeesRT.cpp b/SRC/runtime/OpenSeesRT.cpp index 444fe3b119..114d8ed2a5 100644 --- a/SRC/runtime/OpenSeesRT.cpp +++ b/SRC/runtime/OpenSeesRT.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // This file contains functions that are required by Tcl to load the // OpenSeesRT library. // @@ -12,7 +13,7 @@ #endif // #include -#include "G3_Runtime.h" +#include "runtime/G3_Runtime.h" #include #include #include @@ -28,8 +29,9 @@ #else # include #endif -// -extern int OpenSeesAppInit(Tcl_Interp *interp); + +// interpreter/runtime.cpp +extern int Init_OpenSees(Tcl_Interp *interp); extern void G3_InitTclSequentialAPI(Tcl_Interp* interp); extern int init_g3_tcl_utils(Tcl_Interp*); @@ -53,7 +55,7 @@ version(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) // extern "C" int #ifdef _WIN32 -__declspec(dllexport) // DLLEXPORT +__declspec(dllexport) #endif Openseesrt_Init(Tcl_Interp *interp) { @@ -68,7 +70,7 @@ Openseesrt_Init(Tcl_Interp *interp) Tcl_SetAssocData(interp, "G3_Runtime", NULL, (ClientData)rt); // Initialize OpenSees - OpenSeesAppInit(interp); + Init_OpenSees(interp); G3_InitTclSequentialAPI(interp); // Add sequential API init_g3_tcl_utils(interp); // Add utility commands (linspace, range, etc.) diff --git a/SRC/runtime/commands/CMakeLists.txt b/SRC/runtime/commands/CMakeLists.txt index e048ed6c97..325d796921 100644 --- a/SRC/runtime/commands/CMakeLists.txt +++ b/SRC/runtime/commands/CMakeLists.txt @@ -18,15 +18,28 @@ target_sources(OPS_Runtime PRIVATE "modeling/nodes.cpp" "modeling/constraint.cpp" "modeling/geomTransf.cpp" + "modeling/element.cpp" - "modeling/nDMaterial.cpp" + "modeling/element/frames.cpp" + "modeling/element/shells.cpp" + "modeling/element/brick.cpp" + "modeling/element/plane.cpp" + "modeling/element/truss.cpp" + "modeling/section.cpp" + "modeling/section/plane.cpp" + "modeling/section/frame.cpp" + "modeling/section/truss.cpp" + "modeling/uniaxialMaterial.cpp" "modeling/uniaxial.cpp" + "modeling/printing.cpp" - "modeling/blockND.cpp" - "modeling/Block2D.cpp" - "modeling/Block3D.cpp" + + "modeling/utilities/blockND.cpp" + "modeling/utilities/Block2D.cpp" + "modeling/utilities/Block3D.cpp" + "modeling/invoking/invoke.cpp" "modeling/invoking/invoke_uniaxial.cpp" "modeling/invoking/invoke_section.cpp" @@ -41,6 +54,7 @@ target_sources(OPS_Runtime PRIVATE "analysis/ctest.cpp" "analysis/solver.cpp" "analysis/solver.hpp" + "analysis/sensitivity.cpp" # Utilities "utilities/utilities.cpp" @@ -49,4 +63,9 @@ target_sources(OPS_Runtime PRIVATE ) add_subdirectory(domain) +add_subdirectory(parallel) +add_subdirectory(analysis/modal) +add_subdirectory(modeling) +target_include_directories(OPS_Runtime PUBLIC ${CMAKE_CURRENT_LIST_DIR}) +target_include_directories(OPS_Runtime PUBLIC ${CMAKE_CURRENT_LIST_DIR}/modeling) diff --git a/SRC/runtime/commands/analysis/algorithm.cpp b/SRC/runtime/commands/analysis/algorithm.cpp index 7bc0528c66..00ca755258 100644 --- a/SRC/runtime/commands/analysis/algorithm.cpp +++ b/SRC/runtime/commands/analysis/algorithm.cpp @@ -1,14 +1,17 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // // Description: This file implements commands that allow for construction // and interaction with Algorithm objects. Any command which requires // access to specific Algorithm types (from the standard library) should // be implemented here. // +#include #include #include #include @@ -16,6 +19,7 @@ #include #include #include +#include #include "BasicAnalysisBuilder.h" // Algorithms @@ -25,8 +29,6 @@ #include #include #include -#include -#include #include #include @@ -45,6 +47,8 @@ #include #include #include + + #include class G3_Runtime; @@ -55,29 +59,33 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, typedef EquiSolnAlgo *(TclEquiSolnAlgo)(ClientData, Tcl_Interp *, int, TCL_Char **); -OPS_Routine OPS_NewtonRaphsonAlgorithm; OPS_Routine OPS_ExpressNewton; -OPS_Routine OPS_ModifiedNewton; OPS_Routine OPS_NewtonHallM; TclEquiSolnAlgo G3Parse_newEquiSolnAlgo; -TclEquiSolnAlgo G3Parse_newSecantNewtonAlgorithm; -TclEquiSolnAlgo G3_newNewtonLineSearch; -static TclEquiSolnAlgo G3_newKrylovNewton; static TclEquiSolnAlgo G3_newBroyden; static TclEquiSolnAlgo G3_newBFGS; Tcl_CmdProc TclCommand_newLinearAlgorithm; Tcl_CmdProc TclCommand_newNewtonRaphson; -Tcl_CmdProc TclCommand_newModifiedNewton; Tcl_CmdProc TclCommand_newNewtonHallM; +Tcl_CmdProc TclCommand_newAcceleratedNewton; +static Tcl_CmdProc TclCommand_newNewtonLineSearch; namespace OpenSees { std::unordered_map Algorithms { - {"Linear", TclCommand_newLinearAlgorithm}, - {"Newton", TclCommand_newNewtonRaphson}, - {"NewtonHall", TclCommand_newNewtonHallM}, - {"ModifiedNewton", TclCommand_newModifiedNewton} + {"Linear", TclCommand_newLinearAlgorithm}, + + {"Newton", TclCommand_newNewtonRaphson}, + {"ModifiedNewton", TclCommand_newNewtonRaphson}, + {"NewtonHall", TclCommand_newNewtonHallM}, + {"NewtonLineSearch", TclCommand_newNewtonLineSearch}, + + {"SecantNewton", TclCommand_newAcceleratedNewton}, + {"MillerAccelerator", TclCommand_newAcceleratedNewton}, + {"KrylovNewton", TclCommand_newAcceleratedNewton}, + {"PeriodicNewton", TclCommand_newAcceleratedNewton}, + {"RaphsonNewton", TclCommand_newAcceleratedNewton}, }; } @@ -85,7 +93,7 @@ std::unordered_map Algorithms { // command invoked to allow the SolnAlgorithm object to be built // int -TclCommand_specifyAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, +TclCommand_specifyAlgorithm(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { @@ -94,14 +102,16 @@ TclCommand_specifyAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, // Make sure at least one other argument to contain numberer if (argc < 2) { - opserr << G3_ERROR_PROMPT << "Need to specify an Algorithm type.\n"; + opserr << OpenSees::PromptValueError << "Need to specify an Algorithm type.\n"; return TCL_ERROR; } + auto command = OpenSees::Algorithms.find(std::string{argv[1]}); if (command != OpenSees::Algorithms.end()) return (*command->second)(clientData, interp, argc, argv); + OPS_ResetInputNoBuilder(nullptr, interp, 2, argc, argv, nullptr); EquiSolnAlgo *theNewAlgo = G3Parse_newEquiSolnAlgo(clientData, interp, argc, argv); @@ -119,7 +129,7 @@ TclCommand_specifyAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, EquiSolnAlgo * -G3Parse_newEquiSolnAlgo(ClientData clientData, Tcl_Interp *interp, int argc, +G3Parse_newEquiSolnAlgo(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { @@ -130,66 +140,48 @@ G3Parse_newEquiSolnAlgo(ClientData clientData, Tcl_Interp *interp, int argc, else if (strcmp(argv[1], "BFGS") == 0) return G3_newBFGS(clientData, interp, argc, argv); - else if (strcmp(argv[1], "SecantNewton") == 0) - return G3Parse_newSecantNewtonAlgorithm(clientData, interp, argc, argv); - - else if (strcmp(argv[1], "NewtonLineSearch") == 0) - return G3_newNewtonLineSearch(clientData, interp, argc, argv); - - else if (strcmp(argv[1], "KrylovNewton") == 0) - return G3_newKrylovNewton(clientData, interp, argc, argv); - - EquiSolnAlgo *theNewAlgo = nullptr; G3_Runtime *rt = G3_getRuntime(interp); - if (strcmp(argv[1], "Newton") == 0) { - void *theNewtonAlgo = OPS_NewtonRaphsonAlgorithm(rt, argc, argv); - theNewAlgo = (EquiSolnAlgo *)theNewtonAlgo; - } - - else if ((strcmp(argv[1], "NewtonHallM") == 0) || + if ((strcmp(argv[1], "NewtonHallM") == 0) || (strcmp(argv[1], "NewtonHall") == 0)) { void *theNewtonAlgo = OPS_NewtonHallM(rt, argc, argv); theNewAlgo = (EquiSolnAlgo *)theNewtonAlgo; } - else if (strcmp(argv[1], "ModifiedNewton") == 0) { - void *theNewtonAlgo = OPS_ModifiedNewton(rt, argc, argv); - theNewAlgo = (EquiSolnAlgo *)theNewtonAlgo; - } - else if (strcmp(argv[1], "ExpressNewton") == 0) { void *theNewtonAlgo = OPS_ExpressNewton(rt, argc, argv); theNewAlgo = (EquiSolnAlgo *)theNewtonAlgo; } else { - opserr << G3_ERROR_PROMPT << "No EquiSolnAlgo of type '" << argv[1] << "' exists\n"; + opserr << OpenSees::PromptValueError + << "Unknown algorithm type '" << argv[1] << "'\n"; return nullptr; } return theNewAlgo; } + int -TclCommand_newLinearAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, +TclCommand_newLinearAlgorithm(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; assert(builder != nullptr); - int formTangent = CURRENT_TANGENT; + IncrementalIntegrator::TangentFlagType correction_tangent = CURRENT_TANGENT; int factorOnce = 0; int count = 2; while (count < argc) { if ((strcmp(argv[count], "-secant") == 0) || (strcmp(argv[count], "-Secant") == 0)) { - formTangent = CURRENT_SECANT; + correction_tangent = CURRENT_SECANT; } else if ((strcmp(argv[count], "-initial") == 0) || (strcmp(argv[count], "-Initial") == 0)) { - formTangent = INITIAL_TANGENT; + correction_tangent = INITIAL_TANGENT; } else if ((strcmp(argv[count], "-factorOnce") == 0) || (strcmp(argv[count], "-FactorOnce") == 0)) { @@ -198,43 +190,51 @@ TclCommand_newLinearAlgorithm(ClientData clientData, Tcl_Interp *interp, int arg count++; } - builder->set(new Linear(formTangent, factorOnce)); + builder->set(new Linear(correction_tangent, factorOnce)); return TCL_OK; } int -TclCommand_newNewtonRaphson(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char**const argv) +TclCommand_newNewtonRaphson(ClientData clientData, + Tcl_Interp* interp, + Tcl_Size argc, TCL_Char**const argv) { BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; assert(builder != nullptr); - int formTangent = CURRENT_TANGENT; + IncrementalIntegrator::TangentFlagType + correction_tangent = CURRENT_TANGENT, + prediction_tangent = CURRENT_TANGENT; double iFactor = 0; double cFactor = 1; for (int i=2; i= 2) { @@ -251,55 +251,24 @@ TclCommand_newNewtonRaphson(ClientData clientData, Tcl_Interp* interp, int argc, } } - builder->set(new NewtonRaphson(formTangent, iFactor, cFactor)); - - return TCL_OK; -} - - -int -TclCommand_newModifiedNewton(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char**const argv) -{ - BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; - assert(builder != nullptr); - - int formTangent = CURRENT_TANGENT; - double iFactor = 0; - double cFactor = 1; - - for (int i=2; i= 2) { - if (Tcl_GetDouble(interp, argv[i+1], &iFactor) != TCL_OK) { - opserr << "WARNING invalid data reading ifactor\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i+2], &cFactor) != TCL_OK) { - opserr << "WARNING invalid data reading cfactor\n"; - return TCL_ERROR; - } - i += 2; - } - } + // + // + if (strcmp(argv[1], "Newton") == 0 || + strcmp(argv[1], "NewtonRaphson") == 0) { + builder->set(new NewtonRaphson(prediction_tangent, + correction_tangent, iFactor, cFactor)); + return TCL_OK; } - - auto algorithm = new ModifiedNewton(formTangent, iFactor, cFactor); - builder->set(algorithm); - return TCL_OK; + else if (strcmp(argv[1], "ModifiedNewton") == 0) { + builder->set(new ModifiedNewton(correction_tangent, iFactor, cFactor)); + return TCL_OK; + } + return TCL_ERROR; } + int -TclCommand_newNewtonHallM(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char**const argv) +TclCommand_newNewtonHallM(ClientData clientData, Tcl_Interp* interp, Tcl_Size argc, TCL_Char**const argv) { BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; assert(builder != nullptr); @@ -360,118 +329,71 @@ TclCommand_newNewtonHallM(ClientData clientData, Tcl_Interp* interp, int argc, T -EquiSolnAlgo * -G3Parse_newSecantNewtonAlgorithm(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; - - ConvergenceTest *theTest = builder->getConvergenceTest(); - - if (theTest == nullptr) { - opserr << G3_ERROR_PROMPT << "No ConvergenceTest yet specified\n"; - return nullptr; - } - - int incrementTangent = CURRENT_TANGENT; - int iterateTangent = CURRENT_TANGENT; - int maxDim = 3; - int numTerms = 2; - for (int i = 2; i < argc; ++i) { - if (strcmp(argv[i], "-iterate") == 0 && i + 1 < argc) { - i++; - if (strcmp(argv[i], "current") == 0) - iterateTangent = CURRENT_TANGENT; - if (strcmp(argv[i], "initial") == 0) - iterateTangent = INITIAL_TANGENT; - if (strcmp(argv[i], "noTangent") == 0) - iterateTangent = NO_TANGENT; - - } else if (strcmp(argv[i], "-increment") == 0 && i + 1 < argc) { - i++; - if (strcmp(argv[i], "current") == 0) - incrementTangent = CURRENT_TANGENT; - if (strcmp(argv[i], "initial") == 0) - incrementTangent = INITIAL_TANGENT; - if (strcmp(argv[i], "noTangent") == 0) - incrementTangent = NO_TANGENT; - - } else if (strcmp(argv[i], "-maxDim") == 0 && i + 1 < argc) { - i++; - maxDim = atoi(argv[i]); - - } else if (strcmp(argv[i], "-numTerms") == 0) { - if (i+1 < argc) - numTerms = atoi(argv[++i]); - else { - opserr << G3_ERROR_PROMPT << "Flag -numTerms requires follow up argument\n"; - return nullptr; - } - } - } - - Accelerator *theAccel = nullptr; - if (numTerms <= 1) - theAccel = new SecantAccelerator1(maxDim, iterateTangent); - if (numTerms >= 3) - theAccel = new SecantAccelerator3(maxDim, iterateTangent); - if (numTerms == 2) - theAccel = new SecantAccelerator2(maxDim, iterateTangent); - return new AcceleratedNewton(*theTest, theAccel, incrementTangent); -} - static EquiSolnAlgo * -G3_newBFGS(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +G3_newBFGS(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); - BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; - - ConvergenceTest *theTest = builder->getConvergenceTest(); - if (theTest == nullptr) { - opserr << G3_ERROR_PROMPT << "No ConvergenceTest yet specified\n"; - return nullptr; - } - - - int formTangent = CURRENT_TANGENT; + int correction_tangent = CURRENT_TANGENT; int count = -1; for (int i = 2; i < argc; ++i) { if (strcmp(argv[i], "-secant") == 0) { - formTangent = CURRENT_SECANT; - } else if (strcmp(argv[i], "-initial") == 0) { - formTangent = INITIAL_TANGENT; - } else if (strcmp(argv[i++], "-count") == 0 && i < argc) { - count = atoi(argv[i]); + correction_tangent = CURRENT_SECANT; + } + else if (strcmp(argv[i], "-initial") == 0) { + correction_tangent = INITIAL_TANGENT; + } + + else if (strcmp(argv[i++], "-count") == 0 && i < argc) { + if (i >= argc) { + opserr << OpenSees::PromptValueError + << "Flag -count requires follow up argument\n"; + return nullptr; + } + if (Tcl_GetInt(interp, argv[i], &count) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Invalid value for -count: " << argv[i] << "\n"; + return nullptr; + } } } EquiSolnAlgo *theNewAlgo = nullptr; if (count == -1) - theNewAlgo = new BFGS(*theTest, formTangent); + theNewAlgo = new BFGS(correction_tangent, 10); else - theNewAlgo = new BFGS(*theTest, formTangent, count); + theNewAlgo = new BFGS(correction_tangent, count); return theNewAlgo; } -EquiSolnAlgo * -G3_newNewtonLineSearch(ClientData clientData, Tcl_Interp *interp, int argc, +static int +TclCommand_newNewtonLineSearch(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { - assert(clientData != nullptr); BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; - ConvergenceTest *theTest = builder->getConvergenceTest(); - - if (theTest == nullptr) { - opserr << G3_ERROR_PROMPT << " No ConvergenceTest yet specified\n"; - return nullptr; - } - - int count = 2; + enum class Positions: int { + EndRequired, + Tolerance, + End, + MaxIter, + MaxEta, + MinEta, + PFlag, + TypeSearch + }; + + enum class LineSearchType: int { + InitialInterpolated, + Bisection, + Secant, + RegulaFalsi + }; + + ArgumentTracker tracker; + std::set positions; // set some default variable double tol = 0.8; @@ -481,53 +403,151 @@ G3_newNewtonLineSearch(ClientData clientData, Tcl_Interp *interp, int argc, int pFlag = 1; int typeSearch = 0; - while (count < argc) { - if (strcmp(argv[count], "-tol") == 0) { - count++; - if (Tcl_GetDouble(interp, argv[count], &tol) != TCL_OK) - return nullptr; - count++; - - } else if (strcmp(argv[count], "-maxIter") == 0) { - count++; - if (Tcl_GetInt(interp, argv[count], &maxIter) != TCL_OK) - return nullptr; - - count++; - } else if (strcmp(argv[count], "-pFlag") == 0) { - count++; - if (Tcl_GetInt(interp, argv[count], &pFlag) != TCL_OK) - return nullptr; - count++; - - } else if (strcmp(argv[count], "-minEta") == 0) { - count++; - if (Tcl_GetDouble(interp, argv[count], &minEta) != TCL_OK) - return nullptr; - count++; + for (int i=2; i= argc) { + opserr << OpenSees::PromptValueError + << "Flag -tol requires follow up argument\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &tol) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Invalid value for -tol: " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Tolerance); + } + else if (strcmp(argv[i], "-maxIter") == 0) { + if (++i >= argc) { + opserr << OpenSees::PromptValueError + << "Flag -maxIter requires follow up argument\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[i], &maxIter) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Invalid value for -maxIter: " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::MaxIter); + + } else if (strcmp(argv[i], "-pFlag") == 0) { + if (++i >= argc) { + opserr << OpenSees::PromptValueError + << "Flag -pFlag requires follow up argument" + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[i], &pFlag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Invalid value for -pFlag: " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::PFlag); - } else if (strcmp(argv[count], "-maxEta") == 0) { - count++; - if (Tcl_GetDouble(interp, argv[count], &maxEta) != TCL_OK) - return nullptr; - count++; + } else if (strcmp(argv[i], "-minEta") == 0) { + if (++i >= argc) { + opserr << OpenSees::PromptValueError + << "Flag -minEta requires follow up argument\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &minEta) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Invalid value for -minEta: " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::MinEta); - } else if (strcmp(argv[count], "-type") == 0) { - count++; - if (strcmp(argv[count], "Bisection") == 0) + } else if (strcmp(argv[i], "-maxEta") == 0) { + if (++i >= argc) { + opserr << OpenSees::PromptValueError + << "Flag -maxEta requires follow up argument\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &maxEta) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Invalid value for -maxEta: " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::MaxEta); + } + + else if (strcmp(argv[i], "-type") == 0) { + if (++i >= argc) { + opserr << OpenSees::PromptValueError + << "Flag -type requires follow up argument\n"; + return TCL_ERROR; + } + if (strcmp(argv[i], "Bisection") == 0) { typeSearch = 1; - else if (strcmp(argv[count], "Secant") == 0) + } else if (strcmp(argv[i], "Secant") == 0) { typeSearch = 2; - else if (strcmp(argv[count], "RegulaFalsi") == 0) + } else if (strcmp(argv[i], "RegulaFalsi") == 0 || + strcmp(argv[i], "LinearInterpolated") == 0) { typeSearch = 3; - else if (strcmp(argv[count], "LinearInterpolated") == 0) - typeSearch = 3; - else if (strcmp(argv[count], "InitialInterpolated") == 0) + } else if (strcmp(argv[i], "InitialInterpolated") == 0) { typeSearch = 0; - count++; + } else { + opserr << OpenSees::PromptValueError + << "Unknown line search type: " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::TypeSearch); + } + else { + positions.insert(i); + } + } - } else - count++; + for (int i : positions) { + if (tracker.current() == Positions::EndRequired) { + tracker.increment(); + } + switch (tracker.current()) { + case Positions::Tolerance: + if (Tcl_GetDouble(interp, argv[i], &tol) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Invalid value for -tol: " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Tolerance); + break; + case Positions::MaxIter: + if (Tcl_GetInt(interp, argv[i], &maxIter) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Invalid value for -maxIter: " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::MaxIter); + break; + case Positions::PFlag: + if (Tcl_GetInt(interp, argv[i], &pFlag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Invalid value for -pFlag: " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::PFlag); + break; + case Positions::MinEta: + if (Tcl_GetDouble(interp, argv[i], &minEta) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Invalid value for -minEta: " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::MinEta); + break; + case Positions::MaxEta: + if (Tcl_GetDouble(interp, argv[i], &maxEta) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Invalid value for -maxEta: " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::MaxEta); + break; + default: + opserr << OpenSees::PromptValueError + << "Unexpected argument: " << argv[i] << "\n"; + return TCL_ERROR; + } } LineSearch *theLineSearch = nullptr; @@ -541,218 +561,176 @@ G3_newNewtonLineSearch(ClientData clientData, Tcl_Interp *interp, int argc, theLineSearch = new RegulaFalsiLineSearch(tol, maxIter, minEta, maxEta, pFlag); - EquiSolnAlgo *theNewAlgo = nullptr; - theNewAlgo = new NewtonLineSearch(*theTest, theLineSearch); - return theNewAlgo; + builder->set(new NewtonLineSearch(theLineSearch)); + return TCL_OK; } -static EquiSolnAlgo * -G3_newKrylovNewton(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) + + +int +TclCommand_newAcceleratedNewton(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, + TCL_Char ** const argv) { assert(clientData != nullptr); BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; - ConvergenceTest *theTest = builder->getConvergenceTest(); - - if (theTest == nullptr) { - opserr << G3_ERROR_PROMPT << "No ConvergenceTest yet specified\n"; - return nullptr; - } - - int incrementTangent = CURRENT_TANGENT; - int iterateTangent = CURRENT_TANGENT; - int maxDim = 3; + + IncrementalIntegrator::TangentFlagType + incrementTangent = CURRENT_TANGENT, + correction_tangent = CURRENT_TANGENT; + + int maxDim = 3; + int numTerms = 2; // Default for SecantAccelerator + double iFactor = 0.0; // Initial factor for RaphsonAccelerator + double cFactor = 1.0; // Current factor for RaphsonAccelerator + + enum class AcceleratorType { + Miller, + Secant, + Raphson, + Krylov, + Periodic + } type = AcceleratorType::Krylov; for (int i = 2; i < argc; ++i) { - if (strcmp(argv[i], "-iterate") == 0 && i + 1 < argc) { - i++; - if (strcmp(argv[i], "current") == 0) - iterateTangent = CURRENT_TANGENT; - if (strcmp(argv[i], "initial") == 0) - iterateTangent = INITIAL_TANGENT; - if (strcmp(argv[i], "noTangent") == 0) - iterateTangent = NO_TANGENT; - - } else if (strcmp(argv[i], "-increment") == 0 && i + 1 < argc) { - i++; - if (strcmp(argv[i], "current") == 0) + if ((strcmp(argv[i], "-iterate") == 0) || + (strcmp(argv[i], "-correction") == 0)) { + if (++i >= argc) { + opserr << OpenSees::PromptValueError + << "Flag -iterate requires follow up argument" + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } + if ((strcmp(argv[i], "current") == 0) || (strcmp(argv[i], "tangent") == 0)) + correction_tangent = CURRENT_TANGENT; + else if (strcmp(argv[i], "initial") == 0) + correction_tangent = INITIAL_TANGENT; + else if ((strcmp(argv[i], "noTangent") == 0) || strcmp(argv[i], "None") == 0) + correction_tangent = NO_TANGENT; + } + + else if ((strcmp(argv[i], "-increment") == 0) || + (strcmp(argv[i], "-prediction") == 0)) { + if (++i >= argc) { + opserr << OpenSees::PromptValueError + << "Flag -increment requires follow up argument" + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } + if ((strcmp(argv[i], "current") == 0) || (strcmp(argv[i], "tangent") == 0)) incrementTangent = CURRENT_TANGENT; - if (strcmp(argv[i], "initial") == 0) + else if (strcmp(argv[i], "initial") == 0) incrementTangent = INITIAL_TANGENT; - if (strcmp(argv[i], "noTangent") == 0) + else if ((strcmp(argv[i], "noTangent") == 0) || strcmp(argv[i], "None") == 0) incrementTangent = NO_TANGENT; - - } else if (strcmp(argv[i], "-maxDim") == 0 && i + 1 < argc) { + } + + else if (strcmp(argv[i], "-maxDim") == 0 && i + 1 < argc) { i++; - maxDim = atoi(argv[i]); + if (i >= argc || Tcl_GetInt(interp, argv[i], &maxDim) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "Flag -maxDim requires follow up argument" + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } } - } - - Accelerator *theAccel = new KrylovAccelerator(maxDim, iterateTangent); - - EquiSolnAlgo *theNewAlgo = new AcceleratedNewton(*theTest, theAccel, incrementTangent); - return theNewAlgo; -} -EquiSolnAlgo * -G3_newRaphsonNewton(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; - ConvergenceTest *theTest = builder->getConvergenceTest(); - - if (theTest == nullptr) { - opserr << G3_ERROR_PROMPT << "No ConvergenceTest yet specified\n"; - return nullptr; - } - - int incrementTangent = CURRENT_TANGENT; - int iterateTangent = CURRENT_TANGENT; - for (int i = 2; i < argc; ++i) { - if (strcmp(argv[i], "-iterate") == 0 && i + 1 < argc) { + else if (strcmp(argv[i], "-accelerator") == 0 && i + 1 < argc) { i++; - if (strcmp(argv[i], "current") == 0) - iterateTangent = CURRENT_TANGENT; - if (strcmp(argv[i], "initial") == 0) - iterateTangent = INITIAL_TANGENT; - if (strcmp(argv[i], "noTangent") == 0) - iterateTangent = NO_TANGENT; - - } else if (strcmp(argv[i], "-increment") == 0 && i + 1 < argc) { - i++; - if (strcmp(argv[i], "current") == 0) - incrementTangent = CURRENT_TANGENT; - if (strcmp(argv[i], "initial") == 0) - incrementTangent = INITIAL_TANGENT; - if (strcmp(argv[i], "noTangent") == 0) - incrementTangent = NO_TANGENT; + if (i >= argc) { + opserr << OpenSees::PromptValueError + << "Flag -accelerator requires follow up argument" + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } + if (strcmp(argv[i], "Miller") == 0) { + type = AcceleratorType::Miller; + } else if (strcmp(argv[i], "Secant") == 0 || strcmp(argv[i], "SecantNewton") == 0) { + type = AcceleratorType::Secant; + } else if (strcmp(argv[i], "Raphson") == 0 || strcmp(argv[i], "RaphsonNewton") == 0) { + type = AcceleratorType::Raphson; + } else if (strcmp(argv[i], "Krylov") == 0 || strcmp(argv[i], "KrylovNewton") == 0) { + type = AcceleratorType::Krylov; + } else if (strcmp(argv[i], "Periodic") == 0 || strcmp(argv[i], "PeriodicNewton") == 0) { + type = AcceleratorType::Periodic; + } else { + opserr << OpenSees::PromptValueError + << "Unknown accelerator '" << argv[i] << "'" + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } } - } - - Accelerator *theAccel; - theAccel = new RaphsonAccelerator(iterateTangent); - - EquiSolnAlgo *theNewAlgo = new AcceleratedNewton(*theTest, theAccel, incrementTangent); - return theNewAlgo; -} -EquiSolnAlgo * -G3_newMillerNewton(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; - ConvergenceTest *theTest = builder->getConvergenceTest(); - - if (theTest == nullptr) { - opserr << G3_ERROR_PROMPT << "No ConvergenceTest yet specified\n"; - return nullptr; - } - - int incrementTangent = CURRENT_TANGENT; - int iterateTangent = CURRENT_TANGENT; - int maxDim = 3; - - for (int i = 2; i < argc; ++i) { - if (strcmp(argv[i], "-iterate") == 0 && i + 1 < argc) { - i++; - if (strcmp(argv[i], "current") == 0) - iterateTangent = CURRENT_TANGENT; - if (strcmp(argv[i], "initial") == 0) - iterateTangent = INITIAL_TANGENT; - if (strcmp(argv[i], "noTangent") == 0) - iterateTangent = NO_TANGENT; - } else if (strcmp(argv[i], "-increment") == 0 && i + 1 < argc) { - i++; - if (strcmp(argv[i], "current") == 0) - incrementTangent = CURRENT_TANGENT; - if (strcmp(argv[i], "initial") == 0) - incrementTangent = INITIAL_TANGENT; - if (strcmp(argv[i], "noTangent") == 0) - incrementTangent = NO_TANGENT; - } else if (strcmp(argv[i], "-maxDim") == 0 && i + 1 < argc) { - i++; - maxDim = atoi(argv[i]); + // SecantAccelerator + else if (strcmp(argv[i], "-numTerms") == 0) { + if (i+1 < argc) + numTerms = atoi(argv[++i]); + else { + opserr << OpenSees::PromptValueError + << "Flag -numTerms requires follow up argument" + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } } } - Accelerator *theAccel = new MillerAccelerator(maxDim, 0.01, iterateTangent); + Accelerator *accel = nullptr; + if (strcmp(argv[1], "MillerNewton") == 0) { + accel = new MillerAccelerator(maxDim, 0.01, correction_tangent); + } - EquiSolnAlgo *theNewAlgo = new AcceleratedNewton(*theTest, theAccel, incrementTangent); - return theNewAlgo; -} + else if (type == AcceleratorType::Secant || + strcmp(argv[1], "SecantNewton") == 0) { + if (numTerms <= 1) + accel = new SecantAccelerator1(maxDim, correction_tangent); + else if (numTerms >= 3) + accel = new SecantAccelerator3(maxDim, correction_tangent); + else + accel = new SecantAccelerator2(maxDim, correction_tangent); + } -EquiSolnAlgo * -G3_newPeriodicNewton(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; - ConvergenceTest *theTest = builder->getConvergenceTest(); + else if (type == AcceleratorType::Raphson || + strcmp(argv[1], "RaphsonNewton") == 0) { + accel = new RaphsonAccelerator(correction_tangent, iFactor, cFactor); + } - if (theTest == nullptr) { - opserr << G3_ERROR_PROMPT << "No ConvergenceTest yet specified\n"; - return nullptr; + else if (type == AcceleratorType::Krylov || + strcmp(argv[1], "KrylovNewton") == 0) { + accel = new KrylovAccelerator(maxDim, correction_tangent); } - int incrementTangent = CURRENT_TANGENT; - int iterateTangent = CURRENT_TANGENT; - int maxDim = 3; - for (int i = 2; i < argc; ++i) { - if (strcmp(argv[i], "-iterate") == 0 && i + 1 < argc) { - i++; - if (strcmp(argv[i], "current") == 0) - iterateTangent = CURRENT_TANGENT; - if (strcmp(argv[i], "initial") == 0) - iterateTangent = INITIAL_TANGENT; - if (strcmp(argv[i], "noTangent") == 0) - iterateTangent = NO_TANGENT; - - } else if (strcmp(argv[i], "-increment") == 0 && i + 1 < argc) { - i++; - if (strcmp(argv[i], "current") == 0) - incrementTangent = CURRENT_TANGENT; - if (strcmp(argv[i], "initial") == 0) - incrementTangent = INITIAL_TANGENT; - if (strcmp(argv[i], "noTangent") == 0) - incrementTangent = NO_TANGENT; + else if (type == AcceleratorType::Periodic || + strcmp(argv[1], "PeriodicNewton") == 0) { + accel = new PeriodicAccelerator(maxDim, correction_tangent); + } - } else if (strcmp(argv[i], "-maxDim") == 0 && i + 1 < argc) { - i++; - maxDim = atoi(argv[i]); - } + else { + opserr << OpenSees::PromptValueError + << "Unknown accelerator type '" << argv[1] << "'\n"; + return TCL_ERROR; } - Accelerator *theAccel; - theAccel = new PeriodicAccelerator(maxDim, iterateTangent); + builder->set(new AcceleratedNewton(accel, incrementTangent)); - EquiSolnAlgo *theNewAlgo = nullptr; - theNewAlgo = new AcceleratedNewton(*theTest, theAccel, incrementTangent); - return theNewAlgo; + return TCL_OK; } + static EquiSolnAlgo * -G3_newBroyden(ClientData clientData, Tcl_Interp *interp, int argc, +G3_newBroyden(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; - ConvergenceTest *theTest = builder->getConvergenceTest(); - int formTangent = CURRENT_TANGENT; + int correction_tangent = CURRENT_TANGENT; int count = -1; - if (theTest == nullptr) { - opserr << G3_ERROR_PROMPT << "No ConvergenceTest yet specified\n"; - return nullptr; - } for (int i = 2; i < argc; ++i) { if (strcmp(argv[i], "-secant") == 0) { - formTangent = CURRENT_SECANT; + correction_tangent = CURRENT_SECANT; } else if (strcmp(argv[i], "-initial") == 0) { - formTangent = INITIAL_TANGENT; + correction_tangent = INITIAL_TANGENT; } else if (strcmp(argv[i++], "-count") == 0 && i < argc) { count = atoi(argv[i]); @@ -761,9 +739,9 @@ G3_newBroyden(ClientData clientData, Tcl_Interp *interp, int argc, EquiSolnAlgo *theNewAlgo = nullptr; if (count == -1) - theNewAlgo = new Broyden(*theTest, formTangent); + theNewAlgo = new Broyden(correction_tangent); else - theNewAlgo = new Broyden(*theTest, formTangent, count); + theNewAlgo = new Broyden(correction_tangent, count); return theNewAlgo; } @@ -772,22 +750,22 @@ G3_newBroyden(ClientData clientData, Tcl_Interp *interp, int argc, // Other commands // int -printAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, +printAlgorithm(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv, OPS_Stream &output) { assert(clientData != nullptr); BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; - EquiSolnAlgo* theAlgorithm = builder->getAlgorithm(); + const EquiSolnAlgo* theAlgorithm = builder->getAlgorithm(); int eleArg = 0; if (theAlgorithm == nullptr) { - opserr << G3_ERROR_PROMPT << "No algorithm has been set.\n"; + opserr << OpenSees::PromptValueError << "No algorithm has been set.\n"; return TCL_ERROR; } // if just 'print algorithm'- no flag if (argc == 0) { - theAlgorithm->Print(output); + theAlgorithm->Print(output, 0); return TCL_OK; } @@ -803,11 +781,11 @@ printAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, } int -TclCommand_accelCPU(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +TclCommand_accelCPU(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; - EquiSolnAlgo* algo = builder->getAlgorithm(); + const EquiSolnAlgo* algo = builder->getAlgorithm(); if (algo == nullptr) return TCL_ERROR; @@ -817,12 +795,13 @@ TclCommand_accelCPU(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Cha return TCL_OK; } + int -TclCommand_numFact(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +TclCommand_numFact(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); BasicAnalysisBuilder *builder = (BasicAnalysisBuilder *)clientData; - EquiSolnAlgo* algo = builder->getAlgorithm(); + const EquiSolnAlgo* algo = builder->getAlgorithm(); if (algo == nullptr) return TCL_ERROR; @@ -833,7 +812,7 @@ TclCommand_numFact(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char } int -TclCommand_algorithmRecorder(ClientData clientData, Tcl_Interp *interp, int argc, +TclCommand_algorithmRecorder(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { #if 1 @@ -869,10 +848,10 @@ TclCommand_algorithmRecorder(ClientData clientData, Tcl_Interp *interp, int argc } int -TclCommand_totalCPU(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +TclCommand_totalCPU(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); - EquiSolnAlgo *algo = ((BasicAnalysisBuilder *)clientData)->getAlgorithm(); + const EquiSolnAlgo *algo = ((BasicAnalysisBuilder *)clientData)->getAlgorithm(); if (algo == nullptr) return TCL_ERROR; @@ -883,10 +862,10 @@ TclCommand_totalCPU(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Cha } int -TclCommand_solveCPU(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +TclCommand_solveCPU(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); - EquiSolnAlgo *algo = ((BasicAnalysisBuilder *)clientData)->getAlgorithm(); + const EquiSolnAlgo *algo = ((BasicAnalysisBuilder *)clientData)->getAlgorithm(); if (algo == nullptr) @@ -899,10 +878,10 @@ TclCommand_solveCPU(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Cha int -TclCommand_numIter(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +TclCommand_numIter(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); - EquiSolnAlgo *algo = ((BasicAnalysisBuilder *)clientData)->getAlgorithm(); + const EquiSolnAlgo *algo = ((BasicAnalysisBuilder *)clientData)->getAlgorithm(); if (algo == nullptr) return TCL_ERROR; diff --git a/SRC/runtime/commands/analysis/analysis.cpp b/SRC/runtime/commands/analysis/analysis.cpp index ef3cc9da1f..d48c4584dc 100644 --- a/SRC/runtime/commands/analysis/analysis.cpp +++ b/SRC/runtime/commands/analysis/analysis.cpp @@ -1,16 +1,19 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // // Description: This file contains functions that are responsible // for orchestrating an analysis. // #include #include +#include #include -#include +#include #include #include @@ -20,10 +23,6 @@ #include "BasicAnalysisBuilder.h" -#include -#include -#include - #include #include // for printA @@ -44,35 +43,37 @@ #include // numberers -#include -#include +#include +#include #include "analysis.h" -// for response spectrum analysis -extern void OPS_DomainModalProperties(G3_Runtime*); -extern int OPS_ResponseSpectrumAnalysis(G3_Runtime*); +// extern int OPS_ResponseSpectrumAnalysis(G3_Runtime*); extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp *interp, int cArg, int mArg, TCL_Char ** const argv, Domain *domain); Tcl_CmdProc TclCommand_clearAnalysis; Tcl_CmdProc TclCommand_setNumberer; +namespace OpenSees { +Tcl_CmdProc responseSpectrumAnalysis; +} // // Add commands to the interpreter that take the AnalysisBuilder as clientData. // int -G3_AddTclAnalysisAPI(Tcl_Interp *interp, Domain* domain) +G3_AddTclAnalysisAPI(Tcl_Interp *interp, BasicModelBuilder& context) { - - BasicAnalysisBuilder *builder = new BasicAnalysisBuilder(domain); + BasicAnalysisBuilder *builder = new BasicAnalysisBuilder(context); Tcl_CreateCommand(interp, "wipeAnalysis", &wipeAnalysis, builder, nullptr); Tcl_CreateCommand(interp, "_clearAnalysis", &TclCommand_clearAnalysis, builder, nullptr); Tcl_CreateCommand(interp, "numberer", TclCommand_setNumberer, builder, nullptr); + Tcl_CreateCommand(interp, "responseSpectrumAnalysis", &OpenSees::responseSpectrumAnalysis, nullptr, nullptr); + static int ncmd = sizeof(tcl_analysis_cmds)/sizeof(char_cmd); for (int i = 0; i < ncmd; ++i) @@ -88,14 +89,15 @@ G3_AddTclAnalysisAPI(Tcl_Interp *interp, Domain* domain) // command invoked to build an Analysis object // static int -specifyAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, +specifyAnalysis(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); BasicAnalysisBuilder *builder = (BasicAnalysisBuilder*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "need to specify an analysis type (Static, Transient)\n"; + opserr << OpenSees::PromptValueError + << "need to specify an analysis type (Static, Transient)\n"; return TCL_ERROR; } @@ -103,7 +105,7 @@ specifyAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, if (strcmp(argv[argi], "-linear") == 0) { if (argc < 3) { - opserr << G3_ERROR_PROMPT << "need to specify an analysis type (Static, Transient)\n"; + opserr << OpenSees::PromptValueError << "need to specify an analysis type (Static, Transient)\n"; return TCL_ERROR; } Tcl_Eval(interp, "algorithm Linear\n" @@ -127,7 +129,7 @@ specifyAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } else { - opserr << G3_ERROR_PROMPT << "Analysis type '" << argv[1] + opserr << OpenSees::PromptValueError << "Analysis type '" << argv[1] << "' does not exists (Static or Transient only). \n"; return TCL_ERROR; } @@ -140,35 +142,55 @@ specifyAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, // on the Analysis object // static int -analyzeModel(ClientData clientData, Tcl_Interp *interp, int argc, +analyzeModel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); BasicAnalysisBuilder *builder = (BasicAnalysisBuilder*)clientData; - VariableTimeStepDirectIntegrationAnalysis* theVariableTimeStepTransientAnalysis = - builder->getVariableTimeStepDirectIntegrationAnalysis(); - int result = 0; + int commit = BasicAnalysisBuilder::Increment + | BasicAnalysisBuilder::Iterate + | BasicAnalysisBuilder::Commit; + + for (int i=2; iCurrentAnalysisFlag) { case BasicAnalysisBuilder::STATIC_ANALYSIS: { int numIncr; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "static analysis: analysis numIncr?\n"; + opserr << OpenSees::PromptValueError << "static analysis: analysis numIncr?\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[1], &numIncr) != TCL_OK) return TCL_ERROR; - result = builder->analyze(numIncr, 0.0); + result = builder->analyze(numIncr, 0.0, commit); break; } case BasicAnalysisBuilder::TRANSIENT_ANALYSIS: { double dT; int numIncr; if (argc < 3) { - opserr << G3_ERROR_PROMPT << "transient analysis: analysis numIncr? deltaT?\n"; + opserr << OpenSees::PromptValueError << "transient analysis: analysis numIncr? deltaT?\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[1], &numIncr) != TCL_OK) @@ -186,36 +208,26 @@ analyzeModel(ClientData clientData, Tcl_Interp *interp, int argc, if (Tcl_GetInt(interp, argv[5], &Jd) != TCL_OK) return TCL_ERROR; - if (theVariableTimeStepTransientAnalysis != nullptr) - result = theVariableTimeStepTransientAnalysis->analyze( - numIncr, dT, dtMin, dtMax, Jd); - else { - opserr << G3_ERROR_PROMPT << "analyze - no variable time step transient analysis " - "object constructed\n"; - return TCL_ERROR; - } + result = builder->analyzeVariable(numIncr, dT, dtMin, dtMax, Jd); } else { - // result = theTransientAnalysis->analyze(numIncr, dT); - result = builder->analyze(numIncr, dT); + result = builder->analyze(numIncr, dT, commit); } break; } default: - opserr << G3_ERROR_PROMPT << "No Analysis type has been specified \n"; + opserr << OpenSees::PromptValueError << "No Analysis type has been specified \n"; return TCL_ERROR; } - char buffer[10]; - sprintf(buffer, "%d", result); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewIntObj(result)); return TCL_OK; } static int -initializeAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, +initializeAnalysis(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -228,11 +240,9 @@ initializeAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, static int -eigenAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, +eigenAnalysis(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { - static char *resDataPtr = 0; - static int resDataSize = 0; BasicAnalysisBuilder *builder = (BasicAnalysisBuilder*)clientData; @@ -241,7 +251,7 @@ eigenAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, // make sure at least one other argument to contain type of system if (argc < 2) { - opserr << G3_ERROR_PROMPT << "eigen numModes?\n"; + opserr << OpenSees::PromptValueError << "eigen numModes?\n"; return TCL_ERROR; } @@ -299,22 +309,10 @@ eigenAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, // check argv[loc] for number of modes if ((Tcl_GetInt(interp, argv[loc], &numEigen) != TCL_OK) || numEigen < 0) { - opserr << G3_ERROR_PROMPT << "eigen numModes? - invalid numModes\n"; + opserr << OpenSees::PromptValueError << "eigen numModes? - invalid numModes\n"; return TCL_ERROR; } - int requiredDataSize = 40 * numEigen; - if (requiredDataSize > resDataSize) { - if (resDataPtr != nullptr) - delete[] resDataPtr; - - resDataPtr = new char[requiredDataSize]; - resDataSize = requiredDataSize; - } - - for (int i = 0; i < requiredDataSize; ++i) - resDataPtr[i] = '\n'; - // // create a transient analysis if no analysis exists // @@ -322,43 +320,25 @@ eigenAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, int result = builder->eigen(numEigen,generalizedAlgo,findSmallest); + Tcl_Obj* eig_values = Tcl_NewListObj(numEigen, nullptr); + if (result == 0) { const Vector &eigenvalues = domain->getEigenvalues(); - int cnt = 0; for (int i = 0; i < numEigen; ++i) { - cnt += sprintf(&resDataPtr[cnt], "%35.20f ", eigenvalues[i]); + Tcl_ListObjAppendElement(interp, eig_values, Tcl_NewDoubleObj(eigenvalues[i])); } - - Tcl_SetResult(interp, resDataPtr, TCL_STATIC); } + Tcl_SetObjResult(interp, eig_values); return TCL_OK; } -static int -modalProperties(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - G3_Runtime *rt = G3_getRuntime(interp); - OPS_ResetInputNoBuilder(clientData, interp, 1, argc, argv, nullptr); - OPS_DomainModalProperties(rt); - return TCL_OK; -} -static int -responseSpectrum(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - OPS_ResetInputNoBuilder(clientData, interp, 1, argc, argv, nullptr); - G3_Runtime *rt = G3_getRuntime(interp); - OPS_ResponseSpectrumAnalysis(rt); - return TCL_OK; -} // TODO: Move this to commands/modeling/damping.cpp? ...but it uses and // AnalysisBuilder static int -modalDamping(ClientData clientData, Tcl_Interp *interp, int argc, +modalDamping(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -367,7 +347,7 @@ modalDamping(ClientData clientData, Tcl_Interp *interp, int argc, if (argc < 2) { opserr - << G3_ERROR_PROMPT << argv[0] << " ?factor - not enough arguments to command\n"; + << OpenSees::PromptValueError << argv[0] << " ?factor - not enough arguments to command\n"; return TCL_ERROR; } @@ -398,7 +378,8 @@ modalDamping(ClientData clientData, Tcl_Interp *interp, int argc, if (numModes != 1 && numModes != numEigen) { // TODO: Just call eigen again? - opserr << G3_ERROR_PROMPT << "modalDampingQ - same number of damping factors as modes must be " + opserr << OpenSees::PromptValueError + << "modalDampingQ - same number of damping factors as modes must be " "specified\n"; // opserr << " - same damping ratio will be applied to all\n"; return TCL_ERROR; @@ -412,7 +393,7 @@ modalDamping(ClientData clientData, Tcl_Interp *interp, int argc, // read in all factors one at a time for (int i = 0; i < numEigen; ++i) { if (Tcl_GetDouble(interp, argv[1 + i], &factor) != TCL_OK) { - opserr << G3_ERROR_PROMPT << argv[0] << " - could not read factor at position " + opserr << OpenSees::PromptValueError << argv[0] << " - could not read factor at position " << i << "\n"; return TCL_ERROR; } @@ -422,7 +403,7 @@ modalDamping(ClientData clientData, Tcl_Interp *interp, int argc, } else { // read in one & set all factors to that value if (Tcl_GetDouble(interp, argv[1], &factor) != TCL_OK) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " "read betaK? \n"; return TCL_ERROR; @@ -441,7 +422,7 @@ modalDamping(ClientData clientData, Tcl_Interp *interp, int argc, } static int -resetModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +resetModel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); BasicAnalysisBuilder *builder = (BasicAnalysisBuilder*)clientData; @@ -459,7 +440,7 @@ resetModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** cons int -printIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, +printIntegrator(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv, OPS_Stream &output) { assert(clientData != nullptr); @@ -472,37 +453,36 @@ printIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, if (the_static_integrator == nullptr && theTransientIntegrator == nullptr) return TCL_OK; - Integrator *theIntegrator; - if (the_static_integrator != 0) - theIntegrator = the_static_integrator; - else - theIntegrator = theTransientIntegrator; - - // if just 'print integrator'- no flag - if (argc == 0) { - theIntegrator->Print(output); - return TCL_OK; - } - // if 'print Algorithm flag' get the flag - int flag; - if (Tcl_GetInt(interp, argv[eleArg], &flag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "print algorithm failed to get integer flag: \n"; - opserr << argv[eleArg] << endln; - return TCL_ERROR; + int flag = 0; + if (argc > 2) { + if (Tcl_GetInt(interp, argv[eleArg], &flag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "print algorithm failed to get integer flag: \n"; + opserr << argv[eleArg] << endln; + return TCL_ERROR; + } } - theIntegrator->Print(output, flag); + + if (the_static_integrator != 0) + the_static_integrator->Print(output, flag); + else + theTransientIntegrator->Print(output, flag); return TCL_OK; } static int -printA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +printA(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { + // printA - m -c -k assert(clientData != nullptr); BasicAnalysisBuilder *builder = (BasicAnalysisBuilder*)clientData; int res = 0; + enum class Format { + None + } format = Format::None; + FileStream outputFile; OPS_Stream *output = &opserr; LinearSOE *oldSOE = builder->getLinearSOE(); @@ -520,9 +500,9 @@ printA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const ar bool ret = false; - int currentArg = 1; double m = 0.0, c = 0.0, k = 0.0; bool do_mck = false; + int currentArg = 1; while (currentArg < argc) { if ((strcmp(argv[currentArg], "file") == 0) || (strcmp(argv[currentArg], "-file") == 0)) { @@ -533,19 +513,20 @@ printA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const ar } if (outputFile.setFile(argv[currentArg]) != 0) { - opserr << "printA .. - failed to open file: " - << argv[currentArg] << endln; + opserr << "failed to open file: " + << argv[currentArg] << "\n"; return TCL_ERROR; } output = &outputFile; - } else if ((strcmp(argv[currentArg], "ret") == 0) || + } + else if ((strcmp(argv[currentArg], "ret") == 0) || (strcmp(argv[currentArg], "-ret") == 0)) { ret = true; } else if ((strcmp(argv[currentArg], "-m") == 0)) { currentArg++; if (Tcl_GetDouble(interp, argv[currentArg], &m) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "failed to read float following flag -m\n"; + opserr << OpenSees::PromptValueError << "failed to read float following flag -m\n"; return TCL_ERROR; } do_mck = true; @@ -553,7 +534,7 @@ printA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const ar } else if ((strcmp(argv[currentArg], "-c") == 0)) { currentArg++; if (Tcl_GetDouble(interp, argv[currentArg], &c) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "failed to read float following flag -c\n"; + opserr << OpenSees::PromptValueError << "failed to read float following flag -c\n"; return TCL_ERROR; } do_mck = true; @@ -561,7 +542,7 @@ printA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const ar } else if ((strcmp(argv[currentArg], "-k") == 0)) { currentArg++; if (Tcl_GetDouble(interp, argv[currentArg], &k) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "failed to read float following flag -k\n"; + opserr << OpenSees::PromptValueError << "failed to read float following flag -k\n"; return TCL_ERROR; } do_mck = true; @@ -593,7 +574,11 @@ printA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const ar builder->getTransientIntegrator()->formTangent(0); builder->getTransientIntegrator()->revertToLastStep(); } - builder->getDomain()->revertToLastCommit(); + else { + opserr << OpenSees::PromptValueError + << "No integrator has been set, cannot form tangent\n"; + return TCL_ERROR; + } const Matrix *A = theSOE.getA(); if (A == nullptr) { @@ -602,37 +587,40 @@ printA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const ar return TCL_ERROR; } - if (ret) { - int n = A->noRows(); - int m = A->noCols(); - if (n*m == 0) { - opserr << OpenSees::PromptValueError - << "linear system is empty\n"; - return TCL_ERROR; - } + if (format == Format::None) { + if (ret) { + int n = A->noRows(); + int m = A->noCols(); + if (n*m == 0) { + opserr << OpenSees::PromptValueError + << "linear system is empty, got n=" << n << " m= " << m << "\n"; + return TCL_ERROR; + } - // Create an empty list with space preallocated for - // n*m elements. This is not formally documented, but - // it is mentioned here - // https://wiki.tcl-lang.org/page/Tcl_NewListObj - // - // and evident from the source code here: - // https://github.com/enthought/tcl/blob/master/generic/tclListObj.c - // - Tcl_Obj* list = Tcl_NewListObj(n*m, nullptr); + // Create an empty list with space preallocated for + // n*m elements. This is not formally documented, but + // it is mentioned here + // https://wiki.tcl-lang.org/page/Tcl_NewListObj + // + // and evident from the source code here: + // https://github.com/enthought/tcl/blob/master/generic/tclListObj.c + // + Tcl_Obj* list = Tcl_NewListObj(n*m, nullptr); - for (int i = 0; i < n; ++i) { - for (int j = 0; j < m; j++) - Tcl_ListObjAppendElement(interp, list, Tcl_NewDoubleObj((*A)(i, j))); - } - Tcl_SetObjResult(interp, list); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; j++) + Tcl_ListObjAppendElement(interp, list, Tcl_NewDoubleObj((*A)(i, j))); + } + Tcl_SetObjResult(interp, list); - } else { - *output << *A; - outputFile.close(); + } else { + *output << *A; + outputFile.close(); + } } + builder->getDomain()->revertToLastCommit(); // put the original SOE back. if (oldSOE != nullptr) builder->set(oldSOE, true); @@ -644,7 +632,7 @@ printA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const ar } static int -printB(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +printB(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); BasicAnalysisBuilder *builder = (BasicAnalysisBuilder*)clientData; @@ -707,9 +695,9 @@ printB(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const ar return res; } -// This is removed in model.cpp +// This is removed from the Tcl_Interp in model.cpp extern int -TclCommand_clearAnalysis(ClientData cd, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +TclCommand_clearAnalysis(ClientData cd, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { if (cd != nullptr) { @@ -729,7 +717,7 @@ TclCommand_clearAnalysis(ClientData cd, Tcl_Interp *interp, int argc, TCL_Char * } static int -wipeAnalysis(ClientData cd, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +wipeAnalysis(ClientData cd, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { if (cd != nullptr) { @@ -744,7 +732,7 @@ wipeAnalysis(ClientData cd, Tcl_Interp *interp, int argc, TCL_Char ** const argv // command invoked to allow the ConstraintHandler object to be built // static int -specifyConstraintHandler(ClientData clientData, Tcl_Interp *interp, int argc, +specifyConstraintHandler(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { @@ -752,7 +740,7 @@ specifyConstraintHandler(ClientData clientData, Tcl_Interp *interp, int argc, // make sure at least one other argument to contain type name if (argc < 2) { - opserr << G3_ERROR_PROMPT << "need to specify a constraint type \n"; + opserr << OpenSees::PromptValueError << "need to specify a constraint type \n"; return TCL_ERROR; } @@ -791,7 +779,7 @@ specifyConstraintHandler(ClientData clientData, Tcl_Interp *interp, int argc, } else { - opserr << G3_ERROR_PROMPT << "ConstraintHandler type '" << argv[1] + opserr << OpenSees::PromptValueError << "ConstraintHandler type '" << argv[1] << "' does not exists \n\t(Plain, Penalty, Lagrange, Transformation) only\n"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/analysis/analysis.h b/SRC/runtime/commands/analysis/analysis.h index e28e8f9ca7..2f6cce7d24 100644 --- a/SRC/runtime/commands/analysis/analysis.h +++ b/SRC/runtime/commands/analysis/analysis.h @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // #include // @@ -13,8 +14,6 @@ static Tcl_CmdProc wipeAnalysis; // static Tcl_CmdProc specifyAnalysis; static Tcl_CmdProc eigenAnalysis; -static Tcl_CmdProc modalProperties; -static Tcl_CmdProc responseSpectrum; static Tcl_CmdProc printA; static Tcl_CmdProc printB; static Tcl_CmdProc initializeAnalysis; @@ -29,6 +28,7 @@ extern Tcl_CmdProc specifyIntegrator; // commands/analysis/solver.cpp extern Tcl_CmdProc specifySOE; extern Tcl_CmdProc specifySysOfEqnTable; +extern Tcl_CmdProc TclCommand_systemSize; // commands/analysis/algorithm.cpp extern Tcl_CmdProc TclCommand_specifyAlgorithm; @@ -44,11 +44,16 @@ extern Tcl_CmdProc getCTestNorms; extern Tcl_CmdProc getCTestIter; extern Tcl_CmdProc TclCommand_algorithmRecorder; +// from commands/analysis/sensitivity.cpp +extern Tcl_CmdProc TclCommand_sensitivityAlgorithm; +extern Tcl_CmdProc TclCommand_sensLambda; + struct char_cmd { const char* name; Tcl_CmdProc* func; -} const tcl_analysis_cmds[] = { +} const tcl_analysis_cmds[] = { {"system", &specifySysOfEqnTable}, + {"systemSize", &TclCommand_systemSize}, {"test", &specifyCTest}, {"testIter", &getCTestIter}, @@ -61,10 +66,8 @@ struct char_cmd { {"analyze", &analyzeModel}, {"initialize", &initializeAnalysis}, - {"modalProperties", &modalProperties}, {"modalDamping", &modalDamping}, {"modalDampingQ", &modalDamping}, - {"responseSpectrum", &responseSpectrum}, {"printA", &printA}, {"printB", &printB}, {"reset", &resetModel}, @@ -78,5 +81,9 @@ struct char_cmd { {"solveCPU", &TclCommand_solveCPU}, // recorder.cpp {"algorithmRecorder", &TclCommand_algorithmRecorder}, + + // sensitivity + {"sensitivityAlgorithm", TclCommand_sensitivityAlgorithm}, + {"sensLambda", TclCommand_sensLambda}, }; diff --git a/SRC/runtime/commands/analysis/ctest.cpp b/SRC/runtime/commands/analysis/ctest.cpp index 52e0e2422d..ae90f69866 100644 --- a/SRC/runtime/commands/analysis/ctest.cpp +++ b/SRC/runtime/commands/analysis/ctest.cpp @@ -1,9 +1,11 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// +// // Description: This file implements the selection of a convergence test. // #include @@ -14,7 +16,7 @@ #include #include -// convergence tests +// Convergence tests #include #include #include @@ -27,7 +29,7 @@ #include -ConvergenceTest* +static ConvergenceTest* TclDispatch_newConvergenceTest(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char ** const argv); @@ -51,7 +53,7 @@ specifyCTest(ClientData clientData, Tcl_Interp *interp, int argc, G3_Char ** con return TCL_OK; } -ConvergenceTest* +static ConvergenceTest* TclDispatch_newConvergenceTest(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char ** const argv) { // get the tolerence first @@ -70,12 +72,13 @@ TclDispatch_newConvergenceTest(ClientData clientData, Tcl_Interp* interp, int ar // make sure at least one other argument to contain test type if (argc < 2) { - opserr << G3_ERROR_PROMPT << "need to specify a ConvergenceTest type \n"; + opserr << OpenSees::PromptValueError << "need to specify a ConvergenceTest type \n"; return nullptr; } if ((strcmp(argv[1], "NormDispAndUnbalance") == 0) || - (strcmp(argv[1], "NormDispOrUnbalance") == 0)) { + (strcmp(argv[1], "NormDispOrUnbalance") == 0)) + { if (argc == 5) { if (Tcl_GetDouble(interp, argv[2], &tol) != TCL_OK) return nullptr; @@ -118,8 +121,8 @@ TclDispatch_newConvergenceTest(ClientData clientData, Tcl_Interp* interp, int ar if (Tcl_GetInt(interp, argv[7], &maxIncr) != TCL_OK) return nullptr; } - - } else if (strcmp(argv[1], "FixedNumIter") == 0) { + } + else if (strcmp(argv[1], "FixedNumIter") == 0) { // test FixedNumIter $iter <$pFlag> <$nType> if (argc == 3) { if (Tcl_GetInt(interp, argv[2], &numIter) != TCL_OK) @@ -146,8 +149,8 @@ TclDispatch_newConvergenceTest(ClientData clientData, Tcl_Interp* interp, int ar if (Tcl_GetDouble(interp, argv[5], &maxTol) != TCL_OK) return nullptr; } - - } else { + } + else { // // All others // @@ -222,40 +225,44 @@ TclDispatch_newConvergenceTest(ClientData clientData, Tcl_Interp* interp, int ar break; } - ConvergenceTest *theNewTest = nullptr; if (numIter == 0) { - opserr << G3_ERROR_PROMPT << "no numIter specified in test command\n"; + opserr << OpenSees::PromptValueError << "no numIter specified in test command\n"; return nullptr; } + + // ConvergenceTest *theNewTest = nullptr; if (strcmp(argv[1], "FixedNumIter") == 0) - theNewTest = new CTestFixedNumIter(numIter, flag, normType); + return new CTestFixedNumIter(numIter, flag, normType); else { if (tol == 0.0) { - opserr << G3_ERROR_PROMPT << "no tolerance specified in test command\n"; + opserr << OpenSees::PromptValueError << "no tolerance specified in test command\n"; return nullptr; } - if (strcmp(argv[1], "NormUnbalance") == 0) + if ((strcmp(argv[1], "Residual") == 0) || (strcmp(argv[1], "NormUnbalance") == 0)) return new CTestNormUnbalance(tol, numIter, flag, normType, maxIncr, maxTol); - else if (strcmp(argv[1], "NormDispIncr") == 0) + else if ((strcmp(argv[1], "Correction") == 0) || (strcmp(argv[1], "NormDispIncr") == 0)) return new CTestNormDispIncr(tol, numIter, flag, normType, maxTol); - else if (strcmp(argv[1], "NormDispAndUnbalance") == 0) - return new NormDispAndUnbalance(tol, tol2, numIter, flag, - normType, maxIncr); + else if ((strcmp(argv[1], "EnergyIncr") == 0) || + (strcmp(argv[1], "Energy") == 0)) + return new CTestEnergyIncr(tol, numIter, flag, normType, maxTol); + + + else if ((strcmp(argv[1], "Residual&Correction") == 0) || + (strcmp(argv[1], "Correction&Residual") == 0) || + (strcmp(argv[1], "NormDispAndUnbalance") == 0)) + return new NormDispAndUnbalance(tol, tol2, numIter, flag, normType, maxIncr); else if (strcmp(argv[1], "NormDispOrUnbalance") == 0) return new NormDispOrUnbalance(tol, tol2, numIter, flag, normType, maxIncr); - else if (strcmp(argv[1], "EnergyIncr") == 0) - theNewTest = new CTestEnergyIncr(tol, numIter, flag, normType, maxTol); - else if (strcmp(argv[1], "RelativeNormUnbalance") == 0) return new CTestRelativeNormUnbalance(tol, numIter, flag, normType); @@ -269,11 +276,12 @@ TclDispatch_newConvergenceTest(ClientData clientData, Tcl_Interp* interp, int ar return new CTestRelativeTotalNormDispIncr(tol, numIter, flag, normType); else { - opserr << G3_ERROR_PROMPT << "unknown ConvergenceTest type"; + opserr << OpenSees::PromptValueError << "unknown ConvergenceTest type"; return nullptr; } } - return theNewTest; + + return nullptr; } int @@ -297,7 +305,7 @@ getCTestNorms(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_OK; } - opserr << G3_ERROR_PROMPT << "testNorms - no convergence test has been constructed.\n"; + opserr << OpenSees::PromptValueError << "no convergence test has been defined.\n"; return TCL_ERROR; } @@ -318,7 +326,7 @@ getCTestIter(ClientData clientData, Tcl_Interp *interp, int argc, G3_Char ** con return TCL_OK; } - opserr << G3_ERROR_PROMPT << "testIter - no convergence test.\n"; + opserr << OpenSees::PromptValueError << "no convergence test was found.\n"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/analysis/integrator.cpp b/SRC/runtime/commands/analysis/integrator.cpp index 3a846cb0a1..239b5c15c8 100644 --- a/SRC/runtime/commands/analysis/integrator.cpp +++ b/SRC/runtime/commands/analysis/integrator.cpp @@ -1,15 +1,16 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara +// https://xara.so // //===----------------------------------------------------------------------===// // -// Description: This file implements selection of an integrator object. +// Description: This file implements selection of an integrator. // -#include -#include "integrator.h" -#include #include +#include +#include +#include #include #include #include @@ -23,6 +24,71 @@ #include #include +// +// Helpers +// + +// Type 1 +template +static int +dispatch(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char** const argv) +{ + BasicAnalysisBuilder *builder = static_cast(clientData); + Type* theIntegrator = (Type*)fn( G3_getRuntime(interp), argc, argv ); + + if (theIntegrator == nullptr) + return TCL_ERROR; + + + opsdbg << G3_DEBUG_PROMPT << "Set integrator to \n"; + theIntegrator->Print(opsdbg); + builder->set(*theIntegrator); + return TCL_OK; +} + +// Type 2 +template +static int +dispatch(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) +{ + assert(clientData != nullptr); + + + Type* theIntegrator = fn( clientData, interp, argc, argv ); + + if (theIntegrator == nullptr) + return TCL_ERROR; + + BasicAnalysisBuilder *builder = static_cast(clientData); + + opsdbg << G3_DEBUG_PROMPT << "Set integrator to \n"; + theIntegrator->Print(opsdbg); + builder->set(*theIntegrator); + return TCL_OK; +} + +// Type 3 +template +static int +dispatch(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char** const argv) +{ + assert(clientData != nullptr); + return fn( clientData, interp, argc, argv ); +} + +#define DISPATCH(Type, Class) \ + (Tcl_CmdProc*)[](ClientData clientData, Tcl_Interp*, int, G3_Char**const)->int{ \ + BasicAnalysisBuilder *builder = static_cast(clientData); \ + Type* theIntegrator = new Class(); \ + opsdbg << G3_DEBUG_PROMPT << "Set integrator to \n"; \ + theIntegrator->Print(opsdbg); \ + builder->set(*theIntegrator); \ + return TCL_OK; \ + } + +#include "integrator.h" + + extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp *interp, int cArg, int mArg, TCL_Char ** const argv, Domain *domain); @@ -60,7 +126,7 @@ specifyIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char int TclCommand_newStaticIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { - BasicAnalysisBuilder *builder = (BasicAnalysisBuilder*)clientData; + BasicAnalysisBuilder *builder = static_cast(clientData); auto tcl_cmd = StaticIntegratorLibrary.find(std::string(argv[1])); if (tcl_cmd != StaticIntegratorLibrary.end()) @@ -100,7 +166,7 @@ TclCommand_newStaticIntegrator(ClientData clientData, Tcl_Interp *interp, int ar int TclCommand_newTransientIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { - BasicAnalysisBuilder *builder = (BasicAnalysisBuilder*)clientData; + BasicAnalysisBuilder *builder = static_cast(clientData); auto tcl_cmd = TransientIntegratorLibrary.find(std::string(argv[1])); if (tcl_cmd != TransientIntegratorLibrary.end()) @@ -136,7 +202,7 @@ TclCommand_newTransientIntegrator(ClientData clientData, Tcl_Interp *interp, int } #include -StaticIntegrator* +int G3Parse_newHSIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { double arcLength, psi_u, psi_f, u_ref; @@ -144,57 +210,78 @@ G3Parse_newHSIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, con if (argc < 3) { opserr << "WARNING integrator HSConstraint " " \n"; - return nullptr; + return TCL_ERROR;; } + if (argc >= 3 && Tcl_GetDouble(interp, argv[2], &arcLength) != TCL_OK) - return nullptr; + return TCL_ERROR;; if (argc >= 4 && Tcl_GetDouble(interp, argv[3], &psi_u) != TCL_OK) - return nullptr; + return TCL_ERROR;; if (argc >= 5 && Tcl_GetDouble(interp, argv[4], &psi_f) != TCL_OK) - return nullptr; + return TCL_ERROR;; if (argc == 6 && Tcl_GetDouble(interp, argv[5], &u_ref) != TCL_OK) - return nullptr; + return TCL_ERROR;; + // Create the integrator + StaticIntegrator* theStaticIntegrator = nullptr; switch (argc) { case 3: - return new HSConstraint(arcLength); + theStaticIntegrator = new HSConstraint(arcLength); + break; case 4: - return new HSConstraint(arcLength, psi_u); + theStaticIntegrator = new HSConstraint(arcLength, psi_u); + break; case 5: - return new HSConstraint(arcLength, psi_u, psi_f); + theStaticIntegrator = new HSConstraint(arcLength, psi_u, psi_f); + break; case 6: - return new HSConstraint(arcLength, psi_u, psi_f, u_ref); - default: - return nullptr; + theStaticIntegrator = new HSConstraint(arcLength, psi_u, psi_f, u_ref); + break; } + + if (theStaticIntegrator == nullptr) + return TCL_ERROR; + + + BasicAnalysisBuilder *builder = static_cast(clientData); + + builder->set(*theStaticIntegrator); + return TCL_OK; } -StaticIntegrator* +int G3Parse_newLoadControl(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { - double dLambda; - double minIncr, maxIncr; - int numIter; - if (argc < 3) { - opserr << "WARNING incorrect # args - integrator LoadControl dlam \n"; - return nullptr; - } - if (Tcl_GetDouble(interp, argv[2], &dLambda) != TCL_OK) - return nullptr; - if (argc > 5) { - if (Tcl_GetInt(interp, argv[3], &numIter) != TCL_OK) - return nullptr; - if (Tcl_GetDouble(interp, argv[4], &minIncr) != TCL_OK) - return nullptr; - if (Tcl_GetDouble(interp, argv[5], &maxIncr) != TCL_OK) - return nullptr; - } else { - minIncr = dLambda; - maxIncr = dLambda; - numIter = 1; - } - return new LoadControl(dLambda, numIter, minIncr, maxIncr); + double dLambda; + double minIncr, maxIncr; + int numIter; + if (argc < 3) { + opserr << "WARNING incorrect # args - integrator LoadControl dlam \n"; + return TCL_ERROR;; + } + if (Tcl_GetDouble(interp, argv[2], &dLambda) != TCL_OK) + return TCL_ERROR;; + if (argc > 5) { + if (Tcl_GetInt(interp, argv[3], &numIter) != TCL_OK) + return TCL_ERROR;; + if (Tcl_GetDouble(interp, argv[4], &minIncr) != TCL_OK) + return TCL_ERROR;; + if (Tcl_GetDouble(interp, argv[5], &maxIncr) != TCL_OK) + return TCL_ERROR;; + } else { + minIncr = dLambda; + maxIncr = dLambda; + numIter = 1; + } + + StaticIntegrator *theStaticIntegrator = + new LoadControl(dLambda, numIter, minIncr, maxIncr); + + BasicAnalysisBuilder *builder = static_cast(clientData); + + builder->set(*theStaticIntegrator); + return TCL_OK; } #include @@ -213,8 +300,6 @@ G3Parse_newEQPathIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, if (Tcl_GetDouble(interp, argv[2], &arcLength) != TCL_OK) { opserr << "WARNING integrator EQPath $arc_length $type \n"; - opserr << " https://doi.org/10.12989/sem.2013.48.6.849 \n"; - opserr << " https://doi.org/10.12989/sem.2013.48.6.879 \n"; return nullptr; } @@ -232,7 +317,8 @@ G3Parse_newEQPathIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, #include StaticIntegrator * -G3Parse_newArcLengthIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +G3Parse_newArcLengthIntegrator(ClientData clientData, Tcl_Interp *interp, + Tcl_Size argc, TCL_Char ** const argv) { double arcLength; double alpha = 1.0; @@ -246,7 +332,7 @@ G3Parse_newArcLengthIntegrator(ClientData clientData, Tcl_Interp *interp, int ar // Begin parse if (argc < 3) { - opserr << G3_ERROR_PROMPT << "integrator ArcLength arcLength alpha \n"; + opserr << OpenSees::PromptValueError << "integrator ArcLength arcLength alpha \n"; return nullptr; } @@ -259,13 +345,13 @@ G3Parse_newArcLengthIntegrator(ClientData clientData, Tcl_Interp *interp, int ar } else if ((strcmp(argv[i], "-exp") == 0)) { if (++i >= argc || Tcl_GetDouble(interp, argv[i], &expon) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "failed to read expon\n"; + opserr << OpenSees::PromptValueError << "failed to read expon\n"; return nullptr; } } else if ((strcmp(argv[i], "-j") == 0)) { if (++i >= argc || Tcl_GetDouble(interp, argv[i], &numIter) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "failed to read iter\n"; + opserr << OpenSees::PromptValueError << "failed to read iter\n"; return nullptr; } } @@ -273,9 +359,11 @@ G3Parse_newArcLengthIntegrator(ClientData clientData, Tcl_Interp *interp, int ar if (++i < argc && strcmp(argv[i], "point")==0) { reference = ReferencePattern::Point; } - } else if (!got_alpha) { + } + else if (!got_alpha) { if (Tcl_GetDouble(interp, argv[i], &alpha) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "failed to read alpha, got " << argv[i] << "\n"; + opserr << OpenSees::PromptValueError + << "failed to read alpha, got " << argv[i] << "\n"; return nullptr; } got_alpha = true; @@ -299,7 +387,7 @@ G3Parse_newMinUnbalDispNormIntegrator(ClientData clientData, Tcl_Interp* interp, double lambda11; if (Tcl_GetDouble(interp, argv[2], &lambda11) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "expected float for lambda11 but got " << argv[2] << "\n"; + opserr << OpenSees::PromptValueError << "expected float for lambda11 but got " << argv[2] << "\n"; return nullptr; } @@ -332,10 +420,12 @@ G3Parse_newMinUnbalDispNormIntegrator(ClientData clientData, Tcl_Interp* interp, } else if ((recvd&MinLamb) == 0) { if (Tcl_GetDouble(interp, argv[i], &minlambda) != TCL_OK) return nullptr; + recvd |= MinLamb; } else if ((recvd&MaxLamb) == 0) { if (Tcl_GetDouble(interp, argv[i], &maxlambda) != TCL_OK) return nullptr; + recvd |= MaxLamb; } } @@ -417,35 +507,6 @@ G3Parse_newDisplacementControlIntegrator(ClientData clientData, Tcl_Interp *inte #endif } -#if 0 -StaticIntegrator* -G3Parse_newStagedLoadControlIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - double dLambda; - double minIncr, maxIncr; - int numIter; - if (argc < 3) { - opserr << "WARNING incorrect # args - integrator StagedLoadControl dlam " - "\n"; - return nullptr; - } - if (Tcl_GetDouble(interp, argv[2], &dLambda) != TCL_OK) - return nullptr; - if (argc > 5) { - if (Tcl_GetInt(interp, argv[3], &numIter) != TCL_OK) - return nullptr; - if (Tcl_GetDouble(interp, argv[4], &minIncr) != TCL_OK) - return nullptr; - if (Tcl_GetDouble(interp, argv[5], &maxIncr) != TCL_OK) - return nullptr; - } else { - minIncr = dLambda; - maxIncr = dLambda; - numIter = 1; - } - return new StagedLoadControl(dLambda, numIter, minIncr, maxIncr); -} -#endif #ifdef _PARALLEL_INTERPRETERS diff --git a/SRC/runtime/commands/analysis/integrator.h b/SRC/runtime/commands/analysis/integrator.h index 756dde417a..fcc8e9d283 100644 --- a/SRC/runtime/commands/analysis/integrator.h +++ b/SRC/runtime/commands/analysis/integrator.h @@ -1,22 +1,17 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// All dispatching macros and templates are defined in integrator.cpp before +// this file is included. // #include OPS_Routine OPS_Newmark; -OPS_Routine OPS_StagedNewmark; OPS_Routine OPS_GimmeMCK; -OPS_Routine OPS_AlphaOS; -OPS_Routine OPS_AlphaOS_TP; -OPS_Routine OPS_AlphaOSGeneralized; -OPS_Routine OPS_AlphaOSGeneralized_TP; -OPS_Routine OPS_ExplicitDifference; -OPS_Routine OPS_CentralDifference; -OPS_Routine OPS_CentralDifferenceAlternative; -OPS_Routine OPS_CentralDifferenceNoDamping; OPS_Routine OPS_Collocation; OPS_Routine OPS_CollocationHSFixedNumIter; OPS_Routine OPS_CollocationHSIncrLimit; @@ -64,10 +59,13 @@ OPS_Routine OPS_WilsonTheta; #include #include #include +#include +#include +#include +#include - -StaticIntegrator* G3Parse_newHSIntegrator(ClientData, Tcl_Interp*, int, TCL_Char ** const); -StaticIntegrator* G3Parse_newLoadControl(ClientData, Tcl_Interp*, int argc, TCL_Char *argv[]); +Tcl_CmdProc G3Parse_newHSIntegrator; +Tcl_CmdProc G3Parse_newLoadControl; StaticIntegrator* G3Parse_newEQPathIntegrator(ClientData, Tcl_Interp*, int argc, TCL_Char ** const); StaticIntegrator* G3Parse_newArcLengthIntegrator(ClientData, Tcl_Interp*, int argc, TCL_Char ** const); StaticIntegrator* G3Parse_newMinUnbalDispNormIntegrator(ClientData, Tcl_Interp*, int, TCL_Char ** const); @@ -79,86 +77,12 @@ TransientIntegrator* TclCommand_newNewmarkIntegrator(ClientData, Tcl_Interp*, in // -// Helpers // - -// Type 1 -template -static int -dispatch(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char** const argv) -{ - BasicAnalysisBuilder *builder = static_cast(clientData); - Type* theIntegrator = (Type*)fn( G3_getRuntime(interp), argc, argv ); - - if (theIntegrator == nullptr) - return TCL_ERROR; - - - opsdbg << G3_DEBUG_PROMPT << "Set integrator to \n"; - theIntegrator->Print(opsdbg); - builder->set(*theIntegrator); - return TCL_OK; -} - -// Type 2 -template -static int -dispatch(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) -{ - assert(clientData != nullptr); - - - Type* theIntegrator = fn( clientData, interp, argc, argv ); - - if (theIntegrator == nullptr) - return TCL_ERROR; - - BasicAnalysisBuilder *builder = static_cast(clientData); - - opsdbg << G3_DEBUG_PROMPT << "Set integrator to \n"; - theIntegrator->Print(opsdbg); - builder->set(*theIntegrator); - return TCL_OK; -} - -// Type 3 -template -static int -dispatch(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char** const argv) -{ - assert(clientData != nullptr); - return fn( clientData, interp, argc, argv ); -} - -#define DISPATCH(Type, Class) \ - (Tcl_CmdProc*)[](ClientData clientData, Tcl_Interp*, int, G3_Char**const)->int{ \ - BasicAnalysisBuilder *builder = static_cast(clientData); \ - Type* theIntegrator = new Class(); \ - opsdbg << G3_DEBUG_PROMPT << "Set integrator to \n"; \ - theIntegrator->Print(opsdbg); \ - builder->set(*theIntegrator); \ - return TCL_OK; \ - } - // -// -// -#if 0 -std::unordered_map -StaticIntegratorLibrary = { - {"LoadControl", G3Parse_newLoadControl}, -//{"StagedLoadControl", G3Parse_newStagedLoadControlIntegrator}, - {"EQPath", G3Parse_newEQPathIntegrator}, - {"ArcLength", G3Parse_newArcLengthIntegrator}, - {"MinUnbalDispNorm", G3Parse_newMinUnbalDispNormIntegrator}, - {"DisplacementControl", G3Parse_newDisplacementControlIntegrator}, -}; -#endif - std::unordered_map StaticIntegratorLibrary = { - {"LoadControl", dispatch}, + {"LoadControl", G3Parse_newLoadControl}, {"EQPath", dispatch}, @@ -185,82 +109,75 @@ TransientIntegratorLibrary = { {"ParkLMS3", DISPATCH(TransientIntegrator, ParkLMS3)}, // MCK - {"GimmeMCK", dispatch }, - {"MCK", dispatch }, - {"ZZTop", dispatch }, - - {"Newmark", dispatch }, - - {"NewmarkExplicit", dispatch}, + {"GimmeMCK", dispatch }, + {"MCK", dispatch }, + {"ZZTop", dispatch }, - {"Newmark1", dispatch}, + {"Newmark", dispatch }, - {"NewmarkHSIncrReduct", dispatch}, + {"NewmarkExplicit", dispatch}, - {"NewmarkHSIncrLimit", dispatch}, + {"Newmark1", dispatch}, - {"NewmarkHSFixedNumIter", dispatch}, + {"NewmarkHSIncrReduct", dispatch}, - {"HHT", dispatch}, + {"NewmarkHSIncrLimit", dispatch}, - {"HHT_TP", dispatch}, + {"NewmarkHSFixedNumIter", dispatch}, - {"HHTGeneralized", dispatch}, + {"HHT", dispatch}, - {"HHTGeneralized_TP", dispatch}, + {"HHT_TP", dispatch}, - {"HHTExplicit", dispatch}, + {"HHTGeneralized", dispatch}, - {"HHTExplicit_TP", dispatch}, + {"HHTGeneralized_TP", dispatch}, - {"HHTGeneralizedExplicit", dispatch}, + {"HHTExplicit", dispatch}, - {"HHTGeneralizedExplicit_TP", dispatch}, + {"HHTExplicit_TP", dispatch}, - {"HHTHSIncrLimit", dispatch}, + {"HHTGeneralizedExplicit", dispatch}, - {"HHTHSIncrLimit_TP", dispatch}, + {"HHTGeneralizedExplicit_TP", dispatch}, - {"HHTHSIncrReduct", dispatch}, + {"HHTHSIncrLimit", dispatch}, - {"HHTHSIncrReduct_TP", dispatch}, + {"HHTHSIncrLimit_TP", dispatch}, - {"HHTHSFixedNumIter", dispatch}, + {"HHTHSIncrReduct", dispatch}, - {"HHTHSFixedNumIter_TP", dispatch}, + {"HHTHSIncrReduct_TP", dispatch}, - {"GeneralizedAlpha", dispatch}, + {"HHTHSFixedNumIter", dispatch}, - {"KRAlphaExplicit", dispatch}, + {"HHTHSFixedNumIter_TP", dispatch}, - {"KRAlphaExplicit_TP", dispatch}, + {"GeneralizedAlpha", dispatch}, - {"AlphaOS", dispatch}, + {"KRAlphaExplicit", dispatch}, - {"AlphaOS_TP", dispatch}, + {"KRAlphaExplicit_TP", dispatch}, - {"AlphaOSGeneralized", dispatch}, + {"Collocation", dispatch}, - {"AlphaOSGeneralized_TP", dispatch}, + {"CollocationHSIncrReduct", dispatch}, - {"Collocation", dispatch}, - - {"CollocationHSIncrReduct", dispatch}, - - {"CollocationHSIncrLimit", dispatch}, + {"CollocationHSIncrLimit", dispatch}, {"CollocationHSFixedNumIter", dispatch}, {"WilsonTheta", dispatch}, - {"ExplicitDifference", dispatch}, + {"ExplicitDifference", DISPATCH(TransientIntegrator, ExplicitDifference)}, - {"CentralDifference", dispatch}, + {"CentralDifference", DISPATCH(TransientIntegrator, CentralDifference)}, - {"CentralDifferenceAlternative", dispatch}, + {"CentralDifferenceAlternative", DISPATCH(TransientIntegrator, CentralDifferenceAlternative)}, - {"CentralDifferenceNoDamping", dispatch}, + {"CentralDifferenceNoDamping", DISPATCH(TransientIntegrator, CentralDifferenceNoDamping)}, }; + diff --git a/SRC/runtime/commands/analysis/modal/CMakeLists.txt b/SRC/runtime/commands/analysis/modal/CMakeLists.txt new file mode 100644 index 0000000000..154506f6ba --- /dev/null +++ b/SRC/runtime/commands/analysis/modal/CMakeLists.txt @@ -0,0 +1,8 @@ + + + +target_sources(OPS_Runtime PRIVATE + "modal.cpp" + "ResponseSpectrumAnalysis.cpp" + "DomainModalProperties.cpp" +) \ No newline at end of file diff --git a/SRC/runtime/commands/analysis/modal/DomainModalProperties.cpp b/SRC/runtime/commands/analysis/modal/DomainModalProperties.cpp new file mode 100644 index 0000000000..c0a9b1ed28 --- /dev/null +++ b/SRC/runtime/commands/analysis/modal/DomainModalProperties.cpp @@ -0,0 +1,859 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// Written: Massimo Petracca (ASDEA Software) +// Created: Fri Nov 27 18:07:11: 2020 +// Revision: A +// +// Description: This file contains the class definition for DomainModalProperties. +// It contains all data optionally computed after an Eigenvalue analysis. +// +// What: "@(#) DomainModalProperties.h, revA" +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "DomainModalProperties.h" +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif + +#if defined(_WIN32) +#ifndef NOMINMAX +#define NOMINMAX +#endif +#endif + +//#define DMP_VERBOSE +//#define DMP_DEBUG + +#define DMP_ERR_INFO "( function: " << __func__ << ", file: \"" << __FILE__ << "\", line: " << __LINE__ << " )\n" +#define DMP_ERR(X) opserr << "FATAL ERROR: " << X << DMP_ERR_INFO, exit(-1) + +#define DMP_DBL_LARGE 1.0e200 + +// find domain size +static int +domainSize(Domain *domain) { + int ndm = 0; + Node* node; + NodeIter& theNodes = domain->getNodes(); + while ((node = theNodes()) != nullptr) { + int trial = node->getCrds().Size(); + if (ndm == 0) + ndm = trial; + if (ndm != trial) + DMP_ERR("Cannot mix nodes with different dimensions\n"); + } + + if ((ndm != 2) && (ndm != 3)) + DMP_ERR("DomainModalProperties can be calculated only when NDM is 2 or 3, not " << ndm << "\n"); + return ndm; +} + +// Anonymous namespace for utilities +namespace +{ + // a simple structure to collect nodes in a contiguos array + // and with a map that maps the node tag to its position in the array + struct node_map_t + { + enum DOF_TYPE { DOF_EXCLUDED = -1, DOF_FIXED = -2}; + + // the contiguous list of nodes + std::vector nodes; + // for each node, save a re-mapped ID to the contiguous list of dofs + // (-1 means "exluded", -2 means "fixed") + std::vector node_ids; + // for each node, save a list of local DOF id (0 to ndf) + std::vector > node_u_flags; + // for each node, save the first position in the contiguos list of dofs, ndf for each node (3 in 2D and 6 in 3D) + std::map pos; + + node_map_t(Domain* domain, int ndm, int ndf) { + size_t n = static_cast(domain->getNumNodes()); + if (n > 0) { + nodes.resize(n); + node_ids.resize(n); + node_u_flags.resize(n); + Node* nodePtr; + NodeIter& theNodes = domain->getNodes(); + size_t counter = 0; + while ((nodePtr = theNodes()) != 0) { + // node + nodes[counter] = nodePtr; + // map + pos.emplace(std::make_pair(nodePtr->getTag(), counter)); + // id (original), needed to see if this dof is fixed + const ID& id_source = nodePtr->getDOF_GroupPtr()->getID(); + // id (remapped) + auto& id = node_ids[counter]; + int node_ndf = nodePtr->getNumberDOF(); + id.resize(node_ndf); + int offset = static_cast(counter)* ndf; // each node has ndf DOFs in this context + for (int j = 0; j < node_ndf; ++j) { + if (j < ndf) { + // exclude pressure dofs + // we can detect a pressure node (node_ndf=4) in 3d.. but not in 2d! + if (node_ndf == 4 && ndf == 6 && j == 3) { + id(j) = DOF_EXCLUDED; + } + else { + if (id_source(j) == -1) + id(j) = DOF_FIXED; + else + id(j) = offset; + } + ++offset; + } + else { + // exclude any dof >= ndf + id(j) = DOF_EXCLUDED; + } + } + // local dof flags + std::vector& flags = node_u_flags[counter]; + flags.resize(node_ndf); + for (int j = 0; j < node_ndf; ++j) + flags[static_cast(j)] = id(j) == DOF_EXCLUDED ? -1 : j; + // go on + ++counter; + } + } + +#ifdef DMP_VERBOSE + opserr << "NODE RE-MAPPING:\n"; + opserr << "num eq: " << (int)(n * ndf) << "\n"; + for (size_t i = 0; i < n; ++i) { + auto node = nodes[i]; + const auto& id = node_ids[i]; + const auto& uf = node_u_flags[i]; + opserr << "[" << (int)i << "] Node " << node->getTag() << " -> ("; + for (int j = 0; j < id.Size(); ++j) + opserr << " " << id(j); + opserr << " ) {"; + for (size_t j = 0; j < uf.size(); ++j) + opserr << " " << static_cast(uf[j]); + opserr << " }\n"; + } +#endif // DMP_VERBOSE + } + + inline size_t getPosition(int tag) const { + auto it = pos.find(tag); + if (it == pos.end()) + DMP_ERR("Cannot find node " << tag << "\n"); + return it->second; + } + + }; + + // a simple structure to collect element data + struct ele_map_t + { + // the contiguous list of elements + std::vector elements; + // for each element, save a re-mapped ID to the contiguous list of dofs + std::vector element_ids; + // for each element, save a list of nodal position pointing to the contiguos position of the node + // in the node map + std::vector > element_node_pos; + // for each element, save a list of flags. true if the dof is translational, false otherwise + std::vector > element_u_flags; + + ele_map_t(Domain* domain, const node_map_t& nm) { + size_t count = static_cast(domain->getNumElements()); + elements.resize(count); + element_ids.resize(count); + element_u_flags.resize(count); + element_node_pos.resize(count); + count = 0; + { + Element* elePtr; + ElementIter& theEles = domain->getElements(); + while ((elePtr = theEles()) != 0) { + // save element + elements[count] = elePtr; + // element node tags + const ID& ele_nodes = elePtr->getExternalNodes(); + // count number of dofs + size_t dof_count = 0; + for (int i = 0; i < ele_nodes.Size(); ++i) { + size_t pos = nm.getPosition(ele_nodes(i)); + const ID& node_id = nm.node_ids[pos]; + dof_count += static_cast(node_id.Size()); + } + // initialize element data + ID& id = element_ids[count]; + std::vector& uf = element_u_flags[count]; + std::vector& positions = element_node_pos[count]; + id.resize(static_cast(dof_count)); + uf.resize(dof_count); + positions.resize(dof_count); + // remap element data + dof_count = 0; + for (int i = 0; i < ele_nodes.Size(); ++i) { + size_t pos = nm.getPosition(ele_nodes(i)); + const ID& node_id = nm.node_ids[pos]; + const std::vector& node_uf = nm.node_u_flags[pos]; + if (static_cast(dof_count) + node_id.Size() > id.Size()) + DMP_ERR("FE_Element::getID() Size < sum(size(mapped node IDs))"); + for (int j = 0; j < node_id.Size(); ++j) { + id(dof_count) = node_id(j); + uf[dof_count] = node_uf[static_cast(j)]; + positions[dof_count] = pos; + ++dof_count; + } + } + ++count; +#ifdef DMP_VERBOSE + int dof_count_print = 0; + size_t uf_count_print = 0; + size_t pos_count_print = 0; + opserr << "ELEMENT " << elePtr->getTag() << " RE-MAPPING:\n"; + for (size_t i = 0; i < ele_nodes.Size(); ++i) { + size_t pos = nm.getPosition(ele_nodes(i)); + const ID& node_id = nm.node_ids[pos]; + opserr << " [" << ele_nodes(i) << "] ("; + for (int j = 0; j < node_id.Size(); ++j) + opserr << " " << id(dof_count_print++); + opserr << " ) {"; + for (size_t j = 0; j < static_cast(node_id.Size()); ++j) + opserr << " " << uf[uf_count_print++]; + opserr << " } <"; + for (size_t j = 0; j < static_cast(node_id.Size()); ++j) + opserr << " " << static_cast(positions[pos_count_print++]); + opserr << " >\n"; + } +#endif // DMP_VERBOSE + } + } + } + }; +} + +DomainModalProperties::DomainModalProperties(Domain *domain, bool unorm) + : m_domain(domain) + , m_unorm(unorm) +{ +} + +bool +DomainModalProperties::compute() +{ + /* + Notes: + 1 - we assemble the global mass matrix and eigenvectors with our own (plain) numbering + 2 - we make room for rotational DOFs even if some nodes are translational only, because we + also include the rotational effect given by the translational masses gyrating about the + center of mass + 3 - the mass matrix may be consistent. however we need also a diagonalized version of it + to compute the center of mass, the total mass of the structure, and the rotational masses + due to the translational masses gyrating about the center of mass + */ + + Domain* domain = m_domain; + + // number of eigen-modes + int num_eigen = domain->getEigenvalues().Size(); + if (num_eigen < 1) + DMP_ERR("No Eigenvalue provided.\n"); + + // eigenvalues + m_eigenvalues = domain->getEigenvalues(); + // number of dimensions + int ndm = domainSize(domain); + // max number of DOFs per node, translational and rotational only + int ndf = ndm == 2 ? 3 : 6; + // number of nodes + int num_nodes = domain->getNumNodes(); + // number of equations (not the real one, include rotational dofs even if not present) + int num_eq = num_nodes * ndf; + + // initialize members + m_center_of_mass.resize(ndm); + m_total_mass.resize(ndf); + m_total_free_mass.resize(ndf); + m_generalized_mass_matrix.resize(num_eigen); + m_modal_participation_factors.resize(num_eigen, ndf); + m_modal_participation_masses.resize(num_eigen, ndf); + m_modal_participation_masses_cumulative.resize(num_eigen, ndf); + m_modal_participation_mass_ratios.resize(num_eigen, ndf); + m_modal_participation_mass_ratios_cumulative.resize(num_eigen, ndf); + + // map all nodes + node_map_t nodemap(domain, ndm, ndf); + + // map all elements + ele_map_t elemap(domain, nodemap); + + // the sparse mass matrix + SparseMatrix M; + // the equivalent diagonalized masses for each node (total) + Matrix ML(num_nodes, ndf); + // the equivalent diagonalized masses for each node (only at free DOFs) + Matrix MLfree(num_nodes, ndf); + // the array of eigenvectors + std::vector V(num_eigen); + for (auto& iV : V) { + iV.resize(num_eq); + iV.Zero(); + } + + + // + // + // + { + // + // assemble in the sparse mass matrix + // + Vector aux_MD; // auxiliary: sum of each row of iM + Vector aux_ML(ndf); // auxiliary: sum of MD for each DOF + Vector aux_MC(ndf); // auxiliary: sum of consistent mass iM diagonal terms only + Vector aux_C(ndf); // auxiliary: scale factors + Vector aux_Lumped; // auxiliary: lumped diagonalized mass matrix + auto addM = [&M, &ML, &MLfree, &aux_MD, &aux_ML, &aux_MC, &aux_C, &aux_Lumped]( + const Matrix& iM, const ID& iD, const std::vector &uflags, const std::vector &npos) { + int n = iD.Size(); + if (iM.noRows() != n || iM.noCols() != n) + DMP_ERR("Error: inconsistent mass matrix and ID\n"); + + for (int i = 0; i < n; ++i) { + int iloc = iD(i); + if (iloc >= 0) { + for (int j = 0; j < n; ++j) { + int jloc = iD(j); + if (jloc >= 0) { + double value = iM(i, j); + if (value != 0.0) + M.append(iloc, jloc, value); + } + } + } + } + // compute diagonal terms summing each row (it can have negative terms, so + // it cannot be directly used as a lumping approach) + aux_MD.resize(n); + aux_MD.Zero(); + for (int i = 0; i < n; ++i) { + if (uflags[static_cast(i)] >= 0) { + for (int j = 0; j < n; ++j) { + aux_MD(i) += iM(i, j); + } + } + } + // sum terms in MD DOF by DOF. This will give the total mass of the element + // for each DOF + aux_ML.Zero(); + for (int i = 0; i < n; i++) { + int local_dof = uflags[static_cast(i)]; + if (local_dof >= 0) + aux_ML(local_dof) += aux_MD(i); + } + // sum consistent diagonal terms of iM DOF by DOF + aux_MC.Zero(); + for (int i = 0; i < n; i++) { + int local_dof = uflags[static_cast(i)]; + if (local_dof >= 0) + aux_MC(local_dof) += iM(i, i); + } + // obtain scale factors + for (int i = 0; i < aux_C.Size(); ++i) { + double ml = aux_ML(i); + double mc = aux_MC(i); + aux_C(i) = std::abs(mc) > 0.0 ? ml / mc : 0.0; + } + // obtain lumped mass matrix + aux_Lumped.resize(n); + aux_Lumped.Zero(); + for (int i = 0; i < n; ++i) { + int local_dof = uflags[static_cast(i)]; + if (local_dof >= 0) { + aux_Lumped(i) = iM(i, i) * aux_C(local_dof); + int node_pos = npos[static_cast(i)]; + ML(node_pos, local_dof) += aux_Lumped(i); + if (iD(i) >= 0) + MLfree(node_pos, local_dof) += aux_Lumped(i); + } + } + }; + + // assemble in the array of eigenvectors + auto addV = [&V](const Matrix& iV, const ID& iD) { + int n = iD.Size(); + if (iV.noRows() != n || iV.noCols() != static_cast(V.size())) + DMP_ERR("Error: inconsistent eigenvector matrix and ID\n"); + for (int j = 0; j < static_cast(V.size()); ++j) { + auto& jV = V[static_cast(j)]; + for (int i = 0; i < n; ++i) { + int iloc = iD(i); + if (iloc >= 0) + jV(iloc) = iV(i, j); + } + } + }; + + // assemble all element contributions + { + for (size_t i = 0; i < elemap.elements.size(); ++i) { + Element* element = elemap.elements[i]; + const ID& iD = elemap.element_ids[i]; + const std::vector& uflags = elemap.element_u_flags[i]; + const std::vector& npos = elemap.element_node_pos[i]; + const Matrix& iM = element->getMass(); + addM(iM, iD, uflags, npos); + } + } + // assemble all nodal contributions + { + std::vector npos; + for (size_t i = 0; i < nodemap.nodes.size(); ++i) { + Node* node = nodemap.nodes[i]; + const ID& iD = nodemap.node_ids[i]; + const std::vector& uflags = nodemap.node_u_flags[i]; + npos.resize(static_cast(iD.Size())); + std::fill(npos.begin(), npos.end(), i); + const Matrix& iV = node->getEigenvectors(); + const Matrix& iM = node->getMass(); + addM(iM, iD, uflags, npos); + addV(iV, iD); + } + } + } + + // done assemling M + M.finish(); + + + // Normalize eigenvectors such that their max component is 1 + // if requested by the user + m_unorm_scale_factors.resize(num_eigen); + if (m_unorm) { + for (int imode = 0; imode < num_eigen; ++imode) { + Vector& iV = V[static_cast(imode)]; + double umax = 0.0; + for (int i = 0; i < iV.Size(); ++i) + umax = std::max(umax, std::abs(iV(i))); + double scale = umax == 0.0 ? DMP_DBL_LARGE : 1.0 / umax; + for (int i = 0; i < iV.Size(); ++i) + iV(i) *= scale; + m_unorm_scale_factors(imode) = scale; + } + } + else { + for (int imode = 0; imode < num_eigen; ++imode) { + m_unorm_scale_factors(imode) = 1.0; + } + } + + // compute the center of mass. + // note that if the total mass in one of the global directions is 0 + // we sould take the geometric center, as otherwise it will be 0. + // TODO: check wether we need the total or free mass. + // accordingly, for the geometric center... should we use free nodes only? + // let's start with free nodes only... by the way they are the only ones + // accounted for by the eigenvalue analysis... + { + Vector geometric_center(ndm); + Vector com_weight(ndm); // weight for center of mass + Vector cog_weight(ndm); // weight for geometric center + m_center_of_mass.Zero(); + for (int i = 0; i < num_nodes; ++i) { + Node* node = nodemap.nodes[static_cast(i)]; + const ID& ids = nodemap.node_ids[static_cast(i)]; + const Vector& pos = node->getCrds(); + for (int j = 0; j < ndm; ++j) { + if ((j < ids.Size()) && (ids(j) >= 0)) { + double Mij = MLfree(i, j); // use the free masses only + double Pi = pos(j); + geometric_center(j) += Pi; + cog_weight(j) += 1.0; + m_center_of_mass(j) += Pi * Mij; + com_weight(j) += Mij; + } + } + } + for (int j = 0; j < ndm; ++j) { + // finish computing geometric center + if (cog_weight(j) > 0.0) + geometric_center(j) /= cog_weight(j); + // finish computing center of mass. + // select the geometric center if not mass is provided in this component + if (com_weight(j) > 0.0) + m_center_of_mass(j) /= com_weight(j); + else + m_center_of_mass(j) = geometric_center(j); + } + } + + // Now the sparse matrix M contains the orignal mass (consistent or lumped). + // ML is a lumped version of M. for rotational DOFs it contains only the + // rotary masses directly input by the user. + // However we also need to compute, for the modal properties, the rotational + // masses due to the translational masses gyrating about the center of mass. + // Of course this goes only in ML, not in M. + auto compute_extra_rotary_mass = [&nodemap, num_nodes, ndf, this](Matrix& iML) { + for (int i = 0; i < num_nodes; ++i) { + Node* node = nodemap.nodes[static_cast(i)]; + /// const ID& ids = nodemap.node_ids[static_cast(i)]; + const Vector& pos = node->getCrds(); + double dx = pos(0) - m_center_of_mass(0); + double dy = pos(1) - m_center_of_mass(1); + double mx = iML(i, 0); + double my = iML(i, 1); + if (ndf == 3) { // 2D case + iML(i, 2) += dx * dx * my + dy * dy * mx; + } + else { // 3D case + double dz = pos(2) - m_center_of_mass(2); + double mz = iML(i, 2); + iML(i, 3) += dy * dy * mz + dz * dz * my; + iML(i, 4) += dx * dx * mz + dz * dz * mx; + iML(i, 5) += dx * dx * my + dy * dy * mx; + } + } + }; + compute_extra_rotary_mass(ML); + compute_extra_rotary_mass(MLfree); + + // compute the total mass of the domain (total and free-only) + m_total_mass.Zero(); + m_total_free_mass.Zero(); + for (int j = 0; j < ndf; ++j) { + double msum = 0.0; + double msum_free = 0.0; + for (int i = 0; i < num_nodes; ++i) { + msum += ML(i, j); + msum_free += MLfree(i, j); + } + m_total_mass(j) = msum; + m_total_free_mass(j) = msum_free; + } + + + // + // Modal Participation + // + + // now we can compute all the modal masses and participation factors. + // we can do it mode by mode due to their orthogonality. + + // a temporary to store the V'*M product + Vector jVTM(num_eq); + // defines the magnitude of the rigid body response of a DOF + // to imposed rigid body motion (displacement or infinitesimal rotation) in the i-direction. + // each (ndf x 1) block correspond to a node (ordered sequentially as in nodemap), and it is defined as: + // | 1 0 0 0 dz -dz | |e1| + // | 0 1 0 -dz 0 dx | |e2| + // | 0 0 1 dy -dx 0 | |e3| + // | 0 0 0 1 0 0 | |e4| + // | 0 0 0 0 1 0 | |e5| + // | 0 0 0 0 0 1 | |e6| + // where ei is 1, and all the other are 0. + Vector R(num_eq); + // for each j mode... + for (int j = 0; j < num_eigen; ++j) { + + // current mode eigenvector + const Vector& jV = V[j]; + + // compute [V' * M] : a temporary to avoid extra calculations + jVTM.Zero(); + for (const auto& it : M.triplets) + jVTM[it.j] += it.val * jV(it.i); + + // compute [V' * M * V] : generalized mass matrix + double GM = jVTM ^ jV; + m_generalized_mass_matrix(j) = GM; + double invGM = GM == 0.0 ? DMP_DBL_LARGE : 1.0 / GM; + + // for each DOF ... + for (int i = 0; i < ndf; ++i) { + + // compute the rigid-body-mode vector R + R.Zero(); + for (int inode = 0; inode < num_nodes; ++inode) { + int index = inode * ndf; + R(index + i) = 1.0; // one at the current DOF for direct translational or rotational effects + if (i >= ndm) { + const Vector& pos = nodemap.nodes[static_cast(inode)]->getCrds(); + double dx = pos(0) - m_center_of_mass(0); + double dy = pos(1) - m_center_of_mass(1); + if (ndf == 3) { // 2D case + if (i == 2) { + R(index + 0) = -dy; + R(index + 1) = dx; + } + } + else { // 3D case + double dz = pos(2) - m_center_of_mass(2); + if (i == 3) { + R(index + 1) = -dz; + R(index + 2) = dy; + } + else if (i == 4) { + R(index + 0) = dz; + R(index + 2) = -dx; + } + else if (i == 5) { + R(index + 0) = -dy; + R(index + 1) = dx; + } + } + } + } + + // compute [V' * M * R] : generalized load vector + double L = jVTM ^ R; + + // compute [(V' * M * R) / diag(V' * M * V)] : modal participation factors + m_modal_participation_factors(j, i) = L * invGM; + + // compute [(V' * M * R)^2 / diag(V' * M * V)] : effective modal masses + m_modal_participation_masses(j, i) = L * L * invGM; + } + } + + // now we can compute the cumulative masses and ratios + for (int j = 0; j < ndf; ++j) { + double tot_mass = m_total_free_mass(j); + double inv_tot_mass = tot_mass == 0.0 ? DMP_DBL_LARGE : 1.0 / tot_mass; + double accum_1 = 0.0; + double accum_2 = 0.0; + for (int i = 0; i < num_eigen; ++i) { + double mpm = m_modal_participation_masses(i, j); + double mpmr = mpm * inv_tot_mass; + accum_1 += mpm; + accum_2 += mpmr; + m_modal_participation_mass_ratios(i, j) = mpmr; + m_modal_participation_masses_cumulative(i, j) = accum_1; + m_modal_participation_mass_ratios_cumulative(i, j) = accum_2; + } + } + + return true; +} + +namespace +{ +#define DMP_OUT_COMMENT "#" +#define DMP_OUT_RECORD "*" +#define DMP_OUT_BLANK " " +#define DMP_OUT_FLOAT(X) std::setw(14) << std::setprecision(6) << X +#define DMP_OUT_GEN(X) std::setw(14) << X +#define DMP_OUT_HLINE "-------------" +#define DMP_OUT_TOL 1.0e-16 +#define DMP_OUT_REL_TOL 1.0e-12 + + inline double getTolerance(const Vector& x) { + double vmax = 0.0; + for (int i = 0; i < x.Size(); ++i) + vmax = std::max(vmax, std::abs(x(i))); + return std::max(DMP_OUT_REL_TOL * vmax, DMP_OUT_TOL); + } + + inline double getTolerance(const Matrix& x) { + double vmax = 0.0; + for (int i = 0; i < x.noRows(); ++i) + for (int j = 0; j < x.noCols(); ++j) + vmax = std::max(vmax, std::abs(x(i, j))); + return std::max(DMP_OUT_REL_TOL * vmax, DMP_OUT_TOL); + } + + inline double cleanFloat(double x, double tol) { + return std::abs(x) > tol ? x : 0.0; + } + + template + void print_internal(TStream& out, const DomainModalProperties& dmp) + { + // utils + auto print_vec = [&out](const Vector& x, const char* fchar = DMP_OUT_BLANK) { + double tol = getTolerance(x); + out << fchar; + for (int i = 0; i < x.Size(); ++i) + out << DMP_OUT_FLOAT(cleanFloat(x(i), tol)); + out << "\n"; + }; + auto print_mat = [&out](const Matrix& x, double scale = 1.0, const char *fchar = DMP_OUT_BLANK) { + double tol = getTolerance(x); + for (int j = 0; j < x.noRows(); ++j) { + out << fchar << DMP_OUT_GEN(j + 1); + for (int i = 0; i < x.noCols(); ++i) + out << DMP_OUT_FLOAT(scale * cleanFloat(x(j, i), tol)); + out << "\n"; + } + }; + auto print_svec = [&out](const std::vector& x, const char* fchar = DMP_OUT_BLANK) { + out << fchar; + for (size_t i = 0; i < x.size(); ++i) + out << DMP_OUT_GEN(x[i]); + out << "\n"; + }; + + // labels + static std::vector lab_freq = { "MODE", "LAMBDA", "OMEGA", "FREQUENCY", "PERIOD" }; + static std::vector lab_mass_2d = { "MX", "MY", "RMZ" }; + static std::vector lab_mass_3d = { "MX", "MY", "MZ", "RMX", "RMY", "RMZ" }; + static std::vector lab_efmass_2d = { "MODE", "MX", "MY", "RMZ" }; + static std::vector lab_efmass_3d = { "MODE", "MX", "MY", "MZ", "RMX", "RMY", "RMZ" }; + static std::vector lab_pos_2d = { "X", "Y" }; + static std::vector lab_pos_3d = { "X", "Y", "Z" }; + static std::vector lab_sep_2 = { DMP_OUT_HLINE, DMP_OUT_HLINE }; + static std::vector lab_sep_3 = { DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE }; + static std::vector lab_sep_4 = { DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE }; + static std::vector lab_sep_5 = { DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE }; + static std::vector lab_sep_6 = { DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE }; + static std::vector lab_sep_7 = { DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE, DMP_OUT_HLINE }; + + // header + out << DMP_OUT_COMMENT << " MODAL ANALYSIS REPORT\n\n"; + + // problem size + int ndm = dmp.centerOfMass().Size(); + out << DMP_OUT_RECORD << " 1. DOMAIN SIZE:\n" + << DMP_OUT_COMMENT << " This is the size of the problem: 2 for 2D problems, 3 for 3D problems.\n" + << ndm << "\n\n\n"; + + // eigenvalues and derived quantities + out << DMP_OUT_RECORD << " 2. EIGENVALUE ANALYSIS:\n"; + print_svec(lab_freq, DMP_OUT_COMMENT); + print_svec(lab_sep_5, DMP_OUT_COMMENT); + for (int i = 0; i < dmp.eigenvalues().Size(); ++i) { + double lambda = dmp.eigenvalues()(i); + double omega = std::sqrt(lambda); + double freq = omega / 2.0 / M_PI; + double period = 1.0 / freq; + out << DMP_OUT_BLANK << DMP_OUT_GEN(i + 1) + << DMP_OUT_FLOAT(lambda) + << DMP_OUT_FLOAT(omega) + << DMP_OUT_FLOAT(freq) + << DMP_OUT_FLOAT(period) + << "\n"; + } + out << "\n\n"; + + // total mass + out << DMP_OUT_RECORD << " 3. TOTAL MASS OF THE STRUCTURE:\n" + << DMP_OUT_COMMENT << " The total masses (translational and rotational) of the structure\n" + << DMP_OUT_COMMENT << " including the masses at fixed DOFs (if any).\n"; + print_svec(ndm == 2 ? lab_mass_2d : lab_mass_3d, DMP_OUT_COMMENT); + print_svec(ndm == 2 ? lab_sep_3 : lab_sep_6, DMP_OUT_COMMENT); + print_vec(dmp.totalMass()); + out << "\n\n"; + out << DMP_OUT_RECORD << " 4. TOTAL FREE MASS OF THE STRUCTURE:\n" + << DMP_OUT_COMMENT << " The total masses (translational and rotational) of the structure\n" + << DMP_OUT_COMMENT << " including only the masses at free DOFs.\n"; + print_svec(ndm == 2 ? lab_mass_2d : lab_mass_3d, DMP_OUT_COMMENT); + print_svec(ndm == 2 ? lab_sep_3 : lab_sep_6, DMP_OUT_COMMENT); + print_vec(dmp.totalFreeMass()); + out << "\n\n"; + + // center of mass + out << DMP_OUT_RECORD << " 5. CENTER OF MASS:\n" + << DMP_OUT_COMMENT << " The center of mass of the structure, calculated from free masses.\n"; + print_svec(ndm == 2 ? lab_pos_2d : lab_pos_3d, DMP_OUT_COMMENT); + print_svec(ndm == 2 ? lab_sep_2 : lab_sep_3, DMP_OUT_COMMENT); + print_vec(dmp.centerOfMass()); + out << "\n\n"; + + // modal participation factors + out << DMP_OUT_RECORD << " 6. MODAL PARTICIPATION FACTORS:\n" + << DMP_OUT_COMMENT << " The participation factor for a certain mode 'a' in a certain direction 'i'\n" + << DMP_OUT_COMMENT << " indicates how strongly displacement along (or rotation about)\n" + << DMP_OUT_COMMENT << " the global axes is represented in the eigenvector of that mode.\n"; + print_svec(ndm == 2 ? lab_efmass_2d : lab_efmass_3d, DMP_OUT_COMMENT); + print_svec(ndm == 2 ? lab_sep_4 : lab_sep_7, DMP_OUT_COMMENT); + print_mat(dmp.modalParticipationFactors()); + out << "\n\n"; + + // modal participation masses + out << DMP_OUT_RECORD << " 7. MODAL PARTICIPATION MASSES:\n" + << DMP_OUT_COMMENT << " The modal participation masses for each mode.\n"; + print_svec(ndm == 2 ? lab_efmass_2d : lab_efmass_3d, DMP_OUT_COMMENT); + print_svec(ndm == 2 ? lab_sep_4 : lab_sep_7, DMP_OUT_COMMENT); + print_mat(dmp.modalParticipationMasses()); + out << "\n\n"; + + // modal participation masses (cumulative) + out << DMP_OUT_RECORD << " 8. MODAL PARTICIPATION MASSES (cumulative):\n" + << DMP_OUT_COMMENT << " The cumulative modal participation masses for each mode.\n"; + print_svec(ndm == 2 ? lab_efmass_2d : lab_efmass_3d, DMP_OUT_COMMENT); + print_svec(ndm == 2 ? lab_sep_4 : lab_sep_7, DMP_OUT_COMMENT); + print_mat(dmp.modalParticipationMassesCumulative()); + out << "\n\n"; + + // modal participation masses + out << DMP_OUT_RECORD << " 9. MODAL PARTICIPATION MASS RATIOS (%):\n" + << DMP_OUT_COMMENT << " The modal participation mass ratios (%) for each mode.\n"; + print_svec(ndm == 2 ? lab_efmass_2d : lab_efmass_3d, DMP_OUT_COMMENT); + print_svec(ndm == 2 ? lab_sep_4 : lab_sep_7, DMP_OUT_COMMENT); + print_mat(dmp.modalParticipationMassRatios(), 100.0); + out << "\n\n"; + + // modal participation masses (cumulative) + out << DMP_OUT_RECORD << " 10. MODAL PARTICIPATION MASS RATIOS (%) (cumulative):\n" + << DMP_OUT_COMMENT << " The cumulative modal participation mass ratios (%) for each mode.\n"; + print_svec(ndm == 2 ? lab_efmass_2d : lab_efmass_3d, DMP_OUT_COMMENT); + print_svec(ndm == 2 ? lab_sep_4 : lab_sep_7, DMP_OUT_COMMENT); + print_mat(dmp.modalParticipationMassRatiosCumulative(), 100.0); + out << "\n\n"; + } +} + +void +DomainModalProperties::print() +{ + std::stringstream ss; + print_internal(ss, *this); + std::string s = ss.str(); + opserr << s.c_str(); +} + +void +DomainModalProperties::print(const std::string& file_name) +{ + std::ofstream ss(file_name); + if (!ss.is_open()) + DMP_ERR("Cannot open file \"" << file_name.c_str() << "\"\n"); + print_internal(ss, *this); + ss.close(); +} + + diff --git a/SRC/runtime/commands/analysis/modal/DomainModalProperties.h b/SRC/runtime/commands/analysis/modal/DomainModalProperties.h new file mode 100644 index 0000000000..376d39664a --- /dev/null +++ b/SRC/runtime/commands/analysis/modal/DomainModalProperties.h @@ -0,0 +1,102 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.0 $ +// $Date: 2020-11-27 18:07:11 $ +// $Source: /usr/local/cvs/OpenSees/SRC/domain/domain/DomainModalProperties.h,v $ + +// Written: Massimo Petracca (ASDEA Software) +// Created: Fri Nov 27 18:07:11: 2020 +// Revision: A +// +// Description: This file contains the class definition for DomainModalProperties. +// It contains all data optionally computed after an Eigenvalue analysis. +// +// What: "@(#) DomainModalProperties.h, revA" + +#ifndef DomainModalProperties_h +#define DomainModalProperties_h + +#include +#include +#include + +class Domain; + +class DomainModalProperties +{ +public: + DomainModalProperties(Domain* domain, bool unorm); + DomainModalProperties(const DomainModalProperties&) = default; + DomainModalProperties& operator = (const DomainModalProperties&) = default; + +public: + Domain* getDomain() const { return m_domain; } + bool compute(); + void print(); + void print(const std::string& file_name); + +public: + inline bool isUnormalized() const { return m_unorm; } + inline const Vector& eigenVectorScaleFactors() const { return m_unorm_scale_factors; } + inline const Vector& centerOfMass() const { return m_center_of_mass; } + inline const Vector& totalMass() const { return m_total_mass; } + inline const Vector& totalFreeMass() const { return m_total_free_mass; } + inline const Vector& eigenvalues() const { return m_eigenvalues; } + inline const Vector& generalizedMasses() const { return m_generalized_mass_matrix; } + inline const Matrix& modalParticipationFactors() const { return m_modal_participation_factors; } + inline const Matrix& modalParticipationMasses() const { return m_modal_participation_masses; } + inline const Matrix& modalParticipationMassesCumulative() const { return m_modal_participation_masses_cumulative; } + inline const Matrix& modalParticipationMassRatios() const { return m_modal_participation_mass_ratios; } + inline const Matrix& modalParticipationMassRatiosCumulative() const { return m_modal_participation_mass_ratios_cumulative; } + +private: + Domain* m_domain; + // optional flag to force eigenvector displacement-normalization + bool m_unorm; + // the scale factors for each eigenvector (equal to 1 if unorm==false) (size = NUM_MODES) + Vector m_unorm_scale_factors; + // the center of mass (size = NDM) + Vector m_center_of_mass; + // the total mass of the domain including the mass of fixed DOFs (size = NDF : 3 if NDM==2, 6 if NDM==3) + Vector m_total_mass; + // the total mass of the domain excluding the mass of fixed DOFs (size = NDF : 3 if NDM==2, 6 if NDM==3) + Vector m_total_free_mass; + // eigenvalues (size = NUM_MODES) + Vector m_eigenvalues; + // diag(V'*M*V) + // the diagonal of the generalized mass matrix (size = NUM_MODES) + // we store this because it the eigenvectors are not properly normalized + // the diagonal entries won't be 1 + Vector m_generalized_mass_matrix; + // (V'*M*R)/diag(V'*M*V) + // the modal participation factors (size = NUM_MODES x NDF) + Matrix m_modal_participation_factors; + // ((V'*M*R)^2)/diag(V'*M*V) + // the modal participation masses (size = NUM_MODES x NDF) + Matrix m_modal_participation_masses; + Matrix m_modal_participation_masses_cumulative; + // ((V'*M*R)^2)/diag(V'*M*V)/m_total_free_mass*100 + // the modal participation mass ratio (%) (size = NUM_MODES x NDF) + Matrix m_modal_participation_mass_ratios; + Matrix m_modal_participation_mass_ratios_cumulative; +}; + +#endif \ No newline at end of file diff --git a/SRC/runtime/commands/analysis/modal/ResponseSpectrumAnalysis.cpp b/SRC/runtime/commands/analysis/modal/ResponseSpectrumAnalysis.cpp new file mode 100644 index 0000000000..95667d6efb --- /dev/null +++ b/SRC/runtime/commands/analysis/modal/ResponseSpectrumAnalysis.cpp @@ -0,0 +1,317 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.0 $ +// $Date: 2020-11-27 18:07:11 $ +// $Source: /usr/local/cvs/OpenSees/SRC/analysis/analysis/ResponseSpectrumAnalysis.h,v $ + +// Written: Massimo Petracca (ASDEA Software) +// Created: Fri Nov 27 18:07:11: 2020 +// Revision: A +// +// Description: This file contains the class definition for ResponseSpectrumAnalysis. +// +// What: "@(#) ResponseSpectrumAnalysis.h, revA" + +#include +#include "ResponseSpectrumAnalysis.h" +#include "DomainModalProperties.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#if defined(_WIN32) +#ifndef NOMINMAX +#define NOMINMAX +#endif +#endif + +ResponseSpectrumAnalysis::ResponseSpectrumAnalysis( + DomainModalProperties& mp, + TimeSeries* theFunction, + const std::vector& Tn, + const std::vector& Sa, + int theDirection, + double scale +) + : mp(mp) + , m_domain(mp.getDomain()) + , m_function(theFunction) + , m_Tn(Tn) + , m_Sa(Sa) + , m_direction(theDirection) + , m_scale(scale) + , m_current_mode(0) +{ + +} + +ResponseSpectrumAnalysis::~ResponseSpectrumAnalysis() +{ +} + +int +ResponseSpectrumAnalysis::analyze() +{ + // get the domain + Domain* domain = m_domain; + + // size info + int num_eigen = domain->getEigenvalues().Size(); + + // check consistency + int error_code; + error_code = check(); + if (error_code < 0) + return error_code; + + // loop over all required eigen-modes, compute the modal displacement + // and save the results. + // we just compute modal displacements without doing any (SRSS, CQC, etc..) + // modal combination otherwise derived results cannot be computed. + // for each mode, this analysis produces a new analysis step. + // modal combination of displacements (or any derived results) + // it's up to the user. + for (m_current_mode = 0; m_current_mode < num_eigen; ++m_current_mode) + { + // init the new step + error_code = beginMode(); + if (error_code < 0) return error_code; + + // compute modal acceleration for this mode using the + // provided response spectrum function (time series) + error_code = solveMode(); + if (error_code < 0) return error_code; + + // done with the current step. + // here the modal displacements will be recorded (and all other results + // if requested via recorders...) + error_code = endMode(); + if (error_code < 0) return error_code; + } + + return 0; +} + +int +ResponseSpectrumAnalysis::analyze(int mode_id) +{ + // get the domain + Domain* domain = m_domain; + + // size info + int num_eigen = domain->getEigenvalues().Size(); + if (mode_id < 0 || mode_id >= num_eigen) { + opserr << "ResponseSpectrumAnalysis::analyze(mode_id) - The provided mode_id (" << mode_id + 1 << ") is out of range (1, " << num_eigen << ")\n"; + return -1; + } + m_current_mode = mode_id; + + // check consistency + int error_code; + error_code = check(); + if (error_code < 0) return error_code; + + // init the new step + error_code = beginMode(); + if (error_code < 0) return error_code; + + // compute modal acceleration for this mode using the + // provided response spectrum function (time series) + error_code = solveMode(); + if (error_code < 0) return error_code; + + // done with the current step. + // here the modal displacements will be recorded (and all other results + // if requested via recorders...) + error_code = endMode(); + if (error_code < 0) return error_code; + + return 0; +} + +int +ResponseSpectrumAnalysis::check() +{ + // get the domain + Domain* domain = m_domain; + + + // number of eigen-modes + int num_eigen = domain->getEigenvalues().Size(); + if (num_eigen < 1) { + opserr << "ResponseSpectrumAnalysis::check() - No Eigenvalue provided.\n"; + return -1; + } + + // check consistency + { + const Vector& ev = domain->getEigenvalues(); + if (ev.Size() != mp.eigenvalues().Size()) + return -2; + double tol = std::max(1.0e-15, 1.0e-12 * ev.Norm()); + for (int i = 0; i < ev.Size(); ++i) { + double a = ev(i); + double b = mp.eigenvalues()(i); + if (std::abs(a - b) > tol) + return -2; + } + return 0; + }; + + return 0; +} + +int +ResponseSpectrumAnalysis::beginMode() +{ + // new step... (do nothing) + if (m_domain->analysisStep(0.0) < 0) { + opserr << "ResponseSpectrumAnalysis::analyze() - the AnalysisModel failed" + " at mode " << m_current_mode << "\n"; + return -1; + } + + return 0; +} + +int ResponseSpectrumAnalysis::endMode() +{ + // update domain + if (m_domain->update() < 0) { + opserr << "ResponseSpectrumAnalysis::analyze() - the AnalysisModel failed in updateDomain" + " at mode " << m_current_mode << "\n"; + return -1; + } + // update Handler (cmp) + + // commit domain + if (m_domain->commit() < 0) { + opserr << "ResponseSpectrumAnalysis::analyze() - the AnalysisModel failed in commitDomain" + " at mode " << m_current_mode << "\n"; + return -1; + } + + return 0; +} + +int +ResponseSpectrumAnalysis::solveMode() +{ + // get the domain + Domain* domain = m_domain; + + + // size info + int ndf = mp.totalMass().Size(); + + // excited DOF. + // Note: now we assume that a RS acts along one of the global directions, so we need + // to consider only the associated column of the modal participation factors. + // in future versions we can implement a general direction vector. + int exdof = m_direction - 1; // make it 0-based + + // compute modal acceleration for this mode using the + // provided response spectrum function (time series) + double lambda = mp.eigenvalues()(m_current_mode); + double omega = std::sqrt(lambda); + double freq = omega / 2.0 / M_PI; + double period = 1.0 / freq; + double mga = getSa(period); + double Vscale = mp.eigenVectorScaleFactors()(m_current_mode); + double MPF = mp.modalParticipationFactors()(m_current_mode, exdof); + + // loop over all nodes and compute the modal displacements + Node* node; + NodeIter& theNodes = domain->getNodes(); + while ((node = theNodes()) != 0) { + + // get the nodal eigenvector, according to the ndf of modal properties + // and its scaling + const Matrix& node_evec = node->getEigenvectors(); + int node_ndf = node_evec.noRows(); + + // for each DOF... + for (int i = 0; i < std::min(node_ndf, ndf); ++i) { + // exclude any dof >= node_ndf (if ndf > node_ndf... in case node is U-only) + // exclude any dof >= ndf (if node_ndf > ndf... in case the node has more DOFs than U and R) + + // we also need to exclude pressure dofs... easy in 3D because node_ndf is 4, + // but in 2D it is 3, as in U-R... + if (ndf == 6 && node_ndf == 4 && i == 3) + continue; + + // eigenvector + double V = node_evec(i, m_current_mode) * Vscale; + + // compute modal displacements for the i-th DOF + double u_modal = V * MPF * mga / lambda; + + // save this displacement at the i-th dof as new trial displacement + node->setTrialDisp(u_modal, i); + } + + } + + return 0; +} + +double ResponseSpectrumAnalysis::getSa(double T) const +{ + // use the time series if provided + if (m_function) + return m_function->getFactor(T); + // otherwise use the vectors + std::size_t n = m_Tn.size(); + // check empty + if (n < 1) + return 0.0; + // check constant + if (n == 1) + return m_Sa[0]; + // check bounds + if (T <= m_Tn.front()) + return m_Sa.front(); + if (T >= m_Tn.back()) + return m_Sa.back(); + // interpolate + for (std::size_t i = 1; i < n; ++i) { + double t1 = m_Tn[i]; + if (T <= t1) { + double t0 = m_Tn[i - 1]; + double s1 = m_Sa[i]; + double s0 = m_Sa[i - 1]; + double dT = t1 - t0; + double dS = s1 - s0; + double scale = dT > 0.0 ? (T - t0) / dT : 0.5; + return s0 + scale * dS; + } + } + return m_Sa.back(); +} diff --git a/SRC/runtime/commands/analysis/modal/ResponseSpectrumAnalysis.h b/SRC/runtime/commands/analysis/modal/ResponseSpectrumAnalysis.h new file mode 100644 index 0000000000..509a8eb536 --- /dev/null +++ b/SRC/runtime/commands/analysis/modal/ResponseSpectrumAnalysis.h @@ -0,0 +1,78 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.0 $ +// $Date: 2020-11-27 18:07:11 $ +// $Source: /usr/local/cvs/OpenSees/SRC/analysis/analysis/ResponseSpectrumAnalysis.h,v $ + +// Written: Massimo Petracca (ASDEA Software) +// Created: Fri Nov 27 18:07:11: 2020 +// Revision: A +// +// Description: This file contains the class definition for ResponseSpectrumAnalysis. +// +// What: "@(#) ResponseSpectrumAnalysis.h, revA" + + +#include +class Domain; +class TimeSeries; +class DomainModalProperties; + +class ResponseSpectrumAnalysis +{ +public: + ResponseSpectrumAnalysis( + DomainModalProperties&, + TimeSeries*, + const std::vector& Tn, + const std::vector& Sa, + int theDirection, + double scale + ); + ~ResponseSpectrumAnalysis(); + +public: + int analyze(); + int analyze(int mode_id); + +private: + int check(); + int beginMode(); + int endMode(); + int solveMode(); + double getSa(double T) const; + +private: + DomainModalProperties& mp; + Domain* m_domain; + // the response spectrum function + TimeSeries* m_function; + std::vector m_Tn; + std::vector m_Sa; + // the direction 1 to 3 (for 2D models) or 1 to 6 (for 3D models) + int m_direction; + // the scale factor for the computed displacement field + double m_scale; + // current mode + int m_current_mode; +}; + + diff --git a/SRC/runtime/commands/analysis/modal/modal.cpp b/SRC/runtime/commands/analysis/modal/modal.cpp new file mode 100644 index 0000000000..9331d191c6 --- /dev/null +++ b/SRC/runtime/commands/analysis/modal/modal.cpp @@ -0,0 +1,352 @@ +#include +#include +#include + +#include +#include "DomainModalProperties.h" +#include "ResponseSpectrumAnalysis.h" + + +namespace OpenSees { + +Tcl_CmdProc responseSpectrumAnalysis; + +namespace DomainCommands { + +int +modalProperties(ClientData clientData, + Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + // modalProperties <-print> <-file $fileName> <-unorm> + + // some kudos + static bool first_done = false; + if (!first_done) { + opserr << "Using DomainModalProperties - Developed by: Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; + first_done = true; + } + + // init default values + bool unorm = false; // by default do not displacement-normalize eigenvectors + bool print_on_console = false; // by default do not print on console + bool print_on_file = false; // by default do no print on file + std::string fname; + + // check options + int loc = 1; + while (loc < argc) { + if (strcmp(argv[loc], "-unorm") == 0) { + unorm = true; + } + else if (strcmp(argv[loc], "-print") == 0) { + print_on_console = true; + } + else if (strcmp(argv[loc], "-file") == 0) { + print_on_file = true; + if (loc < argc - 1) { + ++loc; + fname = argv[loc]; + } + else { + opserr << "Error in modalProperties; " + "After the keyword -file you should specify the file name.\n"; + return TCL_ERROR; + } + } + ++loc; + } + + + Domain* domain = static_cast(clientData); + + // create the modal properties, compute them, + // and add them to the domain + DomainModalProperties *modal_props = new DomainModalProperties(domain, unorm); + if (!modal_props->compute()) + return TCL_ERROR; + // domain->setModalProperties(modal_props); + + // report + if (print_on_console) + modal_props->print(); + + if (print_on_file) + modal_props->print(fname); + + + Tcl_CreateCommand(interp, "responseSpectrumAnalysis", + responseSpectrumAnalysis, modal_props, nullptr); + + return TCL_OK; +} + +} // namespace DomainCommands + + +int +responseSpectrumAnalysis(ClientData clientData, + Tcl_Interp* interp, + Tcl_Size argc, + const char** const argv) +{ + // responseSpectrum $tsTag $dir <-scale $scale> + // + + // some kudos + static bool first_done = false; + if (!first_done) { + opslog << "Using ResponseSpectrumAnalysis - Developed by: Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; + first_done = true; + } + + if (clientData == nullptr) { + opserr << "ResponseSpectrumAnalysis - eigen and modalProperties have not been called" << endln; + return TCL_ERROR; + } + + + // make sure eigenvalue and modal properties have been called before + DomainModalProperties& modal_props = *static_cast(clientData); + + int ndf = modal_props.totalMass().Size(); + + + // + // parse + // + // ResponseSpectrumAnalysis $tsTag $dir <-scale $scale> <-damp $damp> + // or + // ResponseSpectrumAnalysis $dir -Tn $TnValues -fn $fnValues -Sa $SaValues <-scale $scale> <-damp $damp> + // + + // init default arguments + TimeSeries* ts = nullptr; + int dir = 1; + double scale = 1.0; + std::vector Tn; + std::vector Sa; + int mode_id = 0; + bool single_mode = false; + + + int nargs = argc - 1; // skip the command name + if (nargs < 2) { + opserr << "ResponseSpectrumAnalysis $tsTag $dir <-scale $scale> <-damp $damp>\n" + << "or\n" + << "ResponseSpectrumAnalysis $dir -Tn $TnValues -fn $fnValues -Sa $SaValues <-scale $scale> <-damp $damp>\n" + "Error: at least 2 arguments should be provided.\n"; + return TCL_ERROR; + } + + // search for -Tn -Sa, if both found we use them as lists + // otherwise we fallback to the old implementation of the timeSeries + bool found_Tn = false; + bool found_Sa = false; + for (int i=1; i <-damp $damp> + + int tstag; + if (Tcl_GetInt(interp, argv[argi], &tstag) != TCL_OK) { + opserr << "ResponseSpectrumAnalysis Error: Failed to get timeSeries tag.\n"; + return TCL_ERROR; + } + + // ts = OPS_getTimeSeries(tstag); + if (ts == nullptr) { + opserr << "ResponseSpectrumAnalysis Error: Failed to get timeSeries with tag = " << tstag << ".\n"; + return TCL_ERROR; + } + + argi++; // move to the next argument + } + + // get direction + if (Tcl_GetInt(interp, argv[argi], &dir) != TCL_OK) { + opserr << "ResponseSpectrumAnalysis Error: Failed to get direction.\n"; + return TCL_ERROR; + } + if (dir < 1 || dir > ndf) { + opserr << "ResponseSpectrumAnalysis Error: provided direction (" << dir << ") should be in the range 1-" << ndf << ".\n"; + return TCL_ERROR; + } + + // parse optional data + for (int i=argi; i= argc) { + opserr << "ResponseSpectrumAnalysis Error: scale factor requested but not provided.\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i+1], &scale) < 0) { + opserr << "ResponseSpectrumAnalysis Error: Failed to get scale factor.\n"; + return TCL_ERROR; + } + i++; + } + + else if (strcmp(value, "-mode") == 0) { + if (i + 1 >= argc) { + opserr << "ResponseSpectrumAnalysis Error: mode_id requested but not provided.\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[i + 1], &mode_id) < 0) { + opserr << "ResponseSpectrumAnalysis Error: Failed to get mode_id.\n"; + return TCL_ERROR; + } + --mode_id; // make it 0-based + single_mode = true; + i++; + } + + else if (strcmp(value, "-Tn") == 0 || strcmp(value, "-fn") == 0) { + // first try expanded list like {*}$the_list, + // also used in python like *the_list + Tn.clear(); + if (i + 1 >= argc) { + opserr << "ResponseSpectrumAnalysis Error: Tn values requested but not provided.\n"; + return TCL_ERROR; + } + + for (int j=i+1; j= argc) { + opserr << "ResponseSpectrumAnalysis Error: Sa values requested but not provided.\n"; + return TCL_ERROR; + } + + for (int j = i + 1; j < argc; j++) { + double item; + if (Tcl_GetDouble(interp, argv[j], &item) != TCL_OK) { + break; + } + Sa.push_back(item); + } + + if (Sa.size() == 0) { + // try Tcl list + int sa_argc; + const char** sa_argv = nullptr; + if (Tcl_SplitList(interp, argv[i + 1], &sa_argc, &sa_argv) != TCL_OK) { + opserr << "ResponseSpectrumAnalysis Error: cannot parse the Sa list.\n"; + return TCL_ERROR; + } + for (int j = 0; j < sa_argc; ++j) { + double item; + if (Tcl_GetDouble(interp, sa_argv[j], &item) != TCL_OK) { + opserr << "ResponseSpectrumAnalysis Error: cannot parse the Sa list.\n"; + Tcl_Free((char*)sa_argv); + return TCL_ERROR; + } + Sa.push_back(item); + } + Tcl_Free((char*)sa_argv); + } + } + } + + // check Tn and Sa vectors + if (use_lists) { + if (Tn.size() != Sa.size()) { + opserr << "ResponseSpectrumAnalysis Error: Sa and Tn lists must have the same length\n"; + opserr << (int)Tn.size() << " != " << (int)Sa.size() << "\n"; + return TCL_ERROR; + } + if (Tn.size() == 0) { + opserr << "ResponseSpectrumAnalysis Error: Sa and Tn lists cannot be empty\n"; + return TCL_ERROR; + } + for (std::size_t i = 0; i < Tn.size(); ++i) { + if (Tn[i] < 0.0) { + opserr << "ResponseSpectrumAnalysis Error: Tn values must be positive (found " << Tn[i] << ")\n"; + return TCL_ERROR; + } + if (i > 0 && Tn[i] <= Tn[i - 1]) { + opserr << "ResponseSpectrumAnalysis Error: Tn values must be monotonically increasing (found " << Tn[i] << " after " << Tn[i - 1] << ")\n"; + return TCL_ERROR; + } + } + for (double item : Sa) { + if (item < 0.0) { + opserr << "ResponseSpectrumAnalysis Error: Sa values must be positive (found " << item << ")\n"; + return TCL_ERROR; + } + } + } + + // ok, create the response spectrum analysis and run it here... + // no need to store it + ResponseSpectrumAnalysis rsa(modal_props, ts, Tn, Sa, dir, scale); + int result; + if (single_mode) + result = rsa.analyze(mode_id); + else + result = rsa.analyze(); + + return result == 0? TCL_OK : TCL_ERROR; +} + + +} // namespace OpenSees \ No newline at end of file diff --git a/SRC/runtime/commands/analysis/numberer.cpp b/SRC/runtime/commands/analysis/numberer.cpp index f54cd2ce68..3c764e11ce 100644 --- a/SRC/runtime/commands/analysis/numberer.cpp +++ b/SRC/runtime/commands/analysis/numberer.cpp @@ -1,17 +1,18 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file implements the selection of a Numberer object, // which is used to optimally number the degrees of freedom of a problem. // #include #include #include -#include -#include +#include +#include #include #include diff --git a/SRC/runtime/commands/analysis/sensitivity.cpp b/SRC/runtime/commands/analysis/sensitivity.cpp index 324e022a59..22d75ec5bd 100644 --- a/SRC/runtime/commands/analysis/sensitivity.cpp +++ b/SRC/runtime/commands/analysis/sensitivity.cpp @@ -1,57 +1,109 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// #include -#include -#include +#include +#include +#include +#include +#include +#include +#include + + +int +computeGradients(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char**const argv) +{ + BasicAnalysisBuilder *builder = static_cast(clientData); + + if (builder->analyzeGradient() < 0) { + opserr << OpenSees::PromptValueError << "failed to compute sensitivities\n"; + return TCL_ERROR; + } + + return TCL_OK; +} int -TclCommand_sensitivityAlgorithm(ClientData builder, Tcl_Interp* interp, int argc, TCL_Char**const argv) +TclCommand_sensLambda(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { - if (builder == nullptr) - return 0; - - int analysisTypeTag = 1; - - Integrator* theIntegrator = nullptr; - - if (builder->getStaticIntegrator() != nullptr) { - theIntegrator = builder->getStaticIntegrator(); - - } else if(builder->getTransientIntegrator() != nullptr) { - theIntegrator = builder->getTransientIntegrator(); - } - - - // 1: compute at each step (default); - // 2: compute by command; - if (OPS_GetNumRemainingInputArgs() < 1) { - opserr << "ERROR: Wrong number of parameters to sensitivity algorithm." << "\n"; - return -1; - } - if (theIntegrator == nullptr) { - opserr << "The integrator needs to be instantiated before " << "\n" - << " setting sensitivity algorithm." << "\n"; - return -1; - } - - const char* type = OPS_GetString(); - if (strcmp(type,"-computeAtEachStep") == 0) - analysisTypeTag = 1; - else if (strcmp(type,"-computeByCommand") == 0) - analysisTypeTag = 2; - else { - opserr << "Unknown sensitivity algorithm option: " << type << "\n"; - return -1; - } - - theIntegrator->setComputeType(analysisTypeTag); - theIntegrator->activateSensitivityKey(); - - return 0; + BasicAnalysisBuilder* builder = static_cast(clientData); + + if (argc < 3) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + return TCL_ERROR; + } + + int pattern, paramTag; + if (Tcl_GetInt(interp, argv[1], &pattern) != TCL_OK) { + opserr << "ERROR reading load pattern tag\n"; + return TCL_ERROR; + } + + LoadPattern *thePattern = builder->getDomain()->getLoadPattern(pattern); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << pattern + << " not found in domain\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2], ¶mTag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "sensLambda patternTag? paramTag? - could not read " + "paramTag? "; + return TCL_ERROR; + } + + Parameter *theParam = builder->getDomain()->getParameter(paramTag); + if (theParam == nullptr) { + opserr << OpenSees::PromptValueError + << "sensLambda: parameter " << paramTag << " not found" << "\n"; + return TCL_ERROR; + } + + int gradIndex = theParam->getGradIndex(); + double value = thePattern->getLoadFactorSensitivity(gradIndex); + + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(value)); + + return TCL_OK; +} + + +int +TclCommand_sensitivityAlgorithm(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char**const argv) +{ + BasicAnalysisBuilder *builder = static_cast(clientData); + + if (argc < 2) { + opserr << "ERROR: Wrong number of parameters to sensitivity algorithm." << "\n"; + return TCL_ERROR; + } + + // 1: compute at each step (default); + // 2: compute by command; + + int analysisTypeTag = 1; + if (strcmp(argv[1],"-computeAtEachStep") == 0) + analysisTypeTag = 1; + + else if (strcmp(argv[1],"-computeByCommand") == 0) + analysisTypeTag = 2; + + else { + opserr << "Unknown sensitivity algorithm option: " << argv[1] << "\n"; + return TCL_ERROR; + } + + if (builder->setGradientType(analysisTypeTag) < 0) { + return TCL_ERROR; + } + + return TCL_OK; } diff --git a/SRC/runtime/commands/analysis/solver.cpp b/SRC/runtime/commands/analysis/solver.cpp index 66239dd0e9..1abd16de83 100644 --- a/SRC/runtime/commands/analysis/solver.cpp +++ b/SRC/runtime/commands/analysis/solver.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file implements commands that configure the linear // solver. // @@ -15,21 +16,15 @@ #else # include #endif -// #define strcmp strcasecmp #include -#include +#include +#include #include // #include "analysis.h" -#include #include "solver.hpp" #include "BasicAnalysisBuilder.h" -// analysis -#include -#include -#include - // system of eqn and solvers #include #include @@ -73,42 +68,36 @@ // extern DirectIntegrationAnalysis *theTransientAnalysis; // extern LinearSOE *theSOE; -// LinearSOE* -// G3Parse_newLinearSOE(G3_Runtime*, int, G3_Char **); + LinearSOE* -// G3Parse_newLinearSOE(G3_Runtime* rt, int argc, G3_Char ** const argv) G3Parse_newLinearSOE(ClientData, Tcl_Interp* interp, int, G3_Char **const); LinearSOE* TclDispatch_newPetscSOE(ClientData, Tcl_Interp *interp, int, G3_Char **const); -#if 0 // TODO: implement AnalysisBuilder->getLinearSOE(); + int TclCommand_systemSize(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { assert(clientData != nullptr); LinearSOE *theSOE = ((BasicAnalysisBuilder *)clientData)->getLinearSOE(); - char buffer[20]; - - if (theSOE == 0) { - sprintf(buffer, "NO SYSTEM SET"); + if (theSOE == nullptr) { + opserr << "No system has been set"; return TCL_OK; } - sprintf(buffer, "%d", theSOE->getNumEqn()); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewIntObj(theSOE->getNumEqn())); return TCL_OK; } -#endif int specifySysOfEqnTable(ClientData clientData, Tcl_Interp *interp, int argc, G3_Char ** const argv) { // make sure at least one other argument to contain type of system if (argc < 2) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "need to specify a system type" << "\n"; return TCL_ERROR; } @@ -126,7 +115,8 @@ specifySysOfEqnTable(ClientData clientData, Tcl_Interp *interp, int argc, G3_Cha } LinearSOE* -G3Parse_newLinearSOE(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char ** const argv) +G3Parse_newLinearSOE(ClientData clientData, Tcl_Interp* interp, Tcl_Size argc, + G3_Char ** const argv) { G3_Runtime* rt = G3_getRuntime(interp); @@ -140,7 +130,13 @@ G3Parse_newLinearSOE(ClientData clientData, Tcl_Interp* interp, int argc, G3_Cha if (ctor != soe_table.end()) { return ctor->second.ss(rt, argc, argv); - } else if (strcasecmp(argv[1], "Umfpack")==0) { + } +#ifdef XARA_USE_MUMPS + else if (strcasecmp(argv[1], "mumps") == 0) { + return TclDispatch_newMumpsLinearSOE(clientData, interp, argc, argv); + } +#endif + else if (strcasecmp(argv[1], "Umfpack")==0) { // TODO: if "umfpack" is in solver.hpp, this wont be reached return TclDispatch_newUmfpackLinearSOE(clientData, interp, argc, argv); } @@ -186,7 +182,7 @@ G3Parse_newLinearSOE(ClientData clientData, Tcl_Interp* interp, int argc, G3_Cha #endif else { - opserr << G3_ERROR_PROMPT << " system '" << argv[1] << "' is unknown or not installed\n"; + opserr << OpenSees::PromptValueError << " system '" << argv[1] << "' is unknown or not installed\n"; return nullptr; } diff --git a/SRC/runtime/commands/analysis/solver.hpp b/SRC/runtime/commands/analysis/solver.hpp index 83224f00fd..6e4c7d4056 100644 --- a/SRC/runtime/commands/analysis/solver.hpp +++ b/SRC/runtime/commands/analysis/solver.hpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // standard library #include #include @@ -12,10 +13,7 @@ #include #include #include -// analysis -#include -#include -#include + // system of eqn and solvers #include #include @@ -98,8 +96,8 @@ G3_SysOfEqnSpecifier specify_SparseSPD; G3_SysOfEqnSpecifier specifySparseGen; TclDispatch TclDispatch_newMumpsLinearSOE; // TclDispatch TclDispatch_newUmfpackLinearSOE; -LinearSOE* TclDispatch_newUmfpackLinearSOE(ClientData, Tcl_Interp*, int, const char** const); -LinearSOE* TclDispatch_newItpackLinearSOE(ClientData, Tcl_Interp*, int, const char** const); +LinearSOE* TclDispatch_newUmfpackLinearSOE(ClientData, Tcl_Interp*, Tcl_Size, const char** const); +LinearSOE* TclDispatch_newItpackLinearSOE(ClientData, Tcl_Interp*, Tcl_Size, const char** const); // Helpers to automatically create constructors for systems/solvers // that do not take arguments when they are constructed. @@ -115,9 +113,13 @@ struct soefps {fn ss, sp, mp;}; std::unordered_map soe_table = { {"bandspd", { G3_SOE(BandSPDLinLapackSolver, BandSPDLinSOE), +#if 1 + SP_SOE(BandSPDLinLapackSolver, BandSPDLinSOE), + MP_SOE(BandSPDLinLapackSolver, BandSPDLinSOE)}}, +#else SP_SOE(BandSPDLinLapackSolver, DistributedBandSPDLinSOE), MP_SOE(BandSPDLinLapackSolver, DistributedBandSPDLinSOE)}}, - +#endif {"bandgeneral", { // BandGen, BandGEN G3_SOE(BandGenLinLapackSolver, BandGenLinSOE), SP_SOE(BandGenLinLapackSolver, DistributedBandGenLinSOE), @@ -126,13 +128,6 @@ std::unordered_map soe_table = { G3_SOE(BandGenLinLapackSolver, BandGenLinSOE), SP_SOE(BandGenLinLapackSolver, DistributedBandGenLinSOE), MP_SOE(BandGenLinLapackSolver, DistributedBandGenLinSOE)}}, -#if 0 - // TODO: Umfpack - {"umfpack", { - G3_SOE(BandGenLinLapackSolver, BandGenLinSOE), - SP_SOE(BandGenLinLapackSolver, DistributedBandGenLinSOE), - MP_SOE(BandGenLinLapackSolver, DistributedBandGenLinSOE)}}, -#endif {"sparsegen", {specifySparseGen, nullptr, nullptr}}, {"sparsegeneral", {specifySparseGen, nullptr, nullptr}}, @@ -162,13 +157,17 @@ std::unordered_map soe_table = { {"profilespd", { G3_SOE(ProfileSPDLinDirectSolver, ProfileSPDLinSOE), +#ifndef PARALLEL_PROFILESPD + SP_SOE(ProfileSPDLinDirectSolver, ProfileSPDLinSOE), + MP_SOE(ProfileSPDLinDirectSolver, ProfileSPDLinSOE)}}, +#else SP_SOE(ProfileSPDLinDirectSolver, DistributedProfileSPDLinSOE), MP_SOE(ProfileSPDLinDirectSolver, DistributedProfileSPDLinSOE)}}, {"parallelprofilespd", { nullptr, nullptr, MP_SOE(ProfileSPDLinDirectSolver, DistributedProfileSPDLinSOE)}}, - +#endif {"fullgeneral", { G3_SOE(FullGenLinLapackSolver, FullGenLinSOE), SP_SOE(FullGenLinLapackSolver, FullGenLinSOE), diff --git a/SRC/runtime/commands/analysis/spectrum.cpp b/SRC/runtime/commands/analysis/spectrum.cpp new file mode 100644 index 0000000000..95da08d271 --- /dev/null +++ b/SRC/runtime/commands/analysis/spectrum.cpp @@ -0,0 +1,77 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.0 $ +// $Date: 2020-11-27 18:07:11 $ +// $Source: /usr/local/cvs/OpenSees/SRC/analysis/analysis/ResponseSpectrumAnalysis.h,v $ + +// Written: Massimo Petracca (ASDEA Software) +// Created: Fri Nov 27 18:07:11: 2020 +// Revision: A +// +// Description: This file contains the class definition for ResponseSpectrumAnalysis. +// +// What: "@(#) ResponseSpectrumAnalysis.h, revA" + + +#include +class Domain; +class TimeSeries; + +class ResponseSpectrumAnalysis +{ +public: + ResponseSpectrumAnalysis( + DomainModalProperties&, + TimeSeries*, + const std::vector& Tn, + const std::vector& Sa, + int theDirection, + double scale + ); + ~ResponseSpectrumAnalysis(); + +public: + int analyze(); + int analyze(int mode_id); + +private: + int check(); + int beginMode(); + int endMode(); + int solveMode(); + double getSa(double T) const; + +private: + DomainModalProperties& mp; + Domain* m_domain; + // the response spectrum function + TimeSeries* m_function; + std::vector m_Tn; + std::vector m_Sa; + // the direction 1 to 3 (for 2D models) or 1 to 6 (for 3D models) + int m_direction; + // the scale factor for the computed displacement field + double m_scale; + // current mode + int m_current_mode; +}; + + diff --git a/SRC/runtime/commands/analysis/transient.cpp b/SRC/runtime/commands/analysis/transient.cpp index 3016b5deea..7de54416db 100644 --- a/SRC/runtime/commands/analysis/transient.cpp +++ b/SRC/runtime/commands/analysis/transient.cpp @@ -7,19 +7,22 @@ // Written: cmp and cc // #include -#include -#include +#include +#include +#include #include #include #include TransientIntegrator* -TclCommand_newNewmarkIntegrator(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char ** const argv) +TclCommand_newNewmarkIntegrator(ClientData clientData, Tcl_Interp* interp, + Tcl_Size argc, G3_Char ** const argv) { if (argc < 4) { - opserr << G3_ERROR_PROMPT << " incorrect number of args want Newmark $gamma $beta " + opserr << OpenSees::PromptValueError + << " incorrect number of args want Newmark $gamma $beta " "<-form $typeUnknown>\n"; opserr << " got "; for (int i=0; igetDomain(); if (argc < 5) { - opserr << "WARNING insufficient number of UpdateMaterialStage arguments\n"; - opserr << "Want: UpdateMaterialStage material matTag? stage value?" - << endln; + opserr << "WARNING insufficient number of UpdateMaterialStage arguments" + << "\n"; return TCL_ERROR; } if (strcmp(argv[1], "-material") != 0) { - opserr << "WARNING UpdateMaterialStage: Only accept parameter '-material' " - "for now" - << endln; + opserr << "WARNING unknown argument " << argv[1] + << "\n"; return TCL_ERROR; } int materialTag, value; if (Tcl_GetInt(interp, argv[2], &materialTag) != TCL_OK) { - opserr << "WARNING MYSstage: invalid material tag" << endln; + opserr << "WARNING MYSstage: invalid material tag" + << endln; return TCL_ERROR; } @@ -74,6 +80,7 @@ TclCommand_updateMaterialStage(ClientData clientData, parTag++; if (argc > 6) { + // updateMaterialStage -material matTag? ? ? -parameter $tag? if (strcmp(argv[5], "-parameter") == 0) { if (Tcl_GetInt(interp, argv[6], &parTag) != TCL_OK) { opserr << "WARNING UpdateMaterialStage: invalid parameter tag used" @@ -83,8 +90,8 @@ TclCommand_updateMaterialStage(ClientData clientData, } } - MaterialStageParameter *theParameter = - new MaterialStageParameter(parTag, materialTag); + + MaterialStageParameter *theParameter = new MaterialStageParameter(parTag, materialTag); if (domain->addParameter(theParameter) == false) { opserr << "WARNING could not add updateMaterialStage - " "MaterialStageParameter to domain" diff --git a/SRC/runtime/commands/domain/commands.cpp b/SRC/runtime/commands/domain/commands.cpp index ef81a54f1f..f3a76f2af8 100644 --- a/SRC/runtime/commands/domain/commands.cpp +++ b/SRC/runtime/commands/domain/commands.cpp @@ -1,15 +1,17 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // // Description: This file contains the functions that will be called by // the interpreter when the appropriate command name is specified. // #include -#include -#include +#include +#include #include #include // @@ -45,12 +47,8 @@ #include #include // Analysis -#include -#include -#include #include #include -#include #include #include #include @@ -65,8 +63,6 @@ // class ModelBuilder; ModelBuilder *theBuilder = nullptr; -VariableTimeStepDirectIntegrationAnalysis - *theVariableTimeStepTransientAnalysis = nullptr; // // Forward declarations // @@ -89,6 +85,35 @@ G3_AddTclDomainCommands(Tcl_Interp *interp, Domain* the_domain) ClientData domain = (ClientData)the_domain; + { + using namespace OpenSees::DomainCommands; + // Domain + Tcl_CreateObjCommand(interp, "fixedNodes", &fixedNodes, domain, nullptr); + Tcl_CreateObjCommand(interp, "fixedDOFs", &fixedDOFs, domain, nullptr); + Tcl_CreateObjCommand(interp, "constrainedNodes", &constrainedNodes, domain, nullptr); + Tcl_CreateObjCommand(interp, "constrainedDOFs", &constrainedDOFs, domain, nullptr); + Tcl_CreateObjCommand(interp, "domainChange", &domainChange, domain, nullptr); + Tcl_CreateObjCommand(interp, "remove", &removeObject, domain, nullptr); + Tcl_CreateCommand(interp, "retainedNodes", &retainedNodes, domain, nullptr); + Tcl_CreateCommand(interp, "retainedDOFs", &retainedDOFs, domain, nullptr); + // Elements + Tcl_CreateCommand(interp, "localForce", &localForce, domain, nullptr); + Tcl_CreateCommand(interp, "eleType", &eleType, domain, nullptr); + Tcl_CreateCommand(interp, "eleNodes", &eleNodes, domain, nullptr); + Tcl_CreateCommand(interp, "getEleTags", &getEleTags, domain, nullptr); + Tcl_CreateCommand(interp, "getNumElements", &getNumElements, domain, nullptr); + Tcl_CreateCommand(interp, "getEleClassTags", &getEleClassTags, domain, nullptr); + Tcl_CreateCommand(interp, "eleForce", &eleForce, domain, nullptr); + Tcl_CreateCommand(interp, "eleResponse", &eleResponse, domain, nullptr); + Tcl_CreateCommand(interp, "eleDynamicalForce", &eleDynamicalForce, domain, nullptr); + Tcl_CreateCommand(interp, "updateElementDomain", &updateElementDomain, nullptr, nullptr); + // damping + Tcl_CreateCommand(interp, "setElementRayleighDampingFactors", &addElementRayleigh, domain, nullptr); + Tcl_CreateCommand(interp, "setElementRayleighFactors", &addElementRayleigh, domain, nullptr); + // Modal + Tcl_CreateCommand(interp, "modalProperties", &modalProperties, domain, nullptr); + } + Tcl_CreateCommand(interp, "loadConst", &TclCommand_setLoadConst, domain, nullptr); Tcl_CreateCommand(interp, "recorder", &TclAddRecorder, domain, nullptr); Tcl_CreateCommand(interp, "region", &TclCommand_addMeshRegion, domain, nullptr); @@ -101,21 +126,14 @@ G3_AddTclDomainCommands(Tcl_Interp *interp, Domain* the_domain) // DAMPING Tcl_CreateCommand(interp, "rayleigh", &rayleighDamping, domain, nullptr); - - Tcl_CreateCommand(interp, "setElementRayleighDampingFactors", &TclCommand_addElementRayleigh, domain, nullptr); - Tcl_CreateCommand(interp, "setElementRayleighFactors", &TclCommand_addElementRayleigh, domain, nullptr); + Tcl_CreateCommand(interp, "getLoadFactor", &getLoadFactor, domain, nullptr); - Tcl_CreateCommand(interp, "localForce", &localForce, domain, nullptr); - Tcl_CreateCommand(interp, "eleType", &eleType, domain, nullptr); - Tcl_CreateCommand(interp, "eleNodes", &eleNodes, domain, nullptr); - Tcl_CreateCommand(interp, "getEleTags", &TclCommand_getEleTags, domain, nullptr); + + // Tcl_CreateCommand(interp, "basicDeformation", &basicDeformation, domain, nullptr); Tcl_CreateCommand(interp, "basicForce", &basicForce, domain, nullptr); Tcl_CreateCommand(interp, "basicStiffness", &basicStiffness, domain, nullptr); - Tcl_CreateCommand(interp, "eleForce", &eleForce, domain, nullptr); - Tcl_CreateCommand(interp, "eleResponse", &eleResponse, domain, nullptr); - Tcl_CreateCommand(interp, "eleDynamicalForce", &eleDynamicalForce, domain, nullptr); Tcl_CreateCommand(interp, "nodeDOFs", &nodeDOFs, domain, nullptr); Tcl_CreateCommand(interp, "nodeCoord", &nodeCoord, domain, nullptr); @@ -129,35 +147,27 @@ G3_AddTclDomainCommands(Tcl_Interp *interp, Domain* the_domain) Tcl_CreateCommand(interp, "findNodeWithID", &findID, domain, nullptr); Tcl_CreateCommand(interp, "nodeUnbalance", &nodeUnbalance, domain, nullptr); Tcl_CreateCommand(interp, "nodeEigenvector", &nodeEigenvector, domain, nullptr); - Tcl_CreateCommand(interp, "nodeReaction", &nodeReaction, domain, nullptr); + Tcl_CreateCommand(interp, "reactions", &calculateNodalReactions, domain, nullptr); Tcl_CreateCommand(interp, "setNodeVel", &setNodeVel, domain, nullptr); Tcl_CreateCommand(interp, "setNodeDisp", &setNodeDisp, domain, nullptr); Tcl_CreateCommand(interp, "setNodeAccel", &setNodeAccel, domain, nullptr); Tcl_CreateCommand(interp, "setNodeCoord", &setNodeCoord, domain, nullptr); - - Tcl_CreateCommand(interp, "getEleTags", &getEleTags, domain, nullptr); + Tcl_CreateCommand(interp, "nodeRotation", &nodeRotation, domain, nullptr); Tcl_CreateCommand(interp, "getNodeTags", &getNodeTags, domain, nullptr); + + Tcl_CreateCommand(interp, "getParamTags", &getParamTags, domain, nullptr); Tcl_CreateCommand(interp, "getParamValue", &getParamValue, domain, nullptr); Tcl_CreateCommand(interp, "parameter", &TclCommand_parameter, domain, nullptr); Tcl_CreateCommand(interp, "addToParameter", &TclCommand_parameter, domain, nullptr); Tcl_CreateCommand(interp, "updateParameter", &TclCommand_parameter, domain, nullptr); + Tcl_CreateCommand(interp, "setParameter", &TclCommand_setParameter, domain, nullptr); + - Tcl_CreateObjCommand(interp, "fixedNodes", &fixedNodes, domain, nullptr); - Tcl_CreateObjCommand(interp, "fixedDOFs", &fixedDOFs, domain, nullptr); - Tcl_CreateObjCommand(interp, "constrainedNodes", &constrainedNodes, domain, nullptr); - Tcl_CreateObjCommand(interp, "constrainedDOFs", &constrainedDOFs, domain, nullptr); - Tcl_CreateObjCommand(interp, "domainChange", &domainChange, domain, nullptr); - Tcl_CreateObjCommand(interp, "remove", &removeObject, domain, nullptr); - Tcl_CreateCommand(interp, "retainedNodes", &retainedNodes, domain, nullptr); - Tcl_CreateCommand(interp, "retainedDOFs", &retainedDOFs, domain, nullptr); - - Tcl_CreateCommand(interp, "getNumElements", &getNumElements, domain, nullptr); - Tcl_CreateCommand(interp, "getEleClassTags", &getEleClassTags, domain, nullptr); Tcl_CreateCommand(interp, "getEleLoadTags", &getEleLoadTags, domain, nullptr); Tcl_CreateCommand(interp, "getEleLoadData", &getEleLoadData, domain, nullptr); Tcl_CreateCommand(interp, "getEleLoadClassTags", &getEleLoadClassTags, domain, nullptr); @@ -175,13 +185,21 @@ G3_AddTclDomainCommands(Tcl_Interp *interp, Domain* the_domain) Tcl_CreateCommand(interp, "recorderValue", &OPS_recorderValue, domain, nullptr); Tcl_CreateCommand(interp, "record", &TclCommand_record, domain, nullptr); - Tcl_CreateCommand(interp, "updateElementDomain", &updateElementDomain, nullptr, nullptr); - Tcl_CreateCommand(interp, "InitialStateAnalysis", &InitialStateAnalysis, nullptr, nullptr); + // sensitivity + Tcl_CreateCommand(interp, "computeGradients", &computeGradients, (ClientData)domain, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "sensitivityAlgorithm", &TclCommand_sensitivityAlgorithm, (ClientData)domain, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "sensNodeDisp", &sensNodeDisp, (ClientData)domain, (Tcl_CmdDeleteProc *)NULL); +//Tcl_CreateCommand(interp, "sensLambda", &sensLambda, (ClientData)domain, (Tcl_CmdDeleteProc *)NULL); // Abbas + Tcl_CreateCommand(interp, "sensNodeVel", &sensNodeVel, (ClientData)domain, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "sensNodeAccel", &sensNodeAccel, (ClientData)domain, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "sensSectionForce", &sensSectionForce, (ClientData)domain, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "sensNodePressure", &sensNodePressure, (ClientData)domain, (Tcl_CmdDeleteProc *)NULL); + + // TODO: cmp, moved definition to packages/optimization; need to link in optionally -// Tcl_CreateCommand(interp, "setParameter", &setParameter, nullptr, nullptr); // Tcl_CreateCommand(interp, "sdfResponse", &sdfResponse, nullptr, nullptr); // Tcl_CreateCommand(interp, "database", &addDatabase, nullptr, nullptr); @@ -193,26 +211,28 @@ G3_AddTclDomainCommands(Tcl_Interp *interp, Domain* the_domain) int -getLoadFactor(ClientData clientData, Tcl_Interp *interp, int argc, +getLoadFactor(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); Domain* domain = (Domain*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "no load pattern supplied -- getLoadFactor\n"; + opserr << OpenSees::PromptValueError + << "no load pattern supplied -- getLoadFactor\n"; return TCL_ERROR; } int pattern; if (Tcl_GetInt(interp, argv[1], &pattern) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "reading load pattern tag -- getLoadFactor\n"; + opserr << OpenSees::PromptValueError + << "reading load pattern tag -- getLoadFactor\n"; return TCL_ERROR; } LoadPattern *the_pattern = domain->getLoadPattern(pattern); if (the_pattern == nullptr) { - opserr << G3_ERROR_PROMPT << "load pattern with tag " << pattern + opserr << OpenSees::PromptValueError << "load pattern with tag " << pattern << " not found in domain -- getLoadFactor\n"; return TCL_ERROR; } @@ -227,7 +247,7 @@ getLoadFactor(ClientData clientData, Tcl_Interp *interp, int argc, // added by C.McGann, U.Washington int -InitialStateAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, +InitialStateAnalysis(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -278,39 +298,40 @@ InitialStateAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, } int -rayleighDamping(ClientData clientData, Tcl_Interp *interp, int argc, +rayleighDamping(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { - + // + // rayleigh alphaM? betaK? betaK0? betaKc? + // if (argc < 3) { - opserr << G3_ERROR_PROMPT - << "rayleigh alphaM? betaK? betaK0? betaKc? - not enough " - "arguments to command\n"; + opserr << OpenSees::PromptValueError + << "not enough arguments to command\n"; return TCL_ERROR; } double alphaM, betaK, betaK0=0.0, betaKc=0.0; if (Tcl_GetDouble(interp, argv[1], &alphaM) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " - "read alphaM? \n"; + opserr << OpenSees::PromptValueError + << "could not read alphaM? \n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[2], &betaK) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " - "read betaK? \n"; + opserr << OpenSees::PromptValueError + << "could not read betaK? \n"; return TCL_ERROR; } if (argc > 3 && Tcl_GetDouble(interp, argv[3], &betaK0) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " - "read betaK0? \n"; + opserr << OpenSees::PromptValueError + << "could not read betaK0? \n"; return TCL_ERROR; } if (argc > 4 && Tcl_GetDouble(interp, argv[4], &betaKc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " - "read betaKc? \n"; + opserr << OpenSees::PromptValueError + << "could not read betaKc? \n"; return TCL_ERROR; } @@ -322,48 +343,12 @@ rayleighDamping(ClientData clientData, Tcl_Interp *interp, int argc, int -getEleClassTags(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *the_domain = (Domain*)clientData; - - if (argc == 1) { - Element *theEle; - ElementIter &eleIter = the_domain->getElements(); - - char buffer[20]; - - while ((theEle = eleIter()) != nullptr) { - sprintf(buffer, "%d ", theEle->getClassTag()); - Tcl_AppendResult(interp, buffer, NULL); - } - } else if (argc == 2) { - int eleTag; - - if (Tcl_GetInt(interp, argv[1], &eleTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "getParamValue -- could not read paramTag \n"; - return TCL_ERROR; - } - - Element *theEle = the_domain->getElement(eleTag); - - char buffer[20]; - sprintf(buffer, "%d ", theEle->getClassTag()); - Tcl_AppendResult(interp, buffer, NULL); - - } else { - opserr << G3_ERROR_PROMPT << "want - getEleClassTags \n" << endln; - return TCL_ERROR; - } - - return TCL_OK; -} - -int -getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, int argc, +getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { + // + // getEleLoadClassTags + // assert(clientData != nullptr); Domain *the_domain = (Domain*)clientData; @@ -387,29 +372,32 @@ getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, int argc, int patternTag; if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "getEleLoadClassTags -- could not read patternTag\n"; + opserr << OpenSees::PromptValueError << "failed to read patternTag\n"; return TCL_ERROR; } LoadPattern *thePattern = the_domain->getLoadPattern(patternTag); if (thePattern == nullptr) { - opserr << G3_ERROR_PROMPT << "load pattern with tag " << patternTag - << " not found in domain -- getEleLoadClassTags\n"; + opserr << OpenSees::PromptValueError + << "load pattern with tag " << patternTag + << " not found in domain" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); - ElementalLoad *theLoad; char buffer[20]; + ElementalLoad *theLoad; while ((theLoad = theEleLoads()) != nullptr) { sprintf(buffer, "%d ", theLoad->getClassTag()); Tcl_AppendResult(interp, buffer, NULL); } } else { - opserr << G3_ERROR_PROMPT << "want - getEleLoadClassTags \n" << endln; + opserr << OpenSees::PromptValueError << "unexpected arguments\n" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -417,9 +405,12 @@ getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, int argc, } int -getEleLoadTags(ClientData clientData, Tcl_Interp *interp, int argc, +getEleLoadTags(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { + // + // getEleLoadTags + // assert(clientData != nullptr); Domain *the_domain = (Domain*)clientData; @@ -427,30 +418,35 @@ getEleLoadTags(ClientData clientData, Tcl_Interp *interp, int argc, LoadPattern *thePattern; LoadPatternIter &thePatterns = the_domain->getLoadPatterns(); - char buffer[20]; + // char buffer[20]; + + Tcl_Obj *result = Tcl_NewListObj(0, nullptr); while ((thePattern = thePatterns()) != nullptr) { ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); ElementalLoad *theLoad; while ((theLoad = theEleLoads()) != nullptr) { - sprintf(buffer, "%d ", theLoad->getElementTag()); - Tcl_AppendResult(interp, buffer, NULL); + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(theLoad->getElementTag())); + // sprintf(buffer, "%d ", theLoad->getElementTag()); + // Tcl_AppendResult(interp, buffer, NULL); } } + Tcl_SetObjResult(interp, result); + } else if (argc == 2) { int patternTag; if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "getEleLoadTags -- could not read patternTag \n"; + opserr << OpenSees::PromptValueError << "failed to read patternTag \n"; return TCL_ERROR; } LoadPattern *thePattern = the_domain->getLoadPattern(patternTag); if (thePattern == nullptr) { - opserr << G3_ERROR_PROMPT << "load pattern with tag " << patternTag - << " not found in domain -- getEleLoadTags\n"; + opserr << OpenSees::PromptValueError << "load pattern with tag " << patternTag + << " not found in domain\n"; return TCL_ERROR; } @@ -465,7 +461,7 @@ getEleLoadTags(ClientData clientData, Tcl_Interp *interp, int argc, } } else { - opserr << G3_ERROR_PROMPT << "want - getEleLoadTags \n" << endln; + opserr << OpenSees::PromptValueError << "unexpectd arguments\n" << endln; return TCL_ERROR; } @@ -473,9 +469,10 @@ getEleLoadTags(ClientData clientData, Tcl_Interp *interp, int argc, } int -getEleLoadData(ClientData clientData, Tcl_Interp *interp, int argc, +getEleLoadData(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { + // getLoadData assert(clientData != nullptr); Domain *the_domain = (Domain*)clientData; @@ -494,26 +491,26 @@ getEleLoadData(ClientData clientData, Tcl_Interp *interp, int argc, const Vector &eleLoadData = theLoad->getData(typeEL, 1.0); int eleLoadDataSize = eleLoadData.Size(); - opserr << "eleLoadDataSize: " << eleLoadDataSize << "\n"; for (int i = 0; i < eleLoadDataSize; ++i) { sprintf(buffer, "%35.20f ", eleLoadData(i)); Tcl_AppendResult(interp, buffer, NULL); } } } - - } else if (argc == 2) { + } + + else if (argc == 2) { int patternTag; if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "getEleLoadData -- could not read patternTag \n"; + opserr << OpenSees::PromptValueError << "failed to read patternTag\n"; return TCL_ERROR; } LoadPattern *thePattern = the_domain->getLoadPattern(patternTag); if (thePattern == nullptr) { - opserr << G3_ERROR_PROMPT << "load pattern with tag " << patternTag - << " not found in domain -- getEleLoadData\n"; + opserr << OpenSees::PromptValueError << "load pattern with tag " << patternTag + << " not found in domain\n"; return TCL_ERROR; } @@ -534,31 +531,10 @@ getEleLoadData(ClientData clientData, Tcl_Interp *interp, int argc, } } else { - opserr << G3_ERROR_PROMPT << "want - getEleLoadTags \n" << endln; + opserr << OpenSees::PromptValueError + << "want - getEleLoadTags " << endln; return TCL_ERROR; } return TCL_OK; } - -int -getEleTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - // NOTE: Maybe this can use a base class of ElementIter so we only need - // to work in terms of tagged object - assert(clientData != nullptr); - Domain *the_domain = (Domain*)clientData; - - Element *theEle; - ElementIter &eleIter = the_domain->getElements(); - - char buffer[20]; - - while ((theEle = eleIter()) != nullptr) { - sprintf(buffer, "%d ", theEle->getTag()); - Tcl_AppendResult(interp, buffer, NULL); - } - - return TCL_OK; -} - diff --git a/SRC/runtime/commands/domain/commands.h b/SRC/runtime/commands/domain/commands.h index 736f117319..5d509df6b7 100644 --- a/SRC/runtime/commands/domain/commands.h +++ b/SRC/runtime/commands/domain/commands.h @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // domain/node.cpp Tcl_CmdProc nodeCoord; @@ -15,19 +16,14 @@ Tcl_CmdProc nodeReaction; Tcl_CmdProc nodeUnbalance; Tcl_CmdProc nodeEigenvector; Tcl_CmdProc setNodeCoord; +Tcl_CmdProc nodeRotation; // domain/region.cpp Tcl_CmdProc TclCommand_addMeshRegion; +// domain/recorder.cpp +Tcl_CmdProc OPS_recorderValue; -// domain/element.cpp -Tcl_CmdProc TclCommand_addElementRayleigh; -Tcl_CmdProc TclCommand_getEleTags; -Tcl_CmdProc getNumElements; -Tcl_CmdProc getEleClassTags; -Tcl_CmdProc getEleLoadClassTags; -Tcl_CmdProc getEleLoadTags; -Tcl_CmdProc getEleLoadData; // domain/section.cpp Tcl_CmdProc sectionForce; @@ -39,6 +35,81 @@ Tcl_CmdProc sectionWeight; Tcl_CmdProc sectionTag; Tcl_CmdProc sectionDisplacement; + + +namespace OpenSees { +namespace DomainCommands { + // domain.cpp + Tcl_ObjCmdProc removeObject; + Tcl_ObjCmdProc fixedNodes; + Tcl_ObjCmdProc constrainedNodes; + Tcl_ObjCmdProc fixedDOFs; + Tcl_ObjCmdProc constrainedDOFs; + Tcl_ObjCmdProc domainChange; + Tcl_CmdProc retainedDOFs; + Tcl_CmdProc updateElementDomain; + + // domain/element.cpp + Tcl_CmdProc addElementRayleigh; + Tcl_CmdProc getEleTags; + Tcl_CmdProc getNumElements; + Tcl_CmdProc getEleClassTags; + Tcl_CmdProc eleNodes; + Tcl_CmdProc eleType; + Tcl_CmdProc eleForce; + Tcl_CmdProc localForce; + Tcl_CmdProc eleDynamicalForce; + Tcl_CmdProc eleResponse; + + // modal.cpp + Tcl_CmdProc modalProperties; +} +} + +// parameter.cpp +Tcl_CmdProc getParamTags; +Tcl_CmdProc TclCommand_parameter; +Tcl_CmdProc getParamValue; +Tcl_CmdProc TclCommand_setParameter; + + +// + + +// sensitivity.cpp +Tcl_CmdProc computeGradients; +Tcl_CmdProc sensNodeDisp; +Tcl_CmdProc sensLambda; // Abbas +Tcl_CmdProc sensNodeVel; +Tcl_CmdProc sensNodeAccel; +Tcl_CmdProc sensNodePressure; +Tcl_CmdProc sensSectionForce; +Tcl_CmdProc TclCommand_sensitivityAlgorithm; +// Tcl_CmdProc sensitivityIntegrator; + + +// Tcl_CmdProc startTimer; +// Tcl_CmdProc stopTimer; +Tcl_CmdProc TclCommand_getTime; +Tcl_CmdProc TclCommand_setTime; + +Tcl_CmdProc rayleighDamping; + +Tcl_CmdProc modalDamping; + +Tcl_CmdProc modalDampingQ; + +Tcl_CmdProc basicDeformation; + +Tcl_CmdProc basicForce; + +Tcl_CmdProc basicStiffness; + +// added: Chris McGann, U.Washington for initial state analysis of nDMaterials +Tcl_CmdProc InitialStateAnalysis; + + + Tcl_CmdProc setLoadConst; Tcl_CmdProc setCreep; @@ -60,24 +131,15 @@ Tcl_CmdProc playbackAlgorithmRecorders; Tcl_CmdProc groundExcitation; -Tcl_CmdProc eleForce; - -Tcl_CmdProc localForce; - -Tcl_CmdProc eleDynamicalForce; +Tcl_CmdProc getEleLoadData; +Tcl_CmdProc getEleLoadClassTags; +Tcl_CmdProc getEleLoadTags; -Tcl_CmdProc eleResponse; Tcl_CmdProc findID; -Tcl_CmdProc eleType; - -Tcl_CmdProc eleNodes; - -Tcl_CmdProc getEleTags; - // Tcl_CmdProc nodeBounds; @@ -96,59 +158,4 @@ Tcl_CmdProc nodeResponse; Tcl_CmdProc calculateNodalReactions; Tcl_CmdProc getNodeTags; -Tcl_CmdProc retainedNodes; - -// domain.cpp -Tcl_ObjCmdProc removeObject; -Tcl_ObjCmdProc fixedNodes; -Tcl_ObjCmdProc constrainedNodes; -Tcl_ObjCmdProc fixedDOFs; -Tcl_ObjCmdProc constrainedDOFs; -Tcl_ObjCmdProc domainChange; -Tcl_CmdProc retainedDOFs; -Tcl_CmdProc updateElementDomain; - -// parameter.cpp -Tcl_CmdProc getParamTags; -Tcl_CmdProc TclCommand_parameter; -Tcl_CmdProc getParamValue; - - -// - - -// AddingSensitivity:BEGIN ///////////////////////////////////////////////// -Tcl_CmdProc computeGradients; -Tcl_CmdProc sensNodeDisp; -Tcl_CmdProc sensLambda; // Abbas -Tcl_CmdProc sensNodeVel; -Tcl_CmdProc sensNodeAccel; -Tcl_CmdProc sensNodePressure; -Tcl_CmdProc sensSectionForce; -Tcl_CmdProc sensitivityAlgorithm; -// Tcl_CmdProc sensitivityIntegrator; -// AddingSensitivity:END /////////////////////////////////////////////////// - -// Tcl_CmdProc startTimer; -// Tcl_CmdProc stopTimer; -Tcl_CmdProc TclCommand_getTime; -Tcl_CmdProc TclCommand_setTime; - -Tcl_CmdProc rayleighDamping; - -Tcl_CmdProc modalDamping; - -Tcl_CmdProc modalDampingQ; - -Tcl_CmdProc basicDeformation; - -Tcl_CmdProc basicForce; - -Tcl_CmdProc basicStiffness; - -// added: Chris McGann, U.Washington for initial state analysis of nDMaterials -Tcl_CmdProc InitialStateAnalysis; - -// domain/recorder.cpp -Tcl_CmdProc OPS_recorderValue; - +Tcl_CmdProc retainedNodes; \ No newline at end of file diff --git a/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp b/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp index aeb48fe544..0c20272813 100644 --- a/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp +++ b/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // // Description: This file contains the function invoked when the user invokes // the MySQL command in the interpreter. diff --git a/SRC/runtime/commands/domain/domain.cpp b/SRC/runtime/commands/domain/domain.cpp index 56d8527d9e..abe498f879 100644 --- a/SRC/runtime/commands/domain/domain.cpp +++ b/SRC/runtime/commands/domain/domain.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: Domain manipulation commands which do not require // additional namespacing. // @@ -36,6 +37,8 @@ #define MAX_NDF 6 +namespace OpenSees { +namespace DomainCommands { int domainChange(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const *objv) @@ -184,18 +187,18 @@ removeObject(ClientData clientData, Tcl_Interp *interp, int argc, else if (strcmp(remove_type, "recorder") == 0) { if (argc < 3) { - opserr << G3_ERROR_PROMPT << "want - remove recorder recorderTag?\n"; + opserr << OpenSees::PromptValueError << "want - remove recorder recorderTag?\n"; return TCL_ERROR; } int tag; if (Tcl_GetIntFromObj(interp, objv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "remove recorder tag? failed to read tag: " << Tcl_GetString(objv[2]) << "\n"; return TCL_ERROR; } if (the_domain->removeRecorder(tag) != 0) { - opserr << G3_ERROR_PROMPT << "No recorder found with tag " << tag << "\n"; + opserr << OpenSees::PromptValueError << "No recorder found with tag " << tag << "\n"; return TCL_ERROR; } return TCL_OK; @@ -204,9 +207,46 @@ removeObject(ClientData clientData, Tcl_Interp *interp, int argc, else if ((strcmp(remove_type, "SPconstraint") == 0) || (strcmp(remove_type, "sp") == 0)) { - return TCL_ERROR; - // + if (argc < 3) { + opserr << "WARNING want - remove SPconstraint spTag? -or- remove SPconstraint nodeTag? dofTag? \n"; + return TCL_ERROR; + } + if (argc == 3) { + if (Tcl_GetIntFromObj(interp, objv[2], &tag) != TCL_OK) { + opserr << "WARNING remove sp tag? failed to read tag: " << objv[2] << "\n"; + return TCL_ERROR; + } + + SP_Constraint *theSPconstraint = the_domain->removeSP_Constraint(tag); + if (theSPconstraint != nullptr) + delete theSPconstraint; + + } else { + int nodeTag, dofTag; + int patternTag = -1; + + if (Tcl_GetIntFromObj(interp, objv[2], &nodeTag) != TCL_OK) { + opserr << "WARNING remove sp tag? failed to read node tag: " << objv[2] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetIntFromObj(interp, objv[3], &dofTag) != TCL_OK) { + opserr << "WARNING remove sp tag? failed to read dof tag: " << objv[3] << "\n"; + return TCL_ERROR; + } + + if (argc == 5) { + if (Tcl_GetIntFromObj(interp, objv[4], &patternTag) != TCL_OK) { + opserr << "WARNING remove sp tag? failed to read pattern tag: " << objv[4] << "\n"; + return TCL_ERROR; + } + } + dofTag--; // one for C++ indexing of dof + + the_domain->removeSP_Constraint(nodeTag, dofTag, patternTag); + return TCL_OK; + } + // // const char** const args = new const char*[argc+1]; // args[0] = objv[1]; @@ -359,7 +399,7 @@ fixedDOFs(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const *o Node *node = theDomain->getNode(fNode); if (node == nullptr) { - opserr << G3_ERROR_PROMPT << " fixedDOFs fNode? - could not find node with tag " << fNode << "\n"; + opserr << OpenSees::PromptValueError << " fixedDOFs fNode? - could not find node with tag " << fNode << "\n"; return TCL_ERROR; } @@ -504,18 +544,20 @@ int retainedDOFs(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { + // + // retainedDOFs rNode? + // assert(clientData != nullptr); Domain *domain = (Domain*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "want - retainedDOFs rNode? \n"; + opserr << OpenSees::PromptValueError << "want - retainedDOFs rNode? \n"; return TCL_ERROR; } int rNode; if (Tcl_GetInt(interp, argv[1], &rNode) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "retainedDOFs rNode? - could not read " - "rNode? \n"; + opserr << OpenSees::PromptValueError << "could not read rNode? \n"; return TCL_ERROR; } @@ -523,8 +565,7 @@ retainedDOFs(ClientData clientData, Tcl_Interp *interp, int argc, bool allNodes = 1; if (argc > 2) { if (Tcl_GetInt(interp, argv[2], &cNode) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "retainedDOFs rNode? - could not read " - "cNode? \n"; + opserr << OpenSees::PromptValueError << "could not read cNode? \n"; return TCL_ERROR; } allNodes = 0; @@ -534,8 +575,8 @@ retainedDOFs(ClientData clientData, Tcl_Interp *interp, int argc, bool allDOFs = 1; if (argc > 3) { if (Tcl_GetInt(interp, argv[3], &cDOF) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "retainedDOFs rNode? - could not read " - "cDOF? \n"; + opserr << OpenSees::PromptValueError + << "could not read cDOF? \n"; return TCL_ERROR; } cDOF--; @@ -595,4 +636,5 @@ updateElementDomain(ClientData clientData, Tcl_Interp *interp, int argc, return 0; } - +} +} diff --git a/SRC/runtime/commands/domain/element.cpp b/SRC/runtime/commands/domain/element.cpp index 4912b8a29b..f3569c0b60 100644 --- a/SRC/runtime/commands/domain/element.cpp +++ b/SRC/runtime/commands/domain/element.cpp @@ -1,23 +1,10 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ +//===----------------------------------------------------------------------===// // +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // #include #include @@ -27,21 +14,28 @@ #include #include +namespace OpenSees { +namespace DomainCommands { + int -TclCommand_getEleTags(ClientData clientData, Tcl_Interp *interp, int argc, +getEleTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { + // NOTE: Maybe this can use a base class of ElementIter so we only need + // to work in terms of tagged object + assert(clientData != nullptr); Domain *the_domain = (Domain*)clientData; ElementIter &elemIter = the_domain->getElements(); + Tcl_Obj* result = Tcl_NewListObj(the_domain->getNumElements(), nullptr); + Element *elem; - char buffer[128]; - while ((elem = elemIter()) != nullptr) { - sprintf(buffer, "%d ", elem->getTag()); - Tcl_AppendResult(interp, buffer, NULL); - } + while ((elem = elemIter()) != nullptr) + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(elem->getTag())); + + Tcl_SetObjResult(interp, result); return TCL_OK; } @@ -58,9 +52,8 @@ getNumElements(ClientData clientData, Tcl_Interp *interp, int argc, } - int -TclCommand_addElementRayleigh(ClientData clientData, Tcl_Interp *interp, +addElementRayleigh(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { @@ -133,7 +126,7 @@ setElementRayleighDampingFactors(ClientData clientData, Tcl_Interp *interp, Domain *the_domain = (Domain*)clientData; if (argc < 6) { - opserr << G3_ERROR_PROMPT << "setElementRayleighDampingFactors eleTag? alphaM? betaK? " + opserr << OpenSees::PromptValueError << "setElementRayleighDampingFactors eleTag? alphaM? betaK? " "betaK0? betaKc? - not enough arguments to command\n"; return TCL_ERROR; } @@ -142,28 +135,28 @@ setElementRayleighDampingFactors(ClientData clientData, Tcl_Interp *interp, double alphaM, betaK, betaK0, betaKc; if (Tcl_GetInt(interp, argv[1], &eleTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " + opserr << OpenSees::PromptValueError << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " "read eleTag? \n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[2], &alphaM) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " + opserr << OpenSees::PromptValueError << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " "read alphaM? \n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3], &betaK) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " + opserr << OpenSees::PromptValueError << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " "read betaK? \n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &betaK0) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " + opserr << OpenSees::PromptValueError << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " "read betaK0? \n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &betaKc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " + opserr << OpenSees::PromptValueError << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " "read betaKc? \n"; return TCL_ERROR; } @@ -181,7 +174,7 @@ eleForce(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char** const a Domain *domain = (Domain*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "want - eleForce eleTag? \n"; + opserr << OpenSees::PromptValueError << "want - eleForce eleTag? \n"; return TCL_ERROR; } @@ -189,13 +182,13 @@ eleForce(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char** const a int dof = -1; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "eleForce eleTag? dof? - could not read nodeTag? \n"; + opserr << OpenSees::PromptValueError << "eleForce eleTag? dof? - could not read nodeTag? \n"; return TCL_ERROR; } if (argc > 2) { if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "eleForce eleTag? dof? - could not read dof? \n"; + opserr << OpenSees::PromptValueError << "eleForce eleTag? dof? - could not read dof? \n"; return TCL_ERROR; } } @@ -227,14 +220,17 @@ eleForce(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char** const a Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*force)(dof))); } else { - char buffer[128]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*force)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } + Tcl_Obj* result = Tcl_NewListObj(size, nullptr); + for (int i = 0; i < size; ++i) + Tcl_ListObjAppendElement(interp, result, Tcl_NewDoubleObj((*force)(i))); + + Tcl_SetObjResult(interp, result); } + } else { - opserr << G3_ERROR_PROMPT << "- failed to retrieve element force.\n"; + opserr << OpenSees::PromptValueError + << "- failed to retrieve element force." + << OpenSees::SignalMessageEnd; return TCL_ERROR; } return TCL_OK; @@ -247,7 +243,8 @@ localForce(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char** const Domain *theDomain = (Domain*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "want - localForce eleTag? \n"; + opserr << OpenSees::PromptValueError + << "want - localForce eleTag? \n"; return TCL_ERROR; } @@ -255,13 +252,15 @@ localForce(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char** const int dof = -1; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "localForce eleTag? dof? - could not read eleTag? \n"; + opserr << OpenSees::PromptValueError + << "localForce eleTag? dof? - could not read eleTag? \n"; return TCL_ERROR; } if (argc > 2) { if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "localForce eleTag? dof? - could not read dof? \n"; + opserr << OpenSees::PromptValueError + << "localForce eleTag? dof? - could not read dof? \n"; return TCL_ERROR; } } @@ -306,7 +305,7 @@ eleDynamicalForce(ClientData clientData, Tcl_Interp *interp, int argc, Domain *theDomain = (Domain*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "want - eleForce eleTag? \n"; + opserr << OpenSees::PromptValueError << "want - eleForce eleTag? \n"; return TCL_ERROR; } @@ -314,13 +313,13 @@ eleDynamicalForce(ClientData clientData, Tcl_Interp *interp, int argc, int dof = -1; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "eleForce eleTag? dof? - could not read nodeTag? \n"; + opserr << OpenSees::PromptValueError << "eleForce eleTag? dof? - could not read nodeTag? \n"; return TCL_ERROR; } if (argc > 2) { if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "eleForce eleTag? dof? - could not read dof? \n"; + opserr << OpenSees::PromptValueError << "eleForce eleTag? dof? - could not read dof? \n"; return TCL_ERROR; } } @@ -359,14 +358,13 @@ eleResponse(ClientData clientData, Tcl_Interp *interp, int argc, Domain* the_domain = (Domain*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "want - eleResponse eleTag? eleArgs...\n"; + opserr << OpenSees::PromptValueError << "want - eleResponse tag? eleArgs...\n"; return TCL_ERROR; } int tag; - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "eleResponse eleTag? args? - could not read eleTag? \n"; + opserr << OpenSees::PromptValueError << "eleResponse tag? args? - could not read tag? \n"; return TCL_ERROR; } @@ -390,14 +388,14 @@ eleNodes(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const Domain *the_domain = (Domain*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "want - eleNodes eleTag?\n"; + opserr << OpenSees::PromptValueError << "want - eleNodes eleTag?\n"; return TCL_ERROR; } int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "eleNodes eleTag? \n"; + opserr << OpenSees::PromptValueError << "eleNodes eleTag? \n"; return TCL_ERROR; } @@ -405,7 +403,7 @@ eleNodes(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const Element *theElement = the_domain->getElement(tag); if (theElement == nullptr) { - opserr << G3_ERROR_PROMPT << "eleNodes ele " << tag << " not found" << "\n"; + opserr << OpenSees::PromptValueError << "eleNodes ele " << tag << " not found" << "\n"; return TCL_ERROR; } int numTags = theElement->getNumExternalNodes(); @@ -425,20 +423,20 @@ eleType(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const a Domain *the_domain = (Domain*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "want - eleType eleTag?\n"; + opserr << OpenSees::PromptValueError << "want - eleType eleTag?\n"; return TCL_ERROR; } int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "eleType eleTag? \n"; + opserr << OpenSees::PromptValueError << "eleType eleTag? \n"; return TCL_ERROR; } Element *theElement = the_domain->getElement(tag); if (theElement == nullptr) { - opserr << G3_ERROR_PROMPT << "eleType ele " << tag << " not found" << "\n"; + opserr << OpenSees::PromptValueError << "eleType ele " << tag << " not found" << "\n"; return TCL_ERROR; } const char *type = theElement->getClassType(); @@ -448,3 +446,48 @@ eleType(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const a return TCL_OK; } + +int +getEleClassTags(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + assert(clientData != nullptr); + Domain *the_domain = (Domain*)clientData; + + if (argc == 1) { + Element *theEle; + ElementIter &eleIter = the_domain->getElements(); + + char buffer[20]; + + while ((theEle = eleIter()) != nullptr) { + sprintf(buffer, "%d ", theEle->getClassTag()); + Tcl_AppendResult(interp, buffer, NULL); + } + + } else if (argc == 2) { + int eleTag; + + if (Tcl_GetInt(interp, argv[1], &eleTag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "getParamValue -- could not read paramTag \n"; + return TCL_ERROR; + } + + Element *theEle = the_domain->getElement(eleTag); + + char buffer[20]; + sprintf(buffer, "%d ", theEle->getClassTag()); + Tcl_AppendResult(interp, buffer, NULL); + + } else { + opserr << OpenSees::PromptValueError + << "want - getEleClassTags \n" << endln; + return TCL_ERROR; + } + + return TCL_OK; +} + +} // namespace DomainCommands +} // namespace OpenSees diff --git a/SRC/runtime/commands/domain/loading/TclSeriesIntegratorCommand.cpp b/SRC/runtime/commands/domain/loading/TclSeriesIntegratorCommand.cpp index ca26411179..e1d1a4c20b 100644 --- a/SRC/runtime/commands/domain/loading/TclSeriesIntegratorCommand.cpp +++ b/SRC/runtime/commands/domain/loading/TclSeriesIntegratorCommand.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file contains the function invoked when the user invokes // the groundMotion command in the interpreter. // diff --git a/SRC/runtime/commands/domain/loading/drm/TclPatternCommand.cpp b/SRC/runtime/commands/domain/loading/drm/TclPatternCommand.cpp index 8569e9a14f..4c8ca54434 100644 --- a/SRC/runtime/commands/domain/loading/drm/TclPatternCommand.cpp +++ b/SRC/runtime/commands/domain/loading/drm/TclPatternCommand.cpp @@ -24,7 +24,8 @@ // #include -#include +#include +#include #include #include #include @@ -46,6 +47,7 @@ #include #include + extern SimulationInformation simulationInfo; extern const char *getInterpPWD(Tcl_Interp *interp); // interpreter.cpp @@ -67,7 +69,7 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, int argc, // make sure at least one other argument to contain integrator if (argc < 4) { - opserr << G3_ERROR_PROMPT << "invalid command - want: pattern type "; + opserr << OpenSees::PromptValueError << "invalid command - want: pattern type "; opserr << " {list of load and sp constraints commands}\n"; opserr << " valid types: Plain, UniformExcitation, MultiSupport\n"; diff --git a/SRC/runtime/commands/domain/loading/element_load.cpp b/SRC/runtime/commands/domain/loading/element_load.cpp index 321428cd6e..1d6d1999c4 100644 --- a/SRC/runtime/commands/domain/loading/element_load.cpp +++ b/SRC/runtime/commands/domain/loading/element_load.cpp @@ -1,12 +1,14 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // #include #include +#include #include #include #include @@ -14,6 +16,7 @@ #include #include +#include #include #include #include @@ -31,22 +34,266 @@ #include #include - int -TclCommand_addElementalLoad(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **const argv) +TclCommand_addFrameLoad(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char **const argv) { BasicModelBuilder *builder = static_cast(clientData); Domain *domain = builder->getDomain(); - static int eleLoadTag = 0; // TODO: this is ugly - // ensure the destructor has not been called + std::vector tags; + std::vector n(1); + std::vector m(1); + std::vector r(1); + int shape, basis=FrameLoad::Reference; + enum class Position : int { + Force, End + }; + ArgumentTracker tracker; + + + LoadPattern *pattern = builder->getEnclosingPattern(); + + // eleLoad FrameForce $shape -n $n -offset $r -pattern $pattern -basis $basis -ele $ele + + if (argc < 3) { + opserr << "WARNING eleLoad FrameLoad $shape -force $n -couple $m -offset r -pattern pattern -basis $basis\n"; + return TCL_ERROR; + } + + if (strcmp(argv[2], "Dirac") == 0) + shape = FrameLoad::Dirac; + else if (strcmp(argv[2], "Heaviside") == 0) + shape = FrameLoad::Heaviside; + else if (strcmp(argv[2], "Lagrange") == 0) { + shape = FrameLoad::Lagrange; + opserr << "Lagrange shape not yet implemented\n"; + return TCL_ERROR; + } + else { + opserr << "WARNING unknown shape for FrameLoad " << argv[2] << "\n"; + return TCL_ERROR; + } + + // Keywords + for (int i=0; igetDomain()->getLoadPattern(ptag); + if (pattern == nullptr) { + opserr << "WARNING pattern " << argv[i+1] << " not found\n"; + return TCL_ERROR; + } + i++; + } + else if (strcmp(argv[i], "-basis") == 0) { + if (i == argc-1) { + opserr << "WARNING -basis paramter missing required argument\n"; + return TCL_ERROR; + } + if (strcmp(argv[i+1], "global") == 0) + basis = FrameLoad::Embedding; + else if ((strcmp(argv[i+1], "reference") == 0) || + (strcmp(argv[i+1], "local") == 0)) + basis = FrameLoad::Reference; + else if (strcmp(argv[i+1], "director") == 0) + basis = FrameLoad::Director; + else { + opserr << "WARNING unknown basis for FrameLoad " << argv[i+1] << "\n"; + return TCL_ERROR; + } + i++; + } + else if (strcmp(argv[i], "-force") == 0) { + if (i == argc-1) { + opserr << "WARNING -force paramter missing required argument\n"; + return TCL_ERROR; + } + int list_argc; + TCL_Char **list_argv; + if (Tcl_SplitList(interp, argv[i+1], &list_argc, &list_argv) != TCL_OK) { + opserr << "WARNING force parameter expected list of floats\n"; + return TCL_ERROR; + } + if (list_argc != 3) { + opserr << "WARNING force parameter expected list of 3 floats\n"; + Tcl_Free((char *) list_argv); + return TCL_ERROR; + } + Vector3D force; + for (int j = 0; j < 3; j++) { + if (Tcl_GetDouble(interp, list_argv[j], &force[j]) != TCL_OK) { + opserr << "WARNING force parameter expected list of 3 floats\n"; + Tcl_Free((char *) list_argv); + return TCL_ERROR; + } + } + // n.push_back(force); + n[0] = force; + Tcl_Free((char *) list_argv); + + tracker.consume(Position::Force); + } + else if (strcmp(argv[i], "-couple") == 0) { + if (i == argc-1) { + opserr << "WARNING -couple paramter missing required argument\n"; + return TCL_ERROR; + } + int list_argc; + TCL_Char **list_argv; + if (Tcl_SplitList(interp, argv[i+1], &list_argc, &list_argv) != TCL_OK) { + opserr << "WARNING couple parameter expected list of floats\n"; + return TCL_ERROR; + } + if (list_argc != 3) { + opserr << "WARNING couple parameter expected list of 3 floats\n"; + Tcl_Free((char *) list_argv); + return TCL_ERROR; + } + Vector3D couple; + for (int j = 0; j < 3; j++) { + if (Tcl_GetDouble(interp, list_argv[j], &couple[j]) != TCL_OK) { + opserr << "WARNING couple parameter expected list of 3 floats\n"; + Tcl_Free((char *) list_argv); + return TCL_ERROR; + } + } + // m.push_back(couple); + m[0] = couple; + Tcl_Free((char *) list_argv); + + tracker.consume(Position::Force); + } + else if (strcmp(argv[i], "-offset") == 0) { + if (i == argc-1) { + opserr << "WARNING -offset paramter missing required argument\n"; + return TCL_ERROR; + } + int list_argc; + TCL_Char **list_argv; + if (Tcl_SplitList(interp, argv[i+1], &list_argc, &list_argv) != TCL_OK) { + opserr << "WARNING offset parameter expected list of floats\n"; + return TCL_ERROR; + } + if (list_argc != 3) { + opserr << "WARNING offset parameter expected list of 3 floats\n"; + Tcl_Free((char *) list_argv); + return TCL_ERROR; + } + Vector3D offset; + for (int j = 0; j < 3; j++) { + if (Tcl_GetDouble(interp, list_argv[j], &offset[j]) != TCL_OK) { + opserr << "WARNING offset parameter expected list of 3 floats\n"; + Tcl_Free((char *) list_argv); + return TCL_ERROR; + } + } + // r.push_back(offset); + r[0] = offset; + Tcl_Free((char *) list_argv); + } + else if (strcmp(argv[i], "-elements") == 0) { + if (i == argc-1) { + opserr << "WARNING -elements paramter missing required argument\n"; + return TCL_ERROR; + } + int list_argc; + TCL_Char **list_argv; + if (Tcl_SplitList(interp, argv[i+1], &list_argc, &list_argv) != TCL_OK) { + opserr << "WARNING elements parameter expected list of integers\n"; + return TCL_ERROR; + } + for (int j = 0; j < list_argc; j++) { + int tag; + if (Tcl_GetInt(interp, list_argv[j], &tag) != TCL_OK) { + opserr << "WARNING elements parameter expected list of integers\n"; + Tcl_Free((char *) list_argv); + return TCL_ERROR; + } + tags.push_back(tag); + } + Tcl_Free((char *) list_argv); + } + } + + // Make sure we got everything we need. + if (tracker.current() != Position::End) { + opserr << OpenSees::PromptParseError + << "missing required arguments: "; + while (tracker.current() != Position::End) { + switch (tracker.current()) { + case Position::Force : + opserr << "force "; + break; + case Position::End: + break; + } + if (tracker.current() == Position::End) + break; + tracker.consume(tracker.current()); + } + opserr << "\n"; + return TCL_ERROR; + } - if (builder == 0 || clientData == 0) { - opserr << "WARNING current builder has been destroyed - eleLoad\n"; + if (pattern == nullptr) { + opserr << "WARNING no current load pattern\n"; return TCL_ERROR; } + FrameLoad *load = new FrameLoad(basis, shape, n, m, r, *pattern); + + for (int i : tags) { + Element *elem = domain->getElement(i); + if (elem == nullptr) { + opserr << "WARNING eleLoad - no element with tag " << i << "\n"; + delete load; + return TCL_ERROR; + } + if (load->addElement(*elem) != 0) { + opserr << "WARNING eleLoad - could not add load to element\n"; + delete load; + return TCL_ERROR; + } + } + + if (domain->addElementalLoad(load, pattern->getTag()) == false) { + opserr + << "WARNING eleLoad - could not add load to domain\n "; + delete load; + return TCL_ERROR; + } + + return TCL_OK; +} + + +int +TclCommand_addElementalLoad(ClientData clientData, Tcl_Interp *interp, int argc_main, + TCL_Char **const argv_main) +{ + if (argc_main < 2) { + opserr << "WARNING eleLoad - expecting eleLoad type\n"; + return TCL_ERROR; + } + + if (strcmp(argv_main[1], "Frame") == 0) { + return TclCommand_addFrameLoad(clientData, interp, argc_main, argv_main); + } + + + BasicModelBuilder *builder = static_cast(clientData); + Domain *domain = builder->getDomain(); + static int eleLoadTag = 0; // TODO: this is ugly + int ndm = builder->getNDM(); bool explicitPatternPassed = false; @@ -54,69 +301,84 @@ TclCommand_addElementalLoad(ClientData clientData, Tcl_Interp *interp, int argc, std::vector element_tags; int loadPatternTag = 0; - // First create an ID containing the ele tags of all elements + // Arguments argv_main will be copied into argv. + // We initialize with two placeholders for "-type" and $typeName. + // Everything else will be appended. + std::vector argv{nullptr, nullptr}; + + int typeIndex = -1; + // Create an ID containing the ele tags of all elements // for which the load applies. int count = 1; - int doneEle = 0; - int typeIndex = -1; - while (doneEle == 0 && count < argc) { + while (count < argc_main) { // Element tags - if (strcmp(argv[count], "-ele") == 0) { + if (strcmp(argv_main[count], "-ele") == 0) { count++; int eleStart = count; int eleEnd = 0; int eleID; - while (count < argc && eleEnd == 0) { - if (Tcl_GetInt(interp, argv[count], &eleID) != TCL_OK) + while (count < argc_main && eleEnd == 0) { + if (Tcl_GetInt(interp, argv_main[count], &eleID) != TCL_OK) eleEnd = count; else count++; } if (eleStart != eleEnd) { for (int i = eleStart; i < eleEnd; ++i) { - Tcl_GetInt(interp, argv[i], &eleID); + Tcl_GetInt(interp, argv_main[i], &eleID); element_tags.push_back(eleID); } } } - else if (strcmp(argv[count], "-range") == 0) { + + else if (strcmp(argv_main[count], "-range") == 0) { count++; int eleStart, eleEnd; - if (Tcl_GetInt(interp, argv[count], &eleStart) != TCL_OK) { - opserr << "WARNING eleLoad -range invalid eleStart " << argv[count] + if (Tcl_GetInt(interp, argv_main[count], &eleStart) != TCL_OK) { + opserr << "WARNING eleLoad -range invalid eleStart " << argv_main[count] << "\n"; return TCL_ERROR; } count++; - if (Tcl_GetInt(interp, argv[count], &eleEnd) != TCL_OK) { - opserr << "WARNING eleLoad -range invalid eleEnd " << argv[count] << "\n"; + if (Tcl_GetInt(interp, argv_main[count], &eleEnd) != TCL_OK) { + opserr << "WARNING eleLoad -range invalid eleEnd " << argv_main[count] << "\n"; return TCL_ERROR; } count++; for (int i = eleStart; i <= eleEnd; ++i) element_tags.push_back(i); + } - } - - else if (strcmp(argv[count], "-pattern") == 0) { - count++; - explicitPatternPassed = true; - if (Tcl_GetInt(interp, argv[count], &loadPatternTag) != TCL_OK) { - opserr << "WARNING eleLoad -range invalid eleStart " << argv[count] - << "\n"; + else if (strcmp(argv_main[count], "-pattern") == 0) { + if (count == argc_main - 1) { + opserr << "WARNING eleLoad -pattern paramter missing required argument\n"; + return TCL_ERROR; + } + int ptag; + if (Tcl_GetInt(interp, argv_main[++count], &ptag) != TCL_OK) { + opserr << "WARNING eleLoad -pattern parameter expected integer\n"; return TCL_ERROR; } + explicitPatternPassed = true; + loadPatternTag = ptag; count++; + } - } - else if (strcmp(argv[count], "-type") == 0) { - typeIndex = count; - doneEle = 1; + else if (strcmp(argv_main[count], "-type") == 0) { + argv[0] = argv_main[count++]; + argv[1] = argv_main[count++]; + if (count >= argc_main) { + opserr << "WARNING eleLoad -type paramter missing required argument\n"; + return TCL_ERROR; + } + typeIndex = 0; - } else - doneEle = 1; + } else { + argv.push_back(argv_main[count++]); + } } + const int argc = static_cast(argv.size()); // If -pattern wasnt given explicitly, see if there is one // activated in the builder @@ -132,20 +394,20 @@ TclCommand_addElementalLoad(ClientData clientData, Tcl_Interp *interp, int argc, } - // - // Create the load - // - if ((typeIndex == -1) && (strcmp(argv[count], "-type") != 0)) { - opserr << "WARNING eleLoad - expecting -type option but got " << argv[count] + if (typeIndex == -1) { + opserr << "WARNING missing required -type option" << "\n"; return TCL_ERROR; } + // + // Create the load + // count = typeIndex+1; -//count++; - if (strcmp(argv[count], "-beamUniform") == 0 || - strcmp(argv[count], "beamUniform") == 0) { + if ((strcmp(argv[count], "-beamUniform") == 0) || + (strcmp(argv[count], "BeamUniform") == 0) || + (strcmp(argv[count], "beamUniform") == 0)) { // // see https://portwooddigital.com/2021/05/05/trapezoidal-beam-loads // @@ -623,24 +885,24 @@ TclCommand_addElementalLoad(ClientData clientData, Tcl_Interp *interp, int argc, else if (argc - count == 4) { if (Tcl_GetDouble(interp, argv[count], &t1) != TCL_OK) { opserr << "WARNING eleLoad - invalid T1 " << argv[count] - << " for -shellThermal\n"; + << OpenSees::SignalMessageEnd; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[count + 1], &locY1) != TCL_OK) { opserr << "WARNING eleLoad - invalid LocY1 " << argv[count + 1] - << " for -shellThermal\n"; + << OpenSees::SignalMessageEnd; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[count + 2], &t2) != TCL_OK) { opserr << "WARNING eleLoad - invalid T2 " << argv[count] - << " for -shellThermal\n"; + << OpenSees::SignalMessageEnd; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[count + 3], &locY2) != TCL_OK) { opserr << "WARNING eleLoad - invalid LocY2 " << argv[count + 1] - << " for -shellThermal\n"; + << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -650,11 +912,8 @@ TclCommand_addElementalLoad(ClientData clientData, Tcl_Interp *interp, int argc, element_tags[i]); // add the load to the domain - if (domain->addElementalLoad(theLoad, loadPatternTag) == - false) { - opserr << "WARNING eleLoad - could not add following load to " - "domain:\n "; - opserr << theLoad; + if (domain->addElementalLoad(theLoad, loadPatternTag) == false) { + opserr << "WARNING eleLoad - could not add load to domain\n "; delete theLoad; return TCL_ERROR; } @@ -723,7 +982,7 @@ TclCommand_addElementalLoad(ClientData clientData, Tcl_Interp *interp, int argc, int NodalTtag; if (Tcl_GetInt(interp, argv[count + i], &NodalTtag) != TCL_OK) { - opserr << "WARNING invalid nodeId: " << argv[1]; + opserr << "WARNING invalid nodeId " << argv[1]; return TCL_ERROR; } @@ -790,9 +1049,8 @@ TclCommand_addElementalLoad(ClientData clientData, Tcl_Interp *interp, int argc, } //end of for loop return 0; } - //------------------------end of using ThermalActionWrapper-------------------------- - //-----------------Adding tcl command for beam thermal action(2D&3D), 2013..[Begin]--------------- + //-----------------Adding tcl command for beam thermal action(2D&3D), 2013..[Begin]--------------- else if (strcmp(argv[count], "-beamThermal") == 0) { count++; //For two dimensional model @@ -889,7 +1147,7 @@ TclCommand_addElementalLoad(ClientData clientData, Tcl_Interp *interp, int argc, eleLoadTag++; } //end of for loop return 0; - } //end of + } // end of //--------------------------end for beam2DThermalAction with time series ---------------------------------------- } else { //(1) 9 temperature points, i.e. 8 layers @@ -1424,6 +1682,7 @@ TclCommand_addElementalLoad(ClientData clientData, Tcl_Interp *interp, int argc, eleLoadTag++; } } + // One twmp change give, uniform temp change in element else if (argc - count == 1) { if (Tcl_GetDouble(interp, argv[count], &temp1) != TCL_OK) { diff --git a/SRC/runtime/commands/domain/loading/groundExcitation.cpp b/SRC/runtime/commands/domain/loading/groundExcitation.cpp index 8b09138c18..910f28ff94 100644 --- a/SRC/runtime/commands/domain/loading/groundExcitation.cpp +++ b/SRC/runtime/commands/domain/loading/groundExcitation.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // #if 0 int diff --git a/SRC/runtime/commands/domain/loading/groundMotion.cpp b/SRC/runtime/commands/domain/loading/groundMotion.cpp index 24db3a1d49..07320373bc 100644 --- a/SRC/runtime/commands/domain/loading/groundMotion.cpp +++ b/SRC/runtime/commands/domain/loading/groundMotion.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file contains the function invoked when the user invokes // the GroundMotion command in the interpreter. // @@ -18,6 +19,7 @@ #include #include #include +#include extern TimeSeries *TclSeriesCommand(ClientData clientData, Tcl_Interp *interp, TCL_Char * const arg); @@ -27,7 +29,7 @@ extern TimeSeriesIntegrator *TclDispatch_newSeriesIntegrator(ClientData clientDa TCL_Char * const arg); static int -TclCommand_newGroundMotion(G3_Runtime* rt, +TclCommand_newGroundMotion(ClientData, Tcl_Interp*, int argc, TCL_Char ** const argv, MultiSupportPattern *thePattern); @@ -37,7 +39,6 @@ TclCommand_addGroundMotion(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { - G3_Runtime *rt = G3_getRuntime(interp); MultiSupportPattern* pattern = (MultiSupportPattern *)Tcl_GetAssocData(interp,"theTclMultiSupportPattern", NULL); @@ -45,18 +46,16 @@ TclCommand_addGroundMotion(ClientData clientData, Tcl_Interp *interp, opserr << "ERROR no multi-support pattern\n"; return TCL_ERROR; } - return TclCommand_newGroundMotion(rt, argc, argv, pattern); + return TclCommand_newGroundMotion(clientData, interp, argc, argv, pattern); } static int -TclCommand_newGroundMotion(G3_Runtime* rt, int argc, +TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char ** const argv, MultiSupportPattern *thePattern) { - int gMotionTag; - GroundMotion *theMotion = nullptr; - Tcl_Interp *interp = G3_getInterpreter(rt); + BasicModelBuilder *builder = static_cast(clientData); // make sure at least one other argument to contain integrator if (argc < 4) { @@ -65,6 +64,7 @@ TclCommand_newGroundMotion(G3_Runtime* rt, int argc, return TCL_ERROR; } + int gMotionTag; if (Tcl_GetInt(interp, argv[1], &gMotionTag) != TCL_OK) { opserr << "WARNING invalid tag: groundMotion tag type \n"; return TCL_ERROR; @@ -72,6 +72,7 @@ TclCommand_newGroundMotion(G3_Runtime* rt, int argc, int startArg = 2; + GroundMotion *theMotion = nullptr; if ((strcmp(argv[startArg], "Series") == 0) || (strcmp(argv[startArg], "Plain") == 0)) { @@ -89,7 +90,7 @@ TclCommand_newGroundMotion(G3_Runtime* rt, int argc, (strcmp(argv[currentArg], "-acceleration") == 0)) { currentArg++; - accelSeries = TclSeriesCommand((ClientData)0, interp, argv[currentArg]); + accelSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); if (accelSeries == 0) { opserr << "WARNING invalid accel series: " << argv[currentArg]; @@ -102,7 +103,7 @@ TclCommand_newGroundMotion(G3_Runtime* rt, int argc, (strcmp(argv[currentArg], "-velocity") == 0)) { currentArg++; - velSeries = TclSeriesCommand((ClientData)0, interp, argv[currentArg]); + velSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); if (velSeries == 0) { opserr << "WARNING invalid vel series: " << argv[currentArg]; @@ -115,7 +116,7 @@ TclCommand_newGroundMotion(G3_Runtime* rt, int argc, (strcmp(argv[currentArg], "-displacement") == 0)) { currentArg++; - dispSeries = TclSeriesCommand((ClientData)0, interp, argv[currentArg]); + dispSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); if (dispSeries == 0) { opserr << "WARNING invalid disp series: " << argv[currentArg]; diff --git a/SRC/runtime/commands/domain/loading/pattern.cpp b/SRC/runtime/commands/domain/loading/pattern.cpp index 1feb9e3a32..3e0e022ba3 100644 --- a/SRC/runtime/commands/domain/loading/pattern.cpp +++ b/SRC/runtime/commands/domain/loading/pattern.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file contains the function invoked when the user invokes // the "pattern" command in the interpreter. // @@ -26,11 +27,10 @@ #include #include #include -#include #include -#include - +#include +#include #include #include @@ -48,7 +48,7 @@ #endif #ifdef _H5DRM -# include +# include #endif #include //L.Jiang [SIF] @@ -84,7 +84,7 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, // make sure at least one other argument to contain integrator if (argc < 3) { - opserr << G3_ERROR_PROMPT << "invalid command - want: pattern type "; + opserr << OpenSees::PromptValueError << "invalid command - want: pattern type "; opserr << " {list of load and sp constraints commands}\n"; opserr << " valid types: Plain, UniformExcitation, MultiSupport\n"; return TCL_ERROR; @@ -96,13 +96,13 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, int patternID; if (Tcl_GetInt(interp, argv[2], &patternID) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid patternID: " << argv[2] << "\n"; + opserr << OpenSees::PromptValueError << "invalid patternID: " << argv[2] << "\n"; return TCL_ERROR; } if (strcmp(argv[1], "Plain") == 0) { if (argc < 4) { - opserr << G3_ERROR_PROMPT << "Invalid command for Plain pattern.\n"; + opserr << OpenSees::PromptValueError << "Invalid command for Plain pattern.\n"; return TCL_ERROR; } @@ -114,7 +114,7 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, (strcmp(argv[commandEndMarker], "-factor") == 0)) { if (Tcl_GetDouble(interp, argv[++commandEndMarker], &fact) != TCL_OK) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "invalid factor: " << argv[commandEndMarker] << "\n"; return TCL_ERROR; } @@ -133,7 +133,7 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, theSeries = TclSeriesCommand(clientData, interp, series_arg); if (theSeries == nullptr) { - opserr << G3_ERROR_PROMPT << "problem creating TimeSeries for LoadPattern " + opserr << OpenSees::PromptValueError << "problem creating TimeSeries for LoadPattern " << patternID << endln; // clean up the memory and return an error @@ -150,7 +150,7 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, int dir; if (Tcl_GetInt(interp, argv[3], &dir) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid patternID: pattern type " << argv[2] + opserr << OpenSees::PromptValueError << "invalid patternID: pattern type " << argv[2] << "\n"; return TCL_ERROR; } @@ -254,7 +254,7 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, } if (dispSeries == nullptr && velSeries == nullptr && accelSeries == nullptr) { - opserr << G3_ERROR_PROMPT << "invalid series, expected:\n pattern UniformExcitation"; + opserr << OpenSees::PromptValueError << "invalid series, expected:\n pattern UniformExcitation"; opserr << "-disp {dispSeries} -vel {velSeries} -accel {accelSeries} "; opserr << "-int {Series Integrator}" << "\n"; return TCL_ERROR; @@ -339,7 +339,7 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, // Read in the ground motion if (accelFileName == 0) { - opserr << G3_ERROR_PROMPT << "No ground motion data provided\n"; + opserr << OpenSees::PromptValueError << "No ground motion data provided\n"; opserr << "UniformExcitation tag: " << patternID << endln; return TCL_ERROR; } @@ -738,7 +738,8 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, // now add the load pattern to the modelBuilder if (domain->addLoadPattern(thePattern) == false) { - opserr << OpenSees::PromptValueError << "could not add load pattern to the domain " + opserr << OpenSees::PromptValueError + << "could not add load pattern to the domain " << *thePattern; delete thePattern; return TCL_ERROR; @@ -762,7 +763,7 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Eval(interp, "rename nodalLoad load;"); if (Tcl_Eval(interp, argv[commandEndMarker]) != TCL_OK) { // opserr << OpenSees::PromptValueError << "- error reading load pattern information in { }"; - opserr << G3_ERROR_PROMPT << Tcl_GetStringResult(interp); + opserr << OpenSees::PromptValueError << Tcl_GetStringResult(interp); // Tcl_Eval(interp, "puts $errorInfo; flush stdout;"); // Tcl_Exit(TCL_ERROR); return TCL_ERROR; @@ -798,7 +799,6 @@ TclCommand_addNodalLoad(ClientData clientData, Tcl_Interp *interp, int argc, TCL int loadPatternTag = 0; if (true) { - // make sure at least one other argument to contain type if (argc < (2 + ndf)) { opserr << OpenSees::PromptValueError << "bad command - want: load nodeId " << ndf << " forces\n"; return TCL_ERROR; @@ -808,7 +808,6 @@ TclCommand_addNodalLoad(ClientData clientData, Tcl_Interp *interp, int argc, TCL int nodeId; if (Tcl_GetInt(interp, argv[1], &nodeId) != TCL_OK) { opserr << OpenSees::PromptValueError << "invalid nodeId: " << argv[1]; - opserr << " - load nodeId " << ndf << " forces\n"; return TCL_ERROR; } @@ -817,7 +816,8 @@ TclCommand_addNodalLoad(ClientData clientData, Tcl_Interp *interp, int argc, TCL for (int i = 0; i < ndf; ++i) { double theForce; if (Tcl_GetDouble(interp, argv[2 + i], &theForce) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid force " << i + 1 << " in load " << nodeId; + opserr << OpenSees::PromptValueError + << "invalid force " << i + 1 << " in load " << nodeId; opserr << ", got " << ndf << " forces\n"; return TCL_ERROR; } else @@ -837,8 +837,9 @@ TclCommand_addNodalLoad(ClientData clientData, Tcl_Interp *interp, int argc, TCL if (endMarker == argc || Tcl_GetInt(interp, argv[endMarker], &loadPatternTag) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid patternTag - load " << nodeId << " "; - opserr << ndf << " forces pattern patterntag\n"; + opserr << OpenSees::PromptValueError + << "invalid patternTag " << argv[endMarker] + << "\n"; return TCL_ERROR; } } @@ -848,8 +849,8 @@ TclCommand_addNodalLoad(ClientData clientData, Tcl_Interp *interp, int argc, TCL // get the current pattern tag if no tag given in i/p if (explicitPatternPassed == false) { if (theTclLoadPattern == nullptr) { - opserr << OpenSees::PromptParseError << "no current load pattern - load " << nodeId; - opserr << " " << ndf << " forces\n"; + opserr << OpenSees::PromptParseError + << "no current load pattern\n"; return TCL_ERROR; } else loadPatternTag = theTclLoadPattern->getTag(); diff --git a/SRC/runtime/commands/domain/loading/series.cpp b/SRC/runtime/commands/domain/loading/series.cpp index 018da6dfeb..7704421e0b 100644 --- a/SRC/runtime/commands/domain/loading/series.cpp +++ b/SRC/runtime/commands/domain/loading/series.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file contains the function invoked when the user invokes // the pattern command in the interpreter. It is invoked by the // TclBasicBuilder_addPattern function. @@ -16,7 +17,6 @@ #include #include -#include #include #include #include @@ -62,7 +62,7 @@ TclDispatch_newLinearSeries(ClientData clientData, Tcl_Interp* interp, int argc, if (numRemainingArgs == 1 || numRemainingArgs == 3) { if (Tcl_GetInt(interp, argv[0], &tag) != 0) { - opserr << G3_ERROR_PROMPT << "invalid series tag in LinearSeries tag? <-factor " + opserr << OpenSees::PromptValueError << "invalid series tag in LinearSeries tag? <-factor " "factor?>" << "\n"; return nullptr; @@ -73,12 +73,12 @@ TclDispatch_newLinearSeries(ClientData clientData, Tcl_Interp* interp, int argc, if (numRemainingArgs > 1) { const char *argvS = argv[1]; if (argvS == 0) { - opserr << G3_ERROR_PROMPT << "string error in LinearSeries with tag: " << tag + opserr << OpenSees::PromptValueError << "string error in LinearSeries with tag: " << tag << "\n"; return nullptr; } if (Tcl_GetDouble(interp, argv[2], &cFactor) != 0) { - opserr << G3_ERROR_PROMPT << "invalid factor in LinearSeries with tag: " << tag + opserr << OpenSees::PromptValueError << "invalid factor in LinearSeries with tag: " << tag << "\n"; return nullptr; } @@ -117,12 +117,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T endMarker++; } - theSeries = new ConstantSeries(cFactor); - - -// void *theResult = OPS_ConstantSeries(rt, argc, argv); -// if (theResult != nullptr) -// theSeries = (TimeSeries *)theResult; + theSeries = new ConstantSeries(cFactor); } else if (strcmp(argv[0],"Trig") == 0 || @@ -142,7 +137,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T if (argc == 5 || argc == 7 || argc == 9 || argc == 11) { if (Tcl_GetInt(interp, argv[argi++], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid series tag in Trig tag?" << "\n"; + opserr << OpenSees::PromptValueError << "invalid series tag in Trig tag?" << "\n"; return nullptr; } } @@ -441,7 +436,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T double cFactor = 1.0; if (argc < 3) { - opserr << G3_ERROR_PROMPT << "not enough args - "; + opserr << OpenSees::PromptValueError << "not enough args - "; opserr << " Series -dt timeIncr -values {list of points }\n"; return 0; } @@ -473,7 +468,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T if (endMarker == argc || Tcl_GetDouble(interp, argv[endMarker], &timeIncr) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid dt " << argv[endMarker] << " - "; + opserr << OpenSees::PromptValueError << "invalid dt " << argv[endMarker] << " - "; opserr << " Series -dt dt ... \n"; return 0; } @@ -485,7 +480,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T if (endMarker == argc || Tcl_GetInt(interp, argv[endMarker], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid tag " << argv[endMarker] << " - "; + opserr << OpenSees::PromptValueError << "invalid tag " << argv[endMarker] << " - "; return 0; } } @@ -496,7 +491,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T if (endMarker == argc || Tcl_GetDouble(interp, argv[endMarker], &cFactor) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid cFactor " << argv[endMarker] << " - "; + opserr << OpenSees::PromptValueError << "invalid scale factor " << argv[endMarker] << " - "; opserr << " Series -factor ... \n"; return 0; } @@ -508,7 +503,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T if (endMarker != argc) { fileName = endMarker; // argv[endMarker]; if (stat(argv[endMarker], &fileInfo ) != 0) { - opserr << G3_ERROR_PROMPT << "Cannot open file " + opserr << OpenSees::PromptValueError << "Cannot open file " << argv[endMarker] << "\n"; return nullptr; } @@ -521,7 +516,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T if (endMarker != argc) { filePathName = endMarker; // argv[endMarker]; if (stat(argv[endMarker], &fileInfo ) != 0) { - opserr << G3_ERROR_PROMPT << "Cannot open file " + opserr << OpenSees::PromptValueError << "Cannot open file " << argv[endMarker] << "\n"; return nullptr; } @@ -534,7 +529,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T if (endMarker != argc) { fileTimeName = endMarker; // argv[endMarker]; if (stat(argv[endMarker], &fileInfo ) != 0) { - opserr << G3_ERROR_PROMPT << "Cannot open file " + opserr << OpenSees::PromptValueError << "Cannot open file " << argv[endMarker] << "\n"; return nullptr; } @@ -551,7 +546,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T if (Tcl_SplitList(interp, argv[endMarker], &pathSize, &pathStrings) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "problem splitting path list " << argv[endMarker] + opserr << OpenSees::PromptValueError << "problem splitting path list " << argv[endMarker] << " - "; opserr << " Series -values {path} ... \n"; return nullptr; @@ -561,7 +556,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T for (int i = 0; i < pathSize; ++i) { double value; if (Tcl_GetDouble(interp, pathStrings[i], &value) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "problem reading path data value " + opserr << OpenSees::PromptValueError << "problem reading path data value " << pathStrings[i] << " - "; opserr << " Series -values {path} ... \n"; Tcl_Free((char *)pathStrings); @@ -584,7 +579,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T if (Tcl_SplitList(interp, argv[endMarker], &pathSize, &pathStrings) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "problem spltting time path " << argv[endMarker] + opserr << OpenSees::PromptValueError << "problem spltting time path " << argv[endMarker] << " - "; opserr << " Series -time {times} ... \n"; return 0; @@ -594,7 +589,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T for (int i = 0; i < pathSize; ++i) { double value; if (Tcl_GetDouble(interp, pathStrings[i], &value) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "problem reading time path value " + opserr << OpenSees::PromptValueError << "problem reading time path value " << pathStrings[i] << " - "; opserr << " Series -values {path} ... \n"; @@ -623,7 +618,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T if (endMarker == argc || Tcl_GetDouble(interp, argv[endMarker], &startTime) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid tStart " << argv[endMarker] << " - "; + opserr << OpenSees::PromptValueError << "invalid tStart " << argv[endMarker] << " - "; opserr << " Series -startTime tStart ... \n"; return 0; } @@ -651,7 +646,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T } else if (dataPath != 0 && dataTime != 0) { if (dataTime->Size() != dataPath->Size()) { - opserr << G3_ERROR_PROMPT << "size of time vector (" << dataTime->Size() + opserr << OpenSees::PromptValueError << "size of time vector (" << dataTime->Size() << ") must be equal to size of values (" << dataPath->Size() << ")\n"; return nullptr; } @@ -661,7 +656,7 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T delete dataTime; } else { - opserr << G3_ERROR_PROMPT << "choice of options for Path Series invalid - valid " + opserr << OpenSees::PromptValueError << "choice of options for Path Series invalid - valid " "options for "; opserr << " Path are\n"; opserr << " \t -fileT fileTimeName -fileP filePathName \n"; @@ -763,111 +758,8 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T } } #endif - -#ifdef _RELIABILITY - - else if (strcmp(argv[0], "DiscretizedRandomProcess") == 0) { - - double mean, maxStdv; - ModulatingFunction *theModFunc; - - if (Tcl_GetDouble(interp, argv[1], &mean) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid input: random process mean \n"; - return 0; - } - - if (Tcl_GetDouble(interp, argv[2], &maxStdv) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid input: random process max stdv \n"; - return 0; - } - - // Number of modulating functions - int argsBeforeModList = 3; - int numModFuncs = argc - argsBeforeModList; - - // Create an array to hold pointers to modulating functions - ModulatingFunction **theModFUNCS = new ModulatingFunction *[numModFuncs]; - - // For each modulating function, get the tag and ensure it exists - int tagI; - for (int i = 0; i < numModFuncs; ++i) { - if (Tcl_GetInt(interp, argv[i + argsBeforeModList], &tagI) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid modulating function tag. " << "\n"; - return 0; - } - - theModFunc = 0; - theModFunc = theReliabilityDomain->getModulatingFunction(tagI); - - if (theModFunc == 0) { - opserr << G3_ERROR_PROMPT << "modulating function number " - << argv[i + argsBeforeModList] << "does not exist...\n"; - delete[] theModFUNCS; - return 0; - } else { - theModFUNCS[i] = theModFunc; - } - } - - // Parsing was successful, create the random process series object - theSeries = new DiscretizedRandomProcessSeries(0, numModFuncs, theModFUNCS, - mean, maxStdv); - } - - else if (strcmp(argv[0], "SimulatedRandomProcess") == 0) { - - int spectrumTag, numFreqIntervals; - double mean; - - if (Tcl_GetInt(interp, argv[1], &spectrumTag) != TCL_OK) { - opserr << "WARNING invalid input to SimulatedRandomProcess: spectrumTag" - << "\n"; - return 0; - } - - if (Tcl_GetDouble(interp, argv[2], &mean) != TCL_OK) { - opserr << "WARNING invalid input to SimulatedRandomProcess: mean" - << "\n"; - return 0; - } - - if (Tcl_GetInt(interp, argv[3], &numFreqIntervals) != TCL_OK) { - opserr - << "WARNING invalid input to SimulatedRandomProcess: numFreqIntervals" - << "\n"; - return 0; - } - - // Check that the random number generator exists - if (theRandomNumberGenerator == 0) { - opserr << "WARNING: A random number generator must be instantiated " - "before SimulatedRandomProcess." - << "\n"; - return 0; - } - - // Check that the spectrum exists - Spectrum *theSpectrum = 0; - theSpectrum = theReliabilityDomain->getSpectrum(spectrumTag); - if (theSpectrum == 0) { - opserr << "WARNING: Could not find the spectrum for the " - "SimulatedRandomProcess." - << "\n"; - return 0; - } - - // Parsing was successful, create the random process series object - theSeries = new SimulatedRandomProcessSeries( - 0, theRandomNumberGenerator, theSpectrum, numFreqIntervals, mean); - } - -#endif - else { - for (int i = 0; i < argc; ++i) - opserr << argv[i] << ' '; - opserr << "\n"; - // type of load pattern type unknown + // type unknown opserr << "WARNING unknown Series type " << argv[0] << " - "; opserr << " valid types: Linear, Rectangular, Path, Constant, Trig, Sine\n"; return 0; diff --git a/SRC/runtime/commands/domain/nodes.cpp b/SRC/runtime/commands/domain/nodes.cpp index 99f01f1699..9fe4b4a53a 100644 --- a/SRC/runtime/commands/domain/nodes.cpp +++ b/SRC/runtime/commands/domain/nodes.cpp @@ -1,23 +1,11 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ +//===----------------------------------------------------------------------===// // +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// // Description: This file implements commands for interacting with nodes // in the domain. // @@ -50,8 +38,8 @@ static int resDataSize = 0; int -getNodeTags(ClientData clientData, - Tcl_Interp *interp, +getNodeTags(ClientData clientData, + Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { @@ -60,12 +48,13 @@ getNodeTags(ClientData clientData, NodeIter &nodeIter = the_domain->getNodes(); + Tcl_Obj* result = Tcl_NewListObj(the_domain->getNumNodes(), nullptr); + Node *node; - char buffer[20]; - while ((node = nodeIter()) != nullptr) { - sprintf(buffer, "%d ", node->getTag()); - Tcl_AppendResult(interp, buffer, NULL); - } + while ((node = nodeIter()) != nullptr) + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(node->getTag())); + + Tcl_SetObjResult(interp, result); return TCL_OK; } @@ -138,8 +127,9 @@ setNodeCoord(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, double value; if (Tcl_GetInt(interp, argv[2], &dim) != TCL_OK) { - opserr - << "WARNING setNodeCoord nodeTag? dim? value? - could not read dim? \n"; + opserr << OpenSees::PromptValueError + << "could not read dim" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3], &value) != TCL_OK) { @@ -151,12 +141,15 @@ setNodeCoord(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, Node *theNode = domain->getNode(tag); if (theNode == nullptr) { - // TODO: add error message + opserr << OpenSees::PromptValueError + << "Unable to find node with tag '" << tag << "'" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } // // TODO: Check dimensions + // Vector coords(theNode->getCrds()); coords(dim - 1) = value; @@ -168,6 +161,8 @@ setNodeCoord(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, +#if 1 + template int nodeResponseTemplate(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) @@ -264,6 +259,291 @@ nodeReaction(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char return nodeResponseTemplate(clientData, interp, argc, argv); } +#else +int +nodeDisp(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + assert(clientData != nullptr); + Domain *domain = (Domain*)clientData; + + if (argc < 2) { + opserr << "WARNING want - nodeDisp nodeTag? \n"; + return TCL_ERROR; + } + + int tag; + int dof = -1; + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING could not read nodeTag? \n"; + return TCL_ERROR; + } + + if (argc > 2) { + if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { + opserr << "WARNING nodeDisp nodeTag? dof? - could not read dof? \n"; + return TCL_ERROR; + } + } + + dof--; + + const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::Disp); + + if (nodalResponse == nullptr) + // TODO: add error message + return TCL_ERROR; + + int size = nodalResponse->Size(); + + if (dof >= 0) { + + if (dof >= size) { + opserr << "WARNING nodeDisp nodeTag? dof? - dofTag? too large\n"; + return TCL_ERROR; + } + + Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); + + } else { + char buffer[40]; + for (int i = 0; i < size; ++i) { + sprintf(buffer, "%35.20f", (*nodalResponse)(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + return TCL_OK; +} + +int +nodeVel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + assert(clientData != nullptr); + Domain *the_domain = (Domain*)clientData; + + if (argc < 2) { + opserr << "WARNING want - nodeVel nodeTag? \n"; + return TCL_ERROR; + } + + int tag; + int dof = -1; + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING nodeVel nodeTag? dof? - could not read nodeTag? \n"; + return TCL_ERROR; + } + if (argc > 2) { + if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { + opserr << "WARNING nodeVel nodeTag? dof? - could not read dof? \n"; + return TCL_ERROR; + } + } + + dof--; + + const Vector *nodalResponse = the_domain->getNodeResponse(tag, NodeData::Vel); + + if (nodalResponse == nullptr) + // TODO: add error message + return TCL_ERROR; + + int size = nodalResponse->Size(); + + if (dof >= 0) { + if (size < dof) + // TODO: add error message + return TCL_ERROR; + + double value = (*nodalResponse)(dof); + + // now we copy the value to the tcl string that is returned + char buffer[40]; + sprintf(buffer, "%35.20f", value); + Tcl_SetResult(interp, buffer, TCL_VOLATILE); + + } else { + + char buffer[40]; + for (int i = 0; i < size; ++i) { + sprintf(buffer, "%35.20f", (*nodalResponse)(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + return TCL_OK; +} + +int +nodeAccel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) +{ + assert(clientData != nullptr); + + Domain *the_domain = (Domain *)clientData; + + if (argc < 2) { + opserr << "WARNING want - nodeAccel nodeTag? dof?\n"; + return TCL_ERROR; + } + + int tag; + int dof = -1; + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING nodeAccel nodeTag? dof? - could not read nodeTag? \n"; + return TCL_ERROR; + } + if (argc > 2) { + if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { + opserr << "WARNING nodeAccel nodeTag? dof? - could not read dof? \n"; + return TCL_ERROR; + } + } + + dof--; + + const Vector *nodalResponse = the_domain->getNodeResponse(tag, NodeData::Accel); + if (nodalResponse == nullptr) + // TODO: add error message + return TCL_ERROR; + + int size = nodalResponse->Size(); + + if (dof >= 0) { + if (size < dof) + return TCL_ERROR; + + Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); + + } else { + char buffer[40]; + for (int i = 0; i < size; ++i) { + sprintf(buffer, "%35.20f", (*nodalResponse)(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + return TCL_OK; +} + + +int +nodeUnbalance(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, + TCL_Char ** const argv) +{ + assert(clientData != nullptr); + Domain *domain = (Domain*)clientData; + + if (argc < 2) { + opserr << "WARNING want - nodeUnbalance nodeTag? \n"; + return TCL_ERROR; + } + + int tag; + int dof = -1; + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr + << "WARNING nodeUnbalance nodeTag? dof? - could not read nodeTag? \n"; + return TCL_ERROR; + } + + if (argc > 2) { + if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { + opserr << "WARNING nodeUnbalance nodeTag? dof? - could not read dof? \n"; + return TCL_ERROR; + } + } + + dof--; + + const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::UnbalancedLoad); + + if (nodalResponse == nullptr) + // TODO: add error message + return TCL_ERROR; + + int size = nodalResponse->Size(); + + if (dof >= 0) { + + if (dof >= size) { + opserr << "WARNING nodeUnbalance nodeTag? dof? - dofTag? too large\n"; + return TCL_ERROR; + } + + Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); + + } else { + char buffer[40]; + for (int i = 0; i < size; ++i) { + sprintf(buffer, "%35.20f", (*nodalResponse)(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + return TCL_OK; +} + + +int +nodeReaction(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, + TCL_Char ** const argv) +{ + assert(clientData != nullptr); + Domain *domain = (Domain*)clientData; + + if (argc < 2) { + opserr << "WARNING want - nodeReaction nodeTag? \n"; + return TCL_ERROR; + } + + int tag; + int dof = -1; + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING nodeReaction nodeTag? dof? - could not read nodeTag? \n"; + return TCL_ERROR; + } + + if (argc > 2) { + if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { + opserr << "WARNING nodeReaction nodeTag? dof? - could not read dof? \n"; + return TCL_ERROR; + } + } + + dof--; + + const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::Reaction); + + if (nodalResponse == nullptr) + // TODO: add error message + return TCL_ERROR; + + int size = nodalResponse->Size(); + + if (dof >= 0) { + + if (dof >= size) { + opserr << "WARNING nodeReaction nodeTag? dof? - dofTag? too large\n"; + return TCL_ERROR; + } + + Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); + + } else { + char buffer[40]; + for (int i = 0; i < size; ++i) { + sprintf(buffer, "%35.20f", (*nodalResponse)(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + return TCL_OK; +} +#endif int nodeMass(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) @@ -592,11 +872,11 @@ nodeResponse(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, int tag, dof, responseID; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING nodeResponse nodeTag? dof? - could not read nodeTag? \n"; + opserr << "WARNING could not read nodeTag? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeResponse nodeTag? dof? - could not read dof? \n"; + opserr << "WARNING could not read dof? \n"; return TCL_ERROR; } @@ -609,6 +889,8 @@ nodeResponse(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, responseID = (int)NodeData::Accel; else if (strcmp(argv[3], "resiudal") == 0) responseID = (int)NodeData::UnbalancedLoad; + else if (strcmp(argv[3], "reactionForce") == 0) + responseID = (int)NodeData::Reaction; else { opserr << "WARNING unknown response " << argv[3] << "\n"; return TCL_ERROR; @@ -773,7 +1055,9 @@ nodeCoord(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** strcmp(argv[2], "3") == 0) dim = 2; else { - opserr << OpenSees::PromptValueError << "" << "nodeCoord nodeTag? dim? - could not read dim? \n"; + opserr << OpenSees::PromptValueError + << "could not read dim" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } } @@ -781,7 +1065,9 @@ nodeCoord(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** Node *theNode = the_domain->getNode(tag); if (theNode == nullptr) { - opserr << OpenSees::PromptValueError << "Unable to retrieve node with tag '" << tag << "'\n"; + opserr << OpenSees::PromptValueError + << "Unable to find node with tag '" << tag << "'" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } diff --git a/SRC/runtime/commands/domain/parameter.cpp b/SRC/runtime/commands/domain/parameter.cpp index 3f52fc2fc7..5017198462 100644 --- a/SRC/runtime/commands/domain/parameter.cpp +++ b/SRC/runtime/commands/domain/parameter.cpp @@ -1,15 +1,17 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// #include #include +#include +#include #include #include #include -#include #include #include #include @@ -36,19 +38,18 @@ extern ReliabilityDomain *theReliabilityDomain; #endif +// parameter tag int -TclCommand_parameter(ClientData clientData, Tcl_Interp *interp, int argc, +TclCommand_parameter(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); - Domain* domain = (Domain*)clientData; + Domain* domain = static_cast(clientData); - // check at least two arguments so don't segemnt fault on strcmp + // ensure at least two arguments if (argc < 2) { opserr << "WARNING need to specify a parameter tag\n"; - opserr << "Want: parameter tag .. see manual for " - "valid parameter types and arguments\n"; return TCL_ERROR; } @@ -59,8 +60,6 @@ TclCommand_parameter(ClientData clientData, Tcl_Interp *interp, int argc, } Parameter *theParameter = domain->getParameter(paramTag); - int eleTag = -1; - bool isele = false; // First, check special case of a blank parameter if (argc == 2 && strcmp(argv[0], "parameter") == 0) { @@ -94,8 +93,14 @@ TclCommand_parameter(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_OK; } - if (argc >= 6 && strcmp(argv[0], "parameter") == 0 && - strcmp(argv[2], "node") == 0 && strcmp(argv[4], "disp") == 0) { + int eleTag = -1; + bool isele = false; + + + if (argc >= 6 && + strcmp(argv[0], "parameter") == 0 && + strcmp(argv[2], "node") == 0 && + strcmp(argv[4], "disp") == 0) { int nodeTag; if (Tcl_GetInt(interp, argv[3], &nodeTag) != TCL_OK) { @@ -120,55 +125,42 @@ TclCommand_parameter(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_OK; } - if (argc >= 5 && strcmp(argv[0], "parameter") == 0 && - strcmp(argv[2], "pattern") == 0 && strcmp(argv[4], "lambda") == 0) { + if (argc >= 5 && + strcmp(argv[0], "parameter") == 0 && + strcmp(argv[2], "pattern") == 0 && + strcmp(argv[4], "lambda") == 0) { int patternTag; if (Tcl_GetInt(interp, argv[3], &patternTag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read pattern tag\n"; return TCL_ERROR; } + LoadPattern *thePattern = domain->getLoadPattern(patternTag); Parameter *newParameter = new LoadFactorParameter(paramTag, thePattern); domain->addParameter(newParameter); - char buffer[40]; - sprintf(buffer, "%d", paramTag); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewIntObj(paramTag)); return TCL_OK; } + // // Now handle the parameter according to which command is invoked + // if (strcmp(argv[0], "parameter") == 0 || strcmp(argv[0], "addToParameter") == 0) { - // RandomVariable *theRV = 0; - void *theRV = 0; + void *theRV = nullptr; MovableObject *theObject = nullptr; if (strstr(argv[2], "randomVariable") != 0) { -#ifdef _RELIABILITY - int rvTag; - if (Tcl_GetInt(interp, argv[3], &rvTag) != TCL_OK) { - return TCL_ERROR; - } - - if (theReliabilityDomain == 0) { - opserr << "ERROR parameter " << paramTag - << " -- reliability domain has not been created" << endln; - } - - theRV = theReliabilityDomain->getRandomVariablePtr(rvTag); - if (theRV == 0) { - opserr << "ERROR parameter " << paramTag - << " -- random variable with tag " << rvTag << " not defined" - << endln; - return TCL_ERROR; - } -#endif + // return TCL_ERROR; + // REMOVED } int argStart = (theRV) ? 4 : 2; @@ -212,8 +204,8 @@ TclCommand_parameter(ClientData clientData, Tcl_Interp *interp, int argc, theObject = static_cast(domain->getNode(nodeTag)); argStart = (theRV) ? 6 : 4; - - } else if (argc > argStart && strstr(argv[argStart], "loadPattern") != 0) { + } + else if (argc > argStart && strstr(argv[argStart], "loadPattern") != 0) { if (argc < 4) { @@ -241,7 +233,7 @@ TclCommand_parameter(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } - /////////////////////////////////// + // Create new parameter if (strcmp(argv[0], "parameter") == 0) { @@ -267,7 +259,7 @@ TclCommand_parameter(ClientData clientData, Tcl_Interp *interp, int argc, } else newParameter = new Parameter(paramTag, 0, 0, 0); - if (theRV != 0) { + if (theRV != nullptr) { #ifdef _RELIABILITY RVParameter *newRVParameter = new RVParameter(paramTag, theRV, newParameter); @@ -287,7 +279,7 @@ TclCommand_parameter(ClientData clientData, Tcl_Interp *interp, int argc, // Add to an existing parameter else if (strcmp(argv[0], "addToParameter") == 0) { - if (theParameter == 0) { + if (theParameter == nullptr) { opserr << "WARNING addToParameter -- parameter with tag " << paramTag << " not found in domain\n"; return TCL_ERROR; @@ -298,8 +290,13 @@ TclCommand_parameter(ClientData clientData, Tcl_Interp *interp, int argc, argc - argStart); else { theObject = static_cast(domain->getElement(eleTag)); + if (theObject == nullptr) { + opserr << OpenSees::PromptValueError << "failed to find element with tag " << eleTag << "\n"; + return TCL_ERROR; + } theParameter->addComponent(theObject, (const char **)&argv[argStart], argc - argStart); + // Sorry, Frank, had to change this -- MHS // theParameter->addComponent(eleTag, (const char **)&argv[argStart], // argc-argStart); @@ -313,7 +310,7 @@ TclCommand_parameter(ClientData clientData, Tcl_Interp *interp, int argc, else if (strcmp(argv[0], "updateParameter") == 0) { // Cannot update a parameter that is not present - if (theParameter == 0) { + if (theParameter == nullptr) { opserr << "WARNING updateParameter -- parameter with tag " << paramTag << " not found in domain\n"; // return TCL_ERROR; @@ -333,7 +330,7 @@ TclCommand_parameter(ClientData clientData, Tcl_Interp *interp, int argc, } int -getParamTags(ClientData clientData, Tcl_Interp *interp, int argc, +getParamTags(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -342,18 +339,20 @@ getParamTags(ClientData clientData, Tcl_Interp *interp, int argc, Parameter *theParam; ParameterIter ¶mIter = the_domain->getParameters(); - char buffer[20]; + Tcl_Obj* result = Tcl_NewListObj(0, nullptr); - while ((theParam = paramIter()) != nullptr) { - sprintf(buffer, "%d ", theParam->getTag()); - Tcl_AppendResult(interp, buffer, NULL); - } + while ((theParam = paramIter()) != nullptr) + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(theParam->getTag())); + + + Tcl_SetObjResult(interp, result); return TCL_OK; } + int -getParamValue(ClientData clientData, Tcl_Interp *interp, int argc, +getParamValue(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -367,7 +366,7 @@ getParamValue(ClientData clientData, Tcl_Interp *interp, int argc, int paramTag; if (Tcl_GetInt(interp, argv[1], ¶mTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "getParamValue -- could not read paramTag \n"; + opserr << OpenSees::PromptValueError << "getParamValue -- could not read paramTag \n"; return TCL_ERROR; } @@ -383,24 +382,25 @@ getParamValue(ClientData clientData, Tcl_Interp *interp, int argc, int -setParameter(ClientData clientData, Tcl_Interp *interp, int argc, +TclCommand_setParameter(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { Domain *theDomain = (Domain*)clientData; - int argLoc = 1; double newValue = 0.0; ID eleIDs(0, 32); int numEle = 0; int flag = 0; - if (strstr(argv[argLoc], "-val") != 0) { + int argLoc = 1; + if ((strstr(argv[argLoc], "-val") != 0) || + (strcmp(argv[argLoc], "-value") == 0)) { if (Tcl_GetDouble(interp, argv[argLoc + 1], &newValue) != TCL_OK) { - opserr << "WARNING setParameter: invalid parameter value\n"; + opserr << "WARNING invalid parameter value\n"; return TCL_ERROR; } } else { - opserr << "WARNING setParameter: -val not found " << endln; + opserr << "WARNING setParameter: -val not found\n"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/domain/recorder.cpp b/SRC/runtime/commands/domain/recorder.cpp index ffdc898918..38a33681a1 100644 --- a/SRC/runtime/commands/domain/recorder.cpp +++ b/SRC/runtime/commands/domain/recorder.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file contains the function that is invoked // by the interpreter when the comand 'record' is invoked by the // user. @@ -23,6 +24,8 @@ #endif #define strcmp strcasecmp + +// #include #include #include #include @@ -67,7 +70,6 @@ extern FEM_ObjectBroker theBroker; OPS_Routine OPS_PVDRecorder; OPS_Routine OPS_GmshRecorder; OPS_Routine OPS_MPCORecorder; -OPS_Routine OPS_VTKHDF_Recorder; OPS_Routine OPS_VTK_Recorder; OPS_Routine OPS_ElementRecorderRMS; @@ -179,29 +181,29 @@ getNodeDataFlag(const char *dataToStore, Domain& theDomain, int* dataIndex) NodeData dataFlag = NodeData::DisplTrial; // 10; if (dataToStore == nullptr) - dataFlag = NodeData::DisplTrial; // 0; + dataFlag = NodeData::DisplTrial; // 0; else if ((strcmp(dataToStore, "disp") == 0)) { - dataFlag = NodeData::DisplTrial; // 0 + dataFlag = NodeData::DisplTrial; // 0 } else if ((strcmp(dataToStore, "vel") == 0)) { - dataFlag = NodeData::VelocTrial; // 1 + dataFlag = NodeData::VelocTrial; // 1 } else if ((strcmp(dataToStore, "accel") == 0)) { - dataFlag = NodeData::AccelTrial; // 2 + dataFlag = NodeData::AccelTrial; // 2 } else if ((strcmp(dataToStore, "incrDisp") == 0)) { - dataFlag = NodeData::IncrDisp; // 3; + dataFlag = NodeData::IncrDisp; // 3; } else if ((strcmp(dataToStore, "incrDeltaDisp") == 0)) { - dataFlag = NodeData::IncrDeltaDisp; // 4; + dataFlag = NodeData::IncrDeltaDisp; // 4; } else if ((strcmp(dataToStore, "unbalance") == 0)) { - dataFlag = NodeData::UnbalancedLoad; // 5 + dataFlag = NodeData::UnbalancedLoad; // 5 } else if ((strcmp(dataToStore, "unbalanceInclInertia") == 0) || - (strcmp(dataToStore, "unbalanceIncInertia") == 0) || - (strcmp(dataToStore, "unbalanceIncludingInertia") == 0)) { + (strcmp(dataToStore, "unbalanceIncInertia") == 0) || + (strcmp(dataToStore, "unbalanceIncludingInertia") == 0)) { dataFlag = NodeData::UnbalanceInclInertia; // 6 } else if ((strcmp(dataToStore, "reaction") == 0)) { - dataFlag = NodeData::Reaction; // 7 + dataFlag = NodeData::Reaction; // 7 } else if (((strcmp(dataToStore, "reactionIncInertia") == 0)) || ((strcmp(dataToStore, "reactionInclInertia") == 0)) || ((strcmp(dataToStore, "reactionIncludingInertia") == 0))) { - dataFlag = NodeData::ReactionInclInertia; // 8; + dataFlag = NodeData::ReactionInclInertia; // 8; } else if (((strcmp(dataToStore, "rayleighForces") == 0)) || ((strcmp(dataToStore, "rayleighDampingForces") == 0))) { dataFlag = NodeData::ReactionInclRayleigh; // 9; @@ -222,8 +224,9 @@ getNodeDataFlag(const char *dataToStore, Domain& theDomain, int* dataIndex) dataFlag = NodeData::EigenVector; // 10 + mode; else dataFlag = NodeData::Empty; // 10; + } - } else if ((strncmp(dataToStore, "sensitivity",11) == 0)) { + else if ((strncmp(dataToStore, "sensitivity",11) == 0)) { int paramTag = atoi(&(dataToStore[11])); Parameter *theParameter = theDomain.getParameter(paramTag); int grad = -1; @@ -234,8 +237,9 @@ getNodeDataFlag(const char *dataToStore, Domain& theDomain, int* dataIndex) dataFlag = NodeData::DisplSensitivity; // 1000 + grad; else dataFlag = NodeData::Empty; // 10; + } - } else if ((strncmp(dataToStore, "velSensitivity",14) == 0)) { + else if ((strncmp(dataToStore, "velSensitivity",14) == 0)) { int paramTag = atoi(&(dataToStore[14])); Parameter *theParameter = theDomain.getParameter(paramTag); int grad = -1; @@ -247,8 +251,9 @@ getNodeDataFlag(const char *dataToStore, Domain& theDomain, int* dataIndex) dataFlag = NodeData::VelocSensitivity; // 2000 + grad; else dataFlag = NodeData::Empty; // 10; + } - } else if ((strncmp(dataToStore, "accSensitivity",14) == 0)) { + else if ((strncmp(dataToStore, "accSensitivity",14) == 0)) { int paramTag = atoi(&(dataToStore[14])); Parameter *theParameter = theDomain.getParameter(paramTag); int grad = -1; @@ -351,7 +356,7 @@ parseOutputOption(OutputOptions *options, Tcl_Interp* interp, int argc, TCL_Char options->filename = argv[loc + 1]; options->eMode = eMode; } else { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "expected file name after flag '" << argv[loc] << "\n"; return -1; } @@ -366,7 +371,9 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, Domain &theDomain, Recorder **theRecorder) { assert(clientData != nullptr); - Domain* domain = (Domain*)clientData; + Domain* domain = static_cast(clientData); + // BasicModelBuilder *builder = static_cast(clientData); + // Domain* domain = builder->getDomain(); G3_Runtime *rt = G3_getRuntime(interp); (*theRecorder) = nullptr; @@ -389,6 +396,7 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, (strcmp(argv[1], "NormEnvelopeElement") == 0)) { OutputOptions options; + std::vector unused; int numEle = 0; int endEleIDs = 2; @@ -396,13 +404,11 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, double rTolDt = 1e-5; bool echoTime = false; int loc = endEleIDs; - int flags = 0; - int eleData = 0; ID *eleIDs = 0; ID *specificIndices = nullptr; - while (flags == 0 && loc < argc) { + while (loc < argc) { int consumed; if ((consumed = parseOutputOption(&options, interp, argc-loc, &argv[loc])) != 0) { if (consumed > 0) @@ -413,6 +419,10 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, else if (strcmp(argv[loc], "-rTolDt") == 0) { loc++; + if (loc == argc) { + opserr << OpenSees::PromptValueError << "flag -rTolDt is missing required argument\n"; + return TCL_ERROR; + } if (Tcl_GetDouble(interp, argv[loc], &rTolDt) != TCL_OK) return TCL_ERROR; loc++; @@ -431,7 +441,7 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } - // read in a list of ele until end of command or other flag + // read in a list of integer tags until end of command or other flag loc++; int eleTag; eleIDs = new ID(0, 32); @@ -442,19 +452,13 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, } Tcl_ResetResult(interp); - if (loc == argc) { - opserr << "ERROR: No response type specified for element recorder. " - << endln; - delete eleIDs; - return TCL_ERROR; - } - - if (strcmp(argv[loc], "all") == 0) { + if (loc < argc && (strcmp(argv[loc], "all") == 0)) { eleIDs = nullptr; loc++; } + } - } else if ((strcmp(argv[loc], "-eleRange") == 0) || + else if ((strcmp(argv[loc], "-eleRange") == 0) || (strcmp(argv[loc], "-range") == 0)) { // ensure no segmentation fault if user messes up @@ -469,14 +473,14 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, if (Tcl_GetInt(interp, argv[loc + 1], &start) != TCL_OK) { opserr << "WARNING recorder Element -eleRange start? end? - invalid " "start " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[loc + 2], &end) != TCL_OK) { opserr << "WARNING recorder Element -eleRange start? end? - invalid end " - << argv[loc + 2] << endln; + << argv[loc + 2] << "\n"; return TCL_ERROR; } @@ -503,13 +507,13 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, int tag; if (Tcl_GetInt(interp, argv[loc + 1], &tag) != TCL_OK) { opserr << "WARNING recorder Element -region tag? - invalid tag " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } MeshRegion *theRegion = domain->getRegion(tag); if (theRegion == nullptr) { opserr << "WARNING recorder Element -region " << tag - << " - region does not exist" << endln; + << " - region does not exist" << "\n"; return TCL_ERROR; // was TCL_OK } const ID &eleRegion = theRegion->getElements(); @@ -542,62 +546,70 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, loc++; } Tcl_ResetResult(interp); + } - } else if ((strcmp(argv[loc], "-time") == 0) || + else if ((strcmp(argv[loc], "-time") == 0) || (strcmp(argv[loc], "-load") == 0)) { echoTime = true; loc++; } - else if (strcmp(argv[loc], "-dT") == 0) { + else if (strcasecmp(argv[loc], "-dT") == 0) { // allow user to specify time step size for recording loc++; + if (loc == argc) { + opserr << OpenSees::PromptValueError << "flag -dT is missing required argument\n"; + return TCL_ERROR; + } if (Tcl_GetDouble(interp, argv[loc], &dT) != TCL_OK) return TCL_ERROR; loc++; } else { - // TODO: handle the same as Node recorder; see Example1.1.py - // first unknown string then is assumed to start - // element response request starts - eleData = loc; - flags = 1; + unused.push_back(loc); + loc++; } } - if (eleData >= argc) { + if (unused.size() == 0) { opserr << "ERROR: No response type specified for element recorder. " - << endln; + << "\n"; return TCL_ERROR; } - const char **data = new const char *[argc - eleData]; - for (int i = eleData, j = 0; i < argc; i++, j++) - data[j] = argv[i]; + // Forward any unused arguments to the element + const char **data = new const char *[unused.size()]; + for (unsigned i=0; i< unused.size(); i++) + data[i] = argv[unused[i]]; // construct the DataHandler theOutputStream = createOutputStream(options); if (strcmp(argv[1], "Element") == 0) - (*theRecorder) = new ElementRecorder(eleIDs, data, argc - eleData, echoTime, *domain, + (*theRecorder) = new ElementRecorder(eleIDs, data, unused.size(), echoTime, *domain, *theOutputStream, dT, rTolDt, specificIndices); else if (strcmp(argv[1], "EnvelopeElement") == 0) - (*theRecorder) = new EnvelopeElementRecorder(eleIDs, data, argc - eleData, + (*theRecorder) = new EnvelopeElementRecorder(eleIDs, data, unused.size(), *domain, *theOutputStream, dT, rTolDt, echoTime, specificIndices); else if (strcmp(argv[1], "NormElement") == 0) - (*theRecorder) = new NormElementRecorder(eleIDs, data, argc - eleData, + (*theRecorder) = new NormElementRecorder(eleIDs, data, unused.size(), echoTime, *domain, *theOutputStream, dT, rTolDt, specificIndices); else - (*theRecorder) = new NormEnvelopeElementRecorder(eleIDs, data, argc - eleData, + (*theRecorder) = new NormEnvelopeElementRecorder(eleIDs, data, unused.size(), *domain, *theOutputStream, dT, 1e-6, echoTime, specificIndices); + if (*theRecorder != nullptr) { + opsdbg << G3_DEBUG_PROMPT << "Created recorder \n"; + (*theRecorder)->Print(opsdbg, 0); + } + if (eleIDs != nullptr) delete eleIDs; @@ -610,7 +622,9 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, (strcmp(argv[1], "elementDamage") == 0)) { ////////// By Arash Altoontash ///////////////// TCL_Char *filename = nullptr; - +#if 1 + +#else if (argc < 7) { opserr << "WARNING recorder ElementDamage eleID? <-time> " << "<-file filename?> <-section secID1? secID2? ...> <-dof " @@ -702,7 +716,7 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, } DamageModel *dmgPTR; - dmgPTR = OPS_getDamageModel(dmgID); + dmgPTR = builder->getTypedObject(dmgID); if (dmgPTR == NULL) { opserr << "WARNING recorder ElementDamage: specified damage model not " @@ -716,7 +730,7 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, // now construct the recorder (*theRecorder) = new DamageRecorder(eleID, secIDs, dofID, dmgPTR, *domain, echoTime, dT, 1e-6, *theOutput); - +#endif } else if (/* (strcmp(argv[1], "Remove") == 0) || */ @@ -731,7 +745,7 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, "secID1? secID2? ...> -crit crit1? value1?" << " <-crit crit2? value2?> <-time> <-file filename?> <-mass " "mass1? mass2? ...> <-g gAcc gDir? gPat?>?" - << endln; + << "\n"; return TCL_ERROR; } @@ -782,19 +796,18 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, if (Tcl_GetInt(interp, argv[loc + 1], &nodeTag) != TCL_OK) { opserr << "WARNING recorder Collapse -node - invalid node tag " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } Node *theNode = domain->getNode(nodeTag); if (theNode == nullptr) { opserr << "WARNING recorder Collapse -node - invalid node " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } loc += 2; } - // new else if (strcmp(argv[loc], "-file_infill") == 0) { filenameinf = argv[loc + 1]; @@ -804,17 +817,17 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, else if (strcmp(argv[loc], "-checknodes") == 0) { if (Tcl_GetInt(interp, argv[loc + 1], &nTagbotn) != TCL_OK) { opserr << "WARNING recorder Collapse -node - invalid node tag " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[loc + 2], &nTagmidn) != TCL_OK) { opserr << "WARNING recorder Collapse -node - invalid node tag " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[loc + 3], &nTagtopn) != TCL_OK) { opserr << "WARNING recorder Collapse -node - invalid node tag " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } loc += 4; @@ -824,14 +837,12 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, if (Tcl_GetInt(interp, argv[loc + 1], &globgrav) != TCL_OK) { opserr << "WARNING recorder Collapse -global_gravaxis - invalid " "global axis for gravity " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } loc += 2; } - // end of new - else if ((strcmp(argv[loc], "-slave") == 0) || (strcmp(argv[loc], "-secondary") == 0)) { secondaryFlag = true; @@ -850,7 +861,7 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, } // - // read in a list of ele until end of command or other flag + // read in a list of integer tags until end of command or other flag // loc++; int eleTag; @@ -865,10 +876,10 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_ResetResult(interp); - if (strcmp(argv[loc], "all") == 0) { + if (loc < argc && (strcmp(argv[loc], "all") == 0)) { ElementIter &theEleIter = domain->getElements(); Element *theEle; - while ((theEle = theEleIter()) != 0) + while ((theEle = theEleIter()) != nullptr) eleIDs[numEle++] = theEle->getTag(); loc++; } @@ -891,13 +902,13 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, if (Tcl_GetInt(interp, argv[loc + 1], &start) != TCL_OK) { opserr << "WARNING recorder Element -eleRange start? end? - invalid " "start " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[loc + 2], &end) != TCL_OK) { opserr << "WARNING recorder Element -eleRange start? end? - invalid end " - << argv[loc + 2] << endln; + << argv[loc + 2] << "\n"; return TCL_ERROR; } if (start > end) { @@ -926,13 +937,13 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, int tag; if (Tcl_GetInt(interp, argv[loc + 1], &tag) != TCL_OK) { opserr << "WARNING recorder Element -region tag? - invalid tag " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } MeshRegion *theRegion = domain->getRegion(tag); if (theRegion == 0) { opserr << "WARNING recorder Element -region " << tag - << " - region does not exist" << endln; + << " - region does not exist" << "\n"; return TCL_OK; } const ID &eleRegion = theRegion->getElements(); @@ -956,6 +967,10 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, else if (strcmp(argv[loc], "-dT") == 0) { // allow user to specify time step size for recording loc++; + if (loc == argc) { + opserr << OpenSees::PromptValueError << "flag -dT is missing required argument\n"; + return TCL_ERROR; + } if (Tcl_GetDouble(interp, argv[loc], &dT) != TCL_OK) return TCL_ERROR; loc++; @@ -995,21 +1010,21 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, if (Tcl_GetDouble(interp, argv[loc], &gAcc) != TCL_OK) { opserr << "WARNING recorder Remove -g gValue? gDir? gPat?... invalid " "gValue "; - opserr << argv[loc] << endln; + opserr << argv[loc] << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[loc + 1], &gDir) != TCL_OK) { opserr << "WARNING recorder Remove -g gValue? gDir? gPat?... invalid " "gDir "; - opserr << argv[loc + 1] << endln; + opserr << argv[loc + 1] << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[loc + 2], &gPat) != TCL_OK) { opserr << "WARNING recorder Remove -g gValue? gDir? gPat?... invalid " "gPat "; - opserr << argv[loc + 1] << endln; + opserr << argv[loc + 1] << "\n"; return TCL_ERROR; } loc += 3; @@ -1071,14 +1086,14 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, critTag = 7; else { opserr << "Error: RemoveRecorder - Removal Criteria " << argv[loc + 1] - << " not recognized" << endln; + << " not recognized" << "\n"; return TCL_ERROR; } if (critTag != 7) { if (Tcl_GetDouble(interp, argv[loc + 2], &critValue) != TCL_OK) { opserr << "WARNING recorder Remove -crit critTag? critValue?... " "invalid critValue "; - opserr << argv[loc + 1] << endln; + opserr << argv[loc + 1] << "\n"; return TCL_ERROR; } } @@ -1184,12 +1199,15 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, else if (strcmp(argv[pos], "-time") == 0) { echoTimeFlag = true; pos += 1; - } else if (strcmp(argv[pos], "-dT") == 0) { // allow user to specify time step size for recording pos++; + if (pos == argc) { + opserr << OpenSees::PromptValueError << "flag -dT is missing required argument\n"; + return TCL_ERROR; + } if (Tcl_GetDouble(interp, argv[pos], &dT) != TCL_OK) return TCL_ERROR; pos++; @@ -1249,7 +1267,7 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, if (iNodes.Size() != jNodes.Size()) { opserr << "WARNING recorder Drift - the number of iNodes and jNodes must " "be the same " - << iNodes << " " << jNodes << endln; + << iNodes << " " << jNodes << "\n"; return TCL_ERROR; } @@ -1307,14 +1325,6 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } } - - else if (strcmp(argv[1], "vtkhdf") == 0 || strcmp(argv[1], "VTKHDF") == 0) { - OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, &theDomain); - (*theRecorder) = (Recorder *)OPS_VTKHDF_Recorder(rt, argc, argv); - if (theRecorder == 0) { - return TCL_ERROR; - } - } #endif #if 0 @@ -1422,7 +1432,7 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, } if (*theRecorder == nullptr) { - opserr << G3_ERROR_PROMPT << "No recorder exists " + opserr << OpenSees::PromptValueError << "No recorder exists " << "with type '" << argv[1] << "'\n"; return TCL_ERROR; @@ -1439,6 +1449,11 @@ TclAddRecorder(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** Recorder *theRecorder = nullptr; + if (argc > 1 && strcasecmp(argv[1], "flush") == 0) { + domain->flushRecorders(); + return TCL_OK; + } + if (TclCreateRecorder(clientData, interp, argc, argv, *domain, &theRecorder) != TCL_OK) return TCL_ERROR; @@ -1448,7 +1463,7 @@ TclAddRecorder(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** } else if ((domain->addRecorder(*theRecorder)) < 0) { - opserr << G3_ERROR_PROMPT << "Failed to add recorder to domain" << endln; + opserr << OpenSees::PromptValueError << "Failed to add recorder to domain" << "\n"; delete theRecorder; Tcl_SetObjResult(interp, Tcl_NewIntObj(-1)); return TCL_ERROR; @@ -1561,7 +1576,7 @@ createNodeRecorder(ClientData clientData, Tcl_Interp *interp, int argc, OutputOptions options; if (argc < 7) { - opserr << G3_ERROR_PROMPT << "recorder Node "; + opserr << OpenSees::PromptValueError << "recorder Node "; opserr << "-node -dof -file -dT
" ""; return TCL_ERROR; @@ -1587,12 +1602,20 @@ createNodeRecorder(ClientData clientData, Tcl_Interp *interp, int argc, else if (strcmp(argv[pos], "-dT") == 0) { // allow user to specify time step size for recording pos++; + if (pos == argc) { + opserr << OpenSees::PromptValueError << "flag -dT is missing required argument\n"; + return TCL_ERROR; + } if (Tcl_GetDouble(interp, argv[pos], &dT) != TCL_OK) return TCL_ERROR; pos++; } else if (strcmp(argv[pos], "-rTolDt") == 0) { pos++; + if (pos == argc) { + opserr << OpenSees::PromptValueError << "flag -rTolDt is missing required argument\n"; + return TCL_ERROR; + } if (Tcl_GetDouble(interp, argv[pos], &rTolDt) != TCL_OK) return TCL_ERROR; pos++; @@ -1647,7 +1670,7 @@ createNodeRecorder(ClientData clientData, Tcl_Interp *interp, int argc, } else if (domain->getNode(node) == nullptr) { delete theNodes; theNodes = nullptr; - opserr << G3_ERROR_PROMPT << "cannot find node with tag " << node << "\n"; + opserr << OpenSees::PromptValueError << "cannot find node with tag " << node << "\n"; return TCL_ERROR; } else { @@ -1662,7 +1685,7 @@ createNodeRecorder(ClientData clientData, Tcl_Interp *interp, int argc, (strcmp(argv[pos], "-range")==0)) { // ensure no segmentation fault if user messes up if (argc < pos + 3) { - opserr << G3_ERROR_PROMPT << "recorder " << argv[1] + opserr << OpenSees::PromptValueError << "recorder " << argv[1] << " .. -range start? end? .. - missing start/end tags\n"; return TCL_ERROR; } @@ -1670,16 +1693,16 @@ createNodeRecorder(ClientData clientData, Tcl_Interp *interp, int argc, // read in start and end tags of two elements & add set [start,end] int start, end; if (Tcl_GetInt(interp, argv[pos + 1], &start) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "recorder " << argv[1] + opserr << OpenSees::PromptValueError << "recorder " << argv[1] << " -range start? end? - invalid start " - << argv[pos + 1] << endln; + << argv[pos + 1] << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[pos + 2], &end) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "recorder " << argv[1] + opserr << OpenSees::PromptValueError << "recorder " << argv[1] << " -range start? end? - invalid end " - << argv[pos + 2] << endln; + << argv[pos + 2] << "\n"; return TCL_ERROR; } @@ -1706,13 +1729,13 @@ createNodeRecorder(ClientData clientData, Tcl_Interp *interp, int argc, int tag; if (Tcl_GetInt(interp, argv[pos + 1], &tag) != TCL_OK) { opserr << "WARNING recorder Node -region tag? - invalid tag " - << argv[pos + 1] << endln; + << argv[pos + 1] << "\n"; return TCL_ERROR; } MeshRegion *theRegion = domain->getRegion(tag); if (theRegion == nullptr) { opserr << "WARNING recorder Node -region " << tag - << " - region does not exist" << endln; + << " - region does not exist" << "\n"; return TCL_OK; } @@ -1736,12 +1759,12 @@ createNodeRecorder(ClientData clientData, Tcl_Interp *interp, int argc, pos++; } } - // AddingSensitivity:BEGIN ////////////////////////////////////// + else if (strcmp(argv[pos], "-sensitivity") == 0) { pos++; int paramTag; if (Tcl_GetInt(interp, argv[pos], ¶mTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid parameter tag to node recorder." << endln; + opserr << OpenSees::PromptValueError << "invalid parameter tag to node recorder." << "\n"; return TCL_ERROR; } pos++; @@ -1749,19 +1772,21 @@ createNodeRecorder(ClientData clientData, Tcl_Interp *interp, int argc, // Now get gradIndex from parameter tag Parameter *theParameter = domain->getParameter(paramTag); if (theParameter == nullptr) { - opserr << G3_ERROR_PROMPT << "parameter " << paramTag << " not found" - << endln; + opserr << OpenSees::PromptValueError << "parameter " << paramTag << " not found" + << "\n"; return TCL_ERROR; } gradIndex = theParameter->getGradIndex(); } - // AddingSensitivity:END //////////////////////////////////////// + else if (responseID == nullptr && pos < argc) { responseID = argv[pos]; pos++; } + else if (pos < argc) { - opserr << "WARNING Unknown argument " << argv[pos] << "\n"; + opserr << "WARNING Unknown argument " << argv[pos] << " at index " << pos << "\n"; + return TCL_ERROR; } } // while (pos < argc) @@ -1773,7 +1798,7 @@ createNodeRecorder(ClientData clientData, Tcl_Interp *interp, int argc, theOutputStream = createOutputStream(options); if (theTimeSeries != nullptr && theTimeSeriesID.Size() < theDofs.Size()) { - opserr << G3_ERROR_PROMPT << "recorder Node/EnvelopNode # TimeSeries must equal # " + opserr << OpenSees::PromptValueError << "recorder Node/EnvelopNode # TimeSeries must equal # " "dof - IGNORING TimeSeries OPTION\n"; for (int i = 0; i < theTimeSeriesID.Size(); ++i) { if (theTimeSeries[i] != nullptr) @@ -1785,7 +1810,7 @@ createNodeRecorder(ClientData clientData, Tcl_Interp *interp, int argc, if ((dataFlag = getNodeDataFlag(responseID, *domain, &dataIndex)) == NodeData::Unknown) { - opserr << G3_ERROR_PROMPT << "invalid response ID '" << responseID << "'\n"; + opserr << OpenSees::PromptValueError << "invalid response ID '" << responseID << "'\n"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/domain/region.cpp b/SRC/runtime/commands/domain/region.cpp index 776dc04f3f..5f595c95a5 100644 --- a/SRC/runtime/commands/domain/region.cpp +++ b/SRC/runtime/commands/domain/region.cpp @@ -1,17 +1,20 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file contains the function that is invoked // by the interpreter when the command 'region' is invoked by the // user. // // Written: fmk, cmp // -#include -#include +#include +#include +// #include +// #include #include #include #include @@ -19,7 +22,7 @@ #include int -TclCommand_addMeshRegion(ClientData clientData, Tcl_Interp *interp, int argc, +TclCommand_addMeshRegion(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { Domain& theDomain = *static_cast(clientData); diff --git a/SRC/runtime/commands/domain/response.cpp b/SRC/runtime/commands/domain/response.cpp index 21b92a72f7..18a7e28368 100644 --- a/SRC/runtime/commands/domain/response.cpp +++ b/SRC/runtime/commands/domain/response.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// #include #include #include @@ -21,26 +22,26 @@ basicDeformation(ClientData clientData, Tcl_Interp *interp, int argc, Domain *the_domain = (Domain*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "want - basicDeformation eleTag? \n"; + opserr << OpenSees::PromptValueError << "want - basicDeformation eleTag? \n"; return TCL_ERROR; } int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "basicDeformation eleTag? dofNum? - could not read " + opserr << OpenSees::PromptValueError << "basicDeformation eleTag? dofNum? - could not read " "eleTag? \n"; return TCL_ERROR; } /* if (Tcl_GetInt(interp, argv[2], &secNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "basicDeformation eleTag? dofNum? - could not read dofNum? + opserr << OpenSees::PromptValueError << "basicDeformation eleTag? dofNum? - could not read dofNum? \n"; return TCL_ERROR; } */ Element *theElement = the_domain->getElement(tag); if (theElement == nullptr) { - opserr << G3_ERROR_PROMPT << "basicDeformation element with tag " << tag + opserr << OpenSees::PromptValueError << "basicDeformation element with tag " << tag << " not found in domain \n"; return TCL_ERROR; } @@ -82,26 +83,26 @@ basicForce(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** cons Domain *the_domain = (Domain*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "want - basicForce eleTag? \n"; + opserr << OpenSees::PromptValueError << "want - basicForce eleTag? \n"; return TCL_ERROR; } int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "basicForce eleTag? dofNum? - could not read eleTag? \n"; + opserr << OpenSees::PromptValueError << "basicForce eleTag? dofNum? - could not read eleTag? \n"; return TCL_ERROR; } /* if (Tcl_GetInt(interp, argv[2], &secNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "basicDeformation eleTag? dofNum? - could not read dofNum \n"; + opserr << OpenSees::PromptValueError << "basicDeformation eleTag? dofNum? - could not read dofNum \n"; return TCL_ERROR; } */ Element *theElement = the_domain->getElement(tag); if (theElement == nullptr) { - opserr << G3_ERROR_PROMPT << "basicDeformation element with tag " << tag + opserr << OpenSees::PromptValueError << "basicDeformation element with tag " << tag << " not found in domain \n"; return TCL_ERROR; } @@ -144,26 +145,26 @@ basicStiffness(ClientData clientData, Tcl_Interp *interp, int argc, Domain *the_domain = (Domain*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "want - basicStiffness eleTag? \n"; + opserr << OpenSees::PromptValueError << "want - basicStiffness eleTag? \n"; return TCL_ERROR; } int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "basicStiffness eleTag? - could not read eleTag? \n"; + opserr << OpenSees::PromptValueError << "basicStiffness eleTag? - could not read eleTag? \n"; return TCL_ERROR; } /* if (Tcl_GetInt(interp, argv[2], &secNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "basicDeformation eleTag? dofNum? - could not read dofNum?\n"; + opserr << OpenSees::PromptValueError << "basicDeformation eleTag? dofNum? - could not read dofNum?\n"; return TCL_ERROR; } */ Element *theElement = the_domain->getElement(tag); if (theElement == nullptr) { - opserr << G3_ERROR_PROMPT << "basicStiffness element with tag " << tag + opserr << OpenSees::PromptValueError << "basicStiffness element with tag " << tag << " not found in domain \n"; return TCL_ERROR; } @@ -208,7 +209,7 @@ sectionForce(ClientData clientData, Tcl_Interp *interp, int argc, Domain *the_domain = (Domain*)clientData; if (argc < 3) { - opserr << G3_ERROR_PROMPT << "want - sectionForce eleTag? dof? \n"; + opserr << OpenSees::PromptValueError << "want - sectionForce eleTag? dof? \n"; return TCL_ERROR; } @@ -216,7 +217,7 @@ sectionForce(ClientData clientData, Tcl_Interp *interp, int argc, int secNum = 0; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionForce eleTag? secNum? dof? - could not read " + opserr << OpenSees::PromptValueError << "sectionForce eleTag? secNum? dof? - could not read " "eleTag? \n"; return TCL_ERROR; } @@ -225,20 +226,20 @@ sectionForce(ClientData clientData, Tcl_Interp *interp, int argc, int currentArg = 2; if (argc > 3) { if (Tcl_GetInt(interp, argv[currentArg++], &secNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionForce eleTag? secNum? dof? - could not read " + opserr << OpenSees::PromptValueError << "sectionForce eleTag? secNum? dof? - could not read " "secNum? \n"; return TCL_ERROR; } } if (Tcl_GetInt(interp, argv[currentArg++], &dof) != TCL_OK) { opserr - << G3_ERROR_PROMPT << "sectionForce eleTag? secNum? dof? - could not read dof? \n"; + << OpenSees::PromptValueError << "sectionForce eleTag? secNum? dof? - could not read dof? \n"; return TCL_ERROR; } Element *theElement = the_domain->getElement(tag); if (theElement == nullptr) { - opserr << G3_ERROR_PROMPT << "sectionForce element with tag " << tag + opserr << OpenSees::PromptValueError << "sectionForce element with tag " << tag << " not found in domain \n"; return TCL_ERROR; } @@ -283,30 +284,30 @@ sectionDeformation(ClientData clientData, Tcl_Interp *interp, int argc, Domain *the_domain = (Domain*)clientData; if (argc < 4) { - opserr << G3_ERROR_PROMPT << "want - sectionDeformation eleTag? secNum? dof? \n"; + opserr << OpenSees::PromptValueError << "want - sectionDeformation eleTag? secNum? dof? \n"; return TCL_ERROR; } int tag, secNum, dof; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionDeformation eleTag? secNum? dof? - could not " + opserr << OpenSees::PromptValueError << "sectionDeformation eleTag? secNum? dof? - could not " "read eleTag? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &secNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionDeformation eleTag? secNum? dof? - could not " + opserr << OpenSees::PromptValueError << "sectionDeformation eleTag? secNum? dof? - could not " "read secNum? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &dof) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionDeformation eleTag? secNum? dof? - could not " + opserr << OpenSees::PromptValueError << "sectionDeformation eleTag? secNum? dof? - could not " "read dof? \n"; return TCL_ERROR; } Element *theElement = the_domain->getElement(tag); if (theElement == nullptr) { - opserr << G3_ERROR_PROMPT << "sectionDeformation element with tag " << tag + opserr << OpenSees::PromptValueError << "sectionDeformation element with tag " << tag << " not found in domain \n"; return TCL_ERROR; } @@ -348,25 +349,25 @@ sectionLocation(ClientData clientData, Tcl_Interp *interp, int argc, Domain *the_domain = (Domain*)clientData; if (argc < 3) { - opserr << G3_ERROR_PROMPT << "want - sectionLocation eleTag? secNum? \n"; + opserr << OpenSees::PromptValueError << "want - sectionLocation eleTag? secNum? \n"; return TCL_ERROR; } int tag, secNum; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionLocation eleTag? secNum? - could not read " + opserr << OpenSees::PromptValueError << "sectionLocation eleTag? secNum? - could not read " "eleTag? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &secNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionLocation eleTag? secNum? - could not read " + opserr << OpenSees::PromptValueError << "sectionLocation eleTag? secNum? - could not read " "secNum? \n"; return TCL_ERROR; } Element *theElement = the_domain->getElement(tag); if (theElement == nullptr) { - opserr << G3_ERROR_PROMPT << "sectionLocation element with tag " << tag + opserr << OpenSees::PromptValueError << "sectionLocation element with tag " << tag << " not found in domain \n"; return TCL_ERROR; } @@ -404,7 +405,7 @@ sectionWeight(ClientData clientData, Tcl_Interp *interp, int argc, Domain *the_domain = (Domain*)clientData; if (argc < 3) { - opserr << G3_ERROR_PROMPT << "want - sectionWeight eleTag? secNum? \n"; + opserr << OpenSees::PromptValueError << "want - sectionWeight eleTag? secNum? \n"; return TCL_ERROR; } @@ -412,18 +413,18 @@ sectionWeight(ClientData clientData, Tcl_Interp *interp, int argc, if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { opserr - << G3_ERROR_PROMPT << "sectionWeight eleTag? secNum? - could not read eleTag? \n"; + << OpenSees::PromptValueError << "sectionWeight eleTag? secNum? - could not read eleTag? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &secNum) != TCL_OK) { opserr - << G3_ERROR_PROMPT << "sectionWeight eleTag? secNum? - could not read secNum? \n"; + << OpenSees::PromptValueError << "sectionWeight eleTag? secNum? - could not read secNum? \n"; return TCL_ERROR; } Element *theElement = the_domain->getElement(tag); if (theElement == nullptr) { - opserr << G3_ERROR_PROMPT << "sectionWeight element with tag " << tag + opserr << OpenSees::PromptValueError << "sectionWeight element with tag " << tag << " not found in domain \n"; return TCL_ERROR; } @@ -460,26 +461,26 @@ sectionStiffness(ClientData clientData, Tcl_Interp *interp, int argc, Domain *the_domain = (Domain*)clientData; if (argc < 3) { - opserr << G3_ERROR_PROMPT << "want - sectionStiffness eleTag? secNum? \n"; + opserr << OpenSees::PromptValueError << "want - sectionStiffness eleTag? secNum? \n"; return TCL_ERROR; } int tag, secNum; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionStiffness eleTag? secNum? - could not read " + opserr << OpenSees::PromptValueError << "sectionStiffness eleTag? secNum? - could not read " "eleTag? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &secNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionStiffness eleTag? secNum? - could not read " + opserr << OpenSees::PromptValueError << "sectionStiffness eleTag? secNum? - could not read " "secNum? \n"; return TCL_ERROR; } Element *theElement = the_domain->getElement(tag); if (theElement == nullptr) { - opserr << G3_ERROR_PROMPT << "sectionStiffness element with tag " << tag + opserr << OpenSees::PromptValueError << "sectionStiffness element with tag " << tag << " not found in domain \n"; return TCL_ERROR; } @@ -529,26 +530,26 @@ sectionFlexibility(ClientData clientData, Tcl_Interp *interp, int argc, Domain *the_domain = (Domain*)clientData; if (argc < 3) { - opserr << G3_ERROR_PROMPT << "want - sectionFlexibility eleTag? secNum? \n"; + opserr << OpenSees::PromptValueError << "want - sectionFlexibility eleTag? secNum? \n"; return TCL_ERROR; } int tag, secNum; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionFlexibility eleTag? secNum? - could not read " + opserr << OpenSees::PromptValueError << "sectionFlexibility eleTag? secNum? - could not read " "eleTag? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &secNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionFlexibility eleTag? secNum? - could not read " + opserr << OpenSees::PromptValueError << "sectionFlexibility eleTag? secNum? - could not read " "secNum? \n"; return TCL_ERROR; } Element *theElement = the_domain->getElement(tag); if (theElement == nullptr) { - opserr << G3_ERROR_PROMPT << "sectionFlexibility element with tag " << tag + opserr << OpenSees::PromptValueError << "sectionFlexibility element with tag " << tag << " not found in domain \n"; return TCL_ERROR; } @@ -598,25 +599,25 @@ sectionTag(ClientData clientData, Tcl_Interp *interp, int argc, Domain *the_domain = (Domain*)clientData; if (argc < 3) { - opserr << G3_ERROR_PROMPT << "want - sectionTag eleTag? secNum? \n"; + opserr << OpenSees::PromptValueError << "want - sectionTag eleTag? secNum? \n"; return TCL_ERROR; } int tag, secNum; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionTag eleTag? secNum? - could not read " + opserr << OpenSees::PromptValueError << "sectionTag eleTag? secNum? - could not read " "eleTag? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &secNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionTag eleTag? secNum? - could not read " + opserr << OpenSees::PromptValueError << "sectionTag eleTag? secNum? - could not read " "secNum? \n"; return TCL_ERROR; } Element *theElement = the_domain->getElement(tag); if (theElement == nullptr) { - opserr << G3_ERROR_PROMPT << "sectionFlexibility element with tag " << tag + opserr << OpenSees::PromptValueError << "sectionFlexibility element with tag " << tag << " not found in domain \n"; return TCL_ERROR; } @@ -667,19 +668,19 @@ sectionDisplacement(ClientData clientData, Tcl_Interp *interp, int argc, Domain *theDomain = (Domain*)clientData; if (argc < 3) { - opserr << G3_ERROR_PROMPT << "want - sectionLocation eleTag? secNum? \n"; + opserr << OpenSees::PromptValueError << "want - sectionLocation eleTag? secNum? \n"; return TCL_ERROR; } int tag, secNum; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionLocation eleTag? secNum? - could not read " + opserr << OpenSees::PromptValueError << "sectionLocation eleTag? secNum? - could not read " "eleTag? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &secNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "sectionLocation eleTag? secNum? - could not read " + opserr << OpenSees::PromptValueError << "sectionLocation eleTag? secNum? - could not read " "secNum? \n"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/domain/rigid_links.cpp b/SRC/runtime/commands/domain/rigid_links.cpp index d6b7662fdf..9d0df0ccc9 100644 --- a/SRC/runtime/commands/domain/rigid_links.cpp +++ b/SRC/runtime/commands/domain/rigid_links.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // // Author: fmk, cmp // @@ -37,15 +38,16 @@ createLinearRigidBeam(Domain &theDomain, int ret_tag, int con_tag) // get a pointer to the retained and constrained nodes - make sure they exist Node *nodeR = theDomain.getNode(ret_tag); + if (nodeR == nullptr) { - opserr << G3_ERROR_PROMPT - << "retained Node" << ret_tag << " not in domain\n"; + opserr << OpenSees::PromptValueError + << "retained node " << ret_tag << " not in domain\n"; return CONSTRAINT_ERROR; } Node *nodeC = theDomain.getNode(con_tag); if (nodeR == nullptr) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "constrained node " << con_tag << " not in domain\n"; return CONSTRAINT_ERROR; } @@ -56,7 +58,7 @@ createLinearRigidBeam(Domain &theDomain, int ret_tag, int con_tag) int dimR = crdR.Size(); int dimC = crdC.Size(); if (dimR != dimC) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "mismatch in dimension between constrained node " << con_tag << " and retained node " << ret_tag << "\n"; return CONSTRAINT_ERROR; @@ -65,7 +67,7 @@ createLinearRigidBeam(Domain &theDomain, int ret_tag, int con_tag) // check the number of dof at each node is the same int numDOF = nodeR->getNumberDOF(); if (numDOF != nodeC->getNumberDOF()){ - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "mismatch in numDOF between constrained node " << con_tag << " and retained node " << ret_tag << "\n"; return CONSTRAINT_ERROR; @@ -73,12 +75,12 @@ createLinearRigidBeam(Domain &theDomain, int ret_tag, int con_tag) // check the number of dof at the nodes >= dimension of problem if(numDOF < dimR){ - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "numDOF at nodes " << ret_tag << " and " << con_tag << " must be >= dimension of problem\n"; return CONSTRAINT_ERROR; } - + // create the ID to identify the constrained dof ID id(numDOF); @@ -118,7 +120,7 @@ createLinearRigidBeam(Domain &theDomain, int ret_tag, int con_tag) mat(2,3) = deltaY; } else { // not valid - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << " for nodes " << ret_tag << " and " << con_tag << " nodes do not have valid numDOF for their dimension\n"; return CONSTRAINT_ERROR; @@ -131,7 +133,7 @@ createLinearRigidBeam(Domain &theDomain, int ret_tag, int con_tag) // add the constraint to the domain if (theDomain.addMP_Constraint(newC) == false) { delete newC; - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "nodes " << con_tag << " and " << ret_tag << ", could not add to domain\n"; return CONSTRAINT_ERROR; } @@ -150,13 +152,13 @@ createLinearRigidRod(Domain &theDomain, int ret_tag, int con_tag) // get a pointer to the retained node and constrained nodes - ensure these exist Node *nodeR = theDomain.getNode(ret_tag); if (nodeR == 0) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "retained node " << ret_tag << " not in domain\n"; return CONSTRAINT_ERROR; } Node *nodeC = theDomain.getNode(con_tag); if (nodeR == 0) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "constrained node " << con_tag << " not in domain\n"; return CONSTRAINT_ERROR; } @@ -167,7 +169,7 @@ createLinearRigidRod(Domain &theDomain, int ret_tag, int con_tag) int dimR = crdR.Size(); int dimC = crdC.Size(); if (dimR != dimC) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "mismatch in dimension between constrained node " << con_tag << " and retained node " << ret_tag << "\n"; return CONSTRAINT_ERROR; @@ -176,7 +178,7 @@ createLinearRigidRod(Domain &theDomain, int ret_tag, int con_tag) // check the number of dof at each node is the same int numDOF = nodeR->getNumberDOF(); if (numDOF != nodeC->getNumberDOF()){ - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "mismatch in numDOF " << "between constrained node " << con_tag << " and retained node " << ret_tag << "\n"; return CONSTRAINT_ERROR; @@ -184,7 +186,7 @@ createLinearRigidRod(Domain &theDomain, int ret_tag, int con_tag) // check the number of dof at the nodes >= dimension of problem if(numDOF < dimR){ - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "numDOF at nodes " << ret_tag << " and " << con_tag << " must be >= dimension of problem\n"; return CONSTRAINT_ERROR; @@ -209,7 +211,7 @@ createLinearRigidRod(Domain &theDomain, int ret_tag, int con_tag) // add the constraint to the domain if (theDomain.addMP_Constraint(newC) == false) { delete newC; - opserr << G3_ERROR_PROMPT << "for nodes " << con_tag << " and " << ret_tag << " could not add to domain\n"; + opserr << OpenSees::PromptValueError << "for nodes " << con_tag << " and " << ret_tag << " could not add to domain\n"; return CONSTRAINT_ERROR; } return CONSTRAINT_OK; @@ -225,14 +227,14 @@ createLinearRigidDiaphragm(Domain &theDomain, int ret_tag, ID &nC, { // check plane is valid, i.e. perpPlaneConstrained must be 0, 1 or 2 if (perpPlaneConstrained < 0 || perpPlaneConstrained > 2) { - opserr << G3_ERROR_PROMPT << + opserr << OpenSees::PromptValueError << "the dirn of perpendicular to constrained plane " << perpPlaneConstrained << " not valid\n"; return CONSTRAINT_ERROR; } // check constrainedNodes ID does not contain the retained node if (nC.getLocation(ret_tag) >= 0) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "retained node " << ret_tag << " is in constrained node list\n"; return CONSTRAINT_ERROR; } @@ -240,15 +242,15 @@ createLinearRigidDiaphragm(Domain &theDomain, int ret_tag, ID &nC, // get a pointer to the retained node and check node in 3d with 6 DOFs Node *nodeR = theDomain.getNode(ret_tag); if (nodeR == nullptr) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "retained Node " << ret_tag << " not in domain\n"; return CONSTRAINT_ERROR; } const Vector &crdR = nodeR->getCrds(); if ((nodeR->getNumberDOF() != 6) || (crdR.Size() != 3)){ - opserr << G3_ERROR_PROMPT - << "retained Node " << ret_tag << " not in 3d space with 6 DOFs\n"; + opserr << OpenSees::PromptValueError + << "retained node " << ret_tag << " not in 3d space with 6 DOFs\n"; return CONSTRAINT_ERROR; } @@ -281,7 +283,7 @@ createLinearRigidDiaphragm(Domain &theDomain, int ret_tag, ID &nC, // ensure node exists if (nodeC == nullptr) { // TODO: Document change; this used to be accepted without error. - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "cannot constrain node " << ndC << " as no node in domain\n"; return CONSTRAINT_ERROR; } @@ -311,7 +313,7 @@ createLinearRigidDiaphragm(Domain &theDomain, int ret_tag, ID &nC, mat(1,2) = deltaX; } else { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "ignoring constrained node " << ndC << ", not in xy plane\n"; return CONSTRAINT_ERROR; } @@ -330,7 +332,7 @@ createLinearRigidDiaphragm(Domain &theDomain, int ret_tag, ID &nC, mat(1,2) = -deltaX; } else { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "ignoring constrained node " << ndC << ", not in xz plane\n"; return CONSTRAINT_ERROR; } @@ -349,7 +351,7 @@ createLinearRigidDiaphragm(Domain &theDomain, int ret_tag, ID &nC, mat(1,2) = deltaY; } else { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "ignoring constrained node " << ndC << ", not in xz plane\n"; return CONSTRAINT_ERROR; } @@ -360,19 +362,20 @@ createLinearRigidDiaphragm(Domain &theDomain, int ret_tag, ID &nC, // add the constraint to the domain if (theDomain.addMP_Constraint(newC) == false) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "ignoring constrained node " << ndC << ", failed to add\n"; delete newC; return CONSTRAINT_ERROR; } + } - } else { + else { opserr << G3_WARN_PROMPT << "ignoring constrained node " << ndC << ", not 3D node\n"; return CONSTRAINT_OK; - } - + } } // for each node in constrained nodes + return CONSTRAINT_OK; } @@ -384,18 +387,18 @@ TclCommand_RigidDiaphragm(ClientData clientData, Tcl_Interp *interp, int argc, T Domain *theTclDomain = ((BasicModelBuilder*)clientData)->getDomain(); if (argc < 3) { - opserr << G3_ERROR_PROMPT << "rigidLink perpDirn? rNode? \n"; + opserr << OpenSees::PromptValueError << "rigidLink perpDirn? rNode? \n"; return TCL_ERROR; } int rNode, perpDirn; if (Tcl_GetInt(interp, argv[1], &perpDirn) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rigidLink perpDirn rNode cNodes - could not read perpDirn? \n"; + opserr << OpenSees::PromptValueError << "rigidLink perpDirn rNode cNodes - could not read perpDirn? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &rNode) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rigidLink perpDirn rNode cNodes - could not read rNode \n"; + opserr << OpenSees::PromptValueError << "rigidLink perpDirn rNode cNodes - could not read rNode \n"; return TCL_ERROR; } @@ -405,7 +408,7 @@ TclCommand_RigidDiaphragm(ClientData clientData, Tcl_Interp *interp, int argc, T for (int i=0; igetDomain(); if (argc < 4) { - opserr << G3_ERROR_PROMPT << "rigidLink linkType? rNode? cNode?\n"; + opserr << OpenSees::PromptValueError << "rigidLink linkType? rNode? cNode?\n"; return TCL_ERROR; } int rNode, cNode; if (Tcl_GetInt(interp, argv[2], &rNode) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rigidLink linkType? rNode? cNode? - could not read rNode \n"; + opserr << OpenSees::PromptValueError + << "invalid rNode" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } + if (Tcl_GetInt(interp, argv[3], &cNode) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "rigidLink linkType? rNode? cNode? - could not read CNode \n"; + opserr << OpenSees::PromptValueError + << "invalid CNode" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } // construct a rigid rod or beam depending on 1st arg if ((strcmp(argv[1],"-bar") == 0) || (strcmp(argv[1],"bar") == 0)) { - // RigidRod theLink(*theTclDomain, rNode, cNode); - createLinearRigidRod(*theTclDomain, rNode, cNode); + return createLinearRigidRod(*theTclDomain, rNode, cNode); } else if ((strcmp(argv[1],"-beam") == 0) || (strcmp(argv[1],"beam") == 0)) { - createLinearRigidBeam(*theTclDomain, rNode, cNode); - //RigidBeam theLink(*theTclDomain, rNode, cNode); + return createLinearRigidBeam(*theTclDomain, rNode, cNode); } else { - opserr << G3_ERROR_PROMPT << "rigidLink linkType? rNode? cNode? - unrecognised link type (-bar, -beam) \n"; + opserr << OpenSees::PromptValueError + << "unrecognised link type (-bar, -beam) \n"; return TCL_ERROR; } return TCL_OK; diff --git a/SRC/runtime/commands/domain/runtime.cpp b/SRC/runtime/commands/domain/runtime.cpp index a08f0324cc..4fb42d0e07 100644 --- a/SRC/runtime/commands/domain/runtime.cpp +++ b/SRC/runtime/commands/domain/runtime.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // These commands expect a Domain* as their clientData. // // Written: cmp @@ -11,7 +12,7 @@ #include #include #include -#include // Tcl_Char +#include #include int @@ -81,20 +82,9 @@ int TclCommand_getTime(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { assert(clientData != nullptr); - Domain* domain = (Domain*)clientData; - - double time = domain->getCurrentTime(); - - // get the display format - char format[80]; - if (argc == 1) { - sprintf(format, "%f", time); - } else if (argc == 2) { - sprintf(format, argv[1], time); - } + Domain* domain = static_cast(clientData); - // now we copy the value to the tcl string that is returned - Tcl_SetResult(interp, format, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(domain->getCurrentTime())); return TCL_OK; } diff --git a/SRC/runtime/commands/domain/sensitivity.cpp b/SRC/runtime/commands/domain/sensitivity.cpp index e4fdbb977b..1a83960d23 100644 --- a/SRC/runtime/commands/domain/sensitivity.cpp +++ b/SRC/runtime/commands/domain/sensitivity.cpp @@ -1,14 +1,21 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// #include #include + +#include #include #include -#include +#include +#include +#include +#include +#include #include #include #include @@ -16,7 +23,6 @@ #include - int sensNodeDisp(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) @@ -26,7 +32,7 @@ sensNodeDisp(ClientData clientData, Tcl_Interp *interp, int argc, // make sure at least one other argument to contain type of system if (argc < 4) { - opserr << "WARNING want - sensNodeDisp nodeTag? dof? paramTag?\n"; + opserr << OpenSees::PromptValueError << "want - sensNodeDisp nodeTag? dof? paramTag?\n"; return TCL_ERROR; } @@ -34,28 +40,30 @@ sensNodeDisp(ClientData clientData, Tcl_Interp *interp, int argc, if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { opserr - << "WARNING nodeDisp nodeTag? dof? paramTag?- could not read nodeTag? "; + << OpenSees::PromptValueError << "nodeDisp nodeTag? dof? paramTag?- could not read nodeTag? "; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeDisp nodeTag? dof? paramTag?- could not read dof? "; + opserr << OpenSees::PromptValueError << "nodeDisp nodeTag? dof? paramTag?- could not read dof? "; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], ¶mTag) != TCL_OK) { - opserr << "WARNING nodeDisp paramTag? dof? paramTag?- could not read " + opserr << OpenSees::PromptValueError << "nodeDisp paramTag? dof? paramTag?- could not read " "paramTag? "; return TCL_ERROR; } + // + // Node *theNode = theDomain->getNode(tag); - if (theNode == 0) { - opserr << "sensNodeDisp: node " << tag << " not found" << endln; + if (theNode == nullptr) { + opserr << "sensNodeDisp: node " << tag << " not found" << "\n"; return TCL_ERROR; } Parameter *theParam = theDomain->getParameter(paramTag); - if (theParam == 0) { - opserr << "sensNodeDisp: parameter " << paramTag << " not found" << endln; + if (theParam == nullptr) { + opserr << "sensNodeDisp: parameter " << paramTag << " not found" << "\n"; return TCL_ERROR; } @@ -63,9 +71,7 @@ sensNodeDisp(ClientData clientData, Tcl_Interp *interp, int argc, double value = theNode->getDispSensitivity(dof, gradIndex); - char buffer[40]; - sprintf(buffer, "%35.20f", value); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(value)); return TCL_OK; } @@ -79,37 +85,37 @@ sensNodeVel(ClientData clientData, Tcl_Interp *interp, int argc, // make sure at least one other argument to contain type of system if (argc < 4) { - opserr << "WARNING want - sensNodeVel nodeTag? dof? paramTag?\n"; + opserr << OpenSees::PromptValueError << "want - sensNodeVel nodeTag? dof? paramTag?\n"; return TCL_ERROR; } int tag, dof, paramTag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING sensNodeVel nodeTag? dof? paramTag? - could not read " + opserr << OpenSees::PromptValueError << "sensNodeVel nodeTag? dof? paramTag? - could not read " "nodeTag? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING sensNodeVel nodeTag? dof? paramTag? - could not read " + opserr << OpenSees::PromptValueError << "sensNodeVel nodeTag? dof? paramTag? - could not read " "dof? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], ¶mTag) != TCL_OK) { - opserr << "WARNING sensNodeVel nodeTag? dof? paramTag? - could not read " + opserr << OpenSees::PromptValueError << "sensNodeVel nodeTag? dof? paramTag? - could not read " "paramTag? \n"; return TCL_ERROR; } Node *theNode = theDomain->getNode(tag); - if (theNode == 0) { - opserr << "sensNodeVel: node " << tag << " not found" << endln; + if (theNode == nullptr) { + opserr << "sensNodeVel: node " << tag << " not found" << "\n"; return TCL_ERROR; } Parameter *theParam = theDomain->getParameter(paramTag); - if (theParam == 0) { - opserr << "sensNodeVel: parameter " << paramTag << " not found" << endln; + if (theParam == nullptr) { + opserr << "sensNodeVel: parameter " << paramTag << " not found" << "\n"; return TCL_ERROR; } @@ -117,10 +123,7 @@ sensNodeVel(ClientData clientData, Tcl_Interp *interp, int argc, double value = theNode->getVelSensitivity(dof, gradIndex); - char buffer[40]; - sprintf(buffer, "%35.20f", value); - - Tcl_SetResult(interp, buffer, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(value)); return TCL_OK; } @@ -134,37 +137,39 @@ sensNodeAccel(ClientData clientData, Tcl_Interp *interp, int argc, // make sure at least one other argument to contain type of system if (argc < 4) { - opserr << "WARNING want - sensNodeAccel nodeTag? dof? paramTag?\n"; + opserr << OpenSees::PromptValueError << "want - sensNodeAccel nodeTag? dof? paramTag?\n"; return TCL_ERROR; } int tag, dof, paramTag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING sensNodeAccel nodeTag? dof? paramTag? - could not read " + opserr << OpenSees::PromptValueError << "sensNodeAccel nodeTag? dof? paramTag? - could not read " "nodeTag? \n"; return TCL_ERROR; } + if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING sensNodeAccel nodeTag? dof? paramTag? - could not read " + opserr << OpenSees::PromptValueError << "sensNodeAccel nodeTag? dof? paramTag? - could not read " "dof? \n"; return TCL_ERROR; } + if (Tcl_GetInt(interp, argv[3], ¶mTag) != TCL_OK) { - opserr << "WARNING sendNodeAccel nodeTag? dof? paramTag? - could not read " + opserr << OpenSees::PromptValueError << "sendNodeAccel nodeTag? dof? paramTag? - could not read " "paramTag? \n"; return TCL_ERROR; } Node *theNode = theDomain->getNode(tag); - if (theNode == 0) { - opserr << "sensNodeAccel: node " << tag << " not found" << endln; + if (theNode == nullptr) { + opserr << "sensNodeAccel: node " << tag << " not found" << "\n"; return TCL_ERROR; } Parameter *theParam = theDomain->getParameter(paramTag); - if (theParam == 0) { - opserr << "sensNodeAccel: parameter " << paramTag << " not found" << endln; + if (theParam == nullptr) { + opserr << "sensNodeAccel: parameter " << paramTag << " not found" << "\n"; return TCL_ERROR; } @@ -172,10 +177,7 @@ sensNodeAccel(ClientData clientData, Tcl_Interp *interp, int argc, double value = theNode->getAccSensitivity(dof, gradIndex); - char buffer[40]; - sprintf(buffer, "%35.20f", value); - - Tcl_SetResult(interp, buffer, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(value)); return TCL_OK; } @@ -189,35 +191,35 @@ sensNodePressure(ClientData clientData, Tcl_Interp *interp, int argc, // make sure at least one other argument to contain type of system if (argc < 3) { - opserr << "WARNING want - sensNodePressure nodeTag? paramTag?\n"; + opserr << OpenSees::PromptValueError << "want - sensNodePressure nodeTag? paramTag?\n"; return TCL_ERROR; } int tag, paramTag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING sensNodePressure nodeTag? paramTag?- could not read " + opserr << OpenSees::PromptValueError << "sensNodePressure nodeTag? paramTag?- could not read " "nodeTag? "; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], ¶mTag) != TCL_OK) { - opserr << "WARNING sensNodePressure paramTag? paramTag?- could not read " + opserr << OpenSees::PromptValueError << "sensNodePressure paramTag? paramTag?- could not read " "paramTag? "; return TCL_ERROR; } double dp = 0.0; Pressure_Constraint *thePC = theDomain->getPressure_Constraint(tag); - if (thePC != 0) { + if (thePC != nullptr) { // int ptag = thePC->getPressureNode(); // Node* pNode = theDomain->getNode(ptag); Node *pNode = thePC->getPressureNode(); - if (pNode != 0) { + if (pNode != nullptr) { Parameter *theParam = theDomain->getParameter(paramTag); - if (theParam == 0) { + if (theParam == nullptr) { opserr << "sensNodePressure: parameter " << paramTag << " not found" - << endln; + << "\n"; return TCL_ERROR; } @@ -226,10 +228,7 @@ sensNodePressure(ClientData clientData, Tcl_Interp *interp, int argc, } } - char buffer[40]; - sprintf(buffer, "%35.20f", dp); - - Tcl_SetResult(interp, buffer, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(dp)); return TCL_OK; } @@ -238,14 +237,14 @@ int sensSectionForce(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { -#ifdef _RELIABILITY +#if 1 // def _RELIABILITY assert(clientData != nullptr); Domain *theDomain = (Domain *)clientData; // make sure at least one other argument to contain type of system if (argc < 4) { opserr - << "WARNING want - sensSectionForce eleTag? dof? paramTag?\n"; + << OpenSees::PromptValueError << "want - sensSectionForce eleTag? dof? paramTag?\n"; return TCL_ERROR; } @@ -253,7 +252,7 @@ sensSectionForce(ClientData clientData, Tcl_Interp *interp, int argc, int secNum = 0; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING sensSectionForce eleTag? secNum? dof? paramTag?- could " + opserr << OpenSees::PromptValueError << "sensSectionForce eleTag? secNum? dof? paramTag?- could " "not read eleTag? \n"; return TCL_ERROR; } @@ -262,18 +261,18 @@ sensSectionForce(ClientData clientData, Tcl_Interp *interp, int argc, int currentArg = 2; if (argc > 4) { if (Tcl_GetInt(interp, argv[currentArg++], &secNum) != TCL_OK) { - opserr << "WARNING sensSectionForce eleTag? secNum? dof? paramTag?- " + opserr << OpenSees::PromptValueError << "sensSectionForce eleTag? secNum? dof? paramTag?- " "could not read secNum? \n"; return TCL_ERROR; } } if (Tcl_GetInt(interp, argv[currentArg++], &dof) != TCL_OK) { - opserr << "WARNING sensSectionForce eleTag? secNum? dof? paramTag?- could " + opserr << OpenSees::PromptValueError << "sensSectionForce eleTag? secNum? dof? paramTag?- could " "not read dof? \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[currentArg++], ¶mTag) != TCL_OK) { - opserr << "WARNING sensSectionForce eleTag? secNum? dof? paramTag?- could " + opserr << OpenSees::PromptValueError << "sensSectionForce eleTag? secNum? dof? paramTag?- could " "not read paramTag? \n"; return TCL_ERROR; } @@ -289,7 +288,7 @@ sensSectionForce(ClientData clientData, Tcl_Interp *interp, int argc, Element *theElement = theDomain->getElement(tag); if (theElement == 0) { - opserr << "WARNING sensSectionForce element with tag " << tag + opserr << OpenSees::PromptValueError << "sensSectionForce element with tag " << tag << " not found in domain \n"; return TCL_ERROR; } @@ -311,8 +310,8 @@ sensSectionForce(ClientData clientData, Tcl_Interp *interp, int argc, DummyStream dummy; Response *theResponse = theElement->setResponse(argvv, argcc, dummy); - if (theResponse == 0) { - Tcl_SetResult(interp, "0.0", TCL_VOLATILE); + if (theResponse == nullptr) { + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(0.0)); return TCL_OK; } @@ -321,10 +320,7 @@ sensSectionForce(ClientData clientData, Tcl_Interp *interp, int argc, const Vector &theVec = *(info.theVector); - char buffer[40]; - sprintf(buffer, "%12.8g", theVec(dof - 1)); - - Tcl_SetResult(interp, buffer, TCL_VOLATILE); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(theVec(dof - 1))); theParam->activate(false); @@ -333,63 +329,5 @@ sensSectionForce(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_OK; } -///////////////////////Abbas////////////////////////////// - -int -sensLambda(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - BasicAnalysisBuilder* builder = (BasicAnalysisBuilder*)clientData; - - - if (argc < 3) { - opserr << "WARNING no load pattern supplied -- getLoadFactor\n"; - return TCL_ERROR; - } - - int pattern, paramTag; - if (Tcl_GetInt(interp, argv[1], &pattern) != TCL_OK) { - opserr << "ERROR reading load pattern tag -- getLoadFactor\n"; - return TCL_ERROR; - } - - LoadPattern *thePattern = builder->getDomain()->getLoadPattern(pattern); - if (thePattern == 0) { - opserr << "ERROR load pattern with tag " << pattern - << " not found in domain -- getLoadFactor\n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[2], ¶mTag) != TCL_OK) { - opserr << "WARNING sensLambda patternTag? paramTag?- could not read " - "paramTag? "; - return TCL_ERROR; - } - Parameter *theParam = builder->getDomain()->getParameter(paramTag); - if (theParam == 0) { - opserr << "sensLambda: parameter " << paramTag << " not found" << endln; - return TCL_ERROR; - } - -#if 0 - IncrementalIntegrator *theIntegrator = nullptr; - - if (the_static_integrator != nullptr) { - theIntegrator = the_static_integrator; - - } else if (theTransientIntegrator != nullptr) { - theIntegrator = theTransientIntegrator; - } -#endif - - int gradIndex = theParam->getGradIndex(); - double factor = thePattern->getLoadFactorSensitivity(gradIndex); - - char buffer[40]; - sprintf(buffer, "%35.20f", factor); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); - - return TCL_OK; -} - - diff --git a/SRC/runtime/commands/domain/staging.cpp b/SRC/runtime/commands/domain/staging.cpp index c305c163ca..5eec8ead18 100644 --- a/SRC/runtime/commands/domain/staging.cpp +++ b/SRC/runtime/commands/domain/staging.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// int elementActivate(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) diff --git a/SRC/runtime/commands/interpreter.cpp b/SRC/runtime/commands/interpreter.cpp index 21cc660d7d..d6d195b681 100644 --- a/SRC/runtime/commands/interpreter.cpp +++ b/SRC/runtime/commands/interpreter.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file contains basic commands that enhance the // experience of the interpreter. This file should not reference // any analysis or modeling classes. @@ -12,16 +13,14 @@ #include #include #include -#include +#include +#include #include +#include "interpreter.h" static Tcl_ObjCmdProc *Tcl_putsCommand = nullptr; static Timer *theTimer = nullptr; -Tcl_CmdProc TclCommand_wipeModel; -Tcl_CmdProc TclCommand_clearAnalysis; -Tcl_CmdProc TclCommand_specifyModel; - class ProgressBar; Tcl_ObjCmdProc TclObjCommand_progress; extern ProgressBar* progress_bar_ptr; @@ -30,19 +29,15 @@ extern ProgressBar* progress_bar_ptr; const char *getInterpPWD(Tcl_Interp *interp); int TclObjCommand_pragma([[maybe_unused]] ClientData clientData, - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); + Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[]); -// formats.cpp -Tcl_CmdProc convertBinaryToText; -Tcl_CmdProc convertTextToBinary; -Tcl_CmdProc stripOpenSeesXML; // // Consider reimplmenting to use Tcl built-ins; see // https://wiki.tcl-lang.org/page/timers // static int -startTimer(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +startTimer(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { if (theTimer == nullptr) theTimer = new Timer(); @@ -52,7 +47,7 @@ startTimer(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** cons } static int -stopTimer(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +stopTimer(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { if (theTimer == nullptr) return TCL_OK; @@ -63,7 +58,7 @@ stopTimer(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const } static int -timer(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) +timer(ClientData clientData, Tcl_Interp* interp, Tcl_Size argc, TCL_Char** const argv) { if ((argc == 1) || (strcmp(argv[1], "start")==0)) { stopTimer(clientData, interp, argc, argv); @@ -79,7 +74,7 @@ timer(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv // revised puts command to send to stderr // static int -OpenSees_putsCommand(ClientData dummy, Tcl_Interp *interp, int objc, +OpenSees_putsCommand(ClientData dummy, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[]) { // Tcl_Channel chan; // The channel to puts on. @@ -153,7 +148,7 @@ OpenSees_putsCommand(ClientData dummy, Tcl_Interp *interp, int objc, static int -OPS_SetObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, +OPS_SetObjCmd(ClientData clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[]) { @@ -184,11 +179,10 @@ OPS_SetObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, static int -logFile(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +logFile(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { - if (argc < 2) { - opserr << "WARNING logFile fileName? - no filename supplied\n"; + opserr << "WARNING no filename supplied\n"; return TCL_ERROR; } bool echo = true; @@ -204,15 +198,21 @@ logFile(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const a cArg++; } - if (opserr.setFile(argv[1], mode, echo) < 0) - opserr << "WARNING logFile " << argv[1] << " failed to set the file\n"; + if (opserr.setFile(argv[1], mode, echo) < 0) { + opserr << "WARNING logFile " << argv[1] << " failed to set the file" + << "\n"; + } + std::string cmd = std::string{"namespace eval opensees::internal {set log_file \""} + + std::string{argv[1]} + + std::string{"\"}\n"}; + Tcl_Eval(interp, cmd.c_str()); return TCL_OK; } static int -setPrecision(ClientData clientData, Tcl_Interp *interp, int argc, +setPrecision(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { @@ -291,7 +291,7 @@ OPS_SourceCmd(ClientData dummy, /* Not used. */ } static int -OpenSeesExit(ClientData clientData, Tcl_Interp *interp, int argc, +OpenSeesExit(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { // theDomain.clearAll(); @@ -325,7 +325,7 @@ OpenSeesExit(ClientData clientData, Tcl_Interp *interp, int argc, } static int -maxOpenFiles(ClientData clientData, Tcl_Interp *interp, int argc, +maxOpenFiles(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { int maxOpenFiles; @@ -352,7 +352,7 @@ maxOpenFiles(ClientData clientData, Tcl_Interp *interp, int argc, } int -OpenSeesAppInit(Tcl_Interp *interp) +Init_OpenSees(Tcl_Interp *interp) { // redo puts command so we can capture puts into std:cerr @@ -388,9 +388,6 @@ OpenSeesAppInit(Tcl_Interp *interp) Tcl_CreateCommand(interp, "timer", timer, nullptr, nullptr); // File utilities - Tcl_CreateCommand(interp, "stripXML", stripOpenSeesXML, nullptr, NULL); - Tcl_CreateCommand(interp, "convertBinaryToText", convertBinaryToText, nullptr, NULL); - Tcl_CreateCommand(interp, "convertTextToBinary", convertTextToBinary, nullptr, NULL); Tcl_CreateCommand(interp, "setMaxOpenFiles", maxOpenFiles, nullptr, nullptr); // Some entry points @@ -399,13 +396,21 @@ OpenSeesAppInit(Tcl_Interp *interp) Tcl_CreateCommand(interp, "wipe", TclCommand_wipeModel, nullptr, nullptr); Tcl_CreateCommand(interp, "_clearAnalysis", TclCommand_clearAnalysis, nullptr, nullptr); + + Tcl_CreateObjCommand(interp, "pset", OPS_SetObjCmd, nullptr, nullptr); Tcl_CreateObjCommand(interp, "source", OPS_SourceCmd, nullptr, nullptr); Tcl_CreateObjCommand(interp, "pragma", TclObjCommand_pragma, nullptr, nullptr); Tcl_CreateObjCommand(interp, "progress", TclObjCommand_progress, (ClientData)&progress_bar_ptr, nullptr); - // Tcl_CreateCommand(interp, "searchPeerNGA", &peerNGA, nullptr, nullptr); - // Tcl_CreateCommand(interp, "defaultUnits", &defaultUnits, nullptr, NULL); + // + static int ncmd = sizeof(InterpreterCommands)/sizeof(char_cmd); + + for (int i = 0; i < ncmd; i++) + Tcl_CreateCommand(interp, + InterpreterCommands[i].name, + InterpreterCommands[i].func, + (ClientData) nullptr, nullptr); return TCL_OK; } diff --git a/SRC/runtime/commands/interpreter.h b/SRC/runtime/commands/interpreter.h new file mode 100644 index 0000000000..b903ab6858 --- /dev/null +++ b/SRC/runtime/commands/interpreter.h @@ -0,0 +1,26 @@ +#include + +Tcl_CmdProc TclCommand_wipeModel; +Tcl_CmdProc TclCommand_clearAnalysis; +Tcl_CmdProc TclCommand_specifyModel; + + +// formats.cpp +Tcl_CmdProc convertBinaryToText; +Tcl_CmdProc convertTextToBinary; +Tcl_CmdProc stripOpenSeesXML; + +// domain/peri/commands.cpp +Tcl_CmdProc Tcl_Peri; + +struct char_cmd { + const char* name; Tcl_CmdProc* func; +} +const InterpreterCommands[] = { + + {"peri", Tcl_Peri}, + + {"stripXML", stripOpenSeesXML }, + {"convertBinaryToText", convertBinaryToText }, + {"convertTextToBinary", convertTextToBinary }, +}; diff --git a/SRC/runtime/commands/modeling/CMakeLists.txt b/SRC/runtime/commands/modeling/CMakeLists.txt new file mode 100644 index 0000000000..108c484f0c --- /dev/null +++ b/SRC/runtime/commands/modeling/CMakeLists.txt @@ -0,0 +1,2 @@ + +add_subdirectory(material) \ No newline at end of file diff --git a/SRC/runtime/commands/modeling/commands.h b/SRC/runtime/commands/modeling/commands.h index 9a12605603..f8f3aa97c8 100644 --- a/SRC/runtime/commands/modeling/commands.h +++ b/SRC/runtime/commands/modeling/commands.h @@ -41,6 +41,10 @@ extern Tcl_CmdProc TclCommand_addReinfLayer; // extern Tcl_CmdProc TclCommand_addRemoFiber; extern Tcl_CmdProc TclCommand_addFiber; extern Tcl_CmdProc TclCommand_addHFiber; +// +extern Tcl_CmdProc TclCommand_addYS_PlasticMaterial; +extern Tcl_CmdProc TclCommand_addYS_EvolutionModel; +extern Tcl_CmdProc TclCommand_addYieldSurface_BC; // Constraints extern Tcl_CmdProc TclCommand_addMP; @@ -66,6 +70,7 @@ extern Tcl_CmdProc TclCommand_updateMaterialStage; // UpdatedLagrange Tcl_CmdProc TclCommand_addCyclicModel; +Tcl_CmdProc TclCommand_addDamageModel; Tcl_CmdProc TclCommand_addParameter; Tcl_CmdProc TclCommand_mesh; @@ -85,10 +90,14 @@ Tcl_CmdProc TclCommand_invoke; Tcl_CmdProc TclCommand_print; Tcl_CmdProc TclCommand_classType; -struct char_cmd { +Tcl_CmdProc TclCommand_addMaterial; + +namespace OpenSees { +struct CommandTableEntry { const char* name; Tcl_CmdProc* func; -} const tcl_char_cmds[] = { +} +constexpr ModelBuilderCommands[] = { {"build", buildModel}, {"getNDM", TclCommand_getNDM}, @@ -106,12 +115,13 @@ struct char_cmd { {"fixY", TclCommand_addHomogeneousBC_Y}, {"fixZ", TclCommand_addHomogeneousBC_Z}, -// // +// {"with", TclCommand_invoke}, {"invoke", TclCommand_invoke}, // Materials & sections {"uniaxialMaterial", TclCommand_addUniaxialMaterial}, {"nDMaterial", TclCommand_addNDMaterial}, + {"material", TclCommand_addMaterial}, {"beamIntegration", TclCommand_addBeamIntegration}, {"section", TclCommand_addSection}, @@ -156,14 +166,14 @@ struct char_cmd { { "backbone", TclCommand_addHystereticBackbone}, {"frictionModel", TclCommand_addFrictionModel}, - {"cyclicModel", TclCommand_addCyclicModel}, -#if 0 - {"yieldSurface_BC", TclCommand_addYieldSurface_BC}, + {"damageModel", TclCommand_addDamageModel}, {"ysEvolutionModel", TclCommand_addYS_EvolutionModel}, + {"yieldSurface_BC", TclCommand_addYieldSurface_BC}, {"plasticMaterial", TclCommand_addYS_PlasticMaterial}, + +#if 0 {"limitCurve", TclCommand_addLimitCurve}, - {"damageModel", TclCommand_addDamageModel}, {"stiffnessDegradation", TclCommand_addStiffnessDegradation}, {"unloadingRule", TclCommand_addUnloadingRule}, {"strengthDegradation", TclCommand_addStrengthDegradation}, @@ -183,6 +193,7 @@ struct char_cmd { #endif }; +} // namespace OpenSees Tcl_CmdProc TclCommand_Package; diff --git a/SRC/runtime/commands/modeling/constraint.cpp b/SRC/runtime/commands/modeling/constraint.cpp index 7a021110a6..9955d56f2f 100644 --- a/SRC/runtime/commands/modeling/constraint.cpp +++ b/SRC/runtime/commands/modeling/constraint.cpp @@ -1,9 +1,17 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara +// https://xara.so // //===----------------------------------------------------------------------===// // +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// // #include #include @@ -15,6 +23,8 @@ #include #include +#include + #include #include #include @@ -27,64 +37,102 @@ int -TclCommand_addHomogeneousBC(ClientData clientData, Tcl_Interp *interp, int argc, +TclCommand_addHomogeneousBC(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); Domain *theTclDomain = ((BasicModelBuilder*)clientData)->getDomain(); - int ndf = argc - 2; - // check number of arguments - if (argc < (2 + ndf)) { - opserr << G3_ERROR_PROMPT << "bad command - want: fix nodeId " << ndf - << " [0,1] conditions"; + if (argc < 3) { + opserr << OpenSees::PromptValueError << "bad command - want: fix tag \n"; return TCL_ERROR; } - // get the id of the node + + // get the tag of the node int nodeId; if (Tcl_GetInt(interp, argv[1], &nodeId) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodeId - fix nodeId " << ndf - << " [0,1] conditions\n"; + opserr << OpenSees::PromptValueError << "invalid tag\n"; return TCL_ERROR; } - char buffer[80]; - strcpy(buffer, ""); + // Alternate form: + // + // fix $node -dof $dof <-value $value> + // + if (strcmp(argv[2], "-dof") == 0) { + if (argc < 4) { + opserr << OpenSees::PromptValueError << "missing required argument for -dof $dof\n"; + return TCL_ERROR; + } + int dof; + if (Tcl_GetInt(interp, argv[3], &dof) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid dof\n"; + return TCL_ERROR; + } + // create a homogeneous constraint + SP_Constraint *theSP = new SP_Constraint(nodeId, dof-1, 0.0, true, true); + + // add it to the domain + if (theTclDomain->addSP_Constraint(theSP) == false) { + opserr << OpenSees::PromptValueError << "could not add SP_Constraint to domain using fix " + "command - node may already be constrained\n"; + delete theSP; + return TCL_ERROR; + } + + return TCL_OK; + } + + int ndf = argc - 2; + + // check number of arguments + if (argc < (2 + ndf)) { + opserr << OpenSees::PromptValueError + << "bad command - want: fix nodeId " << ndf + << " [0,1] conditions"; + return TCL_ERROR; + } // get the fixity condition and add the constraint if fixed + Tcl_Obj* list = Tcl_NewListObj(ndf, nullptr); for (int i = 0; i < ndf; ++i) { int theFixity; if (Tcl_GetInt(interp, argv[2 + i], &theFixity) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid fixity " << i + 1 << " - load " << nodeId; + opserr << OpenSees::PromptValueError << "invalid fixity " << i + 1 << " - load " << nodeId; opserr << " " << ndf << " fixities\n"; return TCL_ERROR; + } else { if (theFixity != 0) { // create a homogeneous constraint - SP_Constraint *theSP = new SP_Constraint(nodeId, i, 0.0, true); + SP_Constraint *theSP = new SP_Constraint(nodeId, i, 0.0, true, true); // add it to the domain if (theTclDomain->addSP_Constraint(theSP) == false) { - opserr << G3_ERROR_PROMPT << "could not add SP_Constraint to domain using fix " + opserr << OpenSees::PromptValueError << "could not add SP_Constraint to domain using fix " "command - node may already be constrained\n"; - sprintf(buffer, "%d ", 0); delete theSP; return TCL_ERROR; + } else { - sprintf(buffer, "%d ", theSP->getTag()); - Tcl_AppendResult(interp, buffer, NULL); +// Tcl(buffer, "%d ", theSP->getTag()); +// Tcl_AppendResult(interp, buffer, NULL); + Tcl_ListObjAppendElement(interp, list, Tcl_NewDoubleObj(theSP->getTag())); } } } } + + Tcl_SetObjResult(interp, list); + return TCL_OK; } int TclCommand_addHomogeneousBC_X(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) + Tcl_Size argc, TCL_Char ** const argv) { int ndf = argc - 2; if (strcmp(argv[argc-2],"-tol") == 0) @@ -92,7 +140,7 @@ TclCommand_addHomogeneousBC_X(ClientData clientData, Tcl_Interp *interp, // check number of arguments if (argc < (2 + ndf)) { - opserr << G3_ERROR_PROMPT << "bad command - want: fixX xLoc " << ndf + opserr << OpenSees::PromptValueError << "bad command - want: fixX xLoc " << ndf << " [0,1] conditions" << "\n"; return TCL_ERROR; } @@ -100,7 +148,7 @@ TclCommand_addHomogeneousBC_X(ClientData clientData, Tcl_Interp *interp, // get the xCrd of nodes to be constrained double xLoc; if (Tcl_GetDouble(interp, argv[1], &xLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid xCrd - fixX xLoc " << ndf + opserr << OpenSees::PromptValueError << "invalid xCrd - fixX xLoc " << ndf << " [0,1] conditions" << "\n"; return TCL_ERROR; } @@ -109,8 +157,7 @@ TclCommand_addHomogeneousBC_X(ClientData clientData, Tcl_Interp *interp, ID fixity(ndf); for (int i=0; i= (4 + ndf)) { if (strcmp(argv[2+ndf],"-tol") == 0) if (Tcl_GetDouble(interp, argv[3+ndf], &tol) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid tol specified - fixX " << xLoc << endln; + opserr << OpenSees::PromptValueError + << "invalid tol specified - fixX " << xLoc + << OpenSees::SignalMessageEnd; return TCL_ERROR; } } @@ -137,7 +186,7 @@ TclCommand_addHomogeneousBC_X(ClientData clientData, Tcl_Interp *interp, int TclCommand_addHomogeneousBC_Y(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) + Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); BasicModelBuilder *builder = static_cast(clientData); @@ -148,21 +197,22 @@ TclCommand_addHomogeneousBC_Y(ClientData clientData, Tcl_Interp *interp, // check number of arguments if (argc < (2 + ndf)) { - opserr << G3_ERROR_PROMPT << "bad command - want: fixY yLoc " << ndf << " [0,1] conditions"; + opserr << OpenSees::PromptValueError << "bad command - want: fixY yLoc " << ndf << " [0,1] conditions"; return TCL_ERROR; } // get the yCrd of nodes to be constrained double yLoc; if (Tcl_GetDouble(interp, argv[1], &yLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid yCrd - fixY yLoc " << ndf << " [0,1] conditions\n"; return TCL_ERROR; + opserr << OpenSees::PromptValueError << "invalid yCrd - fixY yLoc " << ndf << " [0,1] conditions\n"; + return TCL_ERROR; } // read in the fixities ID fixity(ndf); for (int i=0; i= (4 + ndf)) { if (strcmp(argv[2+ndf],"-tol") == 0) if (Tcl_GetDouble(interp, argv[3+ndf], &tol) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid tol specified - fixY " << yLoc << endln; + opserr << OpenSees::PromptValueError << "invalid tol specified - fixY " << yLoc << OpenSees::SignalMessageEnd; return TCL_ERROR; } } @@ -186,7 +236,7 @@ TclCommand_addHomogeneousBC_Y(ClientData clientData, Tcl_Interp *interp, int TclCommand_addHomogeneousBC_Z(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) + Tcl_Size argc, TCL_Char ** const argv) { assert(clientData != nullptr); @@ -198,21 +248,22 @@ TclCommand_addHomogeneousBC_Z(ClientData clientData, Tcl_Interp *interp, // check number of arguments if (argc < (2 + ndf)) { - opserr << G3_ERROR_PROMPT << "bad command - want: fixZ zLoc " << ndf << " [0,1] conditions"; + opserr << OpenSees::PromptValueError << "bad command - want: fixZ zLoc " << ndf << " [0,1] conditions"; return TCL_ERROR; } // get the yCrd of nodes to be constrained double zLoc; if (Tcl_GetDouble(interp, argv[1], &zLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid zCrd - fixZ zLoc " << ndf << " [0,1] conditions\n"; return TCL_ERROR; + opserr << OpenSees::PromptValueError << "invalid zCrd - fixZ zLoc " << ndf << " [0,1] conditions\n"; + return TCL_ERROR; } // read in the fixities ID fixity(ndf); for (int i=0; i= (4 + ndf)) { if (strcmp(argv[2+ndf],"-tol") == 0) if (Tcl_GetDouble(interp, argv[3+ndf], &tol) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid tol specified - fixZ " << zLoc << endln; + opserr << OpenSees::PromptValueError + << "invalid tol specified - fixZ " << zLoc + << OpenSees::SignalMessageEnd; return TCL_ERROR; } } @@ -237,25 +290,26 @@ TclCommand_addHomogeneousBC_Z(ClientData clientData, Tcl_Interp *interp, int -TclCommand_addSP(ClientData clientData, Tcl_Interp *interp, int argc, +TclCommand_addSP(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { -//G3_Runtime *rt = G3_getRuntime(interp); assert(clientData != nullptr); BasicModelBuilder* builder = static_cast(clientData); Domain *theTclDomain = builder->getDomain(); if (argc > 1 && (strcmp(argv[1], "remove") == 0)) { if (argc < 3) { - opserr << G3_ERROR_PROMPT << "want - remove sp spTag? -or- remove " + opserr << OpenSees::PromptValueError + << "want - remove sp spTag? -or- remove " "sp nodeTag? dofTag? \n"; return TCL_ERROR; } int tag; if (argc == 3) { if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "remove sp tag? failed to read tag: " << argv[2] - << endln; + opserr << OpenSees::PromptValueError + << "remove sp tag? failed to read tag: " << argv[2] + << OpenSees::SignalMessageEnd; return TCL_ERROR; } SP_Constraint *theSPconstraint = theTclDomain->removeSP_Constraint(tag); @@ -267,20 +321,20 @@ TclCommand_addSP(ClientData clientData, Tcl_Interp *interp, int argc, int patternTag = -1; if (Tcl_GetInt(interp, argv[2], &nodeTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "remove sp tag? failed to read node tag: " << argv[2] - << endln; + opserr << OpenSees::PromptValueError << "remove sp tag? failed to read node tag: " << argv[2] + << OpenSees::SignalMessageEnd; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &dofTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "remove sp tag? failed to read dof tag: " << argv[3] - << endln; + opserr << OpenSees::PromptValueError << "remove sp tag? failed to read dof tag: " << argv[3] + << OpenSees::SignalMessageEnd; return TCL_ERROR; } if (argc == 5) { if (Tcl_GetInt(interp, argv[4], &patternTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "remove sp tag? failed to read pattern tag: " - << argv[4] << endln; + opserr << OpenSees::PromptValueError << "remove sp tag? failed to read pattern tag: " + << argv[4] << OpenSees::SignalMessageEnd; return TCL_ERROR; } } @@ -296,32 +350,35 @@ TclCommand_addSP(ClientData clientData, Tcl_Interp *interp, int argc, // check number of arguments if (argc < 4) { - opserr << G3_ERROR_PROMPT << "bad command - want: sp nodeId dofID value"; + opserr << OpenSees::PromptValueError << "bad command - want: sp nodeId dofID value"; return TCL_ERROR; } // get the nodeID, dofId and value of the constraint - int nodeId, dofId; - double value; + int nodeId, dofId; if (Tcl_GetInt(interp, argv[1], &nodeId) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodeId: " << argv[1] << " - sp nodeId dofID value\n"; + opserr << OpenSees::PromptValueError << "invalid nodeId: " << argv[1] << " - sp nodeId dofID value\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &dofId) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid dofId: " << argv[2] << " - sp "; + opserr << OpenSees::PromptValueError << "invalid dofId: " << argv[2] << " - sp "; opserr << nodeId << " dofID value\n"; return TCL_ERROR; } - dofId--; // DECREMENT THE DOF VALUE BY 1 TO GO TO OUR C++ INDEXING + // Decrement the DOF index by 1 to go to C/C++ 0-indexing + dofId--; + + double value; if (Tcl_GetDouble(interp, argv[3], &value) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid value: " << argv[3] << " - sp "; + opserr << OpenSees::PromptValueError << "invalid value: " << argv[3] << " - sp "; opserr << nodeId << " dofID value\n"; return TCL_ERROR; } bool isSpConst = false; + bool retZeroInit = true; bool userSpecifiedPattern = false; int loadPatternTag = 0; // some pattern that will never be used! @@ -330,15 +387,18 @@ TclCommand_addSP(ClientData clientData, Tcl_Interp *interp, int argc, if (strcmp(argv[endMarker],"-const") == 0) { // allow user to specify const load isSpConst = true; - - } else if (strcmp(argv[endMarker],"-pattern") == 0) { + } + else if (strcmp(argv[endMarker], "-subtractInit") == 0) { + retZeroInit = false; + } + else if (strcmp(argv[endMarker],"-pattern") == 0) { // allow user to specify load pattern other than current endMarker++; userSpecifiedPattern = true; if (endMarker == argc || Tcl_GetInt(interp, argv[endMarker], &loadPatternTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid patternTag - load " << nodeId << "\n"; + opserr << OpenSees::PromptValueError << "invalid patternTag - load " << nodeId << "\n"; return TCL_ERROR; } } @@ -348,7 +408,7 @@ TclCommand_addSP(ClientData clientData, Tcl_Interp *interp, int argc, // if load pattern tag has not changed - get the pattern tag from current one if (userSpecifiedPattern == false) { if (theTclLoadPattern == nullptr) { - opserr << G3_ERROR_PROMPT << "no current pattern - sp " + opserr << OpenSees::PromptValueError << "no current pattern - sp " << nodeId << " dofID value\n"; return TCL_ERROR; } else { @@ -359,10 +419,10 @@ TclCommand_addSP(ClientData clientData, Tcl_Interp *interp, int argc, // LoadPattern *thePattern = theTclDomain->getLoadPattern(loadPatternTag); // create a homogeneous constraint - SP_Constraint *theSP = new SP_Constraint(nodeId, dofId, value, isSpConst); + SP_Constraint *theSP = new SP_Constraint(nodeId, dofId, value, isSpConst, retZeroInit); if (theTclDomain->addSP_Constraint(theSP, loadPatternTag) == false) { - opserr << G3_ERROR_PROMPT << "could not add SP_Constraint to domain "; + opserr << OpenSees::PromptValueError << "could not add SP_Constraint to domain "; delete theSP; return TCL_ERROR; } @@ -372,7 +432,7 @@ TclCommand_addSP(ClientData clientData, Tcl_Interp *interp, int argc, int TclCommand_addEqualDOF_MP(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) + Tcl_Size argc, TCL_Char ** const argv) { BasicModelBuilder *builder = static_cast(clientData); Domain *theTclDomain = builder->getDomain(); @@ -380,7 +440,7 @@ TclCommand_addEqualDOF_MP(ClientData clientData, Tcl_Interp *interp, // Check number of arguments if (argc < 4) { - opserr << G3_ERROR_PROMPT << "bad command - want: equalDOF RnodeID? CnodeID? DOF1? DOF2? ..."; + opserr << OpenSees::PromptValueError << "bad command - want: equalDOF RnodeID? CnodeID? DOF1? DOF2? ..."; return TCL_ERROR; } @@ -388,12 +448,12 @@ TclCommand_addEqualDOF_MP(ClientData clientData, Tcl_Interp *interp, int RnodeID, CnodeID, dofID; if (Tcl_GetInt(interp, argv[1], &RnodeID) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid RnodeID: " << argv[1] + opserr << OpenSees::PromptValueError << "invalid RnodeID: " << argv[1] << " equalDOF RnodeID? CnodeID? DOF1? DOF2? ..."; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &CnodeID) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid CnodeID: " << argv[2] + opserr << OpenSees::PromptValueError << "invalid CnodeID: " << argv[2] << " equalDOF RnodeID? CnodeID? DOF1? DOF2? ..."; return TCL_ERROR; } @@ -412,14 +472,14 @@ TclCommand_addEqualDOF_MP(ClientData clientData, Tcl_Interp *interp, // Read the degrees of freedom which are to be coupled for (i = 3, j = 0; i < argc; i++, j++) { if (Tcl_GetInt(interp, argv[i], &dofID) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid dofID: " << argv[3] + opserr << OpenSees::PromptValueError << "invalid dofID: " << argv[3] << " equalDOF RnodeID? CnodeID? DOF1? DOF2? ..."; return TCL_ERROR; } dofID -= 1; // Decrement for C++ indexing if (dofID < 0) { - opserr << G3_ERROR_PROMPT << "invalid dofID: " << argv[i] + opserr << OpenSees::PromptValueError << "invalid dofID: " << argv[i] << " must be >= 1"; return TCL_ERROR; } @@ -432,7 +492,7 @@ TclCommand_addEqualDOF_MP(ClientData clientData, Tcl_Interp *interp, // Add the multi-point constraint to the domain if (theTclDomain->addMP_Constraint(theMP) == false) { - opserr << G3_ERROR_PROMPT << "could not add equalDOF MP_Constraint to domain "; + opserr << OpenSees::PromptValueError << "could not add equalDOF MP_Constraint to domain "; delete theMP; return TCL_ERROR; } @@ -443,19 +503,19 @@ TclCommand_addEqualDOF_MP(ClientData clientData, Tcl_Interp *interp, #if 0 int TclCommand_addEqualDOF_MP_Mixed(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) + Tcl_Size argc, TCL_Char ** const argv) { // Ensure the destructor has not been called BasicModelBuilder *builder = static_cast(clientData); if (theTclBuilder == 0 || clientData == 0) { - opserr << G3_ERROR_PROMPT << "builder has been destroyed - equalDOF \n"; + opserr << OpenSees::PromptValueError << "builder has been destroyed - equalDOF \n"; return TCL_ERROR; } // Check number of arguments if (argc < 4) { - opserr << G3_ERROR_PROMPT << "bad command - want: equalDOFmixed RnodeID? CnodeID? numDOF? RDOF1? CDOF1? ... ..."; + opserr << OpenSees::PromptValueError << "bad command - want: equalDOFmixed RnodeID? CnodeID? numDOF? RDOF1? CDOF1? ... ..."; return TCL_ERROR; } @@ -463,18 +523,18 @@ TclCommand_addEqualDOF_MP_Mixed(ClientData clientData, Tcl_Interp *interp, int RnodeID, CnodeID, dofIDR, dofIDC, numDOF; if (Tcl_GetInt(interp, argv[1], &RnodeID) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid RnodeID: " << argv[1] + opserr << OpenSees::PromptValueError << "invalid RnodeID: " << argv[1] << " equalDOF RnodeID? CnodeID? numDOF? RDOF1? CDOF1? ..."; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &CnodeID) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid CnodeID: " << argv[2] + opserr << OpenSees::PromptValueError << "invalid CnodeID: " << argv[2] << " equalDOF RnodeID? CnodeID? numDOF? RDOF1? CDOF1? ..."; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &numDOF) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid numDOF: " << argv[2] + opserr << OpenSees::PromptValueError << "invalid numDOF: " << argv[2] << " equalDOF RnodeID? CnodeID? numDOF? RDOF1? CDOF1? ..."; return TCL_ERROR; } @@ -494,12 +554,12 @@ TclCommand_addEqualDOF_MP_Mixed(ClientData clientData, Tcl_Interp *interp, // Read the degrees of freedom which are to be coupled for (i = 4, j = 5, k = 0; k < numDOF; i+=2, j+=2, k++) { if (Tcl_GetInt(interp, argv[i], &dofIDR) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid dofID: " << argv[3] + opserr << OpenSees::PromptValueError << "invalid dofID: " << argv[3] << " equalDOF RnodeID? CnodeID? DOF1? DOF2? ..."; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[j], &dofIDC) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid dofID: " << argv[3] + opserr << OpenSees::PromptValueError << "invalid dofID: " << argv[3] << " equalDOF RnodeID? CnodeID? DOF1? DOF2? ..."; return TCL_ERROR; } @@ -507,7 +567,7 @@ TclCommand_addEqualDOF_MP_Mixed(ClientData clientData, Tcl_Interp *interp, dofIDR -= 1; // Decrement for 0-based indexing dofIDC -= 1; if (dofIDC < 0 || dofIDR < 0) { - opserr << G3_ERROR_PROMPT << "invalid dofID: " << argv[i] + opserr << OpenSees::PromptValueError << "invalid dofID: " << argv[i] << " must be >= 1"; return TCL_ERROR; } @@ -521,7 +581,7 @@ TclCommand_addEqualDOF_MP_Mixed(ClientData clientData, Tcl_Interp *interp, // Add the multi-point constraint to the domain if (theTclDomain->addMP_Constraint (theMP) == false) { - opserr << G3_ERROR_PROMPT << "could not add equalDOF MP_Constraint to domain "; + opserr << OpenSees::PromptValueError << "could not add equalDOF MP_Constraint to domain "; delete theMP; return TCL_ERROR; } @@ -534,20 +594,19 @@ TclCommand_addEqualDOF_MP_Mixed(ClientData clientData, Tcl_Interp *interp, int TclCommand_addImposedMotionSP(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) + Tcl_Size argc, TCL_Char ** const argv) { // TODO: Cleanup G3_Runtime* rt = G3_getRuntime(interp); Domain *domain = G3_getDomain(rt); // BasicModelBuilder *theTclBuilder = G3_getSafeBuilder(G3_getRuntime(interp)); - // // ensure the destructor has not been called - // BasicModelBuilder *builder = static_cast(clientData); // check number of arguments if (argc < 4) { - opserr << G3_ERROR_PROMPT << "bad command - want: imposedMotion nodeId dofID gMotionID\n"; + opserr << OpenSees::PromptValueError << "bad command - want: imposedMotion nodeId dofID gMotionID\n"; return TCL_ERROR; } @@ -555,20 +614,20 @@ TclCommand_addImposedMotionSP(ClientData clientData, Tcl_Interp *interp, int nodeId, dofId, gMotionID; if (Tcl_GetInt(interp, argv[1], &nodeId) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodeId: " << argv[1] + opserr << OpenSees::PromptValueError << "invalid nodeId: " << argv[1] << " - imposedMotion nodeId dofID gMotionID" << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[2], &dofId) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid dofId: " << argv[2] + opserr << OpenSees::PromptValueError << "invalid dofId: " << argv[2] << " - imposedMotion " << nodeId << " dofID gMotionID\n"; return TCL_ERROR; } dofId--; // DECREMENT THE DOF VALUE BY 1 TO GO TO OUR C++ INDEXING if (Tcl_GetInt(interp, argv[3], &gMotionID) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gMotionID: " << argv[3] << " - imposedMotion "; + opserr << OpenSees::PromptValueError << "invalid gMotionID: " << argv[3] << " - imposedMotion "; opserr << nodeId << " dofID gMotionID\n"; return TCL_ERROR; } @@ -582,16 +641,15 @@ TclCommand_addImposedMotionSP(ClientData clientData, Tcl_Interp *interp, // // check valid node & dof // - Node *theNode = domain->getNode(nodeId); if (theNode == nullptr) { - opserr << G3_ERROR_PROMPT << "invalid node " << argv[2] << " node not found\n "; + opserr << OpenSees::PromptValueError << "invalid node " << argv[2] << " node not found\n "; return -1; } int nDof = theNode->getNumberDOF(); if (dofId < 0 || dofId >= nDof) { - opserr << G3_ERROR_PROMPT << "invalid dofId: " << argv[2] << " dof specified cannot be <= 0 or greater than num dof at nod\n "; + opserr << OpenSees::PromptValueError << "invalid dofId: " << argv[2] << " dof specified cannot be <= 0 or greater than num dof at nod\n "; return -2; } @@ -613,7 +671,7 @@ TclCommand_addImposedMotionSP(ClientData clientData, Tcl_Interp *interp, } if (thePattern->addSP_Constraint(theSP) == false) { - opserr << G3_ERROR_PROMPT << "could not add SP_Constraint to pattern "; + opserr << OpenSees::PromptValueError << "could not add SP_Constraint to pattern "; delete theSP; return TCL_ERROR; } diff --git a/SRC/runtime/commands/modeling/element.cpp b/SRC/runtime/commands/modeling/element.cpp index 2029e033d4..13c37dd028 100644 --- a/SRC/runtime/commands/modeling/element.cpp +++ b/SRC/runtime/commands/modeling/element.cpp @@ -1,6 +1,15 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // //===----------------------------------------------------------------------===// // @@ -53,6 +62,10 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp *interp // THE PROTOTYPES OF THE FUNCTIONS INVOKED BY THE INTERPRETER // +#if 0 // cmp - commented out to eliminate use of TclBasicBuilder +extern int Tcl_addWrapperElement(eleObj *, ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, Domain *, TclBuilder *); +// Added by Quan Gu and Yongdou Liu, et al. on 2018/10/31 (Xiamen University) +#endif static Tcl_CmdProc TclBasicBuilder_addWheelRail; @@ -118,10 +131,10 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, theTclDomain); - // check at least two arguments so don't segemnt fault on strcmp if (argc < 2) { - opserr << OpenSees::PromptValueError << "insufficient arguments, expected:\n"; - opserr << " element eleType .. \n"; + opserr << OpenSees::PromptValueError + << "Missing element type" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -152,9 +165,9 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C theEle = OPS_PML2D(rt, argc, argv); else theEle = OPS_PML3D(rt, argc, argv); - + } #if 0 - } else if (strcmp(argv[1], "gradientInelasticBeamColumn") == 0) { + else if (strcmp(argv[1], "gradientInelasticBeamColumn") == 0) { Element *theEle = 0; if (ndm == 2) @@ -167,11 +180,11 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C else { return TCL_ERROR; } - } + } #endif #if defined(_HAVE_LHNMYS) || defined(OPSDEF_ELEMENT_LHNMYS) - } else if (strcmp(argv[1], "beamColumn2DwLHNMYS") == 0) { + else if (strcmp(argv[1], "beamColumn2DwLHNMYS") == 0) { theEle = OPS_BeamColumn2DwLHNMYS(rt, argc, argv); } else if (strcmp(argv[1], "beamColumn2dDamage") == 0) { @@ -182,9 +195,10 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C } else if (strcmp(argv[1], "beamColumn3DwLHNMYS") == 0) { theEle = OPS_BeamColumn3DwLHNMYS(rt, argc, argv); + } #endif - } else if (strcmp(argv[1], "ElasticTimoshenkoBeam") == 0) { + else if (strcmp(argv[1], "ElasticTimoshenkoBeam") == 0) { if (ndm == 2) theEle = OPS_ElasticTimoshenkoBeam2d(rt, argc, argv); else @@ -403,9 +417,7 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C else if ((strcmp(argv[1], "multipleNormalSpring") == 0) || (strcmp(argv[1], "MNS") == 0)) { - int result = TclBasicBuilder_addMultipleNormalSpring( - clientData, interp, argc, argv, theTclDomain, theTclBuilder); - return result; + return TclBasicBuilder_addMultipleNormalSpring(clientData, interp, argc, argv, theTclDomain, theTclBuilder); } else if (strcmp(argv[1], "KikuchiBearing") == 0) { @@ -413,15 +425,12 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C } else if (strcmp(argv[1], "YamamotoBiaxialHDR") == 0) { - int result = TclBasicBuilder_addYamamotoBiaxialHDR( - clientData, interp, argc, argv, theTclDomain, theTclBuilder); - return result; + return TclBasicBuilder_addYamamotoBiaxialHDR(clientData, interp, argc, argv, theTclDomain, theTclBuilder); } // MSN else if (strcmp(argv[1], "gradientInelasticBeamColumn") == 0) { - int result = TclBasicBuilder_addGradientInelasticBeamColumn(clientData, interp, argc, argv); - return result; + return TclBasicBuilder_addGradientInelasticBeamColumn(clientData, interp, argc, argv); } else { @@ -454,6 +463,7 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C } else eleCommands = eleCommands->next; } + #if 0 // // maybe element in a routine, check existing ones or try loading new ones @@ -488,7 +498,7 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C strcpy(&tclFuncName[4], argv[1]); - opserr << "checking library: " << tclFuncName << endln; + opserr << "checking library: " << tclFuncName << OpenSees::SignalMessageEnd; int res = getLibraryFunction(argv[1], tclFuncName, &libHandle, (void **)&funcPtr); @@ -524,7 +534,7 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C } // If we get here, the element type is unknown - opserr << "ERROR -- element of type " << argv[1] << " not known" << endln; + opserr << "ERROR -- element of type " << argv[1] << " not known" << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -546,10 +556,10 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp int ndf = builder->getNDF(); if (ndm != 3 || ndf != 6) { - opserr << "ndm=" << ndm << ", ndf=" << ndf << endln; + opserr << "ndm=" << ndm << ", ndf=" << ndf << OpenSees::SignalMessageEnd; opserr << "WARNING multipleShearSpring command only works when ndm is 3 " "and ndf is 6" - << endln; + << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -625,8 +635,8 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp material = builder->getTypedObject(matTag); if (material == 0) { opserr << "WARNING material model not found\n"; - opserr << "uniaxialMaterial: " << matTag << endln; - opserr << "multipleShearSpring element: " << eleTag << endln; + opserr << "uniaxialMaterial: " << matTag << OpenSees::SignalMessageEnd; + opserr << "multipleShearSpring element: " << eleTag << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -646,8 +656,8 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp theMaterials[j] = builder->getTypedObject(matTag); if (theMaterials[j] == 0) { opserr << "WARNING material model not found\n"; - opserr << "uniaxialMaterial: " << matTag << endln; - opserr << "multipleShearSpring element: " << eleTag << endln; + opserr << "uniaxialMaterial: " << matTag << OpenSees::SignalMessageEnd; + opserr << "multipleShearSpring element: " << eleTag << OpenSees::SignalMessageEnd; return TCL_ERROR; } } @@ -754,7 +764,7 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp // then add the multipleShearSpring to the domain if (theTclDomain->addElement(theElement) == false) { opserr << "WARNING could not add element to the domain\n"; - opserr << "multipleShearSpring element: " << eleTag << endln; + opserr << "multipleShearSpring element: " << eleTag << OpenSees::SignalMessageEnd; delete theElement; return TCL_ERROR; } @@ -769,12 +779,12 @@ errDetected(bool ifNoError, const char *msg) { if (ifNoError) { - opserr << "" << endln; - opserr << "========================================" << endln; - opserr << " element : input error detected" << endln; - opserr << "------------------------------" << endln; + opserr << "" << OpenSees::SignalMessageEnd; + opserr << "========================================" << OpenSees::SignalMessageEnd; + opserr << " element : input error detected" << OpenSees::SignalMessageEnd; + opserr << "------------------------------" << OpenSees::SignalMessageEnd; } - opserr << " " << msg << endln; + opserr << " " << msg << OpenSees::SignalMessageEnd; return false; }; @@ -793,10 +803,9 @@ TclBasicBuilder_addMultipleNormalSpring(ClientData clientData, Tcl_Interp *inter int ndf = builder->getNDF(); if (ndm != 3 || ndf != 6) { - opserr << "ndm=" << ndm << ", ndf=" << ndf << endln; opserr << "WARNING multipleNormalSpring command only works when ndm is 3 " "and ndf is 6" - << endln; + << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -1035,7 +1044,7 @@ TclBasicBuilder_addMultipleNormalSpring(ClientData clientData, Tcl_Interp *inter opserr << "Want: element multipleNormalSpring eleTag? iNode? jNode? " "\n nDivide? -mat matTag? -shape shape? -size size? <-lambda " "\n lambda?> <-orient yp1? yp2? yp3?> <-mass m?>\n"; - opserr << "" << endln; + opserr << "" << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -1046,7 +1055,7 @@ TclBasicBuilder_addMultipleNormalSpring(ClientData clientData, Tcl_Interp *inter // then add the multipleNormalSpring to the domain if (theTclDomain->addElement(theElement) == false) { opserr << "WARNING could not add element to the domain\n"; - opserr << "multipleNormalSpring element: " << eleTag << endln; + opserr << "multipleNormalSpring element: " << eleTag << OpenSees::SignalMessageEnd; delete theElement; return TCL_ERROR; } @@ -1068,10 +1077,10 @@ TclBasicBuilder_addKikuchiBearing(ClientData clientData, Tcl_Interp *interp, int ndf = builder->getNDF(); if (ndm != 3 || ndf != 6) { - opserr << "ndm=" << ndm << ", ndf=" << ndf << endln; + opserr << "ndm=" << ndm << ", ndf=" << ndf << OpenSees::SignalMessageEnd; opserr << "WARNING KikuchiBearing command only works when ndm is 3 and ndf " "is 6" - << endln; + << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -1522,7 +1531,7 @@ TclBasicBuilder_addKikuchiBearing(ClientData clientData, Tcl_Interp *interp, "yp3?> <-mass m?>\n"; opserr << " <-noPDInput> <-noTilt> " "<-adjustPDOutput ci? cj?> <-doBalance limFo? limFi? nIter?>\n"; - opserr << "" << endln; + opserr << "" << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -1535,7 +1544,7 @@ TclBasicBuilder_addKikuchiBearing(ClientData clientData, Tcl_Interp *interp, // then add the KikuchiBearing to the domain if (builder->getDomain()->addElement(theElement) == false) { opserr << "WARNING could not add element to the domain\n"; - opserr << "KikuchiBearing element: " << eleTag << endln; + opserr << "KikuchiBearing element: " << eleTag << OpenSees::SignalMessageEnd; delete theElement; return TCL_ERROR; } @@ -1559,9 +1568,9 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, int ndf = builder->getNDF(); if (ndm != 3 || ndf != 6) { - opserr << "ndm=" << ndm << ", ndf=" << ndf << endln; + opserr << "ndm=" << ndm << ", ndf=" << ndf << OpenSees::SignalMessageEnd; opserr << "WARNING YamamotoBiaxialHDR command only works when ndm is 3 and " - "ndf is 6" << endln; + "ndf is 6" << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -1618,25 +1627,25 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, if (strcmp(argv[5], "1") == 0) { Tp = 1; // Bridgestone X0.6R (EESD version) } else { - opserr << "WARNING invalid YamamotoBiaxialHDR Tp" << endln; + opserr << "WARNING invalid YamamotoBiaxialHDR Tp" << OpenSees::SignalMessageEnd; ifNoError = false; } // DDo if (Tcl_GetDouble(interp, argv[6], &DDo) != TCL_OK || DDo <= 0.0) { - opserr << "WARNING invalid YamamotoBiaxialHDR DDo" << endln; + opserr << "WARNING invalid YamamotoBiaxialHDR DDo" << OpenSees::SignalMessageEnd; ifNoError = false; } // DDi if (Tcl_GetDouble(interp, argv[7], &DDi) != TCL_OK || DDi < 0.0) { - opserr << "WARNING invalid YamamotoBiaxialHDR DDi" << endln; + opserr << "WARNING invalid YamamotoBiaxialHDR DDi" << OpenSees::SignalMessageEnd; ifNoError = false; } // Hr if (Tcl_GetDouble(interp, argv[8], &Hr) != TCL_OK || Hr <= 0.0) { - opserr << "WARNING invalid YamamotoBiaxialHDR Hr" << endln; + opserr << "WARNING invalid YamamotoBiaxialHDR Hr" << OpenSees::SignalMessageEnd; ifNoError = false; } @@ -1737,7 +1746,7 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, // then add the YamamotoBiaxialHDR to the domain if (theTclDomain->addElement(theElement) == false) { opserr << "WARNING could not add element to the domain\n"; - opserr << "YamamotoBiaxialHDR element: " << eleTag << endln; + opserr << "YamamotoBiaxialHDR element: " << eleTag << OpenSees::SignalMessageEnd; delete theElement; return TCL_ERROR; } @@ -1851,9 +1860,9 @@ TclBasicBuilder_addWheelRail(ClientData clientData, Tcl_Interp *interp, int argc return TCL_ERROR; } //---------------------------------- - Vector *pNodeList = 0; - Vector *pDeltaYList = 0; - Vector *pDeltaYLocationList = 0; + Vector *pNodeList = nullptr; + Vector *pDeltaYList = nullptr; + Vector *pDeltaYLocationList = nullptr; if (strcmp(argv[12 + eleArgStart], "-NodeList") == 0) { int pathSize; @@ -1934,14 +1943,14 @@ TclBasicBuilder_addWheelRail(ClientData clientData, Tcl_Interp *interp, int argc // -- End of a 2D wheel-rail element(By Quan Gu, Yongdou Liu, et al.) on 2018/10/29 else if (ndm == 3) { - opserr << OpenSees::PromptValueError << "Unimplemented." << endln; + opserr << OpenSees::PromptValueError << "Unimplemented." << OpenSees::SignalMessageEnd; return TCL_ERROR; } // add the WheelRail element to the Domain if (builder->getDomain()->addElement(theElement) == false) { opserr << "WARNING could not add element to the domain\n"; - opserr << "YamamotoBiaxialHDR element: " << pTag << endln; + opserr << "YamamotoBiaxialHDR element: " << pTag << OpenSees::SignalMessageEnd; delete theElement; return TCL_ERROR; } diff --git a/SRC/runtime/commands/modeling/element.hpp b/SRC/runtime/commands/modeling/element.hpp index 5f7ec2cc02..0f09aeda65 100644 --- a/SRC/runtime/commands/modeling/element.hpp +++ b/SRC/runtime/commands/modeling/element.hpp @@ -1,15 +1,6 @@ //===----------------------------------------------------------------------===// // -// xara -// https://xara.so -// -//===----------------------------------------------------------------------===// -// -// Copyright (c) 2025, Claudio M. Perez -// All rights reserved. No warranty, explicit or implicit, is provided. -// -// This source code is licensed under the BSD 2-Clause License. -// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// OpenSees - Open System for Earthquake Engineering Simulation // //===----------------------------------------------------------------------===// // diff --git a/SRC/runtime/commands/modeling/element/brick.cpp b/SRC/runtime/commands/modeling/element/brick.cpp new file mode 100644 index 0000000000..a32c9a256c --- /dev/null +++ b/SRC/runtime/commands/modeling/element/brick.cpp @@ -0,0 +1,676 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// Written: fmk +// Created: 03/01 +// +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef _FLBrick +# include +#endif + +int +TclBasicBuilder_addBrick(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char **const argv) +{ + const int eleArgStart = 1; + + BasicModelBuilder* builder = (BasicModelBuilder*)clientData; + Domain* theTclDomain = builder->getDomain(); + + // check the number of arguments is correct + if ((argc - eleArgStart) < 11) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element Brick eleTag? Node1? Node2? Node3? Node4? Node5? " + "Node6? Node7? Node 8? matTag?\n"; + return TCL_ERROR; + } + + // get the id and end nodes + int BrickId; + int matID; + int Node1, Node2, Node3, Node4, + Node5, Node6, Node7, Node8; + + if (Tcl_GetInt(interp, argv[1 + eleArgStart], &BrickId) != TCL_OK) { + opserr << "WARNING invalid Brick eleTag" << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2 + eleArgStart], &Node1) != TCL_OK) { + opserr << "WARNING invalid Node1\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[3 + eleArgStart], &Node2) != TCL_OK) { + opserr << "WARNING invalid Node2\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[4 + eleArgStart], &Node3) != TCL_OK) { + opserr << "WARNING invalid Node3\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[5 + eleArgStart], &Node4) != TCL_OK) { + opserr << "WARNING invalid Node4\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[6 + eleArgStart], &Node5) != TCL_OK) { + opserr << "WARNING invalid Node5\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[7 + eleArgStart], &Node6) != TCL_OK) { + opserr << "WARNING invalid Node6\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[8 + eleArgStart], &Node7) != TCL_OK) { + opserr << "WARNING invalid Node7\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[9 + eleArgStart], &Node8) != TCL_OK) { + opserr << "WARNING invalid Node8\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[10 + eleArgStart], &matID) != TCL_OK) { + opserr << "WARNING invalid matTag\n"; + return TCL_ERROR; + } + + + NDMaterial *theMaterial = builder->getTypedObject(matID); + if (theMaterial == nullptr) + return TCL_ERROR; + + + double b1 = 0.0; + double b2 = 0.0; + double b3 = 0.0; + if ((argc - eleArgStart) > 11) { + if (Tcl_GetDouble(interp, argv[11 + eleArgStart], &b1) != TCL_OK) { + opserr << "WARNING invalid b1\n"; + opserr << "Brick element: " << BrickId << endln; + return TCL_ERROR; + } + } + + if ((argc - eleArgStart) > 12) { + if (Tcl_GetDouble(interp, argv[12 + eleArgStart], &b2) != TCL_OK) { + opserr << "WARNING invalid b2\n"; + opserr << "Brick element: " << BrickId << endln; + return TCL_ERROR; + } + } + + if ((argc - eleArgStart) > 13) { + if (Tcl_GetDouble(interp, argv[13 + eleArgStart], &b3) != TCL_OK) { + opserr << "WARNING invalid b3\n"; + opserr << "Brick element: " << BrickId << endln; + return TCL_ERROR; + } + } + + // now create the Brick and add it to the Domain + Element *theBrick = nullptr; + if (strcmp(argv[1], "stdBrick") == 0) { + theBrick = new Brick(BrickId, Node1, Node2, Node3, Node4, Node5, Node6, + Node7, Node8, *theMaterial, b1, b2, b3); + + } else if (strcmp(argv[1], "bbarBrickWithSensitivity") == 0) { + theBrick = new BbarBrickWithSensitivity(BrickId, Node1, Node2, Node3, Node4, + Node5, Node6, Node7, Node8, + *theMaterial, b1, b2, b3); + } else if (strcmp(argv[1], "bbarBrick") == 0) { + theBrick = new BbarBrick(BrickId, Node1, Node2, Node3, Node4, Node5, Node6, + Node7, Node8, *theMaterial, b1, b2, b3); + } + +#ifdef _FLBrick + else if (strcmp(argv[1], "flBrick") == 0) { + theBrick = new FLBrick(BrickId, Node1, Node2, Node3, Node4, Node5, Node6, + Node7, Node8, *theMaterial, b1, b2, b3); + } +#endif + + else { + opserr << "WARNING element " << argv[1] << " type not recognized\n"; + return TCL_ERROR; + } + + if (theBrick == 0) { + opserr << "WARNING ran out of memory creating element\n"; + return TCL_ERROR; + } + + if (theTclDomain->addElement(theBrick) == false) { + opserr << "WARNING could not add element to the domain\n"; + delete theBrick; + return TCL_ERROR; + } + + // if get here we have successfully created the node and added it to the domain + return TCL_OK; +} + +// +// Description: This file contains the implementation of +// TclBasicBuilder_addBrickUP() , +// TclBasicBuilder_addTwentyEightNodeBrickUP(), +// TclBasicBuilder_addBBarBrickUP() +// +// +// Jinchi Lu and Zhaohui Yang (May 2004) +// +#include +#include +#include +#include +#include +#include +#include + +int +TclBasicBuilder_addTwentyNodeBrick(ClientData clientData, Tcl_Interp *interp, + int argc, + TCL_Char ** const argv) +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + Domain* theTclDomain = builder->getDomain(); + + if (builder == 0 || clientData == 0) { + opserr << "WARNING builder has been destroyed\n"; + return TCL_ERROR; + } + if (builder->getNDM() != 3) { + opserr << "WARNING -- model dimensions and/or nodal DOF not compatible " + "with 20NodeBrick element\n"; + return TCL_ERROR; + } + // check the number of arguments is correct + int argStart = 2; + if ((argc - argStart) < 22) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element 20NodeBrick eleTag? N1? N2? N3? N4? N5? N6? N7? " + "N8? N9? N10? N11? N12? N13? N14? N15? N16? N17? N18? N19? N20? " + "matTag? \n"; + return TCL_ERROR; + } + // get the id and end nodes + int brickId, Nod[20], matID; + double b1 = 0.0; + double b2 = 0.0; + double b3 = 0.0; + if (Tcl_GetInt(interp, argv[argStart], &brickId) != TCL_OK) { + opserr << "WARNING invalid 20NodeBrick eleTag" << endln; + return TCL_ERROR; + } + for (int i = 0; i < 20; i++) + if (Tcl_GetInt(interp, argv[1 + argStart + i], &(Nod[i])) != TCL_OK) { + opserr << "WARNING invalid Node number\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[21 + argStart], &matID) != TCL_OK) { + opserr << "WARNING invalid matID\n"; + return TCL_ERROR; + } + if ((argc - argStart) >= 23) { + if (Tcl_GetDouble(interp, argv[22 + argStart], &b1) != TCL_OK) { + opserr << "WARNING invalid b1\n"; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 24) { + if (Tcl_GetDouble(interp, argv[23 + argStart], &b2) != TCL_OK) { + opserr << "WARNING invalid b2\n"; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 25) { + if (Tcl_GetDouble(interp, argv[24 + argStart], &b3) != TCL_OK) { + opserr << "WARNING invalid b3\n"; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + if (theMaterial == nullptr) { + return TCL_ERROR; + } + + // now create the brick and add it to the Domain + Twenty_Node_Brick *theTwentyNodeBrick = + new Twenty_Node_Brick(brickId, Nod[0], Nod[1], Nod[2], Nod[3], Nod[4], + Nod[5], Nod[6], Nod[7], + Nod[8], Nod[9], Nod[10], Nod[11], Nod[12], Nod[13], + Nod[14], + Nod[15], Nod[16], Nod[17], Nod[18], Nod[19], + *theMaterial, b1, b2, b3); + + if (theTclDomain->addElement(theTwentyNodeBrick) == false) { + opserr << "WARNING could not add element to the domain\n"; + delete theTwentyNodeBrick; + return TCL_ERROR; + } + // if get here we have successfully created the element and added it to the + // domain + return TCL_OK; +} + +int +TclBasicBuilder_addBrickUP(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + Domain* theTclDomain = builder->getDomain(); + + if (builder == 0 || clientData == 0) { + opserr << "WARNING builder has been destroyed\n"; + return TCL_ERROR; + } + + if (builder->getNDM() != 3 || builder->getNDF() != 4) { + opserr << "WARNING -- model dimensions and/or nodal DOF not compatible " + "with QuadUP element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc - argStart) < 15) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element brickUP eleTag? N1? N2? N3? N4? N5? N6? N7? N8? " + "matTag? bulk? rhof? perm_x? perm_y? perm_z? \n"; + return TCL_ERROR; + } + + // get the id and end nodes + int brickUPId, Nod[8], matID; + double bk, r, perm1, perm2, perm3; + double b1 = 0.0; + double b2 = 0.0; + double b3 = 0.0; + + if (Tcl_GetInt(interp, argv[argStart], &brickUPId) != TCL_OK) { + opserr << "WARNING invalid brickUP eleTag" << endln; + return TCL_ERROR; + } + + for (int i = 0; i < 8; i++) + if (Tcl_GetInt(interp, argv[1 + argStart + i], &(Nod[i])) != TCL_OK) { + opserr << "WARNING invalid Node number\n"; + opserr << "brickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[9 + argStart], &matID) != TCL_OK) { + opserr << "WARNING invalid matID\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10 + argStart], &bk) != TCL_OK) { + opserr << "WARNING invalid fluid bulk modulus\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[11 + argStart], &r) != TCL_OK) { + opserr << "WARNING invalid fluid mass density\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[12 + argStart], &perm1) != TCL_OK) { + opserr << "WARNING invalid permeability_x\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[13 + argStart], &perm2) != TCL_OK) { + opserr << "WARNING invalid permeability_y\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[14 + argStart], &perm3) != TCL_OK) { + opserr << "WARNING invalid permeability_z\n"; + return TCL_ERROR; + } + + if ((argc - argStart) >= 16) { + if (Tcl_GetDouble(interp, argv[15 + argStart], &b1) != TCL_OK) { + opserr << "WARNING invalid b1\n"; + opserr << "brickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 17) { + if (Tcl_GetDouble(interp, argv[16 + argStart], &b2) != TCL_OK) { + opserr << "WARNING invalid b2\n"; + opserr << "brickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 18) { + if (Tcl_GetDouble(interp, argv[17 + argStart], &b3) != TCL_OK) { + opserr << "WARNING invalid b3\n"; + opserr << "brickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + + if (theMaterial == 0) { + opserr << "WARNING material not found\n"; + opserr << "Material: " << matID; + opserr << "\nbrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + + // now create the brickUP and add it to the Domain + BrickUP *theBrickUP = new BrickUP( + brickUPId, Nod[0], Nod[1], Nod[2], Nod[3], Nod[4], Nod[5], Nod[6], Nod[7], + *theMaterial, bk, r, perm1, perm2, perm3, b1, b2, b3); + if (theBrickUP == 0) { + opserr << "WARNING ran out of memory creating element\n"; + return TCL_ERROR; + } + + if (theTclDomain->addElement(theBrickUP) == false) { + opserr << "WARNING could not add element to the domain\n"; + delete theBrickUP; + return TCL_ERROR; + } + + // if get here we have successfully created the element and added it to the + // domain + return TCL_OK; +} + +int +TclBasicBuilder_addTwentyEightNodeBrickUP(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) + +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + Domain* theTclDomain = builder->getDomain(); + + + if (builder->getNDM() != 3) { + opserr << "WARNING -- model dimensions and/or nodal DOF not compatible " + "with 20_8_BrickUP element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc - argStart) < 27) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element 20_8_BrickUP eleTag? N1? N2? N3? N4? N5? N6? N7? " + "N8? N9? N10? N11? N12? N13? N14? N15? N16? N17? N18? N19? N20? " + "matTag? bulk? rhof? perm_x? perm_y? perm_z? \n"; + return TCL_ERROR; + } + + // get the id and end nodes + int brickUPId, Nod[20], matID; + double bk, r, perm1, perm2, perm3; + double b1 = 0.0; + double b2 = 0.0; + double b3 = 0.0; + + if (Tcl_GetInt(interp, argv[argStart], &brickUPId) != TCL_OK) { + opserr << "WARNING invalid 20_8_BrickUP eleTag" << endln; + return TCL_ERROR; + } + + for (int i = 0; i < 20; i++) + if (Tcl_GetInt(interp, argv[1 + argStart + i], &(Nod[i])) != TCL_OK) { + opserr << "WARNING invalid Node number\n"; + opserr << "20_8_BrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[21 + argStart], &matID) != TCL_OK) { + opserr << "WARNING invalid matID\n"; + opserr << "20_8_BrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[22 + argStart], &bk) != TCL_OK) { + opserr << "WARNING invalid fluid bulk modulus\n"; + opserr << "20_8_BrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[23 + argStart], &r) != TCL_OK) { + opserr << "WARNING invalid fluid mass density\n"; + opserr << "20_8_BrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[24 + argStart], &perm1) != TCL_OK) { + opserr << "WARNING invalid permeability_x\n"; + opserr << "20_8_BrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[25 + argStart], &perm2) != TCL_OK) { + opserr << "WARNING invalid permeability_y\n"; + opserr << "20_8_BrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[26 + argStart], &perm3) != TCL_OK) { + opserr << "WARNING invalid permeability_z\n"; + opserr << "20_8_BrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + + if ((argc - argStart) >= 28) { + if (Tcl_GetDouble(interp, argv[27 + argStart], &b1) != TCL_OK) { + opserr << "WARNING invalid b1\n"; + opserr << "20_8_BrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 29) { + if (Tcl_GetDouble(interp, argv[28 + argStart], &b2) != TCL_OK) { + opserr << "WARNING invalid b2\n"; + opserr << "20_8_BrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 30) { + if (Tcl_GetDouble(interp, argv[29 + argStart], &b3) != TCL_OK) { + opserr << "WARNING invalid b3\n"; + opserr << "20_8_BrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + + if (theMaterial == 0) { + opserr << "WARNING material not found\n"; + opserr << "Material: " << matID; + opserr << "\n20_8_BrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + + // now create the brickUP and add it to the Domain + TwentyEightNodeBrickUP *theTwentyEightNodeBrickUP = + new TwentyEightNodeBrickUP( + brickUPId, Nod[0], Nod[1], Nod[2], Nod[3], Nod[4], Nod[5], Nod[6], + Nod[7], Nod[8], Nod[9], Nod[10], Nod[11], Nod[12], Nod[13], Nod[14], + Nod[15], Nod[16], Nod[17], Nod[18], Nod[19], *theMaterial, bk, r, + perm1, perm2, perm3, b1, b2, b3); + if (theTwentyEightNodeBrickUP == 0) { + opserr << "WARNING ran out of memory creating element\n"; + opserr << "20_8_BrickUP element: " << brickUPId << endln; + return TCL_ERROR; + } + + if (theTclDomain->addElement(theTwentyEightNodeBrickUP) == false) { + opserr << "WARNING could not add element to the domain\n"; + opserr << "20_8_BrickUP element: " << brickUPId << endln; + delete theTwentyEightNodeBrickUP; + return TCL_ERROR; + } + + // if get here we have successfully created the element and added it to the + // domain + return TCL_OK; +} + +/* ***************************************************************************** + + BBAR BRICK U_P + + ***************************************************************************** + */ + +int +TclBasicBuilder_addBBarBrickUP(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + Domain* theTclDomain = builder->getDomain(); + + if (builder == 0 || clientData == 0) { + opserr << "WARNING builder has been destroyed\n"; + return TCL_ERROR; + } + + if (builder->getNDM() != 3 || builder->getNDF() != 4) { + opserr << "WARNING -- model dimensions and/or nodal DOF not compatible " + "with QuadUP element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc - argStart) < 15) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element BBarBrickUP eleTag? N1? N2? N3? N4? N5? N6? N7? " + "N8? matTag? bulk? rhof? perm_x? perm_y? perm_z? \n"; + return TCL_ERROR; + } + + // get the id and end nodes + int BBarBrickUPId, Nod[8], matID; + double bk, r, perm1, perm2, perm3; + double b1 = 0.0; + double b2 = 0.0; + double b3 = 0.0; + + if (Tcl_GetInt(interp, argv[argStart], &BBarBrickUPId) != TCL_OK) { + opserr << "WARNING invalid BBarBrickUP eleTag" << endln; + return TCL_ERROR; + } + + for (int i = 0; i < 8; i++) + if (Tcl_GetInt(interp, argv[1 + argStart + i], &(Nod[i])) != TCL_OK) { + opserr << "WARNING invalid Node number\n"; + opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[9 + argStart], &matID) != TCL_OK) { + opserr << "WARNING invalid matID\n"; + opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10 + argStart], &bk) != TCL_OK) { + opserr << "WARNING invalid fluid bulk modulus\n"; + opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[11 + argStart], &r) != TCL_OK) { + opserr << "WARNING invalid fluid mass density\n"; + opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[12 + argStart], &perm1) != TCL_OK) { + opserr << "WARNING invalid permeability_x\n"; + opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[13 + argStart], &perm2) != TCL_OK) { + opserr << "WARNING invalid permeability_y\n"; + opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[14 + argStart], &perm3) != TCL_OK) { + opserr << "WARNING invalid permeability_z\n"; + opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + return TCL_ERROR; + } + + if ((argc - argStart) >= 16) { + if (Tcl_GetDouble(interp, argv[15 + argStart], &b1) != TCL_OK) { + opserr << "WARNING invalid b1\n"; + opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 17) { + if (Tcl_GetDouble(interp, argv[16 + argStart], &b2) != TCL_OK) { + opserr << "WARNING invalid b2\n"; + opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 18) { + if (Tcl_GetDouble(interp, argv[17 + argStart], &b3) != TCL_OK) { + opserr << "WARNING invalid b3\n"; + opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + + if (theMaterial == 0) { + opserr << "WARNING material not found\n"; + opserr << "Material: " << matID; + opserr << "\nBBarBrickUP element: " << BBarBrickUPId << endln; + return TCL_ERROR; + } + + // now create the BBarBrickUP and add it to the Domain + BBarBrickUP *theBBarBrickUP = new BBarBrickUP( + BBarBrickUPId, Nod[0], Nod[1], Nod[2], Nod[3], Nod[4], Nod[5], Nod[6], + Nod[7], *theMaterial, bk, r, perm1, perm2, perm3, b1, b2, b3); + if (theBBarBrickUP == 0) { + opserr << "WARNING ran out of memory creating element\n"; + opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + return TCL_ERROR; + } + + if (theTclDomain->addElement(theBBarBrickUP) == false) { + opserr << "WARNING could not add element to the domain\n"; + opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + delete theBBarBrickUP; + return TCL_ERROR; + } + + // if get here we have successfully created the element and added it to the + // domain + return TCL_OK; +} diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index 797a981446..8e382ef3d4 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -144,6 +144,7 @@ CheckTransformation(Domain& domain, int iNode, int jNode, CrdTransf& transform) } + template static Element* CreateFrame(BasicModelBuilder& builder, @@ -249,11 +250,11 @@ CreateFrame(BasicModelBuilder& builder, // ndm == 3 // + if (CheckTransformation(*builder.getDomain(), nodev[0], nodev[nodev.size()-1], *theTransf) != TCL_OK) + return nullptr; if (strstr(name, "Frame") != nullptr) { if (strstr(name, "Exact") == nullptr) { - if (CheckTransformation(*builder.getDomain(), nodev[0], nodev[nodev.size()-1], *theTransf) != TCL_OK) - return nullptr; std::array nodes {nodev[0], nodev[1]}; FrameTransformBuilder* tb = builder.getTypedObject(transfTag); @@ -327,6 +328,10 @@ CreateFrame(BasicModelBuilder& builder, static_loop<0, 3>([&](auto nwm) constexpr { if (nwm.value + 6 == ndf) { + // Create the transform +#if 0 || defined(NEW_TRANSFORM) + FrameTransform<2,6+nwm.value> *tran = tb->template create<2,6+nwm.value>(); +#endif if (!options.shear_flag) { static_loop<2,30>([&](auto nip) constexpr { if (nip.value == sections.size()) @@ -412,6 +417,18 @@ CreateFrame(BasicModelBuilder& builder, } +#if 0 +Element* +CreateInelasticFrame(std::string, std::vector& nodes, + std::vector&, + BeamIntegration&, + // FrameQuadrature&, + FrameTransform&, + Options&); +Element* +CreatePrismaticFrame(std::string); +#endif + // 0 1 2 3 4 // element beam 1 $i $j 0 1 2 // @@ -867,9 +884,16 @@ TclBasicBuilder_addForceBeamColumn(ClientData clientData, Tcl_Interp *interp, // Version a) else { - // If we fail to parse an integer tag, treat it like an inline definition + // If we fail to parse an integer tag for the integration, + // then we assume that the integration is specified as a + // BeamIntegration command builder->findFreeTag(itg_tag); std::string integrCommand{argv[positions[1]]}; + if (integrCommand.find(" ") == std::string::npos) { + for (int i =2; i< positions.size(); i++) { + integrCommand += " " + std::string(argv[positions[i]]); + } + } integrCommand.insert(integrCommand.find(" "), " "+std::to_string(itg_tag)+" "); integrCommand.insert(0, "beamIntegration "); if (Tcl_Eval(interp, integrCommand.c_str()) != TCL_OK) { diff --git a/SRC/runtime/commands/modeling/element/plane.cpp b/SRC/runtime/commands/modeling/element/plane.cpp new file mode 100644 index 0000000000..3e78eb1301 --- /dev/null +++ b/SRC/runtime/commands/modeling/element/plane.cpp @@ -0,0 +1,1598 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// Description: This file contains the implementation of the +// TclBasicBuilder_addFourNodeQuad() command. +// +// Written: fmk +// Created: 07/99 +// +#include +#include +#include +#include +#include +#ifdef _MSC_VER +# include +# define strcasecmp _stricmp +#else +# include +#endif +#include +#include +#include +#include +#include +#include
+#include +#include +#include +#include +#include +#include +#include +#include +#include +// +#include +#include +#include + +#include +#include + +namespace { +static +std::string toLower( const std::string & s ) +{ + std::string copy = s; + transform( copy.begin( ), copy.end( ), copy.begin( ), + [](unsigned char c) { return std::tolower(c); }); + return copy; +} + +static bool +equalsIgnoreCase(const std::string & lhs, const std::string & rhs ) +{ + return toLower(lhs) == toLower( rhs ); +} + +class CaseInsensitive +{ + public: + size_t operator( ) ( const std::string & s ) const + { + static std::hash hf; + return hf( toLower( s ) ); + } + + bool operator( ) ( const std::string & lhs, const std::string & rhs ) const + { + return equalsIgnoreCase( lhs, rhs ); + } +}; +} // namespace + +using namespace OpenSees; + +static std::unordered_map +NodeCounts = { + {"Quad", 4}, + {"FourNodeQuad", 4}, + {"quad8n", 8}, + {"EightNodeQuad", 8}, + {"FourNodeQuad3d", 4}, + {"FourNodeQuadWithSensitivity", 4}, + {"ConstantPressureVolumeQuad", 4}, + {"EnhancedQuad", 4}, + {"NineNodeQuad", 9}, + {"quad9n", 9}, + {"NineNodeMixedQuad", 9}, + {"LagrangeQuad", 4}, + {"Tri31", 3}, + {"CST", 3}, + {"T3", 3}, + {"SixNodeTri", 6} +}; + +int +TclBasicBuilder_addFourNodeQuad(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + // 10 element name eleTag? iNode? jNode? kNode? lNode? thk? type? matTag? + // 14 element name eleTag? iNode? jNode? kNode? lNode? thk? type? matTag? + // + // element name eleTag? iNode? jNode? kNode? lNode? sec? + + if (builder->getNDM() != 2 || (builder->getNDF() != 2 && builder->getNDF() != 3)) { + opserr << OpenSees::PromptValueError + << "model dimensions and/or nodal DOF not compatible with quad element\n"; + return TCL_ERROR; + } + + + int tag; + if (argc < 6) { + opserr << OpenSees::PromptValueError + << "insufficient arguments for element " << argv[1] + << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid element tag " << argv[2] + << "\n"; + return TCL_ERROR; + } + int nen = -1; + + auto it = NodeCounts.find(argv[1]); + if (it != NodeCounts.end()) + nen = it->second; + + int argi = 3; + std::vector multi_nodes; + { + int list_argc; + TCL_Char **list_argv; + if (Tcl_SplitList(interp, argv[argi], &list_argc, &list_argv) == TCL_OK && list_argc >= 2) { + for (int i = 0; i < list_argc; ++i) { + int node; + if (Tcl_GetInt(interp, list_argv[i], &node) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid node " << list_argv[i] + << "\n"; + return TCL_ERROR; + } + multi_nodes.push_back(node); + } + nen = multi_nodes.size(); + Tcl_Free((char *)list_argv); + argi += 1; + + } else { + if (nen == -1) { + opserr << OpenSees::PromptValueError + << "Nodes must be supplied in a list for element type " << argv[1] + << "\n"; + return TCL_ERROR; + } + if (argi + nen > argc) { + opserr << OpenSees::PromptValueError + << "expected " << nen << " nodes for element type " << argv[1] + << "\n"; + return TCL_ERROR; + } + for (int i=0; i tracker; + std::set positional; + + // + // Keywords + // + for (int i=argi; i* section = builder->getTypedObject>(stag); + if (section == nullptr) + return TCL_ERROR; + + thickness = section->getThickness(); + nd_mat = section->getMaterial(); + mat_tag = nd_mat->getTag(); + tracker.consume(Position::Material); + tracker.consume(Position::Type); + tracker.consume(Position::Thickness); + } + else + // continue; + positional.insert(i); + } + + // + // Positional arguments + // + for (int i : positional) { + switch (tracker.current()) { + case Position::Material: + if (Tcl_GetInt(interp, argv[i], &mat_tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid material tag " << argv[i] << "\n"; + return TCL_ERROR; + } else { + nd_mat = builder->getTypedObject(mat_tag); + if (nd_mat == nullptr) + return TCL_ERROR; + + nd_mat = nd_mat->getCopy(type); + if (nd_mat == nullptr) { + opserr << OpenSees::PromptValueError << "invalid material\n"; + return TCL_ERROR; + } + } + tracker.increment(); + break; + + case Position::Thickness: + if (Tcl_GetDouble(interp, argv[i], &thickness) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid thickness\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Position::Type: + type = argv[i]; + + if (strcmp(type,"PlaneStrain") != 0 && + strcmp(type,"PlaneStress") != 0 && + strcmp(type,"PlaneStrain2D") != 0 && + strcmp(type,"PlaneStress2D") != 0) { + opserr << OpenSees::PromptValueError + << "improper material type: " << type << "\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Position::Pressure: + if (Tcl_GetDouble(interp, argv[i], &p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid pressure\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Position::Density: + if (Tcl_GetDouble(interp, argv[i], &rho) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid density\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Position::B1: + if (Tcl_GetDouble(interp, argv[i], &b1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b1\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Position::B2: + if (Tcl_GetDouble(interp, argv[i], &b2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b2\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Position::End: + default: + opserr << OpenSees::PromptParseError << "unexpected argument " << argv[i] << "\n"; + return TCL_ERROR; + } + } + // + // Check required positional arguments + // + while (tracker.current() != Position::End) { + switch (tracker.current()) { + case Position::Thickness: + opserr << OpenSees::PromptValueError + << "missing required positional argument thickness\n"; + return TCL_ERROR; + case Position::Type: + opserr << OpenSees::PromptValueError + << "missing required positional argument type\n"; + return TCL_ERROR; + case Position::Material: + opserr << OpenSees::PromptValueError + << "missing required positional argument material\n"; + return TCL_ERROR; + default: + break; + } + tracker.increment(); + } + } + + + // + // + // + Element* theElement = nullptr; + if (nen == 3) { + if (nd_mat == nullptr) { + opserr << OpenSees::PromptValueError << "invalid material\n"; + return TCL_ERROR; + } + + std::array nodes; + for (int i=0; i<3; i++) + nodes[i] = multi_nodes[i]; + + if (strcasecmp(argv[1], "Tri31") == 0) { + theElement = + new Tri31(tag, nodes, *nd_mat, thickness, p, rho, b1, b2); + } + } + + else if (nen == 4) { + std::array nodes; + for (int i=0; i<4; i++) + nodes[i] = multi_nodes[i]; + + if (strcasecmp(argv[1], "LagrangeQuad") == 0) { + Mate<2> *mat_2d = builder->getTypedObject>(mat_tag); + if (mat_2d == nullptr) + return TCL_ERROR; + + theElement = + new LagrangeQuad<4,4>(tag, nodes, *mat_2d, + thickness, p, rho, b1, b2); + + } else { + if (nd_mat == nullptr) { + opserr << OpenSees::PromptValueError + << "invalid material" + << "\n"; + return TCL_ERROR; + } + if (strcasecmp(argv[1], "EnhancedQuad") == 0) { + theElement = + new EnhancedQuad(tag, nodes, *nd_mat, thickness); + } + else if (strcasecmp(argv[1], "bbarQuad") == 0 || + strcasecmp(argv[1], "mixedQuad") == 0) { + theElement = new ConstantPressureVolumeQuad(tag, nodes[0], nodes[1], nodes[2], nodes[3], *nd_mat, thickness); + + } + else + theElement = + new FourNodeQuad(tag, nodes, *nd_mat, thickness, p, rho, b1, b2); + } + } + + else if (nen == 8) { + std::array nodes; + for (int i=0; i<8; i++) + nodes[i] = multi_nodes[i]; + if ((strcasecmp(argv[1], "eightnodequad") == 0) || + (strcasecmp(argv[1], "quad8n") == 0) || + (strcasecmp(argv[1], "quad") == 0)) { + if (nd_mat == nullptr) { + opserr << OpenSees::PromptValueError + << "invalid material" + << "\n"; + return TCL_ERROR; + } + theElement = + new EightNodeQuad(tag, nodes, *nd_mat, thickness, p, rho, b1, b2); + } + } + else if (nen == 9) { + std::array nodes; + for (int i=0; i<9; i++) + nodes[i] = multi_nodes[i]; + if ((strcasecmp(argv[1], "ninenodequad") == 0) || + (strcasecmp(argv[1], "quad9n") == 0) || + (strcasecmp(argv[1], "quad") == 0)) { + + if (nd_mat == nullptr) { + opserr << OpenSees::PromptValueError + << "invalid material" + << "\n"; + return TCL_ERROR; + } + theElement = + new NineNodeQuad(tag, nodes, *nd_mat, thickness, p, rho, b1, b2); + } + } + + if (theElement == nullptr) { + opserr << OpenSees::PromptValueError << "failed to create element\n"; + return TCL_ERROR; + } + + // + // + // + if (builder->getDomain()->addElement(theElement) == false) { + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; + delete theElement; + return TCL_ERROR; + } + + if (type != nullptr) + delete nd_mat; + return TCL_OK; +} + + +int +TclBasicBuilder_addConstantPressureVolumeQuad(ClientData clientData, + Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + + if (builder->getNDM() != 2 || builder->getNDF() != 2) { + opserr << OpenSees::PromptValueError + << "-- model dimensions and/or nodal DOF not compatible " + "with quad element\n"; + return TCL_ERROR; + } + + int argStart = 2; + + // check the number of arguments is correct + if ((argc - argStart) < 7) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: element ConstantPressureVolumeQuad eleTag? iNode? jNode? kNode? lNode? thk? matTag?\n"; + return TCL_ERROR; + } + + // get the id and end nodes + int tag, iNode, jNode, kNode, lNode, matID; + double thickness = 1.0; + + if (Tcl_GetInt(interp, argv[argStart], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid eleTag" << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[1 + argStart], &iNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid iNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2 + argStart], &jNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid jNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3 + argStart], &kNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid kNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4 + argStart], &lNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid lNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5 + argStart], &thickness) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid thickness\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[6 + argStart], &matID) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid matID\n"; + return TCL_ERROR; + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + if (theMaterial == nullptr) + return TCL_ERROR; + + + // now create the ConstantPressureVolumeQuad and add it to the Domain + ConstantPressureVolumeQuad *theConstantPressureVolumeQuad = + new ConstantPressureVolumeQuad(tag, + iNode, jNode, kNode, lNode, *theMaterial, thickness); + + + if (builder->getDomain()->addElement(theConstantPressureVolumeQuad) == false) { + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; + delete theConstantPressureVolumeQuad; + return TCL_ERROR; + } + + return TCL_OK; +} + + +/* ***************************************************************************** + + N I N E N O D E M I X E D Q U A D + + ***************************************************************************** + */ + +int +TclBasicBuilder_addNineNodeMixedQuad(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + + if (builder->getNDM() != 2 || builder->getNDF() != 2) { + opserr << OpenSees::PromptValueError << "-- model dimensions and/or nodal DOF not compatible " + "with quad element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc - argStart) < 11) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: element NineNodeMixedQuad eleTag?" + << " iNode? jNode? kNode? lNode? mNode, nNode, pNode, qNode, centerNode matTag?\n"; + return TCL_ERROR; + } + + // get the id and end nodes + int tag, iNode, jNode, kNode, lNode; + int mNode, nNode, pNode, qNode; + int centerNode; + int matID; + + if (Tcl_GetInt(interp, argv[argStart], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid NineNodeMixedQuad eleTag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[1 + argStart], &iNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid iNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2 + argStart], &jNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid jNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3 + argStart], &kNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid kNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4 + argStart], &lNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid lNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[5 + argStart], &mNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid mNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[6 + argStart], &nNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid nNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[7 + argStart], &pNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid pNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[8 + argStart], &qNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid qNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[9 + argStart], ¢erNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid centerNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[10 + argStart], &matID) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid matID\n"; + return TCL_ERROR; + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + if (theMaterial == nullptr) + return TCL_ERROR; + + + // now create the NineNodeMixedQuad and add it to the Domain + NineNodeMixedQuad *theNineNodeMixed = new NineNodeMixedQuad( + tag, iNode, jNode, kNode, lNode, mNode, nNode, pNode, + qNode, centerNode, *theMaterial); + + if (builder->getDomain()->addElement(theNineNodeMixed) == false) { + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; + delete theNineNodeMixed; + return TCL_ERROR; + } + + return TCL_OK; +} + +int +TclBasicBuilder_addFourNodeQuadWithSensitivity(ClientData clientData, + Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + + if (builder == 0 || clientData == 0) { + opserr << OpenSees::PromptValueError << "builder has been destroyed\n"; + return TCL_ERROR; + } + + if (builder->getNDM() != 2 || builder->getNDF() != 2) { + opserr << OpenSees::PromptValueError << "-- model dimensions and/or nodal DOF not compatible " + "with quad element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc - argStart) < 8) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: element FourNodeQuad eleTag? iNode? jNode? kNode? lNode? " + "thk? type? matTag? \n"; + return TCL_ERROR; + } + + // get the id and end nodes + int tag, iNode, jNode, kNode, lNode, matID; + double thickness = 1.0; + double p = 0.0; // uniform normal traction (pressure) + double r = 0.0; // mass density + double b1 = 0.0; + double b2 = 0.0; + + if (Tcl_GetInt(interp, argv[argStart], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid element tag" << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[1 + argStart], &iNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid iNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2 + argStart], &jNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid jNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3 + argStart], &kNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid kNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4 + argStart], &lNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid lNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5 + argStart], &thickness) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid thickness\n"; + return TCL_ERROR; + } + + TCL_Char *type = argv[6 + argStart]; + + if (Tcl_GetInt(interp, argv[7 + argStart], &matID) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid matID\n"; + return TCL_ERROR; + } + + if ((argc - argStart) > 11) { + if (Tcl_GetDouble(interp, argv[8 + argStart], &p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid pressure\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[9 + argStart], &r) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid rho\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[10 + argStart], &b1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b1\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[11 + argStart], &b2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b2\n"; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + if (theMaterial == nullptr) + return TCL_ERROR; + + + // now create the FourNodeQuad and add it to the Domain + FourNodeQuadWithSensitivity *theFourNodeQuadWithSensitivity = + new FourNodeQuadWithSensitivity(tag, iNode, jNode, kNode, + lNode, *theMaterial, type, thickness, p, + r, b1, b2); + + if (builder->getDomain()->addElement(theFourNodeQuadWithSensitivity) == false) { + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; + delete theFourNodeQuadWithSensitivity; + return TCL_ERROR; + } + + return TCL_OK; +} + +// +// Description: This file contains the implementation of +// TclBasicBuilder_addFourNodeQuadUP() , +// TclBasicBuilder_addNineFourNodeQuadUP() , +// TclBasicBuilder_addBBarFourNodeQuadUP(), +// +// Zhaohui Yang and Jinchi Lu (September 2009) +// +#include +#include + +#include +#include +#include + + +/* ***************************************************************************** + + Q U A D U_P + + ***************************************************************************** + */ + +int +TclBasicBuilder_addFourNodeQuadUP(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + + if (builder->getNDM() != 2 || builder->getNDF() != 3) { + opserr << OpenSees::PromptValueError << "-- model dimensions and/or nodal DOF not compatible " + "with QuadUP element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc - argStart) < 11) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: element FourNodeQuadUP eleTag? iNode? jNode? kNode? " + "lNode? thk? matTag? bulk? rho? perm_x? perm_y? \n"; + return TCL_ERROR; + } + + // get the id and end nodes + int tag, iNode, jNode, kNode, lNode, matID; + double thickness, bk, r, perm1, perm2; + double p = 0.0; // uniform normal traction (pressure) + double b1 = 0.0; + double b2 = 0.0; + + // TCL_Char *type; + if (Tcl_GetInt(interp, argv[argStart], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid FourNodeQuadUP eleTag" << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[1 + argStart], &iNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid iNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2 + argStart], &jNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid jNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3 + argStart], &kNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid kNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4 + argStart], &lNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid lNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5 + argStart], &thickness) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid thickness\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[6 + argStart], &matID) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid matID\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[7 + argStart], &bk) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid fluid bulk modulus\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[8 + argStart], &r) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid fluid mass density\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[9 + argStart], &perm1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid lateral permeability\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10 + argStart], &perm2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid vertical permeability\n"; + return TCL_ERROR; + } + + if ((argc - argStart) >= 12) { + if (Tcl_GetDouble(interp, argv[11 + argStart], &b1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b1\n"; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 13) { + if (Tcl_GetDouble(interp, argv[12 + argStart], &b2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b2\n"; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 14) { + if (Tcl_GetDouble(interp, argv[13 + argStart], &p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid pressure\n"; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + if (theMaterial == nullptr) + return TCL_ERROR; + + + // now create the FourNodeQuadUP and add it to the Domain + FourNodeQuadUP *theFourNodeQuadUP = new FourNodeQuadUP( + tag, iNode, jNode, kNode, lNode, *theMaterial, "PlaneStrain", + thickness, bk, r, perm1, perm2, b1, b2, p); + + if (builder->getDomain()->addElement(theFourNodeQuadUP) == false) { + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; + delete theFourNodeQuadUP; + return TCL_ERROR; + } + + return TCL_OK; +} + + +/* ***************************************************************************** + + 9-4-N O D E Q U A D U_P + + ***************************************************************************** + */ + +int +TclBasicBuilder_addNineFourNodeQuadUP(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + + if (builder == 0 || clientData == 0) { + opserr << OpenSees::PromptValueError << "builder has been destroyed\n"; + return TCL_ERROR; + } + + if (builder->getNDM() != 2) { + opserr << OpenSees::PromptValueError << "-- model dimensions not compatible with 9-4-NodeQuadUP " + "element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc - argStart) < 16) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr + << "Want: element FourNodeQuadUP eleTag? Node1? ... Node9? thk? " + "matTag? bulk? rho? perm_x? perm_y? \n"; + return TCL_ERROR; + } + + // get the id and end nodes + int Ninetag, Node[9], matID; + double thickness, bk, r, perm1, perm2; + double b1 = 0.0; + double b2 = 0.0; + + if (Tcl_GetInt(interp, argv[argStart], &Ninetag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid FourNodeQuadUP eleTag" << "\n"; + return TCL_ERROR; + } + for (int i = 1; i <= 9; i++) { + if (Tcl_GetInt(interp, argv[i + argStart], &Node[i - 1]) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid Node\n"; + return TCL_ERROR; + } + } + + if (Tcl_GetDouble(interp, argv[10 + argStart], &thickness) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid thickness\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[11 + argStart], &matID) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid matID\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[12 + argStart], &bk) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid fluid bulk modulus\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[13 + argStart], &r) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid fluid mass density\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[14 + argStart], &perm1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid lateral permeability\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[15 + argStart], &perm2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid vertical permeability\n"; + return TCL_ERROR; + } + + if ((argc - argStart) >= 17) { + if (Tcl_GetDouble(interp, argv[16 + argStart], &b1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b1\n"; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 18) { + if (Tcl_GetDouble(interp, argv[17 + argStart], &b2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b2\n"; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + if (theMaterial == nullptr) + return TCL_ERROR; + + + // now create the FourNodeQuadUP and add it to the Domain + NineFourNodeQuadUP *theNineFourNodeQuadUP = new NineFourNodeQuadUP( + Ninetag, Node[0], Node[1], Node[2], Node[3], Node[4], + Node[5], Node[6], Node[7], Node[8], *theMaterial, "PlaneStrain", + thickness, bk, r, perm1, perm2, b1, b2); + if (theNineFourNodeQuadUP == 0) { + opserr << OpenSees::PromptValueError << "ran out of memory creating element\n"; + return TCL_ERROR; + } + + if (builder->getDomain()->addElement(theNineFourNodeQuadUP) == false) { + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; + delete theNineFourNodeQuadUP; + return TCL_ERROR; + } + + return TCL_OK; +} + + +/* ***************************************************************************** + + B B A R Q U A D U_P + + ***************************************************************************** + */ + +int +TclBasicBuilder_addBBarFourNodeQuadUP(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + + if (builder == 0 || clientData == 0) { + opserr << OpenSees::PromptValueError << "builder has been destroyed\n"; + return TCL_ERROR; + } + + if (builder->getNDM() != 2 || builder->getNDF() != 3) { + opserr << OpenSees::PromptValueError + << "model dimensions and/or nodal DOF not compatible " + "with QuadUP element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc - argStart) < 11) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: element bbarQuadUP eleTag? iNode? jNode? kNode? lNode? " + "thk? matTag? bulk? rho? perm_x? perm_y? \n"; + return TCL_ERROR; + } + + // get the id and end nodes + int BBartag, iNode, jNode, kNode, lNode, matID; + double thickness, bk, r, perm1, perm2; + double p = 0.0; // uniform normal traction (pressure) + double b1 = 0.0; + double b2 = 0.0; + + if (Tcl_GetInt(interp, argv[argStart], &BBartag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid BBarFourNodeQuadUP eleTag" << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[1 + argStart], &iNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid iNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2 + argStart], &jNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid jNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3 + argStart], &kNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid kNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4 + argStart], &lNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid lNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5 + argStart], &thickness) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid thickness\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[6 + argStart], &matID) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid matID\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[7 + argStart], &bk) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid fluid bulk modulus\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[8 + argStart], &r) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid fluid mass density\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[9 + argStart], &perm1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid lateral permeability\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10 + argStart], &perm2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid vertical permeability\n"; + return TCL_ERROR; + } + + if ((argc - argStart) >= 12) { + if (Tcl_GetDouble(interp, argv[11 + argStart], &b1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b1\n"; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 13) { + if (Tcl_GetDouble(interp, argv[12 + argStart], &b2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b2\n"; + return TCL_ERROR; + } + } + if ((argc - argStart) >= 14) { + if (Tcl_GetDouble(interp, argv[13 + argStart], &p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid pressure\n"; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + if (theMaterial == nullptr) + return TCL_ERROR; + + + // now create the BBarFourNodeQuadUP and add it to the Domain + BBarFourNodeQuadUP *theBBarFourNodeQuadUP = new BBarFourNodeQuadUP( + BBartag, iNode, jNode, kNode, lNode, *theMaterial, + "PlaneStrain", thickness, bk, r, perm1, perm2, b1, b2, p); + + if (theBBarFourNodeQuadUP == nullptr) { + opserr << OpenSees::PromptValueError << "ran out of memory creating element\n"; + return TCL_ERROR; + } + + if (builder->getDomain()->addElement(theBBarFourNodeQuadUP) == false) { + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; + delete theBBarFourNodeQuadUP; + return TCL_ERROR; + } + + return TCL_OK; +} + +#if 0 +int +TclDispatch_newTri31(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **const argv) +{ + BasicModelBuilder* builder = static_cast(clientData); + + if (argc < 9) { + opserr << "Invalid #args, want: " + // 0 1 2 3 4 5 6 7 8 9 10 11 12 + << "element Tri31 eleTag? iNode? jNode? kNode? thk? type? matTag? \n"; + return TCL_ERROR; + } + + int tag, matID; + std::array nodes; + char *type; + double thickness, + pressure=0, + density=0, + b1 = 0, + b2 = 0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid element tag\n"; + return TCL_ERROR; + } + for (int i=0; i<3; i++) { + if (Tcl_GetInt(interp, argv[i+3], &nodes[i]) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid node tag\n"; + return TCL_ERROR; + } + } + + if (Tcl_GetDouble(interp, argv[6], &thickness) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid element thickness\n"; + return TCL_ERROR; + } + + + type = strdup(argv[7]); + if ( strcmp(type,"PlaneStrain") != 0 + && strcmp(type,"PlaneStress") != 0 + && strcmp(type,"PlaneStrain2D") != 0 + && strcmp(type,"PlaneStress2D") != 0) { + opserr << OpenSees::PromptValueError + << "improper material type: " << type << "for Tri31" + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } + + + if (Tcl_GetInt(interp, argv[8], &matID) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid material tag\n"; + return TCL_ERROR; + } + NDMaterial *theMaterial = builder->getTypedObject(matID); + if (theMaterial == nullptr) { + return TCL_ERROR; + } + + if (argc > 9 && Tcl_GetDouble(interp, argv[ 9], &pressure) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid element pressure\n"; + return TCL_ERROR; + } + if (argc > 10 && Tcl_GetDouble(interp, argv[10], &density) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid element density\n"; + return TCL_ERROR; + } + if (argc > 11 && Tcl_GetDouble(interp, argv[11], &b1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid element load b1\n"; + return TCL_ERROR; + } + if (argc > 12 && Tcl_GetDouble(interp, argv[12], &b2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid element load b2\n"; + return TCL_ERROR; + } + + // parsing was successful, create the element + + Element *theElement = new Tri31(tag, + nodes, + *theMaterial, + type, + thickness, + pressure, + density, + b1, b2); + + if (builder->getDomain()->addElement(theElement) == false) { + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; + delete theElement; + return TCL_ERROR; + } + + free(type); + + return TCL_OK; +} + + +// Regular nine node quad + +int +TclBasicBuilder_addNineNodeQuad(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + // TODO: assertions, clean up + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + + if (builder == 0 || clientData == 0) { + opserr << OpenSees::PromptValueError << "builder has been destroyed\n"; + return TCL_ERROR; + } + + if (builder->getNDM() != 2 || builder->getNDF() != 2) { + opserr << OpenSees::PromptValueError << "-- model dimensions and/or nodal DOF not compatible " + "with quad element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc - argStart) < 13) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: element NineNodeQuad eleTag? iNode? jNode? kNode? lNode? " + "nNode? mNode? pNode? qNode? cNode? thk? type? matTag? " + "\n"; + return TCL_ERROR; + } + + // get the id and end nodes + int NineNodeQuadId; + std::array nodes{}; + int matID; + double thickness = 1.0; + double p = 0.0; // uniform normal traction (pressure) + double rho = 0.0; // mass density + double b1 = 0.0; + double b2 = 0.0; + + if (Tcl_GetInt(interp, argv[argStart], &NineNodeQuadId) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid NineNodeQuad eleTag" << "\n"; + return TCL_ERROR; + } + + for (int i=0; i<9; i++) + if (Tcl_GetInt(interp, argv[1 + argStart+i], &nodes[i]) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid node\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10 + argStart], &thickness) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid thickness\n"; + return TCL_ERROR; + } + + TCL_Char *type = argv[11 + argStart]; + + if (Tcl_GetInt(interp, argv[12 + argStart], &matID) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid matID\n"; + return TCL_ERROR; + } + + if ((argc - argStart) > 16) { + if (Tcl_GetDouble(interp, argv[13 + argStart], &p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid pressure\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[14 + argStart], &rho) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b1\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[15 + argStart], &b1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b1\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[16 + argStart], &b2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b2\n"; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + if (theMaterial == nullptr) + return TCL_ERROR; + + + // now create the NineNodeQuad and add it to the Domain + NineNodeQuad *theNineNodeQuad = new NineNodeQuad( + NineNodeQuadId, nodes, *theMaterial, type, thickness, p, rho, b1, b2); + + + if (builder->getDomain()->addElement(theNineNodeQuad) == false) { + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; + delete theNineNodeQuad; + return TCL_ERROR; + } + + return TCL_OK; +} + + +// +// Regular eight node quad +// +int +TclBasicBuilder_addEightNodeQuad(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + + if (builder->getNDM() != 2 || builder->getNDF() != 2) { + opserr << OpenSees::PromptValueError << "-- model dimensions and/or nodal DOF not compatible " + "with quad element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc - argStart) < 12) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: element EightNodeQuad eleTag? iNode? jNode? kNode? lNode? " + "nNode? mNode? pNode? qNode? thk? type? matTag? \n"; + return TCL_ERROR; + } + + // get the id and end nodes + int EightNodeQuadId; + int iNode, jNode, kNode, lNode, nNode, mNode, pNode, qNode; + int matID; + double thickness = 1.0; + double p = 0.0; // uniform normal traction (pressure) + double rho = 0.0; // mass density + double b1 = 0.0; + double b2 = 0.0; + + if (Tcl_GetInt(interp, argv[argStart], &EightNodeQuadId) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid EightNodeQuad eleTag" << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[1 + argStart], &iNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid iNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2 + argStart], &jNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid jNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3 + argStart], &kNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid kNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4 + argStart], &lNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid lNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[5 + argStart], &nNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid nNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[6 + argStart], &mNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid mNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[7 + argStart], &pNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid pNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[8 + argStart], &qNode) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid qNode\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[9 + argStart], &thickness) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid thickness\n"; + return TCL_ERROR; + } + + TCL_Char *type = argv[10 + argStart]; + + if (Tcl_GetInt(interp, argv[11 + argStart], &matID) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid matID\n"; + return TCL_ERROR; + } + + if ((argc - argStart) > 15) { + if (Tcl_GetDouble(interp, argv[12 + argStart], &p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid pressure\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[13 + argStart], &rho) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b1\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[14 + argStart], &b1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b1\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[15 + argStart], &b2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b2\n"; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + if (theMaterial == nullptr) + return TCL_ERROR; + + + // now create the EightNodeQuad and add it to the Domain + EightNodeQuad *theEightNodeQuad = new EightNodeQuad( + EightNodeQuadId, iNode, jNode, kNode, lNode, nNode, mNode, pNode, qNode, + *theMaterial, type, thickness, p, rho, b1, b2); + + if (builder->getDomain()->addElement(theEightNodeQuad) == false) { + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; + delete theEightNodeQuad; + return TCL_ERROR; + } + + return TCL_OK; +} + +#endif + + +int +TclBasicBuilder_addSixNodeTri(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + + if (builder->getNDM() != 2 || builder->getNDF() != 2) { + opserr << OpenSees::PromptValueError << "-- model dimensions and/or nodal DOF not compatible " + "with quad element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc - argStart) < 10) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: element SixNodeTri eleTag? iNode? jNode? kNode? lNode? " + "nNode? mNode? pNode? qNode? thk? type? matTag? \n"; + return TCL_ERROR; + } + + int SixNodeTriId; + std::array nodes; + int matID; + double thickness = 1.0; + double p = 0.0; // uniform normal traction (pressure) + double rho = 0.0; // mass density + double b1 = 0.0; + double b2 = 0.0; + + if (Tcl_GetInt(interp, argv[argStart], &SixNodeTriId) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid SixNodeTri eleTag" << "\n"; + return TCL_ERROR; + } + + // Nodes + for (int i=0; i<6; i++) + if (Tcl_GetInt(interp, argv[1 + argStart + i], &nodes[i]) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid node\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[7 + argStart], &thickness) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid thickness\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << "\n"; + return TCL_ERROR; + } + + TCL_Char *type = argv[8 + argStart]; + + if (Tcl_GetInt(interp, argv[9 + argStart], &matID) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid matID\n"; + return TCL_ERROR; + } + + if ((argc - argStart) > 13) { + if (Tcl_GetDouble(interp, argv[10 + argStart], &p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid pressure\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[11 + argStart], &rho) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b1\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[12 + argStart], &b1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b1\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[13 + argStart], &b2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid b2\n"; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = builder->getTypedObject(matID); + if (theMaterial == nullptr) + return TCL_ERROR; + + + // now create the SixNodeTri and add it to the Domain + SixNodeTri *theSixNodeTri = + new SixNodeTri(SixNodeTriId, nodes, + *theMaterial, type, thickness, p, rho, b1, b2); + + + if (builder->getDomain()->addElement(theSixNodeTri) == false) { + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; + delete theSixNodeTri; + return TCL_ERROR; + } + + return TCL_OK; +} diff --git a/SRC/runtime/commands/modeling/element/shells.cpp b/SRC/runtime/commands/modeling/element/shells.cpp new file mode 100644 index 0000000000..dc78dd7122 --- /dev/null +++ b/SRC/runtime/commands/modeling/element/shells.cpp @@ -0,0 +1,682 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace OpenSees; + +#include +#include + #ifdef _MSC_VER + # include + # define strcasecmp _stricmp + #else + # include + #endif + +static +std::string +toLower( const std::string & s ) +{ + std::string copy = s; + transform( copy.begin( ), copy.end( ), copy.begin( ), + [](unsigned char c) { return std::tolower(c); }); + return copy; +} + +static bool +equalsIgnoreCase( const std::string & lhs, const std::string & rhs ) +{ + return toLower( lhs ) == toLower( rhs ); +} + +class CaseInsensitive +{ + public: + size_t operator( ) ( const std::string & s ) const + { + static std::hash hf; + return hf( toLower( s ) ); + } + + bool operator( ) ( const std::string & lhs, const std::string & rhs ) const + { + return equalsIgnoreCase( lhs, rhs ); + } +}; + +using namespace OpenSees; + +static std::unordered_map +NodeCounts = { + {"ASDShellQ4", 4}, + {"ShellMITC4", 4}, + {"ShellMITC9", 9}, + {"ShellDKGQ", 4}, + {"ShellNLDKGQ", 4}, + {"ShellDKGT", 3}, + // {"ASDShellT3", 3}, // TODO + {"ShellNLDKGT", 3}, + {"ShellANDeS", 4}, + {"ShellMITC4Thermal", 4}, + {"ShellNLDKGQThermal", 4}, +}; + +int +TclBasicBuilder_addShell(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder *builder = (BasicModelBuilder*)clientData; + int tag; + if (argc < 4) { + opserr << OpenSees::PromptValueError + << "insufficient arguments for element " << argv[1] + << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid element tag " << argv[2] + << "\n"; + return TCL_ERROR; + } + + // Determine the number of nodes + int nen = -1; + auto it = NodeCounts.find(argv[1]); + if (it != NodeCounts.end()) + nen = it->second; + + int argi = 3; + // Parse node tags + std::vector multi_nodes; + { + int list_argc; + TCL_Char **list_argv; + if (Tcl_SplitList(interp, argv[argi], &list_argc, &list_argv) == TCL_OK && list_argc >= 2) { + for (int i = 0; i < list_argc; ++i) { + int node; + if (Tcl_GetInt(interp, list_argv[i], &node) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid node " << list_argv[i] + << "\n"; + return TCL_ERROR; + } + multi_nodes.push_back(node); + } + nen = multi_nodes.size(); + Tcl_Free((char *)list_argv); + argi += 1; + + } else { + if (nen == -1) { + opserr << OpenSees::PromptValueError + << "Nodes must be supplied in a list for element type " << argv[1] + << "\n"; + return TCL_ERROR; + } + if (argi + nen > argc) { + opserr << OpenSees::PromptValueError + << "expected " << nen << " nodes for element type " << argv[1] + << "\n"; + return TCL_ERROR; + } + for (int i=0; i tracker; + std::set positional; + + // + // Keywords + // + for (int i=argi; igetTypedObject(stag); + if (section == nullptr) + return TCL_ERROR; + + tracker.consume(Position::Section); + } + else if (strcmp(argv[i], "-updateBasis") == 0) { + updateBasis = true; + } + + else if ((strcasecmp(argv[i], "-corotational") == 0)) + corotational = true; + + else if (strcmp(argv[i], "-noeas") == 0) { + use_eas = false; + } + + else if (strcmp(argv[i], "-drillingStab") == 0) { + if (drill_mode != ASDShellQ4::DrillingDOF_Elastic) { + opserr << "Error: element ASDShellQ4: -drillingStab and -drillingNL options are mutually exclusive\n"; + return 0; + } + if (argc < i + 2) { + opserr << "Error: drilling stabilization parameter not provided with -drillingStab option\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i+1], &drilling_stab) != TCL_OK) { + opserr << "Error: cannot get drilling stabilization parameter with -drillingStab option\n"; + return TCL_ERROR; + } + drilling_stab = std::max(0.0, std::min(1.0, drilling_stab)); + drill_mode = ASDShellQ4::DrillingDOF_Elastic; + use_drill_stab = true; + i++; + } + else if (strcmp(argv[i], "-drillingNL") == 0) { + if (use_drill_stab) { + opserr << "Error: -drillingStab and -drillingNL options are mutually exclusive\n"; + return 0; + } + drill_mode = ASDShellQ4::DrillingDOF_NonLinear; + drilling_stab = 1.0; + } + // else if (strcmp(argv[i], "-local") == 0) { + // if (OPS_GetNumRemainingInputArgs() < 3) { + // opserr << "Error: element ASDShellQ4: not enough arguments for -local options (3 components are required)\n"; + // return 0; + // } + // for (int i = 0; i < 3; ++i) { + // double local_x_com; + // if (OPS_GetDoubleInput(&numData, &local_x_com) == 0) { + // local_x(i) = local_x_com; + // } + // else { + // opserr << "Error: element ASDShellQ4: cannot get the component " << i + 1 << " for the local X axis\n"; + // return 0; + // } + // } + // } + + else + positional.insert(i); + } + + // + // Positional arguments + // + for (int i : positional) { + switch (tracker.current()) { + case Position::Section: + if (Tcl_GetInt(interp, argv[i], &mat_tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid material tag " << argv[i] << "\n"; + return TCL_ERROR; + } else { + section = builder->getTypedObject(mat_tag); + if (section == nullptr) + return TCL_ERROR; + } + tracker.increment(); + break; + + case Position::End: + default: + opserr << OpenSees::PromptParseError << "unexpected argument " << argv[i] << "\n"; + return TCL_ERROR; + } + // + // Check required positional arguments + // + while (tracker.current() != Position::End) { + switch (tracker.current()) { + case Position::Section: + opserr << OpenSees::PromptValueError + << "missing required positional argument section\n"; + return TCL_ERROR; + default: + break; + } + tracker.increment(); + } + } + + // + // Create the element + // + Element* theElement = nullptr; + if (nen == 3) { + + std::array nodes; + for (int i=0; i<3; i++) + nodes[i] = multi_nodes[i]; + + if (strcasecmp(argv[1], "ShellDKGT") == 0) { + theElement = new ShellDKGT(tag, nodes[0], nodes[1], nodes[2], *section, b[0], b[1], b[2]); + + } else if (strcasecmp(argv[1], "ShellNLDKGT") == 0) { + theElement = new ShellNLDKGT(tag, nodes[0], nodes[1], nodes[2], *section); + + } + } + else if (nen == 4) { + std::array nodes; + for (int i=0; i<4; i++) + nodes[i] = multi_nodes[i]; + + if ((strcasecmp(argv[1], "ShellMITC4") == 0) || + (strcasecmp(argv[1], "Shell") == 0)) { + theElement = new ShellMITC4(tag, nodes[0], nodes[1], nodes[2], nodes[3], *section, updateBasis); + + } else if (strcasecmp(argv[1], "ShellDKGQ") == 0) { + theElement = new ShellDKGQ(tag, nodes[0], nodes[1], nodes[2], nodes[3], *section); + + } else if (strcasecmp(argv[1], "ShellNLDKGQ") == 0) { + theElement = new ShellNLDKGQ(tag, nodes[0], nodes[1], nodes[2], nodes[3], *section); + + } else if (strcasecmp(argv[1], "ASDShellQ4") == 0) { + + theElement = new ASDShellQ4(tag, + nodes[0], nodes[1], nodes[2], nodes[3], + section, local_x, corotational, use_eas, drill_mode, drilling_stab); + + } else if (strcasecmp(argv[1], "ShellNLDKGQThermal") == 0) { + theElement = new ShellNLDKGQThermal(tag, nodes[0], nodes[1], nodes[2], nodes[3], *section); + + } else if (strcasecmp(argv[1], "ShellMITC4Thermal") == 0) { + theElement = new ShellMITC4Thermal(tag, nodes[0], nodes[1], nodes[2], nodes[3], *section); + } + } + else if (nen == 9) { + std::array nodes; + for (int i=0; i<9; i++) + nodes[i] = multi_nodes[i]; + + if (strcasecmp(argv[1], "ShellMITC9") == 0) { + theElement = new ShellMITC9(tag, nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7], nodes[8], *section); + } + } + + if (theElement == nullptr) { + opserr << OpenSees::PromptValueError << "failed to create element\n"; + return TCL_ERROR; + } + + // + // + // + if (builder->getDomain()->addElement(theElement) == false) { + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; + delete theElement; + return TCL_ERROR; + } + + return TCL_OK; +} + + +#include +Element* +TclDispatch_newShellANDeS(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) +{ + + if (argc < 6) { + opserr << "Want: element ShellANDeS $tag $iNode $jNode $kNode $thick $E $nu $rho"; + return nullptr; + } + + int numArgs = OPS_GetNumRemainingInputArgs(); + + int iData[4]; + int numData = 4; + if (OPS_GetIntInput(&numData, iData) != 0) { + opserr << "WARNING invalid integer tag\n"; + return nullptr; + } + + double dData[11]; + numArgs = OPS_GetNumRemainingInputArgs(); + if (OPS_GetDoubleInput(&numArgs, dData) != 0) { + opserr << "WARNING invalid double thickness: element ShellANDeS \n"; + return nullptr; + } + + Element *theElement = nullptr; + + if (numArgs == 4) { + theElement = new ShellANDeS(iData[0], iData[1], iData[2], iData[3], + dData[0], dData[1], dData[2], dData[3]); + } else if (numArgs == 11) { + theElement = + new ShellANDeS(iData[0], iData[1], iData[2], iData[3], dData[0], + dData[1], dData[2], dData[3], dData[4], dData[5], + dData[6], dData[7], dData[8], dData[9], dData[10]); + } + + return theElement; +} + +#if 0 +Element* +TclDispatch_newShellDKGQ(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder* builder = (BasicModelBuilder*)clientData; + + if (argc < 6) { + opserr << "Want: element ShellDKGQ $tag $iNode $jNoe $kNode $lNode $secTag"; + return nullptr; + } + + int iData[6]; + int numData = 6; + if (OPS_GetInt(&numData, iData) != 0) { + opserr << "WARNING invalid integer tag\n"; + return nullptr; + } + + SectionForceDeformation *theSection = builder->getTypedObject(iData[5]); + if (theSection == nullptr) + return nullptr; + + return new ShellDKGQ(iData[0], iData[1], iData[2], iData[3], iData[4], *theSection); +} + +int +TclDispatch_newShellMITC4(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder* builder = (BasicModelBuilder*)clientData; + + bool updateBasis = false; + Element *theElement = nullptr; + + if (argc < 6) { + opserr << "Want: element ShellMITC4 $tag $iNode $jNode $kNode $lNode $secTag <-updateBasis>"; + return TCL_ERROR; + } + + int iData[6]; + int numData = 6; + if (OPS_GetInt(&numData, iData) != 0) { + opserr << "WARNING invalid integer tag\n"; + return TCL_ERROR; + } + + if (argc == 7) { + const char *type = OPS_GetString(); + if (strcmp(type, "-updateBasis") == 0) + updateBasis = true; + } + + SectionForceDeformation *theSection = builder->getTypedObject(iData[5]); + if (theSection == nullptr) + return TCL_ERROR; + + theElement = new ShellMITC4(iData[0], iData[1], iData[2], iData[3], iData[4], + *theSection, updateBasis); + + if (builder->getDomain()->addElement(theElement) == false) + return TCL_ERROR; + return TCL_OK; +} + + + +Element* +TclDispatch_newShellMITC9(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder* builder = (BasicModelBuilder*)clientData; + + int numArgs = OPS_GetNumRemainingInputArgs(); + + if (numArgs < 11) { + opserr << "Want: element ShellMITC9 $tag $node1 $node2 .... $node9 $secTag"; + return nullptr; + } + + int iData[11]; + int numData = 11; + if (OPS_GetInt(&numData, iData) != 0) { + opserr << "WARNING invalid integer tag\n"; + return nullptr; + } + + SectionForceDeformation *theSection = builder->getTypedObject(iData[10]); + if (theSection == nullptr) + return nullptr; + + return + new ShellMITC9(iData[0], iData[1], iData[2], iData[3], iData[4], iData[5], + iData[6], iData[7], iData[8], iData[9], *theSection); +} + + +Element* +TclDispatch_newShellNLDKGQ(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder* builder = (BasicModelBuilder*)clientData; + + int numArgs = OPS_GetNumRemainingInputArgs(); + + if (numArgs < 6) { + opserr + << "Want: element ShellNLDKGQ $tag $iNode $jNoe $kNode $lNode $secTag"; + return nullptr; + } + + int iData[6]; + int numData = 6; + if (OPS_GetInt(&numData, iData) != 0) { + opserr << "WARNING invalid integer tag\n"; + return nullptr; + } + + SectionForceDeformation *theSection = builder->getTypedObject(iData[5]); + if (theSection == nullptr) + return nullptr; + + return new ShellNLDKGQ(iData[0], iData[1], iData[2], iData[3], iData[4], + *theSection); + +} + +Element* +TclDispatch_newShellDKGT(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder* builder = (BasicModelBuilder*)clientData; + + int numArgs = OPS_GetNumRemainingInputArgs(); + + if (numArgs < 5) { + opserr << "Want: element ShellDKGT $tag $iNode $jNoe $kNode $secTag"; + return nullptr; + } + + int iData[5]; + int numData = 5; + if (OPS_GetInt(&numData, iData) != 0) { + opserr << "WARNING invalid integer tag\n"; + return nullptr; + } + + SectionForceDeformation *theSection = builder->getTypedObject(iData[4]); + if (theSection == nullptr) + return nullptr; + + + double b_data[3] = {0, 0, 0}; + + int num_remaining_args = OPS_GetNumRemainingInputArgs(); + + if (num_remaining_args > 3) { + num_remaining_args = 3; + } + if (num_remaining_args > 0) { + if (OPS_GetDoubleInput(&num_remaining_args, b_data) < 0) { + opserr << "WARNING: invalid double b_data\n"; + return nullptr; + } + } + + return new ShellDKGT(iData[0], iData[1], iData[2], iData[3], + *theSection, b_data[0], b_data[1], b_data[2]); +} + +Element* +TclDispatch_newShellMITC4Thermal(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder* builder = (BasicModelBuilder*)clientData; + + int numArgs = OPS_GetNumRemainingInputArgs(); + + if (numArgs < 6) { + opserr << "Want: element ShellMITC4Thermal $tag $iNode $jNoe $kNode $lNode " + "$secTag"; + return nullptr; + } + + int iData[6]; + int numData = 6; + if (OPS_GetInt(&numData, iData) != 0) { + opserr << "WARNING invalid integer tag\n"; + return nullptr; + } + + SectionForceDeformation *theSection = builder->getTypedObject(iData[5]); + if (theSection == nullptr) + return nullptr; + + return new ShellMITC4Thermal(iData[0], iData[1], iData[2], iData[3], iData[4], *theSection); +} + + + +Element* +TclDispatch_newShellNLDKGQThermal(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder* builder = (BasicModelBuilder*)clientData; + + int numArgs = OPS_GetNumRemainingInputArgs(); + + if (numArgs < 6) { + opserr << "Want: element ShellNLDKGQThermal $tag $iNode $jNoe $kNode " + "$lNode $secTag"; + return nullptr; + } + + int iData[6]; + int numData = 6; + if (OPS_GetInt(&numData, iData) != 0) { + opserr << "WARNING invalid integer tag\n"; + return nullptr; + } + + SectionForceDeformation *theSection = builder->getTypedObject(iData[5]); + if (theSection == nullptr) + return nullptr; + + return new ShellNLDKGQThermal(iData[0], iData[1], iData[2], iData[3], + iData[4], *theSection); + +} + + +Element* +TclDispatch_newShellNLDKGT(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder* builder = (BasicModelBuilder*)clientData; + + int numArgs = OPS_GetNumRemainingInputArgs(); + + if (numArgs < 5) { + opserr << "Want: element ShellNLDKGT $tag $iNode $jNoe $kNode $secTag"; + return nullptr; + } + + int iData[5]; + int numData = 5; + if (OPS_GetInt(&numData, iData) != 0) { + opserr << "WARNING invalid integer tag\n"; + return nullptr; + } + + SectionForceDeformation *theSection = builder->getTypedObject(iData[4]); + if (theSection == nullptr) + return nullptr; + + return + new ShellNLDKGT(iData[0], iData[1], iData[2], iData[3], *theSection); + +} +#endif diff --git a/SRC/runtime/commands/modeling/element/truss.cpp b/SRC/runtime/commands/modeling/element/truss.cpp new file mode 100644 index 0000000000..73d2cd03c8 --- /dev/null +++ b/SRC/runtime/commands/modeling/element/truss.cpp @@ -0,0 +1,407 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// +// Written: cmp +// April 2025 +// +#include +#include +#include +// OpenSees +#include +#include +#include +#include +#include +#include +#include +#include +// Elements +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# include +# define strcasecmp _stricmp +#else +# include +#endif +#define strcmp strcasecmp + +// +// element Truss $tag $iNode $jNode $A $matTag <-rho $rho> <-cMass $flag> <-doRayleigh $flag> <-useInitialDisp $flag> +// element Truss $tag $iNode $jNode $sectTag <-rho $rho> <-cMass $flag> <-doRayleigh $flag> +// element TrussSection $tag $iNode $jNode $sectTag <-rho $rho> <-cMass $flag> <-doRayleigh $flag> +// + + +template +static int +CreateTruss(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char **argv) +{ + assert(clientData != nullptr); + + // Parsing is performed in three steps: + // 1. Collect nodes + // 2. Parse out keywords + // 3. Parse remaining positional arguments. + + ArgumentTracker tracker; + std::set positional; + + + BasicModelBuilder* builder = static_cast(clientData); + + int tag; + if (argc < 3 || (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK)) { + opserr << OpenSees::PromptValueError + << "failed to read integer tag\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Tag); + + double rho = 0.0; + int doRayleigh = 0; // by default rayleigh not done + int cMass = 0; // by default use lumped mass matrix + int ndm = builder->getNDM(); + double area = 0; + UniaxialMaterial *material = nullptr; + FrameSection *section = nullptr; + + // + // 1. Parse nodes + // + int nodes[2] = {0, 0}; + int node_end = 5; + if (argc < 4 || (Tcl_GetInt(interp, argv[3], &nodes[0]) != TCL_OK)) { + opserr << OpenSees::PromptValueError + << "failed to read integer node tag\n"; + return TCL_ERROR; + } + tracker.consume(Positions::iNode); + if (argc < 5 || (Tcl_GetInt(interp, argv[4], &nodes[1]) != TCL_OK)) { + opserr << OpenSees::PromptValueError + << "failed to read integer node tag\n"; + return TCL_ERROR; + } + tracker.consume(Positions::jNode); + + // + // 2. Keywords + // + for (int i=node_end; igetTypedObject(sec); + if (section == nullptr) + return TCL_ERROR; + + tracker.consume(Positions::Section); + tracker.consume(Positions::Area); + tracker.consume(Positions::Material); + } + + else if (strcmp(argv[i], "-material") == 0) { + int mat; + if (argc == ++i || Tcl_GetInt(interp, argv[i], &mat) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read material tag\n"; + return TCL_ERROR; + } + + material = builder->getTypedObject(mat); + if (material == nullptr) + return TCL_ERROR; + tracker.consume(Positions::Material); + } + else if ((strcmp(argv[i], "-A") == 0) || + (strcmp(argv[i], "-area") == 0)) { + if (argc == ++i || Tcl_GetDouble(interp, argv[i], &area) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read area\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Area); + } + else if (strcmp(argv[i], "-cMass") == 0) { + if (argc == ++i || Tcl_GetInt(interp, argv[i], &cMass) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read mass flag\n"; + return TCL_ERROR; + } + tracker.consume(Positions::MassFlag); + } + else if (strcmp(argv[i], "-doRayleigh") == 0) { + if (argc == ++i || Tcl_GetInt(interp, argv[i], &doRayleigh) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read rayleigh flag\n"; + return TCL_ERROR; + } + tracker.consume(Positions::RayleighFlag); + } + else if (strcmp(argv[i], "-useInitialDisp") == 0) { + if (argc == ++i || Tcl_GetInt(interp, argv[i], &doRayleigh) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read initial disp flag\n"; + return TCL_ERROR; + } + tracker.consume(Positions::UseInitialDisp); + } + else { + positional.insert(i); + } + } + + // + // 3. Positional arguments + // + for (int i : positional) { + + if (tracker.current() == Positions::EndRequired) + tracker.increment(); + + switch (tracker.current()) { + case Positions::Tag: + if (Tcl_GetInt(interp, argv[i], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read integer tag\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Positions::iNode: + if (Tcl_GetInt(interp, argv[i], &nodes[0]) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read integer node tag\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + case Positions::jNode: + if (Tcl_GetInt(interp, argv[i], &nodes[1]) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read integer node tag\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Positions::Material: { + int mat; + if (Tcl_GetInt(interp, argv[i], &mat) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read integer material tag\n"; + return TCL_ERROR; + } + material = builder->getTypedObject(mat); + if (material == nullptr) { + return TCL_ERROR; + } + tracker.increment(); + break; + } + + case Positions::Density: + if (Tcl_GetDouble(interp, argv[i], &rho) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read density\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Positions::MassFlag: + if (Tcl_GetInt(interp, argv[i], &cMass) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read mass flag\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + case Positions::RayleighFlag: + if (Tcl_GetInt(interp, argv[i], &doRayleigh) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read rayleigh flag\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + case Positions::UseInitialDisp: + if (Tcl_GetInt(interp, argv[i], &doRayleigh) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read initial disp flag\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Positions::Area: + if (Tcl_GetDouble(interp, argv[i], &area) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read area\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Positions::Section: + int sec; + if (Tcl_GetInt(interp, argv[i], &sec) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read section tag\n"; + return TCL_ERROR; + } + section = builder->getTypedObject(sec); + if (section == nullptr) + return TCL_ERROR; + tracker.increment(); + break; + + case Positions::EndRequired: + // This will not be reached + break; + + case Positions::End: + opserr << OpenSees::PromptValueError + << "unexpected argument " << argv[i] << "\n"; + return TCL_ERROR; + } + } + + // + // 4. Check required positional arguments + // + if (tracker.current() < Positions::EndRequired) { + opserr << OpenSees::PromptValueError + << "missing required arguments: "; + while (tracker.current() != Positions::EndRequired) { + switch (tracker.current()) { + case Positions::Tag: + opserr << "tag "; + break; + case Positions::Material: + opserr << "material "; + break; + default: + break; + } + tracker.increment(); + } + return TCL_ERROR; + } + + // + // + // + if (section == nullptr) { + if (tracker.contains(Positions::Area)) { + opserr << OpenSees::PromptValueError + << "missing required argument area\n"; + return TCL_ERROR; + } + if (material == nullptr) { + opserr << OpenSees::PromptValueError + << "missing required argument material\n"; + return TCL_ERROR; + } + + auto fiber_section = new FrameFiberSection3d(0, 1, nullptr, true, 0.0, 0); + fiber_section->addFiber(*material, area, 0, 0); + section = fiber_section; + } + + // + // + // + if (strstr(argv[1], "Corot") != nullptr && strstr(argv[1], "2") == nullptr) { + if (ndm != 3) { + opserr << OpenSees::PromptValueError + << "CorotTruss only valid in 3D\n"; + return TCL_ERROR; + } + + builder->getDomain()->addElement(new CorotTrussSection(tag, ndm, nodes[0], nodes[1], *section, rho, cMass, doRayleigh)); + } + + else if (strstr(argv[1], "Corot") == nullptr && strstr(argv[1], "2") == nullptr) { + builder->getDomain()->addElement(new TrussSection(tag, ndm, nodes[0], nodes[1], *section, rho, cMass, doRayleigh)); + } + return TCL_OK; +} + + +int +TclCommand_addTruss(ClientData clientData, + Tcl_Interp *interp, + Tcl_Size argc, + TCL_Char ** const argv) +{ + + if (strstr(argv[1], "ection") != nullptr || + ((strcasecmp(argv[1], "Truss") == 0) && (argc == 6))) { + enum class Arguments : int { + Tag, + iNode, + jNode, + Section, + EndRequired, + End, + Density, + MassFlag, + RayleighFlag, + UseInitialDisp, + Area, + Material, + }; + return CreateTruss(clientData, interp, argc, argv); + } + else { + enum class Arguments : int { + Tag, + iNode, + jNode, + Area, + Material, + EndRequired, + End, + Density, + MassFlag, + RayleighFlag, + UseInitialDisp, + Section, + }; + return CreateTruss(clientData, interp, argc, argv); + } + +} \ No newline at end of file diff --git a/SRC/runtime/commands/modeling/geomTransf.cpp b/SRC/runtime/commands/modeling/geomTransf.cpp index d5e49fe360..f05a91fc33 100644 --- a/SRC/runtime/commands/modeling/geomTransf.cpp +++ b/SRC/runtime/commands/modeling/geomTransf.cpp @@ -1,38 +1,10 @@ //===----------------------------------------------------------------------===// // // xara -// https://xara.so // //===----------------------------------------------------------------------===// -// -// Copyright (c) 2025, Claudio M. Perez -// All rights reserved. No warranty, explicit or implicit, is provided. -// -// This source code is licensed under the BSD 2-Clause License. -// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause -// +// https://xara.so //===----------------------------------------------------------------------===// - -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - // // Description: Geometric transformation command // @@ -301,6 +273,8 @@ TclCommand_addTransformBuilder(ClientData clientData, Tcl_Interp *interp, int ar } } + transform.vz /= transform.vz.norm(); + if (builder->addTaggedObject(transform) != TCL_OK) return TCL_ERROR; @@ -351,6 +325,12 @@ TclCommand_addGeomTransf(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } CrdTransf* t = new BasicFrameTransf3d(tb->template create<2,6>()); + if (t == nullptr) { + opserr << OpenSees::PromptValueError + << "failed to create transformation with tag " << tag + << "\n"; + return TCL_ERROR; + } return builder->addTaggedObject(*t); } diff --git a/SRC/runtime/commands/modeling/invoking/invoke.cpp b/SRC/runtime/commands/modeling/invoking/invoke.cpp index 52c4bb1274..6f5a8d9b93 100644 --- a/SRC/runtime/commands/modeling/invoking/invoke.cpp +++ b/SRC/runtime/commands/modeling/invoking/invoke.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Written: cmp // Created: Spring 2023 // @@ -32,7 +33,7 @@ TclCommand_invoke(ClientData clientData, Tcl_Interp* interp, int argc, char cons { // check number of arguments in command line if (argc < 4) { - opserr << G3_ERROR_PROMPT << "bad arguments - want: using {...}"; + opserr << OpenSees::PromptValueError << "bad arguments - want: using {...}"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/modeling/invoking/invoke_material.cpp b/SRC/runtime/commands/modeling/invoking/invoke_material.cpp index 549f76df3d..5c11665daf 100644 --- a/SRC/runtime/commands/modeling/invoking/invoke_material.cpp +++ b/SRC/runtime/commands/modeling/invoking/invoke_material.cpp @@ -1,3 +1,11 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// + // ============================================================================ // 2021 By Jose Abell @ Universidad de los Andes, Chile diff --git a/SRC/runtime/commands/modeling/invoking/invoke_section.cpp b/SRC/runtime/commands/modeling/invoking/invoke_section.cpp index 80cbe9f6c2..71c690838a 100644 --- a/SRC/runtime/commands/modeling/invoking/invoke_section.cpp +++ b/SRC/runtime/commands/modeling/invoking/invoke_section.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Written: cmp // @@ -13,6 +14,7 @@ #include #include +#include #include #include #include @@ -23,10 +25,12 @@ static Tcl_CmdProc SectionTest_setStrainSection; static Tcl_CmdProc SectionTest_getStressSection; static Tcl_CmdProc SectionTest_getTangSection; static Tcl_CmdProc SectionTest_getResponseSection; +static Tcl_CmdProc SectionTest_Commit; -static int count; -static int countsTillCommit; +using namespace OpenSees; +// static int count; +// static int countsTillCommit; // invoke Section $tag $commands int @@ -39,7 +43,7 @@ TclCommand_useCrossSection(ClientData clientData, Tcl_Interp *interp, int argc, ((BasicModelBuilder*)clientData)->getTypedObject(std::atoi(argv[2])); if (theSection == nullptr) { - opserr << G3_ERROR_PROMPT << "no section found with tag '" << argv[2] << "'\n"; + opserr << OpenSees::PromptValueError << "no section found with tag '" << argv[2] << "'\n"; return TCL_ERROR; } else { // theSection = theSection->getCopy(); @@ -53,6 +57,9 @@ TclCommand_useCrossSection(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_CreateCommand(interp, "stress", SectionTest_getStressSection, (ClientData)theSection, NULL); + + Tcl_CreateCommand(interp, "commit", + SectionTest_Commit, (ClientData)theSection, NULL); Tcl_CreateCommand(interp, "tangent", SectionTest_getTangSection, (ClientData)theSection, NULL); @@ -71,6 +78,7 @@ TclCommand_useCrossSection(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_DeleteCommand(interp, "strain"); Tcl_DeleteCommand(interp, "stress"); Tcl_DeleteCommand(interp, "tangent"); + Tcl_DeleteCommand(interp, "commit"); Tcl_DeleteCommand(interp, "responseSectionTest"); return TCL_OK; @@ -85,18 +93,21 @@ SectionTest_setStrainSection(ClientData clientData, Tcl_Interp *interp, // check number of arguments in command line if (argc < 2) { - opserr << G3_ERROR_PROMPT << "bad command - want: strainSectionTest strain?\n"; + opserr << OpenSees::PromptValueError << "bad command - want: strainSectionTest strain?\n"; return TCL_ERROR; } // get the sectionID form command line // Need to set the data based on argc, otherwise it crashes when setting // "data(i-1) = strain" - static Vector data(argc - 1); + // VectorND<12> e{}; + int order = theSection->getOrder(); + Vector data(order); double strain; - for (int i = 1; i < argc; ++i) { + for (int i = 1; i < argc && i < order; ++i) { if (Tcl_GetDouble(interp, argv[i], &strain) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "could not read strain: strainSectionTest strain1? " + opserr << OpenSees::PromptValueError + << "could not read strain: strainSectionTest strain1? " "strain2? ... strainN?\n"; return TCL_ERROR; } @@ -105,12 +116,15 @@ SectionTest_setStrainSection(ClientData clientData, Tcl_Interp *interp, theSection->setTrialSectionDeformation(data); - if (count == countsTillCommit) { - theSection->commitState(); - count = 1; - } else - count++; + return TCL_OK; +} +static int +SectionTest_Commit(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + SectionForceDeformation *theSection = (SectionForceDeformation*)clientData; + const Vector &stress = theSection->commitState(); return TCL_OK; } @@ -154,13 +168,13 @@ SectionTest_getResponseSection(ClientData clientData, Tcl_Interp *interp, theSection->setResponse(argv + 1, argc - 1, dummy); if (theResponse == nullptr) { - opserr << G3_ERROR_PROMPT << "Response returned a null pointer\n"; + opserr << OpenSees::PromptValueError << "Response returned a null pointer\n"; return TCL_ERROR; } if (theResponse->getResponse() < 0) { delete theResponse; - opserr << G3_ERROR_PROMPT << "Failed to get response\n"; + opserr << OpenSees::PromptValueError << "Failed to get response\n"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/modeling/invoking/invoke_stress.cpp b/SRC/runtime/commands/modeling/invoking/invoke_stress.cpp index 51a64910b0..82dae848b5 100644 --- a/SRC/runtime/commands/modeling/invoking/invoke_stress.cpp +++ b/SRC/runtime/commands/modeling/invoking/invoke_stress.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Written: cmp // #include @@ -64,10 +65,6 @@ int TclCommand_usePlaneStress(ClientData clientData, Tcl_Interp *interp, int arg - - - - Tcl_DeleteCommand(interp, "setMaterial"); Tcl_DeleteCommand(interp, "setStrain"); Tcl_DeleteCommand(interp, "getStress"); diff --git a/SRC/runtime/commands/modeling/invoking/invoke_uniaxial.cpp b/SRC/runtime/commands/modeling/invoking/invoke_uniaxial.cpp index ba071b3724..4119addb1d 100644 --- a/SRC/runtime/commands/modeling/invoking/invoke_uniaxial.cpp +++ b/SRC/runtime/commands/modeling/invoking/invoke_uniaxial.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // // Description: This file contains the implementaion of functions // used to directly invoke methods of a UniaxialMaterial from a @@ -29,7 +30,7 @@ static Tcl_CmdProc TclCommand_getStressUniaxialMaterial; static Tcl_CmdProc TclCommand_getTangUniaxialMaterial; static Tcl_CmdProc TclCommand_integrateUniaxialMaterial; -const struct {const char*name; const Tcl_CmdProc*func;} command_table[] = { +const struct {const char*name; Tcl_CmdProc*func;} command_table[] = { {"strain", TclCommand_setStrainUniaxialMaterial }, {"commit", TclCommand_commitState }, {"stress", TclCommand_getStressUniaxialMaterial }, @@ -41,9 +42,7 @@ const struct {const char*name; const Tcl_CmdProc*func;} command_table[] = { // {"uniaxialTest", TclCommand_setUniaxialMaterial} }; -// -// THE FUNCTIONS INVOKED BY THE INTERPRETER -// + int TclCommand_useUniaxialMaterial(ClientData clientData, Tcl_Interp *interp, int argc, @@ -53,7 +52,7 @@ TclCommand_useUniaxialMaterial(ClientData clientData, // Get the tag of the material to invoke int tag; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "could not read tag"; + opserr << OpenSees::PromptValueError << "could not read tag"; return TCL_ERROR; } @@ -62,15 +61,11 @@ TclCommand_useUniaxialMaterial(ClientData clientData, // is preserved between invocations. UniaxialMaterial *theMaterial = ((BasicModelBuilder*)clientData)->getTypedObject(tag); - // UniaxialMaterial *theMaterial = - // ((BasicModelBuilder*)clientData)->getTypedObject(argv[2]); + if (theMaterial == nullptr) { - opserr << G3_ERROR_PROMPT << "no material found with tag '" << tag << "'\n"; + opserr << OpenSees::PromptValueError << "no material found with tag '" << tag << "'\n"; return TCL_ERROR; - - } else { - // theMaterial = theOrigMaterial->getCopy(); } @@ -113,15 +108,15 @@ TclCommand_setStrainUniaxialMaterial(ClientData clientData, UniaxialMaterial* theMaterial = (UniaxialMaterial*)clientData; if (argc < 2) { - opserr << G3_ERROR_PROMPT - << "bad arguments - want: strainUniaxialTest strain? \n"; + opserr << OpenSees::PromptValueError + << "missing " << 2 - argc << " arguments, want: strain strain? \n"; return TCL_ERROR; } // get the tag from command line double strain; if (Tcl_GetDouble(interp, argv[1], &strain) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "could not read strain: strainUniaxialTest strain? " + opserr << OpenSees::PromptValueError << "could not read strain: strainUniaxialTest strain? " "\n"; return TCL_ERROR; } @@ -133,7 +128,7 @@ TclCommand_setStrainUniaxialMaterial(ClientData clientData, if (strcmp(argv[i], "-commit")==0){ commit = true; } else if (Tcl_GetDouble(interp, argv[2], &temperature) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "could not read strain: strainUniaxialTest strain? " + opserr << OpenSees::PromptValueError << "could not read strain: strain strain? " "\n"; return TCL_ERROR; } @@ -295,12 +290,12 @@ TclCommand_integrateUniaxialMaterial(ClientData clientData, UniaxialMaterial* material = static_cast(clientData); if (Tcl_GetDouble(interp, argv[1], &dt) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "problem reading time step, got '" << argv[1] << "'\n"; + opserr << OpenSees::PromptValueError << "problem reading time step, got '" << argv[1] << "'\n"; return TCL_ERROR; } if (Tcl_SplitList(interp, argv[2], &n, &str_values) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "problem splitting path list " << argv[2] << "\n"; + opserr << OpenSees::PromptValueError << "problem splitting path list " << argv[2] << "\n"; return TCL_ERROR; } @@ -308,42 +303,42 @@ TclCommand_integrateUniaxialMaterial(ClientData clientData, while (argi < argc) { if (strcmp(argv[argi], "-alphaf") == 0) { if (Tcl_GetDouble(interp, argv[1+argi], &conf.alpha_f) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "problem reading " << argv[argi] << ", got '" << argv[argi+1] << "'\n"; + opserr << OpenSees::PromptValueError << "problem reading " << argv[argi] << ", got '" << argv[argi+1] << "'\n"; return TCL_ERROR; } argi += 2; } else if (strcmp(argv[argi], "-alpham") == 0) { if (Tcl_GetDouble(interp, argv[1+argi], &conf.alpha_m) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "problem reading " << argv[argi] << ", got '" << argv[argi+1] << "'\n"; + opserr << OpenSees::PromptValueError << "problem reading " << argv[argi] << ", got '" << argv[argi+1] << "'\n"; return TCL_ERROR; } argi += 2; } else if (strcmp(argv[argi], "-beta") == 0) { if (Tcl_GetDouble(interp, argv[1+argi], &conf.beta) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "problem reading " << argv[argi] << ", got '" << argv[argi+1] << "'\n"; + opserr << OpenSees::PromptValueError << "problem reading " << argv[argi] << ", got '" << argv[argi+1] << "'\n"; return TCL_ERROR; } argi += 2; } else if (strcmp(argv[argi], "-gamma") == 0) { if (Tcl_GetDouble(interp, argv[1+argi], &conf.gamma) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "problem reading " << argv[argi] << ", got '" << argv[argi+1] << "'\n"; + opserr << OpenSees::PromptValueError << "problem reading " << argv[argi] << ", got '" << argv[argi+1] << "'\n"; return TCL_ERROR; } argi += 2; } else if (strcmp(argv[argi], "-mass") == 0) { if (Tcl_GetDouble(interp, argv[1+argi], &M) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "problem reading " << argv[argi] << ", got '" << argv[argi+1] << "'\n"; + opserr << OpenSees::PromptValueError << "problem reading " << argv[argi] << ", got '" << argv[argi+1] << "'\n"; return TCL_ERROR; } argi += 2; } else if (strcmp(argv[argi], "-damp") == 0) { if (Tcl_GetDouble(interp, argv[1+argi], &C) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "problem reading " << argv[argi] << ", got '" << argv[argi+1] << "'\n"; + opserr << OpenSees::PromptValueError << "problem reading " << argv[argi] << ", got '" << argv[argi+1] << "'\n"; return TCL_ERROR; } argi += 2; diff --git a/SRC/runtime/commands/modeling/material/CMakeLists.txt b/SRC/runtime/commands/modeling/material/CMakeLists.txt new file mode 100644 index 0000000000..c40f25a68e --- /dev/null +++ b/SRC/runtime/commands/modeling/material/CMakeLists.txt @@ -0,0 +1,16 @@ + + +target_sources(OPS_Runtime PRIVATE + material.cpp + nDMaterial.cpp + + shell.cpp + fedeas.cpp + legacy.cpp + wrapper.cpp + plastic.cpp + elastic.cpp + concrete.cpp + isotropy.cpp + boucwen.cpp +) \ No newline at end of file diff --git a/SRC/runtime/commands/modeling/material/boucwen.cpp b/SRC/runtime/commands/modeling/material/boucwen.cpp new file mode 100644 index 0000000000..16f2181106 --- /dev/null +++ b/SRC/runtime/commands/modeling/material/boucwen.cpp @@ -0,0 +1,640 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// +// Written: cmp +// +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# define strcasecmp _stricmp +#else +# include +#endif +#define strcmp strcasecmp + +#include +#include +#include +#include + +template +static int +ParseBoucWen(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + + BasicModelBuilder *builder = static_cast(clientData); + + ArgumentTracker tracker; + std::set positional; + + int tag; + double E, Fy, alpha; + double beta = 0.5, gamma=0.5; + double Ao=1, + delta_a = 0, + delta_n = 0, + delta_v = 0; + + double pinch_slope = 0.0; + double pinch_slip = 0.0; + double pinch_start = 0.0; + double pinch_rate = 0.0; + double pinch_size = 0.0; + double pinch_lamda = 0.5; + + int iterations = 25; + double tolerance = 1e-8; + double n = 1.0; + + // BoucWenOriginal-only + double mu = 2.0, alphaNL = 0.0; + + // + // Begin parse + // + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid uniaxialMaterial tag\n"; + return TCL_ERROR; + } + + for (int i=2; i= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Fy) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Fy); + } + else if ((strcasecmp(argv[i], "-E") == 0) || (strcmp(argv[i], "-ko") == 0)) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &E) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::E); + } + else if (strcasecmp(argv[i], "-alpha") == 0 || strcasecmp(argv[i], "-b") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &alpha) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Alpha); + } + else if (strcasecmp(argv[i], "-n") == 0 || strcasecmp(argv[i], "-N") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &n) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::N); + } + + else if (strcmp(argv[i], "-beta") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &beta) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Beta); + } + else if (strcmp(argv[i], "-gamma") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &gamma) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Gamma); + } + // + // Damage + // + else if (strcmp(argv[i], "-Ao") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Ao) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Ao); + } + else if (strcmp(argv[i], "-delta_a") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &delta_a) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::DeltaA); + } + else if (strcmp(argv[i], "-delta_n") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &delta_n) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::DeltaN); + } + else if (strcmp(argv[i], "-delta_v") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &delta_v) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::DeltaV); + } + // + // Pinching + // + else if (strcmp(argv[i], "-pinch_slope") == 0 || strcmp(argv[i], "-p") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &pinch_slope) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::PinchSlope); + } + else if (strcmp(argv[i], "-pinch_start") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &pinch_start) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::PinchStart); + } + else if (strcmp(argv[i], "-pinch_rate") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &pinch_rate) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::PinchRate); + } + else if (strcmp(argv[i], "-pinch_slip") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &pinch_slip) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::PinchSlip); + } + else if (strcmp(argv[i], "-pinch_size") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &pinch_size) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::PinchSize); + } + else if (strcmp(argv[i], "-pinch_lamda") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &pinch_lamda) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::PinchLamda); + } + // + // Numerics + // + else if (strcmp(argv[i], "-tolerance") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &tolerance) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Tolerance); + } + else if (strcmp(argv[i], "-iterations") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[i], &iterations) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Iterations); + } + else + positional.insert(i); + } + + + for (int i: positional) { + if (tracker.current() == Positions::EndRequired) + tracker.increment(); + + switch (tracker.current()) { + case Positions::Tag : + if (Tcl_GetInt(interp, argv[i], &tag) != TCL_OK) { + opserr << "Invalid tag " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Tag); + break; + + case Positions::Fy: + if (Tcl_GetDouble(interp, argv[i], &Fy) != TCL_OK) { + opserr << "Invalid value for Fy " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Fy); + break; + case Positions::E: + if (Tcl_GetDouble(interp, argv[i], &E) != TCL_OK) { + opserr << "Invalid value for E " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::E); + break; + case Positions::Alpha: + if (Tcl_GetDouble(interp, argv[i], &alpha) != TCL_OK) { + opserr << "Invalid value for Alpha " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Alpha); + break; + case Positions::N: + if (Tcl_GetDouble(interp, argv[i], &n) != TCL_OK) { + opserr << "Invalid value for N " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::N); + break; + case Positions::Beta: + if (Tcl_GetDouble(interp, argv[i], &beta) != TCL_OK) { + opserr << "Invalid value for beta " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Beta); + break; + case Positions::Gamma: + if (Tcl_GetDouble(interp, argv[i], &gamma) != TCL_OK) { + opserr << "Invalid value for gamma " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Gamma); + break; + case Positions::Tolerance: + if (Tcl_GetDouble(interp, argv[i], &tolerance) != TCL_OK) { + opserr << "Invalid value for tolerance " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Tolerance); + break; + case Positions::Iterations: + if (Tcl_GetInt(interp, argv[i], &iterations) != TCL_OK) { + opserr << "Invalid value for iterations " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Iterations); + break; + // + // Degradation + // + case Positions::Ao: + if (Tcl_GetDouble(interp, argv[i], &Ao) != TCL_OK) { + opserr << "Invalid value for Ao " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Ao); + break; + case Positions::DeltaA: + if (Tcl_GetDouble(interp, argv[i], &delta_a) != TCL_OK) { + opserr << "Invalid value for delta_a " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::DeltaA); + break; + case Positions::DeltaN: + if (Tcl_GetDouble(interp, argv[i], &delta_n) != TCL_OK) { + opserr << "Invalid value for delta_n " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::DeltaN); + break; + case Positions::DeltaV: + if (Tcl_GetDouble(interp, argv[i], &delta_v) != TCL_OK) { + opserr << "Invalid value for delta_v " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::DeltaV); + break; + // + // Schellenberg extras + // + case Positions::AlphaNL: + if (Tcl_GetDouble(interp, argv[i], &alphaNL) != TCL_OK) { + opserr << "Invalid value for alphaNL " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::AlphaNL); + break; + case Positions::Mu: + if (Tcl_GetDouble(interp, argv[i], &mu) != TCL_OK) { + opserr << "Invalid value for mu " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Mu); + break; + + case Positions::PinchRate: + case Positions::PinchSlip: + case Positions::PinchSize: + case Positions::PinchSlope: + case Positions::PinchStart: + case Positions::PinchLamda: + break; + // + // + case Positions::EndRequired: + // This will not be reached + break; + + case Positions::End: + opserr << "Invalid value for option " << argv[i] << "\n"; + return TCL_ERROR; + } + } + + if (tracker.current() < Positions::EndRequired) { + opserr << "Missing required arguments: "; + while (tracker.current() != Positions::End) { + switch (tracker.current()) { + case Positions::Fy: + opserr << "Fy "; + break; + case Positions::E: + opserr << "E "; + break; + case Positions::Alpha: + opserr << "Alpha "; + break; + case Positions::N: + opserr << "N "; + break; + case Positions::Beta: + opserr << "Beta "; + break; + case Positions::Gamma: + opserr << "Gamma "; + break; + case Positions::Ao: + opserr << "Ao "; + break; + case Positions::DeltaA: + opserr << "delta_a "; + break; + case Positions::DeltaV: + opserr << "delta_v "; + break; + case Positions::DeltaN: + opserr << "delta_n "; + break; + + case Positions::Tolerance: + opserr << "tolerance "; + break; + case Positions::Iterations: + opserr << "iterations "; + break; + + case Positions::PinchSlope: + opserr << "PinchSlope "; + break; + case Positions::PinchStart: + opserr << "PinchStart "; + break; + case Positions::PinchRate: + opserr << "PinchRate "; + break; + case Positions::PinchSize: + opserr << "PinchSize "; + break; + + case Positions::Mu: + case Positions::AlphaNL: + case Positions::EndRequired: + case Positions::End: + default: + break; + } + + if (tracker.current() == Positions::EndRequired) + break; + + tracker.consume(tracker.current()); + } + opserr << "\n"; + return TCL_ERROR; + } + + // + // + // + + // + // + // + UniaxialMaterial *theMaterial = nullptr; + if ((strcmp(argv[1], "BWBF") == 0) || + (strcmp(argv[1], "Bouc") == 0)) { + + theMaterial = + new BWBF(tag, + E, + Fy, + alpha, + n, + beta, + delta_a, delta_v, delta_n, + // + pinch_slope, + pinch_slip, + pinch_start, + pinch_rate, + pinch_size, + pinch_lamda, + // + tolerance, + iterations); + } + else if ((strcmp(argv[1], "BoucWen") == 0)) { + + theMaterial = + new BoucWenMaterial(tag, alpha, E, n, gamma, beta, Ao, + delta_a, delta_v, delta_n, + tolerance, iterations); + } + else if (strcmp(argv[1], "BoucWenOriginal") == 0) { + theMaterial = + new BoucWenOriginal(tag, E, Fy, alpha, alphaNL, mu, + n, beta, gamma, + tolerance, iterations); + } + else if (strcmp(argv[1], "BWBN") == 0) { + theMaterial = + new BWBN(tag, alpha, E, n, gamma, beta, Ao, + pinch_start, pinch_slip, pinch_slope, + pinch_size, pinch_rate, pinch_lamda, + tolerance, iterations); + } + else { + opserr << "WARNING BoucWen: invalid material type\n"; + return TCL_ERROR; + } + + if (theMaterial == nullptr) + return TCL_ERROR; + + return builder->addTaggedObject(*theMaterial); +} + + +int +TclCommand_newBoucWen(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + + if (strcmp(argv[1], "BWBF") == 0 || + strcmp(argv[1], "Bouc") == 0) { + + enum class Positions: int { + Tag, + E, Fy, Alpha, N, + EndRequired, + Beta, + Tolerance, Iterations, + Ao, DeltaA, DeltaV, DeltaN, + PinchSlope, PinchStart, PinchRate, PinchSize, PinchSlip, PinchLamda, + EndAllowed, + Mu, AlphaNL, + Gamma, + End + }; + + return ParseBoucWen(clientData, interp, argc, argv); + } + + else if ((strcmp(argv[1], "BoucWen") == 0)) { + + enum class Positions: int { + Tag, + Alpha, E, N, Gamma, Beta, Ao, DeltaA, DeltaV, DeltaN, + EndRequired, + EndAllowed, + Fy, + Tolerance, Iterations, + PinchSlope, PinchStart, PinchRate, PinchSize, PinchSlip, PinchLamda, + Mu, AlphaNL, + End + }; + return ParseBoucWen(clientData, interp, argc, argv); + } + + else if ((strcmp(argv[1], "BWBN") == 0)) { + + enum class Positions: int { + Tag, + Alpha, E, N, Gamma, Beta, Ao, + PinchStart, PinchSlip, PinchSlope, PinchSize, PinchRate, PinchLamda, + EndRequired, + EndAllowed, + Fy, + Tolerance, Iterations, + DeltaA, DeltaV, DeltaN, + Mu, AlphaNL, + End + }; + return ParseBoucWen(clientData, interp, argc, argv); + } + + else if (strcmp(argv[1], "BoucWenOriginal") == 0) { + // A. Schellenberg + enum class Positions: int { + Tag, + E, Fy, Alpha, + EndRequired, + AlphaNL, + Mu, + N, Beta, Gamma, + Tolerance, Iterations, + End, + Ao, DeltaA, DeltaV, DeltaN, + PinchSlope, PinchStart, PinchRate, PinchSize, PinchSlip, PinchLamda, + }; + return ParseBoucWen(clientData, interp, argc, argv); + } + + return TCL_ERROR; +} diff --git a/SRC/runtime/commands/modeling/material/concrete.cpp b/SRC/runtime/commands/modeling/material/concrete.cpp new file mode 100644 index 0000000000..4a347f6642 --- /dev/null +++ b/SRC/runtime/commands/modeling/material/concrete.cpp @@ -0,0 +1,408 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// +// Written: cmp +// April 2025 +// +#include +#include +#include +#ifdef _MSC_VER +# include +# define strcasecmp _stricmp +#else +# include +#endif +#include +#include +#include +#include +#include "isotropy.h" + +#include + +int +TclCommand_newConcreteMaterial(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + + assert(clientData != nullptr); + enum class Position { + Tag, E, Nu, PeakTension, PeakCompression, EndRequired, + Beta, Ap, An, Bn, + Density, + G, K, Lambda, + End, + }; + ArgumentTracker tracker; + std::set positional; + + + // Count the number of required isotropic parameters. + // This is needed to accommodate uniaxial materials, which generally + // only require one isotropic parameter (ie, E). + int niso = ( + (Position::E < Position::EndRequired) + + (Position::G < Position::EndRequired) + + (Position::Nu < Position::EndRequired) + + (Position::K < Position::EndRequired) + + (Position::Lambda < Position::EndRequired) + ); + + // + // Values we're parsing for + // + int tag; + double density = 0.0; + // Isotropy + IsotropicConstants consts {}; + // Plasticity + double Fc, Ft=0; + // Hardening + double beta = 0.6; + double Ap = 0.5, + An = 2.0, + Bn = 0.75; + + + // + // 1. Keyword arguments + // + + // Isotropy + IsotropicParse iso {consts, niso}; + if (TclCommand_setIsotropicParameters((ClientData)&iso, interp, argc, argv) == TCL_OK) { + tracker.consume(Position::E); + tracker.consume(Position::G); + tracker.consume(Position::Nu); + tracker.consume(Position::K); + tracker.consume(Position::Lambda); + } + + // Other arguments + for (int i=2; i= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &density) != TCL_OK) { + opserr << "Invalid density value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + } + + // Compression + else if (strcmp(argv[i], "-Fc") == 0 || + strcmp(argv[i], "-fc") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Fc) != TCL_OK) { + opserr << "Invalid " << &argv[i-1][1] << " value " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::PeakCompression); + } + // Tension + else if ((strcmp(argv[i], "-Ft") == 0)) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Ft) != TCL_OK) { + opserr << "Invalid " << &argv[i-1][1] << " value " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::PeakTension); + } + // + // Hardening + // + else if (strcmp(argv[i], "-beta") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &beta) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Beta); + } + // + // + else if (strcmp(argv[i], "-Ap") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Ap) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Ap); + } + else if (strcmp(argv[i], "-An") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &An) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::An); + } + else if (strcmp(argv[i], "-Bn") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Bn) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Bn); + } + else + positional.insert(i); + } + + // + // 2) Positional arguments + // + for (int i : positional) { + + if (tracker.current() == Position::EndRequired) + tracker.increment(); + + switch (tracker.current()) { + // General + case Position::Tag : + if (Tcl_GetInt(interp, argv[i], &tag) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid section Elastic tag.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::Density: + if (Tcl_GetDouble (interp, argv[i], &density) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid density.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + // Isotropy + case Position::E: + if (Tcl_GetDouble (interp, argv[i], &consts.E) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid E.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::G: + if (Tcl_GetDouble (interp, argv[i], &consts.G) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid G.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::K: + if (Tcl_GetDouble (interp, argv[i], &consts.K) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid K.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::Nu: + if (Tcl_GetDouble (interp, argv[i], &consts.nu) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid nu.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::Lambda: + if (Tcl_GetDouble (interp, argv[i], &consts.lambda) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Lame lambda.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + // Yielding + case Position::PeakCompression: + if (Tcl_GetDouble(interp, argv[i], &Fc) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Fc.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::PeakTension: + if (Tcl_GetDouble (interp, argv[i], &Ft) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Ft.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::Beta: + if (Tcl_GetDouble (interp, argv[i], &beta) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid beta.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::Ap: + if (Tcl_GetDouble (interp, argv[i], &Ap) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Ap.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::An: + if (Tcl_GetDouble (interp, argv[i], &An) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid An.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::Bn: + if (Tcl_GetDouble (interp, argv[i], &Bn) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Bn.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + + case Position::EndRequired: + // This will not be reached + break; + + case Position::End: + opserr << OpenSees::PromptParseError << "unexpected argument " << argv[i] << ".\n"; + return TCL_ERROR; + } + } + + + // + // 3. Check for required arguments + // + if (tracker.current() < Position::EndRequired) { + opserr << OpenSees::PromptParseError + << "missing required arguments: "; + while (tracker.current() != Position::EndRequired) { + switch (tracker.current()) { + case Position::Tag : + opserr << "tag "; + break; + // Isotropy + case Position::E: + opserr << "E "; + break; + case Position::G: + opserr << "G "; + break; + case Position::K: + opserr << "K "; + break; + case Position::Nu: + opserr << "nu "; + break; + case Position::Lambda: + opserr << "lambda "; + break; + // Yielding + case Position::PeakCompression: + opserr << "Fc "; + break; + case Position::PeakTension: + opserr << "Ft "; + break; + case Position::Ap: + opserr << "Ap "; + break; + // Hardening + case Position::An: + opserr << "An "; + break; + case Position::Bn: + opserr << "Bn "; + break; + case Position::Beta: + opserr << "beta "; + break; + + case Position::EndRequired: + case Position::End: + default: + break; + } + + if (tracker.current() == Position::EndRequired) + break; + + tracker.consume(tracker.current()); + } + + opserr << "\n"; + + return TCL_ERROR; + } + + // + // Create the material (TODO) + // + BasicModelBuilder *builder = static_cast(clientData); + if ((strcmp(argv[1], "PlasticDamageConcrete3d") == 0) || + (strcasecmp(argv[1], "PlasticDamageConcrete") == 0) || + (strcmp(argv[1], "FariaPlasticDamage") == 0)) { + + NDMaterial* theMaterial = new FariaPlasticDamage3d(tag, consts.E, consts.nu, Ft, Fc, + beta, Ap, An, Bn, density); + if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { + delete theMaterial; + return TCL_ERROR; + } + return TCL_OK; + } + + return TCL_ERROR; +} diff --git a/SRC/runtime/commands/modeling/material/elastic.cpp b/SRC/runtime/commands/modeling/material/elastic.cpp new file mode 100644 index 0000000000..b0c71a3abb --- /dev/null +++ b/SRC/runtime/commands/modeling/material/elastic.cpp @@ -0,0 +1,598 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// cmp +// +#include +#include +#include + +#include +#include +#include "BasicModelBuilder.h" +#include "Logging.h" +#include "Parsing.h" +#include "ArgumentTracker.h" +#include "isotropy.h" + +#include +#include +#include +#include + +#include +#include "ElasticIsotropicPlaneStress2D.h" +#include "ElasticIsotropicPlaneStrain2D.h" +#include +#include +#include +#include +#include +#include +#include +#include + +// #include +#include +#include + + + +template +int +TclCommand_newElasticParser(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + assert(clientData != nullptr); + + ArgumentTracker tracker; + std::set positional; + + int niso = ( + (Position::E < Position::EndRequired) + + (Position::G < Position::EndRequired) + + (Position::Nu < Position::EndRequired) + + (Position::K < Position::EndRequired) + + (Position::Lambda < Position::EndRequired) + ); + + int tag; + double density = 0.0; + // Isotropy + IsotropicConstants consts {}; + // Viscosity + double eta=0; + + + // Isotropy + IsotropicParse iso {consts, niso}; + if (TclCommand_setIsotropicParameters((ClientData)&iso, interp, argc, argv) == TCL_OK) { + tracker.consume(Position::E); + tracker.consume(Position::G); + tracker.consume(Position::Nu); + tracker.consume(Position::K); + tracker.consume(Position::Lambda); + } + + // + // Keywords + // + for (int i=2; i= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &density) != TCL_OK) { + opserr << "Invalid density value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + } + else + positional.insert(i); + } + + // + // Positional arguments + // + for (int i : positional) { + + if (tracker.current() == Position::EndRequired) + tracker.increment(); + + switch (tracker.current()) { + case Position::Tag : + if (Tcl_GetInt(interp, argv[i], &tag) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid section Elastic tag.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::E: + if (Tcl_GetDouble (interp, argv[i], &consts.E) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid E.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::G: + if (Tcl_GetDouble (interp, argv[i], &consts.G) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid G.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::K: + if (Tcl_GetDouble (interp, argv[i], &consts.K) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid K.\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Position::Nu: + if (Tcl_GetDouble (interp, argv[i], &consts.nu) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid nu.\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Position::Lambda: + if (Tcl_GetDouble (interp, argv[i], &consts.lambda) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Lame lambda.\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Position::Eta: + if (Tcl_GetDouble (interp, argv[i], &eta) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid eta.\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Position::Density: + if (Tcl_GetDouble (interp, argv[i], &density) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid density.\n"; + return TCL_ERROR; + } + tracker.increment(); + break; + + case Position::EndRequired: + // This will not be reached + break; + + case Position::End: + opserr << OpenSees::PromptParseError << "unexpected argument " << argv[i] << ".\n"; + return TCL_ERROR; + } + } + + if (tracker.current() < Position::EndRequired) { + opserr << OpenSees::PromptParseError + << "missing required arguments: "; + + while (tracker.current() != Position::EndRequired) { + switch (tracker.current()) { + case Position::Tag : + opserr << "tag "; + break; + case Position::E: + opserr << "E "; + break; + case Position::G: + opserr << "G "; + break; + case Position::K: + opserr << "K "; + break; + case Position::Nu: + opserr << "nu "; + break; + case Position::Lambda: + opserr << "lambda "; + break; + + case Position::EndRequired: + case Position::End: + default: + break; + } + + if (tracker.current() == Position::EndRequired) + break; + + tracker.consume(tracker.current()); + } + + opserr << "\n"; + + return TCL_ERROR; + } + + // + // Create the material + // + BasicModelBuilder *builder = static_cast(clientData); + + if ((strcmp(argv[1], "ElasticIsotropic") == 0) || + (strcmp(argv[1], "Elastic") == 0)) { + double E = consts.E; + double nu = consts.nu; + if (builder->addTaggedObject(*new ElasticIsotropicMaterial(tag, E, nu, density)) != TCL_OK ) { + return TCL_ERROR; + } + if (strcmp(argv[0], "material") == 0) { + if (builder->addTaggedObject(*new ElasticMaterial(tag, E, eta, E, density)) != TCL_OK ) { + return TCL_ERROR; + } + if (builder->addTaggedObject>(*new ElasticIsotropic<3>(tag, E, nu, density)) != TCL_OK ) { + return TCL_ERROR; + } + } + return TCL_OK; + } + else if (strcmp(argv[1], "ElasticIsotropic3D") == 0) { + double E = consts.E; + double nu = consts.nu; + if (builder->addTaggedObject(*new ElasticIsotropicThreeDimensional(tag, E, nu, density)) != TCL_OK ) { + return TCL_ERROR; + } + return TCL_OK; + } + + return TCL_ERROR; +} + +int +TclCommand_newElasticMaterial(ClientData clientData, Tcl_Interp *interp, + Tcl_Size argc, TCL_Char ** const argv) +{ + // + if (strcmp(argv[1], "ElasticIsotropic") == 0 || + strcmp(argv[1], "Elastic") == 0 || + strcmp(argv[1], "PlaneStressSimplifiedJ2") == 0) { + + // "ElasticIsotropic" tag? E? nu? rho? + enum class Position : int { + Tag, E, Nu, EndRequired, + Density, End, + G, K, Lambda, Eta + }; + return TclCommand_newElasticParser(clientData, interp, argc, argv); + } + + return TCL_ERROR; +} + +int +TclCommand_newElasticUniaxialMaterial(ClientData clientData, Tcl_Interp *interp, + Tcl_Size argc, TCL_Char ** const argv) +{ + enum class Position : int { + Tag, Epos, EndRequired, + Eta, Eneg, Density, End + }; + + ArgumentTracker tracker; + std::set positional; + + int tag; + double Epos = 0.0; + double Eneg = 0.0; + double density = 0.0; + double eta = 0.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptParseError + << "invalid tag." + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } + tracker.consume(Position::Tag); + + for (int i=3; i= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Epos) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Epos); + if (!tracker.contains(Position::Eneg)) { + Eneg = Epos; // Default to Epos if Eneg is not specified + } + } + else if (strcmp(argv[i], "-Eneg") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Eneg) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Eneg); + } + else if (strcmp(argv[i], "-rho") == 0 || strcmp(argv[i], "-density") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &density) != TCL_OK) { + opserr << "Invalid density value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Density); + } + else if (strcmp(argv[i], "-eta") == 0 || strcmp(argv[i], "-viscosity") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &eta) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Eta); + } + else + positional.insert(i); + } + + for (int i : positional) { + if (tracker.current() == Position::EndRequired) + tracker.increment(); + + switch (tracker.current()) { + case Position::Tag : + if (Tcl_GetInt(interp, argv[i], &tag) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid tag.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::Epos: + if (Tcl_GetDouble (interp, argv[i], &Epos) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Epos.\n"; + return TCL_ERROR; + } else { + Eneg = Epos; + tracker.increment(); + break; + } + case Position::Eneg: + if (Tcl_GetDouble (interp, argv[i], &Eneg) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Eneg.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::Density: + if (Tcl_GetDouble (interp, argv[i], &density) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid density.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::Eta: + if (Tcl_GetDouble (interp, argv[i], &eta) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid eta.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::EndRequired: + case Position::End: + opserr << OpenSees::PromptParseError + << "unexpected argument " << argv[i] << ".\n"; + return TCL_ERROR; + } + } + + + if (tracker.current() < Position::EndRequired) { + opserr << OpenSees::PromptParseError + << "missing required arguments: "; + + while (tracker.current() != Position::EndRequired) { + switch (tracker.current()) { + case Position::Tag : + opserr << "tag "; + break; + case Position::Epos: + opserr << "Epos "; + break; + case Position::Eneg: + opserr << "Eneg "; + break; + case Position::Density: + opserr << "density "; + break; + case Position::Eta: + opserr << "eta "; + break; + + case Position::EndRequired: + case Position::End: + default: + break; + } + + if (tracker.current() == Position::EndRequired) + break; + + tracker.consume(tracker.current()); + } + + opserr << "\n"; + + return TCL_ERROR; + } + + BasicModelBuilder *builder = static_cast(clientData); + if (strcmp(argv[1], "Elastic") == 0) { + if (builder->addTaggedObject(*new ElasticMaterial(tag, Epos, eta, Eneg, density)) != TCL_OK ) { + return TCL_ERROR; + } + return TCL_OK; + } + + return TCL_ERROR; +} + + +enum class MaterialSymmetry { + Triclinic , // 21 + Monoclinic , // 13 + Orthorhombic , // 9 + Tetragonal , // 7 +//Tetragonal , // 6 + Rhombohedral , // 7 +//Rhombohedral , // 6 + Hexagonal , // 5 + Cubic , // 3 + Isotropic // 2 +}; + + +#if 0 +int +TclCommand_newElasticAnisotropic(ClientData clientData, Tcl_Interp* interp, int argc, const char**const argv) +{ + BasicModelBuilder* builder = static_cast(clientData); + +//MaterialSymmetry symm = MaterialSymmetry::Isotropic; +//PlaneType type = PlaneType::None; + + if ((strcmp(argv[1], "ElasticIsotropic") == 0) || + (strcmp(argv[1], "Elastic") == 0) || + (strcmp(argv[1], "ElasticBeamFiber") == 0) || + (strcmp(argv[1], "ElasticIsotropic3D") == 0)) + { + + int tag; + double E, v; + double rho = 0.0; + + int loc = 2; + if (Tcl_GetInt(interp, argv[loc], &tag) != TCL_OK) { + opserr << "WARNING invalid ElasticIsotropic tag" << "\n"; + return TCL_ERROR; + } + loc++; + + if (Tcl_GetDouble(interp, argv[loc], &E) != TCL_OK) { + opserr << "WARNING invalid E\n"; + return TCL_ERROR; + } + loc++; + + if (Tcl_GetDouble(interp, argv[loc], &v) != TCL_OK) { + opserr << "WARNING invalid v\n"; + return TCL_ERROR; + } + loc++; + + if (argc > loc && Tcl_GetDouble(interp, argv[loc], &rho) != TCL_OK) { + opserr << "WARNING invalid rho\n"; + return TCL_ERROR; + } + loc++; + + + builder->addTaggedObject(*new ElasticMaterial(tag, E, 0.0, E)); + builder->addTaggedObject(*new ElasticIsotropicMaterial(tag, E, v, rho)); + builder->addTaggedObject> (*new ElasticIsotropic<3>(tag, E, v, rho)); + + // builder->addTaggedObject(*new ElasticIsotropicBeamFiber(tag, E, v, rho)); + // builder->addTaggedObject(*new ElasticIsotropicPlaneStrain2D(tag, E, v, rho)); + // builder->addTaggedObject, "PlaneStrain">(*new ElasticIsotropic<2,PlaneType::Strain>(tag, E, v, rho)); + // builder->addTaggedObject(*new ElasticIsotropicPlaneStress2D(tag, E, v, rho)); + // builder->addTaggedObject, "PlaneStress">(*new ElasticIsotropic<2,PlaneType::Stress>(tag, E, v, rho)); + + return TCL_OK; + } + + else if (strcmp(argv[1], "ElasticCrossAnisotropic") == 0) + { + if (argc < 8) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial ElasticCrossAnisotropic tag? Ehh? Ehv? nuhv? nuvv? Ghv? " + << "\n"; + return TCL_ERROR; + } + + int tag; + double Eh, Ev, nuhv, nuhh, Ghv; + double rho = 0.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid ElasticCrossAnisotropic tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &Eh) != TCL_OK) { + opserr << "WARNING invalid Eh\n"; + opserr << "nDMaterial ElasticCrossAnisotropic: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &Ev) != TCL_OK) { + opserr << "WARNING invalid Ev\n"; + opserr << "nDMaterial ElasticCrossAnisotropic: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &nuhv) != TCL_OK) { + opserr << "WARNING invalid nuhv\n"; + opserr << "nDMaterial ElasticCrossAnisotropic: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &nuhh) != TCL_OK) { + opserr << "WARNING invalid nuhh\n"; + opserr << "nDMaterial ElasticCrossAnisotropic: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[7], &Ghv) != TCL_OK) { + opserr << "WARNING invalid Ghv\n"; + opserr << "nDMaterial ElasticCrossAnisotropic: " << tag << "\n"; + return TCL_ERROR; + } + + if (argc > 8 && Tcl_GetDouble(interp, argv[8], &rho) != TCL_OK) { + opserr << "WARNING invalid rho\n"; + opserr << "nDMaterial ElasticCrossAnisotropic: " << tag << "\n"; + return TCL_ERROR; + } + + // theMaterial = new ElasticCrossAnisotropic(tag, Eh, Ev, nuhv, nuhh, Ghv, rho); + } +} +#endif + diff --git a/SRC/runtime/commands/modeling/material/fedeas.cpp b/SRC/runtime/commands/modeling/material/fedeas.cpp new file mode 100644 index 0000000000..98ba2e8e84 --- /dev/null +++ b/SRC/runtime/commands/modeling/material/fedeas.cpp @@ -0,0 +1,1244 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// +// Written: cmp +// +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# define strcasecmp _stricmp +#else +# include +#endif +#define strcmp strcasecmp + +#include +#include +#include +#include +#include +#include +#include + + +template +static int +FedeasConcrParse(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + + BasicModelBuilder *builder = static_cast(clientData); + + ArgumentTracker tracker; + std::set positional; + + + int tag; + double fpc, epsc0, fpcu, epscu; + double rat, ft, Ets; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid uniaxialMaterial tag\n"; + return TCL_ERROR; + } + + for (int i=2; i= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &fpc) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::fpc); + } + else if ((strcasecmp(argv[i], "-epsc0") == 0) || (strcmp(argv[i], "-ec0") == 0)) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &epsc0) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::epsc0); + } + else if (strcasecmp(argv[i], "-fpcu") == 0 || strcasecmp(argv[i], "-Fcu") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &fpcu) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::fpcu); + } + else if (strcasecmp(argv[i], "-epscu") == 0 || strcmp(argv[i], "-ecu") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &epscu) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::epscu); + } + else + positional.insert(i); + } + + + for (int i: positional) { + if (tracker.current() == Positions::EndRequired) + tracker.increment(); + + switch (tracker.current()) { + case Positions::Tag : + if (Tcl_GetInt(interp, argv[i], &tag) != TCL_OK) { + opserr << "Invalid tag " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Tag); + break; + + case Positions::fpc: + if (Tcl_GetDouble(interp, argv[i], &fpc) != TCL_OK) { + opserr << "Invalid value for Fc " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::fpc); + break; + case Positions::epsc0: + if (Tcl_GetDouble(interp, argv[i], &epsc0) != TCL_OK) { + opserr << "Invalid value for ec0 " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::epsc0); + break; + case Positions::fpcu: + if (Tcl_GetDouble(interp, argv[i], &fpcu) != TCL_OK) { + opserr << "Invalid value for Fcu " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::fpcu); + break; + case Positions::epscu: + if (Tcl_GetDouble(interp, argv[i], &epscu) != TCL_OK) { + opserr << "Invalid value for ecu " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::epscu); + break; + case Positions::rat: + if (Tcl_GetDouble(interp, argv[i], &rat) != TCL_OK) { + opserr << "Invalid value for option " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::rat); + break; + case Positions::ft: + if (Tcl_GetDouble(interp, argv[i], &ft) != TCL_OK) { + opserr << "Invalid value for option " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::ft); + break; + case Positions::Ets: + if (Tcl_GetDouble(interp, argv[i], &Ets) != TCL_OK) { + opserr << "Invalid value for option " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Ets); + break; + + case Positions::EndRequired: + // This will not be reached + break; + + case Positions::End: + opserr << "Invalid value for option " << argv[i] << "\n"; + return TCL_ERROR; + } + } + + if (tracker.current() < Positions::EndRequired) { + opserr << "Missing required arguments: "; + while (tracker.current() != Positions::End) { + switch (tracker.current()) { + case Positions::fpc: + opserr << "fpc "; + break; + case Positions::epsc0: + opserr << "epsc0 "; + break; + case Positions::fpcu: + opserr << "Fcu "; + break; + case Positions::epscu: + opserr << "epscu "; + break; + case Positions::rat: + opserr << "rat "; + break; + case Positions::ft: + opserr << "ft "; + break; + case Positions::Ets: + opserr << "Ets "; + break; + case Positions::EndRequired: + case Positions::End: + default: + break; + } + + if (tracker.current() == Positions::End) + break; + + tracker.consume(tracker.current()); + } + opserr << "\n"; + return TCL_ERROR; + } + + // + // + // + if (fpcu > 0.0) { + fpcu *= -1; + // opswrn << OpenSees::SignalWarning << "Fcu should be negative\n"; + } + + // + // + // + UniaxialMaterial *theMaterial = nullptr; + if (strcmp(argv[1], "Concrete1") == 0 || + strcasecmp(argv[1], "Concrete01") == 0) { + + theMaterial = new Concrete01(tag, fpc, epsc0, fpcu, epscu); + } + + else if ((strcmp(argv[1], "concr2") == 0) || + (strcmp(argv[1], "Concrete02") == 0)) { + + theMaterial = + new Concrete02(tag, fpc, epsc0, fpcu, epscu, rat, ft, Ets); + } + + if (theMaterial == nullptr) + return TCL_ERROR; + + return builder->addTaggedObject(*theMaterial); +} + + +template +static int +FedeasSteelParse(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = static_cast(clientData); + + ArgumentTracker tracker; + std::set positional; + + UniaxialMaterial *theMaterial = nullptr; + + int tag; + double fy, E, b; + + double a1 = 0.0, + a2 = 1.0, + a3 = 0.0, + a4 = 1.0; + double R0 = 15.0, + cR1 = 0.925, + cR2 = 0.15; + + for (int i=2; i= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &fy) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::fy); + } + else if (strcmp(argv[i], "-E") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &E) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::E); + } + else if (strcmp(argv[i], "-b") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &b) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::b); + } + else if (strcmp(argv[i], "-R0") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &R0) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::R0); + } + else if (strcmp(argv[i], "-cR1") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &cR1) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::cR1); + } + else if (strcmp(argv[i], "-cR2") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &cR2) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::cR2); + } + else if (strcmp(argv[i], "-a1") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &a1) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::a1); + } + else if (strcmp(argv[i], "-a2") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &a2) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::a2); + } + else if (strcmp(argv[i], "-a3") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &a3) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::a3); + } + else if (strcmp(argv[i], "-a4") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &a4) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::a4); + } + else + positional.insert(i); + } + + // + // Positional arguments + // + for (int i : positional) { + + if (tracker.current() == Positions::EndRequired) + tracker.increment(); + + switch (tracker.current()) { + case Positions::Tag: + if (Tcl_GetInt(interp, argv[i], &tag) != TCL_OK) { + opserr << "invalid tag.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Positions::fy : + if (Tcl_GetDouble(interp, argv[i], &fy) != TCL_OK) { + opserr << "invalid Fy.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Positions::E: + if (Tcl_GetDouble(interp, argv[i], &E) != TCL_OK) { + opserr << "invalid E.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Positions::b: + if (Tcl_GetDouble(interp, argv[i], &b) != TCL_OK) { + opserr << "invalid b.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Positions::R0: + if (Tcl_GetDouble(interp, argv[i], &R0) != TCL_OK) { + opserr << "invalid R0.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Positions::cR1: + if (Tcl_GetDouble(interp, argv[i], &cR1) != TCL_OK) { + opserr << "invalid cR1.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Positions::cR2: + if (Tcl_GetDouble(interp, argv[i], &cR2) != TCL_OK) { + opserr << "invalid cR2.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Positions::a1: + if (Tcl_GetDouble(interp, argv[i], &a1) != TCL_OK) { + opserr << "invalid a1.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Positions::a2: + if (Tcl_GetDouble(interp, argv[i], &a2) != TCL_OK) { + opserr << "invalid a2.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Positions::a3: + if (Tcl_GetDouble(interp, argv[i], &a3) != TCL_OK) { + opserr << "invalid a3.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Positions::a4: + if (Tcl_GetDouble(interp, argv[i], &a4) != TCL_OK) { + opserr << "invalid a4.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Positions::sig0: + if (Tcl_GetDouble(interp, argv[i], &a4) != TCL_OK) { + opserr << "invalid sig0.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Positions::EndRequired: + // This will not be reached + break; + + case Positions::End: + opserr << "unexpected argument " << argv[i] << ".\n"; + return TCL_ERROR; + } + } + + // Check all required arguments are present + if (tracker.current() < Positions::EndRequired) { + opserr << "missing required arguments: "; + while (tracker.current() != Positions::EndRequired) { + switch (tracker.current()) { + case Positions::Tag : + opserr << "tag "; + break; + case Positions::fy : + opserr << "Fy "; + break; + case Positions::E: + opserr << "E "; + break; + case Positions::b: + opserr << "b "; + break; + case Positions::R0: + opserr << "R0 "; + break; + case Positions::cR1: + opserr << "cR1 "; + break; + case Positions::cR2: + opserr << "cR2 "; + break; + case Positions::a1: + opserr << "a1 "; + break; + case Positions::a2: + opserr << "a2 "; + break; + case Positions::a3: + opserr << "a3 "; + break; + case Positions::a4: + opserr << "a4 "; + break; + case Positions::sig0: + opserr << "sig0 "; + break; + + case Positions::EndRequired: + case Positions::End: + default: + break; + } + + if (tracker.current() == Positions::EndRequired) + break; + + tracker.consume(tracker.current()); + } + + opserr << "\n"; + + return TCL_ERROR; + } + + + if (strcmp(argv[1], "Steel1") == 0 || + strcmp(argv[1], "Steel01") == 0) { + theMaterial = new Steel01(tag, fy, E, b, a1, a2, a3, a4); + } + + else if (strcmp(argv[1], "Steel01Thermal") == 0) { + theMaterial = new Steel01Thermal(tag, fy, E, b, a1, a2, a3, a4); + } + + else if ((strcmp(argv[1], "Steel2") == 0)) { + theMaterial = new Steel2(tag, fy, E, b, R0, cR1, cR2, a1, a2, a3, a4); + } + + else if ((strcmp(argv[1], "Steel02") == 0)) { + theMaterial = new Steel02(tag, fy, E, b, R0, cR1, cR2, a1, a2, a3, a4); + } + + else if ((strcmp(argv[1], "Steel02Thermal") == 0)) { + theMaterial = new Steel02Thermal(tag, fy, E, b, R0, cR1, cR2); + } + + if (theMaterial == nullptr) + return TCL_ERROR; + + return builder->addTaggedObject(*theMaterial); +} + + +int +TclCommand_newFedeasSteel(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + + if (strcmp(argv[1], "Steel01") == 0 || + strcmp(argv[1], "Steel01Thermal") == 0 || + strcmp(argv[1], "Steel1") == 0) { + + // uniaxialMaterial Steel01 tag? fy? E? b? + enum class Positions: int { + Tag, + fy, E, b, EndRequired, + a1, a2, a3, a4, End, + R0, cR1, cR2, sig0 + }; + + return FedeasSteelParse(clientData, interp, argc, argv); + } + + else if ((strcmp(argv[1], "Steel02") == 0) || + (strcmp(argv[1], "Steel2") == 0) || + (strcmp(argv[1], "Steel02Thermal") == 0) || + (strcmp(argv[1], "SteelMP") == 0) + ) { + + // uniaxialMaterial Steel02 $tag $Fy $E $b $R0 $cR1 $cR2 <$a1 $a2 $a3 $a4 $sigInit> + enum class Positions: int { + Tag, + fy, E, b, EndRequired, + R0, cR1, cR2, a1, a2, a3, a4, sig0, End + }; + return FedeasSteelParse(clientData, interp, argc, argv); + } + + return TCL_ERROR; +} + + +int +TclCommand_newFedeasConcrete(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + + if (strcmp(argv[1], "Concrete01") == 0 || + strcmp(argv[1], "Concrete1") == 0) { + + // uniaxialMaterial Concrete01 tag? fpc? epsc0? fpcu? epscu? + enum class Positions: int { + Tag, + fpc, epsc0, fpcu, epscu, EndRequired, + End, + rat, ft, Ets + }; + + return FedeasConcrParse(clientData, interp, argc, argv); + } + + else if ((strcmp(argv[1], "Steel02") == 0) || + (strcmp(argv[1], "Steel2") == 0) || + (strcmp(argv[1], "Steel02Thermal") == 0) || + (strcmp(argv[1], "SteelMP") == 0) + ) { + + // uniaxialMaterial Concrete02 tag? fpc? epsc0? fpcu? epscu? rat? ft? Ets? + enum class Positions: int { + Tag, + fpc, epsc0, fpcu, epscu, rat, ft, Ets, EndRequired, + End + }; + return FedeasConcrParse(clientData, interp, argc, argv); + } + + return TCL_ERROR; +} + + + + +#if 0 + + +int +TclBasicBuilder_addUniaxialConcrete(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + + BasicModelBuilder *builder = static_cast(clientData); + + if (argc < 3) { + opserr << "WARNING insufficient number of arguments\n"; + return TCL_ERROR; + } + + // enum Positions { + // E, End + // }; + + + UniaxialMaterial *theMaterial = nullptr; + + double fpc, epsc0, fpcu, epscu; + double rat, ft, Ets; + int tag; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid uniaxialMaterial tag\n"; + return TCL_ERROR; + } + + if (strcmp(argv[1], "Concrete1") == 0 || + strcmp(argv[1], "concrete01") == 0) { + + if (argc < 7) { + opserr << "WARNING invalid number of arguments\n"; + opserr + << "Want: uniaxialMaterial Concrete01 tag? fpc? epsc0? fpcu? epscu?" + << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &fpc) != TCL_OK) { + opserr << "WARNING invalid fpc\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[4], &epsc0) != TCL_OK) { + opserr << "WARNING invalid epsc0\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[5], &fpcu) != TCL_OK) { + opserr << "WARNING invalid fpcu\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[6], &epscu) != TCL_OK) { + opserr << "WARNING invalid epscu\n"; + return TCL_ERROR; + } + + theMaterial = new Concrete01(tag, fpc, epsc0, fpcu, epscu); + } + + else if (strcmp(argv[1], "concr2") == 0) { + if (argc < 10) { + opserr << "WARNING invalid number of arguments\n"; + opserr << "Want: uniaxialMaterial Concrete02 tag? fpc? epsc0? fpcu? epscu? rat? ft? Ets?" + << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &fpc) != TCL_OK) { + opserr << "WARNING invalid fpc\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[4], &epsc0) != TCL_OK) { + opserr << "WARNING invalid epsc0\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[5], &fpcu) != TCL_OK) { + opserr << "WARNING invalid fpcu\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[6], &epscu) != TCL_OK) { + opserr << "WARNING invalid epscu\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[7], &rat) != TCL_OK) { + opserr << "WARNING invalid rat\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[8], &ft) != TCL_OK) { + opserr << "WARNING invalid Ft\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[9], &Ets) != TCL_OK) { + opserr << "WARNING invalid Ets\n"; + return TCL_ERROR; + } + + theMaterial = + new Concrete02(tag, fpc, epsc0, fpcu, epscu, rat, ft, Ets); + } + + return builder->addTaggedObject(*theMaterial); +} + + + +#include +#include +#include +#include +#include +#include +#include +int +Cmd(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) + { + if (strcmp(argv[1], "Hardening1") == 0 || + strcmp(argv[1], "Hardening01") == 0) { + if (argc < 7) { + opserr << "WARNING invalid number of arguments\n"; + opserr << "Want: uniaxialMaterial Hardening01 tag? E? sigY? Hiso? Hkin?" + << endln; + return TCL_ERROR; + } + + double E, sigY, Hiso, Hkin; + + if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { + opserr << "WARNING invalid E\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[4], &sigY) != TCL_OK) { + opserr << "WARNING invalid sigY\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[5], &Hiso) != TCL_OK) { + opserr << "WARNING invalid Hiso\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[6], &Hkin) != TCL_OK) { + opserr << "WARNING invalid Hkin\n"; + return TCL_ERROR; + } + + theMaterial = new FedeasHardeningMaterial(tag, E, sigY, Hiso, Hkin); + } + + else if (strcmp(argv[1], "Bond1") == 0 || strcmp(argv[1], "Bond01") == 0) { + if (argc < 15) { + opserr << "WARNING invalid number of arguments\n"; + opserr << "Want: uniaxialMaterial Bond01 tag? u1p? q1p? u2p? u3p? q3p? " + "u1n? q1n? u2n? u3n? q3n? s0? bb?" + << endln; + return TCL_ERROR; + } + + double u1p, q1p, u2p, u3p, q3p; + double u1n, q1n, u2n, u3n, q3n; + double s0, bb; + + if (Tcl_GetDouble(interp, argv[3], &u1p) != TCL_OK) { + opserr << "WARNING invalid u1p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[4], &q1p) != TCL_OK) { + opserr << "WARNING invalid q1p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[5], &u2p) != TCL_OK) { + opserr << "WARNING invalid u2p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[6], &u3p) != TCL_OK) { + opserr << "WARNING invalid u3p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[7], &q3p) != TCL_OK) { + opserr << "WARNING invalid q3p\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[8], &u1n) != TCL_OK) { + opserr << "WARNING invalid u1n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[9], &q1n) != TCL_OK) { + opserr << "WARNING invalid q1n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[10], &u2n) != TCL_OK) { + opserr << "WARNING invalid u2n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[11], &u3n) != TCL_OK) { + opserr << "WARNING invalid u3n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[12], &q3n) != TCL_OK) { + opserr << "WARNING invalid q3n\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[13], &s0) != TCL_OK) { + opserr << "WARNING invalid s0\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[14], &bb) != TCL_OK) { + opserr << "WARNING invalid bb\n"; + return TCL_ERROR; + } + + theMaterial = new FedeasBond1Material(tag, u1p, q1p, u2p, u3p, q3p, u1n, + q1n, u2n, u3n, q3n, s0, bb); + } + + else if (strcmp(argv[1], "Bond2") == 0 || strcmp(argv[1], "Bond02") == 0) { + if (argc < 17) { + + opserr << "WARNING invalid number of arguments\n"; + opserr << "Want: uniaxialMaterial Bond02 tag? u1p? q1p? u2p? u3p? q3p? " + "u1n? q1n? u2n? u3n? q3n? s0? bb? alp? aln?" + << endln; + return TCL_ERROR; + } + + double u1p, q1p, u2p, u3p, q3p; + double u1n, q1n, u2n, u3n, q3n; + double s0, bb, alp, aln; + + if (Tcl_GetDouble(interp, argv[3], &u1p) != TCL_OK) { + opserr << "WARNING invalid u1p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[4], &q1p) != TCL_OK) { + opserr << "WARNING invalid q1p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[5], &u2p) != TCL_OK) { + opserr << "WARNING invalid u2p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[6], &u3p) != TCL_OK) { + opserr << "WARNING invalid u3p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[7], &q3p) != TCL_OK) { + opserr << "WARNING invalid q3p\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[8], &u1n) != TCL_OK) { + opserr << "WARNING invalid u1n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[9], &q1n) != TCL_OK) { + opserr << "WARNING invalid q1n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[10], &u2n) != TCL_OK) { + opserr << "WARNING invalid u2n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[11], &u3n) != TCL_OK) { + opserr << "WARNING invalid u3n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[12], &q3n) != TCL_OK) { + opserr << "WARNING invalid q3n\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[13], &s0) != TCL_OK) { + opserr << "WARNING invalid s0\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[14], &bb) != TCL_OK) { + opserr << "WARNING invalid bb\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[15], &alp) != TCL_OK) { + opserr << "WARNING invalid alp\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[16], &aln) != TCL_OK) { + opserr << "WARNING invalid aln\n"; + return TCL_ERROR; + } + + theMaterial = new FedeasBond2Material(tag, u1p, q1p, u2p, u3p, q3p, u1n, + q1n, u2n, u3n, q3n, s0, bb, alp, aln); + } + + else if (strcmp(argv[1], "Concrete3") == 0 || + strcmp(argv[1], "Concrete03") == 0) { + if (argc < 13) { + opserr << "WARNING invalid number of arguments\n"; + opserr << "Want: uniaxialMaterial Concrete03 tag? fpc? epsc0? fpcu? " + "epscu? rat? ft? epst0? ft0? beta? epstu?" + << endln; + return TCL_ERROR; + } + + double fpc, epsc0, fpcu, epscu; + double rat, ft, epst0, ft0, beta, epstu; + + if (Tcl_GetDouble(interp, argv[3], &fpc) != TCL_OK) { + opserr << "WARNING invalid fpc\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[4], &epsc0) != TCL_OK) { + opserr << "WARNING invalid epsc0\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[5], &fpcu) != TCL_OK) { + opserr << "WARNING invalid fpcu\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[6], &epscu) != TCL_OK) { + opserr << "WARNING invalid epscu\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[7], &rat) != TCL_OK) { + opserr << "WARNING invalid rat\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[8], &ft) != TCL_OK) { + opserr << "WARNING invalid ft\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[9], &epst0) != TCL_OK) { + opserr << "WARNING invalid epst0\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[10], &ft0) != TCL_OK) { + opserr << "WARNING invalid ft0\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[11], &beta) != TCL_OK) { + opserr << "WARNING invalid beta\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[12], &epstu) != TCL_OK) { + opserr << "WARNING invalid epstu\n"; + return TCL_ERROR; + } + + theMaterial = new FedeasConcr3Material(tag, fpc, epsc0, fpcu, epscu, rat, + ft, epst0, ft0, beta, epstu); + } + + else if (strcmp(argv[1], "Hysteretic1") == 0 || + strcmp(argv[1], "Hysteretic01") == 0) { + if (argc < 15) { + opserr << "WARNING invalid number of arguments\n"; + opserr << "Want: uniaxialMaterial Hysteretic01 tag? s1p? e1p? s2p? e2p? " + "s1n? e1n? s2n? e1n? px? py? d1? d2?" + << endln; + return TCL_ERROR; + } + + double s1p, e1p, s2p, e2p; + double s1n, e1n, s2n, e2n; + double px, py, d1, d2; + + if (Tcl_GetDouble(interp, argv[3], &s1p) != TCL_OK) { + opserr << "WARNING invalid s1p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[4], &e1p) != TCL_OK) { + opserr << "WARNING invalid e1p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[5], &s2p) != TCL_OK) { + opserr << "WARNING invalid s2p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[6], &e2p) != TCL_OK) { + opserr << "WARNING invalid e2p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[7], &s1n) != TCL_OK) { + opserr << "WARNING invalid s1n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[8], &e1n) != TCL_OK) { + opserr << "WARNING invalid e1n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[9], &s2n) != TCL_OK) { + opserr << "WARNING invalid s2n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[10], &e2n) != TCL_OK) { + opserr << "WARNING invalid e2n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[11], &px) != TCL_OK) { + opserr << "WARNING invalid px\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[12], &py) != TCL_OK) { + opserr << "WARNING invalid py\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[13], &d1) != TCL_OK) { + opserr << "WARNING invalid d1\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[14], &d2) != TCL_OK) { + opserr << "WARNING invalid d2\n"; + return TCL_ERROR; + } + + theMaterial = new FedeasHyster1Material(tag, s1p, e1p, s2p, e2p, s1n, e1n, + s2n, e2n, px, py, d1, d2); + } + + else if (strcmp(argv[1], "Hysteretic2") == 0 || + strcmp(argv[1], "Hysteretic02") == 0) { + if (argc < 19) { + opserr << "WARNING invalid number of arguments\n"; + opserr << "Want: uniaxialMaterial Hysteretic02 tag? s1p? e1p? s2p? e2p? " + "s3p? e3p? s1n? e1n? s2n? e1n? s3n? e3n? px? py? d1? d2?" + << endln; + return TCL_ERROR; + } + + double s1p, e1p, s2p, e2p, s3p, e3p; + double s1n, e1n, s2n, e2n, s3n, e3n; + double px, py, d1, d2; + + if (Tcl_GetDouble(interp, argv[3], &s1p) != TCL_OK) { + opserr << "WARNING invalid s1p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[4], &e1p) != TCL_OK) { + opserr << "WARNING invalid e1p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[5], &s2p) != TCL_OK) { + opserr << "WARNING invalid s2p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[6], &e2p) != TCL_OK) { + opserr << "WARNING invalid e2p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[7], &s3p) != TCL_OK) { + opserr << "WARNING invalid s2p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[8], &e3p) != TCL_OK) { + opserr << "WARNING invalid e2p\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[9], &s1n) != TCL_OK) { + opserr << "WARNING invalid s1n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[10], &e1n) != TCL_OK) { + opserr << "WARNING invalid e1n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[11], &s2n) != TCL_OK) { + opserr << "WARNING invalid s2n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[12], &e2n) != TCL_OK) { + opserr << "WARNING invalid e2n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[13], &s3n) != TCL_OK) { + opserr << "WARNING invalid s2n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[14], &e3n) != TCL_OK) { + opserr << "WARNING invalid e2n\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[15], &px) != TCL_OK) { + opserr << "WARNING invalid px\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[16], &py) != TCL_OK) { + opserr << "WARNING invalid py\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[17], &d1) != TCL_OK) { + opserr << "WARNING invalid d1\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[18], &d2) != TCL_OK) { + opserr << "WARNING invalid d2\n"; + return TCL_ERROR; + } + + theMaterial = + new FedeasHyster2Material(tag, s1p, e1p, s2p, e2p, s3p, e3p, s1n, e1n, + s2n, e2n, s3n, e3n, px, py, d1, d2); + } + + else if (strcmp(argv[1], "ConcretePlasticDamage") == 0 || + strcmp(argv[1], "PlasticDamage") == 0) { + if (argc < 11) { + opserr << "WARNING invalid number of arguments\n"; + opserr << "Want: uniaxialMaterial ConcretePlasticDamage tag? $Ec $Gf $Gc " + "$ft $fcy $fc $ktcr $relax" + << endln; + return TCL_ERROR; + } + + double Ec, Ft, Fc, ft_max, fcy, fc, ktcr, relax; + + if (Tcl_GetDouble(interp, argv[3], &Ec) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid Ec\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[4], &Ft) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid Ft\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[5], &Fc) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid Fc\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[6], &ft_max) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid ft_max\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[7], &fcy) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid fcy\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[8], &fc) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid fc\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[9], &ktcr) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid Ktcr\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[10], &relax) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid relax\n"; + return TCL_ERROR; + } + + theMaterial = new PlasticDamageMaterial(tag, Ec, Ft, Fc, ft_max, fcy, fc, + ktcr, relax); + } + else { + opserr << "WARNING invalid uniaxialMaterial type\n"; + return TCL_ERROR; + } +} +#endif diff --git a/SRC/runtime/commands/modeling/material/isotropy.cpp b/SRC/runtime/commands/modeling/material/isotropy.cpp new file mode 100644 index 0000000000..83d1999471 --- /dev/null +++ b/SRC/runtime/commands/modeling/material/isotropy.cpp @@ -0,0 +1,426 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// + +#include "isotropy.h" +#include +#include +#include +#include +#include + +namespace Isotropy { + enum class Parameter : int { + YoungModulus = 1 << 0, // E + ShearModulus = 1 << 1, // G + BulkModulus = 1 << 2, // K + PoissonsRatio = 1 << 3, // ν + LameLambda = 1 << 4 // λ, Lame's first parameter + }; +} + +namespace { + const int E_FLAG = static_cast(Isotropy::Parameter::YoungModulus); + const int G_FLAG = static_cast(Isotropy::Parameter::ShearModulus); + const int K_FLAG = static_cast(Isotropy::Parameter::BulkModulus); + const int NU_FLAG = static_cast(Isotropy::Parameter::PoissonsRatio); + const int LAMBDA_FLAG = static_cast(Isotropy::Parameter::LameLambda); + + const double TOL = 1e-12; + + // Convert any input pair (flag1,in1) and (flag2,in2) to the canonical pair (E, ν). + // Returns 0 on success, nonzero on failure. + int convertToEN(int flag1, double in1, + int flag2, double in2, + double &E, double &nu) + { + // Case A: Already (E, ν) + if ((flag1 == E_FLAG && flag2 == NU_FLAG) || + (flag1 == NU_FLAG && flag2 == E_FLAG)) { + E = (flag1 == E_FLAG) ? in1 : in2; + nu = (flag1 == NU_FLAG) ? in1 : in2; + return 0; + } + // Case B: (G, ν): E = 2G(1+ν) + if ((flag1 == G_FLAG && flag2 == NU_FLAG) || + (flag1 == NU_FLAG && flag2 == G_FLAG)) { + double G = (flag1 == G_FLAG) ? in1 : in2; + nu = (flag1 == NU_FLAG) ? in1 : in2; + E = 2.0 * G * (1.0 + nu); + return 0; + } + // Case C: (K, ν): E = 3K(1-2ν) + if ((flag1 == K_FLAG && flag2 == NU_FLAG) || + (flag1 == NU_FLAG && flag2 == K_FLAG)) { + double K = (flag1 == K_FLAG) ? in1 : in2; + nu = (flag1 == NU_FLAG) ? in1 : in2; + E = 3.0 * K * (1.0 - 2.0 * nu); + return 0; + } + // Case D: (λ, ν): E = λ (1+ν)(1-2ν)/ν (if ν != 0) + if ((flag1 == LAMBDA_FLAG && flag2 == NU_FLAG) || + (flag1 == NU_FLAG && flag2 == LAMBDA_FLAG)) { + double lambda = (flag1 == LAMBDA_FLAG) ? in1 : in2; + nu = (flag1 == NU_FLAG) ? in1 : in2; + if (std::fabs(nu) < TOL) + return -1; + E = lambda * (1.0 + nu) * (1.0 - 2.0 * nu) / nu; + return 0; + } + // Case E: (G, K): Use standard formulas: + // ν = (3K - 2G) / (2(3K+G)) + // E = 9K·G/(3K+G) + if ((flag1 == G_FLAG && flag2 == K_FLAG) || + (flag1 == K_FLAG && flag2 == G_FLAG)) { + double G = (flag1 == G_FLAG) ? in1 : in2; + double K = (flag1 == K_FLAG) ? in1 : in2; + if (std::fabs(3.0*K + G) < TOL) + return -1; + nu = (3.0 * K - 2.0 * G) / (2.0 * (3.0 * K + G)); + E = 9.0 * K * G / (3.0 * K + G); + return 0; + } + // Case F: (G, λ): From known relations for isotropic materials: + // ν = λ / [2(λ+G)] + // E = G(3λ+2G)/(λ+G) + if ((flag1 == G_FLAG && flag2 == LAMBDA_FLAG) || + (flag1 == LAMBDA_FLAG && flag2 == G_FLAG)) { + double G = (flag1 == G_FLAG) ? in1 : in2; + double lambda = (flag1 == LAMBDA_FLAG) ? in1 : in2; + if (std::fabs(lambda + G) < TOL) return -1; + nu = lambda / (2.0 * (lambda + G)); + E = G * (3.0 * lambda + 2.0 * G) / (lambda + G); + return 0; + } + // Case G: (K, λ): Use the relation K = λ + 2G/3. + // Hence G = 3(K - λ)/2, then + // ν = λ / (3K - λ) + // E = 9K(K - λ)/(3K - λ) + if ((flag1 == K_FLAG && flag2 == LAMBDA_FLAG) || + (flag1 == LAMBDA_FLAG && flag2 == K_FLAG)) { + double K = (flag1 == K_FLAG) ? in1 : in2; + double lambda = (flag1 == LAMBDA_FLAG) ? in1 : in2; + if (std::fabs(3.0*K - lambda) < TOL) return -1; + nu = lambda / (3.0 * K - lambda); + E = 9.0 * K * (K - lambda) / (3.0 * K - lambda); + return 0; + } + // Case H: (E, G): ν = E/(2G) - 1. + if ((flag1 == E_FLAG && flag2 == G_FLAG) || + (flag1 == G_FLAG && flag2 == E_FLAG)) { + E = (flag1 == E_FLAG) ? in1 : in2; + double G = (flag1 == G_FLAG) ? in1 : in2; + if (std::fabs(G) < TOL) + return -1; + nu = E / (2.0 * G) - 1.0; + return 0; + } + // Case I: (E, K): ν = (3K - E)/(6K). + if ((flag1 == E_FLAG && flag2 == K_FLAG) || + (flag1 == K_FLAG && flag2 == E_FLAG)) { + E = (flag1 == E_FLAG) ? in1 : in2; + double K = (flag1 == K_FLAG) ? in1 : in2; + if (std::fabs(K) < TOL) return -1; + nu = (3.0 * K - E) / (6.0 * K); + return 0; + } + // Case J: (E, λ): This leads to a quadratic in ν. + if ((flag1 == E_FLAG && flag2 == LAMBDA_FLAG) || + (flag1 == LAMBDA_FLAG && flag2 == E_FLAG)) { + E = (flag1 == E_FLAG) ? in1 : in2; + double lambda = (flag1 == LAMBDA_FLAG) ? in1 : in2; + // Equation: λ(1+ν)(1-2ν) = Eν → 2λ ν² + (λ+E)ν - λ = 0. + double a = 2.0 * lambda; + double b = lambda + E; + double c = -lambda; + double disc = b*b - 4.0 * a * c; + if (disc < 0.0) + return -1; + double sqrt_disc = std::sqrt(disc); + double nu1 = (-b + sqrt_disc) / (2.0 * a); + double nu2 = (-b - sqrt_disc) / (2.0 * a); + // Choose the solution in the physical range (-1, 0.5). + if (nu1 > -1.0 && nu1 < 0.5) { + nu = nu1; + return 0; + } + if (nu2 > -1.0 && nu2 < 0.5) { + nu = nu2; + return 0; + } + return -1; + } + + // Any other combination is not supported. + return -1; + } +} // namespace + + +int +isotropic_constants(int flag1, double in1, int flag2, double in2, IsotropicConstants &iso) +{ + // Convert to canonical (E, ν) + double E, nu; + if (convertToEN(flag1, in1, flag2, in2, E, nu) != 0) + return -1; + + iso.E = E; + iso.nu = nu; + iso.G = E / (2.0 * (1.0 + nu)); + iso.K = E / (3.0 * (1.0 - 2.0 * nu)); + iso.lambda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu)); + return 0; +} + + +int +isotropic_convert(int flag1, double in1, + int flag2, double in2, + int flag_out, + double & out) +{ + + // First converts the given input pair into (E, ν) and then computes the requested + // property (if not already provided as one of the inputs). + + // If the output is already one of the inputs, return it. + if (flag_out == flag1) { + out = in1; + return 0; + } + if (flag_out == flag2) { + out = in2; + return 0; + } + + // Convert to canonical (E, ν) + double E, nu; + if (convertToEN(flag1, in1, flag2, in2, E, nu) != 0) + return -1; + + // Now, based solely on (E, ν), compute the desired property. + if (flag_out == E_FLAG) { + out = E; + return 0; + } + if (flag_out == NU_FLAG) { + out = nu; + return 0; + } + if (flag_out == G_FLAG) { + // G = E / [2(1+ν)] + out = E / (2.0 * (1.0 + nu)); + return 0; + } + if (flag_out == K_FLAG) { + // K = E / [3(1-2ν)] + if (std::fabs(1.0 - 2.0*nu) < TOL) return -1; + out = E / (3.0 * (1.0 - 2.0*nu)); + return 0; + } + if (flag_out == LAMBDA_FLAG) { + // λ = E·ν / [(1+ν)(1-2ν)] + if (std::fabs((1.0+nu)*(1.0-2.0*nu)) < TOL) return -1; + out = E * nu / ((1.0 + nu) * (1.0 - 2.0*nu)); + return 0; + } + return -1; +} + + +int +TclCommand_setIsotropicParameters( + ClientData clientData, + Tcl_Interp *interp, + Tcl_Size argc, + TCL_Char ** const argv) +{ + // We expect the syntax: + // material Isotropic $tag + // The tag is still the first non-option argument (argv[2]). + // Among the options, exactly two independent elastic parameters must be provided. + // Valid elastic options: -E, -G, -K, -nu, -lambda. + + bool gotParam1 = false, + gotParam2 = false; + + int flag1 = 0, + flag2 = 0; + double val1 = 0.0, + val2 = 0.0; + + IsotropicParse* data = static_cast(clientData); + IsotropicConstants* iso = &data->constants; + std::set& positions = data->positions; + + assert(iso != nullptr); + + // Process the remaining arguments. + for (int i = 0; i < argc; i++) { + if ((strcmp(argv[i], "-E") == 0) || + (strcmp(argv[i], "-youngs-modulus") == 0)) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &iso->E) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (!gotParam1) { + gotParam1 = true; + val1 = iso->E; + flag1 = static_cast(Isotropy::Parameter::YoungModulus); + } + else if (!gotParam2) { + gotParam2 = true; + val2 = iso->E; + flag2 = static_cast(Isotropy::Parameter::YoungModulus); + } + else { + opserr << "Too many elastic parameter options provided.\n"; + return TCL_ERROR; + } + positions.insert(i-1); + positions.insert(i); + } + + else if (strcmp(argv[i], "-G") == 0 || + strcmp(argv[i], "-shear-modulus") == 0 || + strcmp(argv[i], "-mu") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i], &iso->G) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (!gotParam1) { + gotParam1 = true; + val1 = iso->G; + flag1 = static_cast(Isotropy::Parameter::ShearModulus); + } + else if (!gotParam2) { + gotParam2 = true; + val2 = iso->G; + flag2 = static_cast(Isotropy::Parameter::ShearModulus); + } + else { + opserr << "Too many elastic parameter options provided.\n"; + return TCL_ERROR; + } + positions.insert(i-1); + positions.insert(i); + } + else if (strcmp(argv[i], "-K") == 0 || strcmp(argv[i], "-bulk-modulus") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + double val; + if (Tcl_GetDouble(interp, argv[i], &val) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (!gotParam1) { + gotParam1 = true; + val1 = val; + flag1 = static_cast(Isotropy::Parameter::BulkModulus); + } + else if (!gotParam2) { + gotParam2 = true; + val2 = val; + flag2 = static_cast(Isotropy::Parameter::BulkModulus); + } + else { + opserr << "Too many elastic parameter options provided.\n"; + return TCL_ERROR; + } + positions.insert(i-1); + positions.insert(i); + } + else if (strcmp(argv[i], "-nu") == 0 || strcmp(argv[i], "-poissons-ratio") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + double val; + if (Tcl_GetDouble(interp, argv[i], &val) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (!gotParam1) { + gotParam1 = true; + val1 = val; + flag1 = static_cast(Isotropy::Parameter::PoissonsRatio); + } + else if (!gotParam2) { + gotParam2 = true; + val2 = val; + flag2 = static_cast(Isotropy::Parameter::PoissonsRatio); + } + else { + opserr << "Too many elastic parameter options provided.\n"; + return TCL_ERROR; + } + positions.insert(i-1); + positions.insert(i); + } + else if (strcmp(argv[i], "-lambda") == 0 || strcmp(argv[i], "-lame-lambda") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + double val; + if (Tcl_GetDouble(interp, argv[i], &val) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (!gotParam1) { + gotParam1 = true; + val1 = val; + flag1 = static_cast(Isotropy::Parameter::LameLambda); + } + else if (!gotParam2) { + gotParam2 = true; + val2 = val; + flag2 = static_cast(Isotropy::Parameter::LameLambda); + } + else { + opserr << "Too many elastic parameter options provided.\n"; + return TCL_ERROR; + } + positions.insert(i-1); + positions.insert(i); + } + } + + // Compute canonical Young's modulus and Poisson's ratio. + int ret = isotropic_constants(flag1, val1, flag2, val2, *iso); + if (data->required == 1 && gotParam1) + return TCL_OK; + + if (!gotParam1 || !gotParam2) { + // opserr << "Must specify exactly two independent elastic parameters.\n"; + return TCL_ERROR; + } + + if (ret != 0) + return TCL_ERROR; + + return TCL_OK; +} diff --git a/SRC/runtime/commands/modeling/material/isotropy.h b/SRC/runtime/commands/modeling/material/isotropy.h new file mode 100644 index 0000000000..7f3857b7ee --- /dev/null +++ b/SRC/runtime/commands/modeling/material/isotropy.h @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +#pragma once +#include +#include +#include + +struct IsotropicConstants { + double E; // Young's modulus + double G; // Shear modulus + double K; // Bulk modulus + double nu; // Poisson's ratio + double lambda; // Lamé's first parameter +}; + +struct IsotropicParse { + IsotropicConstants &constants; + int required; + std::set positions; +}; + +//--------------------------------------------------------------------- +// Conversion routine: +// Given two independent isotropic elastic constants—specified by the pair +// (flag1, in1) and (flag2, in2)—compute the requested output property, +// as indicated by flag_out. If one of the outputs is already among the +// inputs its value is returned; otherwise the function first converts +// the pair to the canonical pair (E, ν) and then computes the desired value. +// +// The function returns 0 on success and a nonzero value if the conversion +// cannot be performed (for example, due to an unrecognized combination or +// division by zero). +// +// Example: To compute the shear modulus (G) from a pair of inputs, +// flag_out should be set to the value corresponding to Isotropy::Parameter::ShearModulus +// + +int +TclCommand_setIsotropicParameters(ClientData, Tcl_Interp *, Tcl_Size argc, TCL_Char **argv); + +int isotropic_convert(int flag1, double in1, + int flag2, double in2, + int flag_out, + double & out); + +int isotropic_constants(int flag1, double in1, int flag2, double in2, IsotropicConstants &iso); diff --git a/SRC/runtime/commands/modeling/material/legacy.cpp b/SRC/runtime/commands/modeling/material/legacy.cpp new file mode 100644 index 0000000000..fafac45336 --- /dev/null +++ b/SRC/runtime/commands/modeling/material/legacy.cpp @@ -0,0 +1,617 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +#include +#include +#include +#include +#include +#include + +#include // MHS +#include // ZHY +#include // Won Lee +#include +#include // NM + + +int +TclDispatch_LegacyUniaxials(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char**const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder *builder = static_cast(clientData); + UniaxialMaterial *theMaterial = nullptr; + + if (strcmp(argv[1], "Elastic2") == 0) { + if (argc < 4 || argc > 5) { + opserr << OpenSees::PromptValueError << "invalid number of arguments\n"; + opserr << "Want: uniaxialMaterial Elastic tag? E? " << "\n"; + return TCL_ERROR; + } + + int tag; + double E; + double eta = 0.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid uniaxialMaterial Elastic tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid E\n"; + opserr << "uniaxiaMaterial Elastic: " << tag << "\n"; + return TCL_ERROR; + } + + if (argc == 5) { + if (Tcl_GetDouble(interp, argv[4], &eta) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid eta\n"; + opserr << "uniaxialMaterial Elastic: " << tag << "\n"; + return TCL_ERROR; + } + } + + // Parsing was successful, allocate the material + theMaterial = new Elastic2Material(tag, E, eta); + + } else if (strcmp(argv[1], "ENT") == 0) { + if (argc < 4) { + opserr << OpenSees::PromptValueError << "invalid number of arguments\n"; + opserr << "Want: uniaxialMaterial ENT tag? E?" << "\n"; + return TCL_ERROR; + } + + int tag; + double E; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid uniaxialMaterial ENT tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid E\n"; + opserr << "uniaxiaMaterial ENT: " << tag << "\n"; + return TCL_ERROR; + } + + // Parsing was successful, allocate the material + theMaterial = new ENTMaterial(tag, E); + + } + + else if (strcmp(argv[1], "BarSlip") == 0) { + if (argc != 17 && argc != 15) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: uniaxialMaterial BarSlip tag? fc? fy? Es? fu? Eh? db? " + "ld? nb? width? depth? bsflag? type? " + << "\n"; + return TCL_ERROR; + } + + int tag, nb, bsf, typ, dmg=1, unt=1; + double fc, fy, Es, fu, Eh, ld, width, depth, db; + + int argStart = 2; + + if (Tcl_GetInt(interp, argv[argStart++], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid tag\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[argStart++], &fc) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid fc\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[argStart++], &fy) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid fy\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[argStart++], &Es) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid Es\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[argStart++], &fu) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid fu\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[argStart++], &Eh) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid Eh\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[argStart++], &db) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid db\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[argStart++], &ld) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid ld\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[argStart++], &nb) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid nbars\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[argStart++], &width) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid width\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[argStart++], &depth) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid depth\n"; + return TCL_ERROR; + } + + int y; + y = argStart; + + if ((strcmp(argv[y], "strong") == 0) || + (strcmp(argv[y], "Strong") == 0) || (strcmp(argv[y], "weak") == 0) || + (strcmp(argv[y], "Weak") == 0)) { + if ((strcmp(argv[y], "strong") == 0) || + (strcmp(argv[y], "Strong") == 0)) { + bsf = 0; + } + + if ((strcmp(argv[y], "weak") == 0) || (strcmp(argv[y], "Weak") == 0)) { + bsf = 1; + } + } else { + opserr << OpenSees::PromptValueError << "invalid bond strength specified\n"; + return TCL_ERROR; + } + y++; + + if ((strcmp(argv[y], "beamtop") == 0) || + (strcmp(argv[y], "beamTop") == 0) || + (strcmp(argv[y], "beambot") == 0) || + (strcmp(argv[y], "beamBot") == 0) || + (strcmp(argv[y], "beambottom") == 0) || + (strcmp(argv[y], "beamBottom") == 0) || + (strcmp(argv[y], "beam") == 0) || (strcmp(argv[y], "Beam") == 0) || + (strcmp(argv[y], "Column") == 0) || + (strcmp(argv[y], "column") == 0)) { + if ((strcmp(argv[y], "beamtop") == 0) || + (strcmp(argv[y], "beamTop") == 0) || + (strcmp(argv[y], "beam") == 0) || (strcmp(argv[y], "Beam") == 0)) { + typ = 0; + } + + if ((strcmp(argv[y], "beambot") == 0) || + (strcmp(argv[y], "beamBot") == 0) || + (strcmp(argv[y], "beambottom") == 0) || + (strcmp(argv[y], "beamBottom") == 0)) { + typ = 1; + } + + if ((strcmp(argv[y], "column") == 0) || + (strcmp(argv[y], "Column") == 0)) { + typ = 2; + } + } else { + opserr << OpenSees::PromptValueError << "invalid location of bar specified\n"; + return TCL_ERROR; + } + if (argc == 17) { + y++; + + if ((strcmp(argv[y], "damage1") == 0) || + (strcmp(argv[y], "Damage1") == 0) || + (strcmp(argv[y], "damage2") == 0) || + (strcmp(argv[y], "Damage2") == 0) || + (strcmp(argv[y], "nodamage") == 0) || + (strcmp(argv[y], "Nodamage") == 0) || + (strcmp(argv[y], "NoDamage") == 0) || + (strcmp(argv[y], "noDamage") == 0)) { + if ((strcmp(argv[y], "damage1") == 0) || + (strcmp(argv[y], "Damage1") == 0)) { + dmg = 1; + } else if ((strcmp(argv[y], "damage2") == 0) || + (strcmp(argv[y], "Damage2") == 0)) { + dmg = 2; + } else if ((strcmp(argv[y], "nodamage") == 0) || + (strcmp(argv[y], "Nodamage") == 0) || + (strcmp(argv[y], "NoDamage") == 0) || + (strcmp(argv[y], "noDamage") == 0)) { + dmg = 0; + } + + } else { + opserr << OpenSees::PromptValueError << "invalid damage specified\n"; + return TCL_ERROR; + } + + y++; + + if ((strcmp(argv[y], "mpa") == 0) || (strcmp(argv[y], "MPa") == 0) || + (strcmp(argv[y], "mPa") == 0) || (strcmp(argv[y], "Mpa") == 0) || + (strcmp(argv[y], "psi") == 0) || (strcmp(argv[y], "Psi") == 0) || + (strcmp(argv[y], "PSI") == 0) || (strcmp(argv[y], "Pa") == 0) || + (strcmp(argv[y], "pa") == 0) || (strcmp(argv[y], "psf") == 0) || + (strcmp(argv[y], "Psf") == 0) || (strcmp(argv[y], "PSF") == 0) || + (strcmp(argv[y], "ksi") == 0) || (strcmp(argv[y], "Ksi") == 0) || + (strcmp(argv[y], "KSI") == 0) || (strcmp(argv[y], "ksf") == 0) || + (strcmp(argv[y], "Ksf") == 0) || (strcmp(argv[y], "KSF") == 0)) { + if ((strcmp(argv[y], "mpa") == 0) || (strcmp(argv[y], "MPa") == 0) || + (strcmp(argv[y], "mPa") == 0) || (strcmp(argv[y], "Mpa") == 0)) { + unt = 1; + } else if ((strcmp(argv[y], "psi") == 0) || + (strcmp(argv[y], "Psi") == 0) || + (strcmp(argv[y], "PSI") == 0)) { + unt = 2; + } else if ((strcmp(argv[y], "Pa") == 0) || + (strcmp(argv[y], "pa") == 0)) { + unt = 3; + } else if ((strcmp(argv[y], "psf") == 0) || + (strcmp(argv[y], "Psf") == 0) || + (strcmp(argv[y], "PSF") == 0)) { + unt = 4; + } else if ((strcmp(argv[y], "ksi") == 0) || + (strcmp(argv[y], "Ksi") == 0) || + (strcmp(argv[y], "KSI") == 0)) { + unt = 5; + } else if ((strcmp(argv[y], "ksf") == 0) || + (strcmp(argv[y], "Ksf") == 0) || + (strcmp(argv[y], "KSF") == 0)) { + unt = 6; + } + } else { + opserr << OpenSees::PromptValueError << "invalid unit specified\n"; + return TCL_ERROR; + } + } + + // allocate the material + if (argc == 15) { + theMaterial = new BarSlipMaterial(tag, fc, fy, Es, fu, Eh, db, ld, nb, + width, depth, bsf, typ); + } + + if (argc == 17) { + theMaterial = new BarSlipMaterial(tag, fc, fy, Es, fu, Eh, db, ld, nb, + width, depth, bsf, typ, dmg, unt); + } + + } + + else if (strcmp(argv[1], "ShearPanel") == 0) { + if (argc != 42 && argc != 31) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: uniaxialMaterial ShearPanel tag? stress1p? strain1p? " + "stress2p? strain2p? stress3p? strain3p? stress4p? strain4p? " + << "\n rDispP? rForceP? uForceP? " + << "\n gammaK1? gammaK2? gammaK3? " + "gammaK4? gammaKLimit? gammaD1? gammaD2? gammaD3? gammaD4? " + << "\ngammaDLimit? gammaF1? gammaF2? gammaF3? gammaF4? " + "gammaFLimit? gammaE? YieldStress? "; + return TCL_ERROR; + } + + int tag; + double stress1p, stress2p, stress3p, stress4p; + double strain1p, strain2p, strain3p, strain4p; + double stress1n, stress2n, stress3n, stress4n; + double strain1n, strain2n, strain3n, strain4n; + double rDispP, rForceP, uForceP, rDispN, rForceN, uForceN; + double gammaK1, gammaK2, gammaK3, gammaK4, gammaKLimit; + double gammaD1, gammaD2, gammaD3, gammaD4, gammaDLimit; + double gammaF1, gammaF2, gammaF3, gammaF4, gammaFLimit; + double gammaE, yStr; + + int i = 2; + + if (Tcl_GetInt(interp, argv[i++], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid uniaxialMaterial ShearPanel tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &stress1p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid stress1p\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &strain1p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid strain1p\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &stress2p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid stress2p\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &strain2p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid strain2p\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &stress3p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid stress3p\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &strain3p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid strain3p\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &stress4p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid stress4p\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &strain4p) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid strain4p\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (argc == 42) { + if (Tcl_GetDouble(interp, argv[i++], &stress1n) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid stress1n\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &strain1n) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid strain1n\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &stress2n) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid stress2n\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &strain2n) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid strain2n\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &stress3n) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid stress3n\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &strain3n) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid strain3n\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &stress4n) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid stress4n\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &strain4n) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid strain4n\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + } + + if (Tcl_GetDouble(interp, argv[i++], &rDispP) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid rDispP\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &rForceP) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid rForceP\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &uForceP) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid uForceP\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (argc == 42) { + if (Tcl_GetDouble(interp, argv[i++], &rDispN) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid rDispN\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &rForceN) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid rForceN\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &uForceN) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid uForceN\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + } + + if (Tcl_GetDouble(interp, argv[i++], &gammaK1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaK1\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaK2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaK2\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaK3) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaK3\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaK4) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaK4\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaKLimit) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaKLimit\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaD1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaD1\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaD2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaD2\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaD3) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaD3\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaD4) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaD4\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaDLimit) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaDLimit\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaF1) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaF1\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaF2) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaF2\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaF3) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaF3\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaF4) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaF4\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i++], &gammaFLimit) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaFLimit\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &gammaE) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid gammaE\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[i++], &yStr) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid yield stress\n"; + opserr << "ShearPanel material: " << tag << "\n"; + return TCL_ERROR; + } + + // allocate the pinching material + if (argc == 42) { + theMaterial = new ShearPanelMaterial( + tag, stress1p, strain1p, stress2p, strain2p, stress3p, strain3p, + stress4p, strain4p, stress1n, strain1n, stress2n, strain2n, + stress3n, strain3n, stress4n, strain4n, rDispP, rForceP, uForceP, + rDispN, rForceN, uForceN, gammaK1, gammaK2, gammaK3, gammaK4, + gammaKLimit, gammaD1, gammaD2, gammaD3, gammaD4, gammaDLimit, + gammaF1, gammaF2, gammaF3, gammaF4, gammaFLimit, gammaE, yStr); + } + if (argc == 31) { + theMaterial = new ShearPanelMaterial( + tag, stress1p, strain1p, stress2p, strain2p, stress3p, strain3p, + stress4p, strain4p, rDispP, rForceP, uForceP, gammaK1, gammaK2, + gammaK3, gammaK4, gammaKLimit, gammaD1, gammaD2, gammaD3, gammaD4, + gammaDLimit, gammaF1, gammaF2, gammaF3, gammaF4, gammaFLimit, + gammaE, yStr); + } + } + + else if (strcmp(argv[1], "Concrete01WithSITC") == 0) { + if (argc < 7) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: uniaxialMaterial Concrete01 tag? fpc? epsc0? fpcu? " + "epscu? " + << "\n"; + return TCL_ERROR; + } + + int tag; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid uniaxialMaterial Concrete01 tag" << "\n"; + return TCL_ERROR; + } + + // Read required Concrete01 material parameters + double fpc, epsc0, fpcu, epscu; + + if (Tcl_GetDouble(interp, argv[3], &fpc) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid fpc\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &epsc0) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid epsc0\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &fpcu) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid fpcu\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &epscu) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid epscu\n"; + return TCL_ERROR; + } + + if (argc == 7) + // Parsing was successful, allocate the material + theMaterial = new Concrete01WithSITC(tag, fpc, epsc0, fpcu, epscu); + else { + double endStrainSITC; + if (Tcl_GetDouble(interp, argv[7], &endStrainSITC) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid epscu\n"; + return TCL_ERROR; + } + theMaterial = + new Concrete01WithSITC(tag, fpc, epsc0, fpcu, epscu, endStrainSITC); + } + } + + if (theMaterial == nullptr) + return TCL_ERROR; + + if (builder->addTaggedObject(*theMaterial) != TCL_OK) { + delete theMaterial; + return TCL_ERROR; + } + + return TCL_OK; +} + diff --git a/SRC/runtime/commands/modeling/material/material.cpp b/SRC/runtime/commands/modeling/material/material.cpp new file mode 100644 index 0000000000..5ce800b466 --- /dev/null +++ b/SRC/runtime/commands/modeling/material/material.cpp @@ -0,0 +1,846 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** With a lot of additions by ** +** Boris Jeremic (jeremic@ucdavis.edu) ** +** Zaohui Yang (zhyang@ucdavis.edu) ** +** Zhao Cheng (zcheng@ucdavis.edu) ** +** ** +** ****************************************************************** */ +// +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +// #include + +// #include +// #include +// #include +// #include + + +Tcl_CmdProc TclCommand_newPlasticMaterial; +Tcl_CmdProc TclCommand_newElasticMaterial; +// Tcl_CmdProc TclCommand_newIsotropicMaterial; + + + +int +TclCommand_addMaterial(ClientData clientData, Tcl_Interp* interp, + Tcl_Size argc, TCL_Char** const argv) +{ + static + std::unordered_map MaterialLibrary = { + {"ElasticIsotropic", TclCommand_newElasticMaterial}, + {"Elastic", TclCommand_newElasticMaterial}, + {"Isotropic", TclCommand_newElasticMaterial}, + {"J2", TclCommand_newPlasticMaterial}, + {"J2Simplified", TclCommand_newPlasticMaterial}, + {"J2BeamFiber", TclCommand_newPlasticMaterial}, + }; + + + if (argc < 2) { + opserr << OpenSees::PromptValueError + << "missing argument type" + << "\n"; + return TCL_ERROR; + } + + + auto cmd = MaterialLibrary.find(std::string(argv[1])); + if (cmd != MaterialLibrary.end()) + return (*cmd->second)(clientData, interp, argc, &argv[0]); + + +#if 0 + // Check argv[1] for ND material type + + // Pointer to an ND material that will be added to the model builder + NDMaterial* theMaterial = nullptr; + + if (strcmp(argv[1], "PressureDependentElastic3D") == 0) { + //Jul. 07, 2001 Boris Jeremic & ZHaohui Yang jeremic|zhyang@ucdavis.edu + // Pressure dependent elastic material + if (argc < 6) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PressureDependentElastic3D tag? E? v? rho?" << "\n"; + return TCL_ERROR; + } + + int tag = 0; + double E = 0.0; + double v = 0.0; + double rho = 0.0; + double expp = 0.0; + double prp = 0.0; + double pop = 0.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid PressureDependentElastic3D tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { + opserr << "WARNING invalid E\n"; + opserr << "nDMaterial PressureDependentElastic3D: E" << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &v) != TCL_OK) { + opserr << "WARNING invalid v\n"; + opserr << "nDMaterial PressureDependentElastic3D: v" << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &rho) != TCL_OK) { + opserr << "WARNING invalid v\n"; + opserr << "nDMaterial PressureDependentElastic3D: rho" << tag << "\n"; + return TCL_ERROR; + } + + if (argc == 6) { + theMaterial = new PressureDependentElastic3D(tag, E, v, rho); + } else if (argc == 7) { + //get the exponent of the pressure sensitive elastic material) + if (Tcl_GetDouble(interp, argv[6], &expp) != TCL_OK) { + opserr << "WARNING invalid v\n"; + opserr << "nDMaterial PressureDependentElastic3D: " << tag << "\n"; + return TCL_ERROR; + } + theMaterial = new PressureDependentElastic3D(tag, E, v, rho, expp); + } else if (argc == 8) { + //get the exponent pressure of the pressure sensitive elastic material) + if (Tcl_GetDouble(interp, argv[6], &expp) != TCL_OK) { + opserr << "WARNING invalid v\n"; + opserr << "nDMaterial PressureDependentElastic3D: expp" << tag << "\n"; + return TCL_ERROR; + } + //get the reference pressure of the pressure sensitive elastic material) + if (Tcl_GetDouble(interp, argv[7], &prp) != TCL_OK) { + opserr << "WARNING invalid v\n"; + opserr << "nDMaterial PressureDependentElastic3D: prp " << tag << "\n"; + return TCL_ERROR; + } + theMaterial = new PressureDependentElastic3D(tag, E, v, rho, expp, prp); + } else if (argc >= 9) { + //get the exponent of the pressure sensitive elastic material) + if (Tcl_GetDouble(interp, argv[6], &expp) != TCL_OK) { + opserr << "WARNING invalid v\n"; + opserr << "nDMaterial PressureDependentElastic3D: expp" << tag << "\n"; + return TCL_ERROR; + } + //get the reference pressure of the pressure sensitive elastic material) + if (Tcl_GetDouble(interp, argv[7], &prp) != TCL_OK) { + opserr << "WARNING invalid v\n"; + opserr << "nDMaterial PressureDependentElastic3D: prp" << tag << "\n"; + return TCL_ERROR; + } + //get the cutoff pressure po of the pressure sensitive elastic material) + if (Tcl_GetDouble(interp, argv[8], &pop) != TCL_OK) { + opserr << "WARNING invalid v\n"; + opserr << "nDMaterial PressureDependentElastic3D: pop" << tag << "\n"; + return TCL_ERROR; + } + theMaterial = new PressureDependentElastic3D(tag, E, v, rho, expp, prp, pop); + } + + } + + + else if ((strcmp(argv[1], "MultiaxialCyclicPlasticity") == 0) || + (strcmp(argv[1], "MCP") == 0)) { + + // + // MultiAxialCyclicPlasticity Model by Gang Wang + // + // nDMaterial MultiaxialCyclicPlasticity $tag, $rho, $K, $G, + // $Su , $Ho , $h, $m, $beta, $KCoeff + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + if (argc < 12) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial MultiaxialCyclicPlasticity tag? rho? K? G? Su? Ho? h? m? beta? " + "KCoeff? " + << "\n"; + return TCL_ERROR; + } + + int tag; + double K, G, rho, Su, Ho, h, m, beta, Kcoeff; + double eta = 0.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid MultiaxialCyclicPlasticity tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &rho) != TCL_OK) { + opserr << "WARNING invalid rho\n"; + opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &K) != TCL_OK) { + opserr << "WARNING invalid K\n"; + opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &G) != TCL_OK) { + opserr << "WARNING invalid G\n"; + opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; + return TCL_ERROR; + } + + + if (Tcl_GetDouble(interp, argv[6], &Su) != TCL_OK) { + opserr << "WARNING invalid alpha1\n"; + opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[7], &Ho) != TCL_OK) { + opserr << "WARNING invalid Ho\n"; + opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[8], &h) != TCL_OK) { + opserr << "WARNING invalid h\n"; + opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[9], &m) != TCL_OK) { + opserr << "WARNING invalid m\n"; + opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10], &beta) != TCL_OK) { + opserr << "WARNING invalid beta\n"; + opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[11], &Kcoeff) != TCL_OK) { + opserr << "WARNING invalid Kcoeff\n"; + opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; + return TCL_ERROR; + } + + + if (argc > 12 && Tcl_GetDouble(interp, argv[12], &eta) != TCL_OK) { + opserr << "WARNING invalid eta\n"; + opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; + return TCL_ERROR; + } + + theMaterial = + new MultiaxialCyclicPlasticity(tag, 0, rho, K, G, Su, Ho, h, m, beta, Kcoeff, eta); + } + + + // Pressure Independend Multi-yield, by ZHY + else if (strcmp(argv[1], "PressureIndependMultiYield") == 0) { + const int numParam = 6; + const int totParam = 10; + int tag; + double param[totParam]; + param[6] = 0.0; + param[7] = 100.; + param[8] = 0.0; + param[9] = 20; + + char* arg[] = {"nd", + "rho", + "refShearModul", + "refBulkModul", + "cohesi", + "peakShearStra", + "frictionAng (=0)", + "refPress (=100)", + "pressDependCoe (=0.0)", + "numberOfYieldSurf (=20)"}; + if (argc < (3 + numParam)) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PressureIndependMultiYield tag? " << arg[0]; + opserr << "? " + << "\n"; + opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " + << "\n"; + opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " + << "\n"; + opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid PressureIndependMultiYield tag" << "\n"; + return TCL_ERROR; + } + + for (int i = 3; (i < argc && i < 13); i++) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + + static double* gredu = 0; + // user defined yield surfaces + if (param[9] < 0 && param[9] > -40) { + param[9] = -int(param[9]); + gredu = new double[int(2 * param[9])]; + for (int i = 0; i < 2 * param[9]; i++) + if (Tcl_GetDouble(interp, argv[i + 13], &gredu[i]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + } + + PressureIndependMultiYield* temp = + new PressureIndependMultiYield(tag, param[0], param[1], param[2], param[3], param[4], + param[5], param[6], param[7], param[8], param[9], gredu); + theMaterial = temp; + + if (gredu != 0) { + delete[] gredu; + gredu = 0; + } + } + + // Pressure Dependend Multi-yield, by ZHY + else if (strcmp(argv[1], "PressureDependMultiYield") == 0) { + const int numParam = 15; + const int totParam = 24; + int tag; + double param[totParam]; + param[15] = 20; + param[16] = 0.6; + param[17] = 0.9; + param[18] = 0.02; + param[19] = 0.7; + param[20] = 101.; + param[21] = .3; + param[22] = 0.; + param[23] = 1.; + + char* arg[] = {"nd", + "rho", + "refShearModul", + "refBulkModul", + "frictionAng", + "peakShearStra", + "refPress", + "pressDependCoe", + "phaseTransformAngle", + "contractionParam1", + "dilationParam1", + "dilationParam2", + "liquefactionParam1", + "liquefactionParam2", + "liquefactionParam4", + "numberOfYieldSurf (=20)", + "e (=0.6)", + "volLimit1 (=0.9)", + "volLimit2 (=0.02)", + "volLimit3 (=0.7)", + "Atmospheric pressure (=101)", + "cohesi (=.5)", + "Hv (=0)", + "Pv (=1.)"}; + if (argc < (3 + numParam)) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PressureDependMultiYield tag? " << arg[0]; + opserr << "? " + << "\n"; + opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " + << "\n"; + opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " + << "\n"; + opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " + << "\n"; + opserr << arg[10] << "? " << arg[11] << "? " << arg[12] << "? " + << "\n"; + opserr << arg[13] << "? " << arg[14] << "? " << arg[15] << "? " + << "\n"; + opserr << arg[16] << "? " << arg[17] << "? " << arg[18] << "? " + << "\n"; + opserr << arg[19] << "? " << arg[20] << "? " << arg[21] << "? " << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid PressureDependMultiYield tag" << "\n"; + return TCL_ERROR; + } + + for (int i = 3; (i < argc && i < 19); i++) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial PressureDependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + + static double* gredu = 0; + // user defined yield surfaces + if (param[15] < 0 && param[15] > -40) { + param[15] = -int(param[15]); + gredu = new double[int(2 * param[15])]; + + for (int i = 0; i < 2 * param[15]; i++) + if (Tcl_GetDouble(interp, argv[i + 19], &gredu[i]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + } + + if (gredu != 0) { + for (int i = 19 + int(2 * param[15]); i < argc; i++) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3 - int(2 * param[15])]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[15])] << "\n"; + opserr << "nDMaterial PressureDependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + } else { + for (int i = 19; i < argc; i++) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[15])] << "\n"; + opserr << "nDMaterial PressureDependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + } + + PressureDependMultiYield* temp = new PressureDependMultiYield( + tag, param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7], + param[8], param[9], param[10], param[11], param[12], param[13], param[14], param[15], gredu, + param[16], param[17], param[18], param[19], param[20], param[21], param[22], param[23]); + + theMaterial = temp; + if (gredu != 0) { + delete[] gredu; + gredu = 0; + } + } + + // Pressure Dependend Multi-yield, by ZHY + else if (strcmp(argv[1], "PressureDependMultiYield02") == 0) { + const int numParam = 13; + const int totParam = 26; + int tag; + double param[totParam]; + param[numParam] = 20; + param[numParam + 1] = 5.0; + param[numParam + 2] = 3.; + param[numParam + 3] = 1.; + param[numParam + 4] = 0.; + param[numParam + 5] = 0.6; + param[numParam + 6] = 0.9; + param[numParam + 7] = 0.02; + param[numParam + 8] = 0.7; + param[numParam + 9] = 101.; + param[numParam + 10] = 0.1; + param[numParam + 11] = 0.; + param[numParam + 12] = 1.; + + char* arg[] = {"nd", + "rho", + "refShearModul", + "refBulkModul", + "frictionAng", + "peakShearStra", + "refPress", + "pressDependCoe", + "phaseTransformAngle", + "contractionParam1", + "contractionParam3", + "dilationParam1", + "dilationParam3", + "numberOfYieldSurf (=20)", + "contractionParam2=5.0", + "dilationParam2=3.0", + "liquefactionParam1=1.0", + "liquefactionParam2=0.0", + "e (=0.6)", + "volLimit1 (=0.9)", + "volLimit2 (=0.02)", + "volLimit3 (=0.7)", + "Atmospheric pressure (=101)", + "cohesi (=.1)", + "Hv (=0)", + "Pv (=1.)"}; + if (argc < (3 + numParam)) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PressureDependMultiYield02 tag? " << arg[0]; + opserr << "? " + << "\n"; + opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " + << "\n"; + opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " + << "\n"; + opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " + << "\n"; + opserr << arg[10] << "? " << arg[11] << "? " << arg[12] << "? " + << "\n"; + opserr << arg[13] << "? " << arg[14] << "? " << arg[15] << "? " + << "\n"; + opserr << arg[16] << "? " << arg[17] << "? " << arg[18] << "? " + << "\n"; + opserr << arg[19] << "? " << arg[20] << "? " << arg[21] << "? " + << "\n"; + opserr << arg[22] << "? " << arg[23] << "? " << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid PressureDependMultiYield02 tag" << "\n"; + return TCL_ERROR; + } + + int in = 17; + for (int i = 3; (i < argc && i < in); i++) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial PressureDependMultiYield02: " << tag << "\n"; + return TCL_ERROR; + } + + static double* gredu = 0; + + // user defined yield surfaces + if (param[numParam] < 0 && param[numParam] > -100) { + param[numParam] = -int(param[numParam]); + gredu = new double[int(2 * param[numParam])]; + + for (int i = 0; i < 2 * param[numParam]; i++) + if (Tcl_GetDouble(interp, argv[i + in], &gredu[i]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + } + + if (gredu != 0) { + for (int i = in + int(2 * param[numParam]); i < argc; i++) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3 - int(2 * param[numParam])]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[numParam])] << "\n"; + opserr << "nDMaterial PressureDependMultiYield02: " << tag << "\n"; + return TCL_ERROR; + } + } else { + for (int i = in; i < argc; i++) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[numParam])] << "\n"; + opserr << "nDMaterial PressureDependMultiYield02: " << tag << "\n"; + return TCL_ERROR; + } + } + + + PressureDependMultiYield02* temp = new PressureDependMultiYield02( + tag, param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7], + param[8], param[9], param[10], param[11], param[12], param[13], gredu, param[14], param[15], + param[16], param[17], param[18], param[19], param[20], param[21], param[22], param[23], + param[24], param[25]); + + theMaterial = temp; + if (gredu != 0) { + delete[] gredu; + gredu = 0; + } + } + + // Fluid Solid Porous, by ZHY + else if (strcmp(argv[1], "FluidSolidPorous") == 0) { + + int tag; + double param[4]; + char* arg[] = {"nd", "soilMatTag", "combinedBulkModul", "Atmospheric pressure"}; + if (argc < 6) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial FluidSolidPorous tag? " << arg[0]; + opserr << "? " + << "\n"; + opserr << arg[1] << "? " << arg[2] << "? " << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid FluidSolidPorous tag" << "\n"; + return TCL_ERROR; + } + + for (int i = 3; i < 6; i++) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial FluidSolidPorous: " << tag << "\n"; + return TCL_ERROR; + } + + NDMaterial* soil = builder->getTypedObject(param[1]); + if (soil == 0) { + opserr << "WARNING FluidSolidPorous: couldn't get soil material "; + opserr << "tagged: " << param[1] << "\n"; + return TCL_ERROR; + } + + param[3] = 101.; + if (argc == 7) { + if (Tcl_GetDouble(interp, argv[6], ¶m[3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[3] << "\n"; + opserr << "nDMaterial FluidSolidPorous: " << tag << "\n"; + return TCL_ERROR; + } + } + + theMaterial = new FluidSolidPorousMaterial(tag, param[0], *soil, param[2], param[3]); + } + + else if (strcmp(argv[1], "Template3Dep") == 0) { + theMaterial = TclModelBuilder_addTemplate3Dep(clientData, interp, argc, argv, theTclBuilder, 2); + } + + else if (strcmp(argv[1], "NewTemplate3Dep") == 0) { + theMaterial = + TclModelBuilder_addNewTemplate3Dep(clientData, interp, argc, argv, theTclBuilder, 2); + } + + else if (strcmp(argv[1], "FiniteDeformationElastic3D") == 0 || + strcmp(argv[1], "FDElastic3D") == 0) { + theMaterial = TclModelBuilder_addFiniteDeformationElastic3D(clientData, interp, argc, argv, + theTclBuilder, 1); + } + + else if (strcmp(argv[1], "FiniteDeformationEP3D") == 0 || strcmp(argv[1], "FDEP3D") == 0) { + theMaterial = + TclModelBuilder_addFiniteDeformationEP3D(clientData, interp, argc, argv, theTclBuilder, 2); + } + + + else if (strcmp(argv[1], "PlaneStressMaterial") == 0 || + strcmp(argv[1], "PlaneStress") == 0) { + if (argc < 4) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PlaneStress tag? matTag?" << "\n"; + return TCL_ERROR; + } + + int tag, matTag; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid nDMaterial PlaneStress tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { + opserr << "WARNING invalid matTag" << "\n"; + opserr << "PlaneStress: " << matTag << "\n"; + return TCL_ERROR; + } + + NDMaterial* threeDMaterial = builder->getTypedObject(matTag); + if (threeDMaterial == 0) { + opserr << "WARNING nD material does not exist\n"; + opserr << "nD material: " << matTag; + opserr << "\nPlaneStress nDMaterial: " << tag << "\n"; + return TCL_ERROR; + } + + theMaterial = new PlaneStressMaterial(tag, *threeDMaterial); + } + + + else if (strcmp(argv[1], "PlateFiberMaterial") == 0 || strcmp(argv[1], "PlateFiber") == 0) { + + if (argc < 4) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PlateFiber tag? matTag?" << "\n"; + return TCL_ERROR; + } + + int tag, matTag; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid nDMaterial PlateFiber tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { + opserr << "WARNING invalid matTag" << "\n"; + opserr << "PlateFiber: " << matTag << "\n"; + return TCL_ERROR; + } + + NDMaterial* threeDMaterial = builder->getTypedObject(matTag); + if (threeDMaterial == 0) { + opserr << "WARNING nD material does not exist\n"; + opserr << "nD material: " << matTag; + opserr << "\nPlateFiber nDMaterial: " << tag << "\n"; + return TCL_ERROR; + } + + theMaterial = new PlateFiberMaterial(tag, *threeDMaterial); + } + + else if (strcmp(argv[1], "BeamFiberMaterial") == 0 || + strcmp(argv[1], "BeamFiber") == 0) { + if (argc < 4) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial BeamFiber tag? matTag?" << "\n"; + return TCL_ERROR; + } + + int tag, matTag; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid nDMaterial BeamFiber tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { + opserr << "WARNING invalid matTag" << "\n"; + opserr << "BeamFiber: " << matTag << "\n"; + return TCL_ERROR; + } + + NDMaterial* threeDMaterial = builder->getTypedObject(matTag); + if (threeDMaterial == nullptr) { + return TCL_ERROR; + } + + theMaterial = new BeamFiberMaterial(tag, *threeDMaterial); + } + + else { + theMaterial = TclModelBuilder_addFeapMaterial(clientData, interp, argc, argv, theTclBuilder); + } + + if (theMaterial == nullptr) + return TCL_ERROR; + + // Now add the material to the modelBuilder + if (theTclBuilder->addNDMaterial(*theMaterial) < 0) { + opserr << "WARNING could not add material to the domain\n"; + opserr << *theMaterial << "\n"; + delete theMaterial; + return TCL_ERROR; + } + + return TCL_OK; +#endif + + return TCL_ERROR; + +} + + + + +#if 0 +Template3Dep* TclModelBuilder_addTemplate3Dep(ClientData clientData, Tcl_Interp* interp, int argc, + TCL_Char** argv, TclModelBuilder* theTclBuilder, + int eleArgStart); + +NewTemplate3Dep* TclModelBuilder_addNewTemplate3Dep(ClientData clientData, Tcl_Interp* interp, + int argc, TCL_Char** argv, + TclModelBuilder* theTclBuilder, + int eleArgStart); + +FiniteDeformationElastic3D* +TclModelBuilder_addFiniteDeformationElastic3D(ClientData clientData, Tcl_Interp* interp, int argc, + TCL_Char** argv, TclModelBuilder* theTclBuilder, + int eleArgStart); + +FiniteDeformationEP3D* TclModelBuilder_addFiniteDeformationEP3D(ClientData clientData, + Tcl_Interp* interp, int argc, + TCL_Char** argv, + TclModelBuilder* theTclBuilder, + int eleArgStart); + +NDMaterial* TclModelBuilder_addFeapMaterial(ClientData clientData, Tcl_Interp* interp, int argc, + TCL_Char** argv, TclModelBuilder* theTclBuilder); + + + + +template +int +TclCommand_newMinMaxND(ClientData clientData, Tcl_Interp* interp, int argc, const char**const argv) +{ + if (argc < 4) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: uniaxialMaterial MinMax tag? matTag?"; + opserr << " <-min min?> <-max max?>" << endln; + return TCL_ERROR; + } + + int tag, matTag; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid uniaxialMaterial MinMax tag" << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { + opserr << "WARNING invalid component tag\n"; + opserr << "uniaxialMaterial MinMax: " << tag << endln; + return TCL_ERROR; + } + + // Search for min and max strains + double epsmin = NEG_INF_STRAIN; + double epsmax = POS_INF_STRAIN; + + for (int j = 4; j < argc; j++) { + if (strcmp(argv[j],"-min") == 0) { + if ((j+1) >= argc || Tcl_GetDouble (interp, argv[j+1], &epsmin) != TCL_OK) { + opserr << "WARNING invalid min\n"; + opserr << "uniaxialMaterial MinMax: " << tag << endln; + return TCL_ERROR; + } + j++; + } + if (strcmp(argv[j],"-max") == 0) { + if ((j+1) >= argc || Tcl_GetDouble (interp, argv[j+1], &epsmax) != TCL_OK) { + opserr << "WARNING invalid max\n"; + opserr << "uniaxialMaterial MinMax: " << tag << endln; + return TCL_ERROR; + } + j++; + } + } + + UniaxialMaterial *theMat = theTclBuilder->getUniaxialMaterial(matTag); + + if (theMat == 0) { + opserr << "WARNING component material does not exist\n"; + opserr << "Component material: " << matTag; + opserr << "\nuniaxialMaterial MinMax: " << tag << endln; + return TCL_ERROR; + } + + // Parsing was successful, allocate the material + theMaterial = new MinMaxNDMaterial(tag, *theMat, epsmin, epsmax); +} +#endif \ No newline at end of file diff --git a/SRC/runtime/commands/modeling/material/material.hpp b/SRC/runtime/commands/modeling/material/material.hpp new file mode 100644 index 0000000000..91b93ebbcf --- /dev/null +++ b/SRC/runtime/commands/modeling/material/material.hpp @@ -0,0 +1,291 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// +// +// +// stress | strain +// 1 2 3 4 5 6 | +// xx yy zz xy yz xz | 11 22 33 12 23 31 +// PSn: 1 2 3 | 1 2 0 3 0 0 +// PSe: 1 2 0 3 - ? | 1 2 [1] 3 [2] [3] +// PF : 1 2 - 3 4 5 | 1 2 [1] 3 4 5 +// BF : 1 0 0 2 0 3 | 1 [1] [2] 2 [3] 3 +// AS?: 1 2 3 4 - +// +// strains ordered 00, 11, 22, 01 +// i.e. 11, 22, 33, 12 +// +// strain(0) = eps_00 +// strain(1) = eps_11 +// strain(2) = eps_22 +// strain(3) = 2*eps_01 +// +// same ordering for stresses but no 2 +// +// +// strains ordered : eps11, eps22, eps33, 2*eps12, 2*eps23, 2*eps31 +// NDmaterial strain order = 11, 22, 33, 12, 23, 31 +// PlaneStress strain order = 11, 22, 12, 33, 23, 31 +// BeamFiber strain order = 11, 12, 31, 22, 33, 23 +// PlateFiber strain order = 11, 22, 12, 23, 31, 33 +// 0 1 2 3 4 5 + +// Platefiber: 22, 33, 13, and 23 are condensed out. + +// PlateFiberMaterial strain order = 11, 22, 12, 23, 31, 33 + +// +// 0 1 2 3 4 5 +// ND : 11 22 33 12 23 31 +// PS : 11 22 12 33 23 31 +// PF : 11 22 12 23 31 33 | +// BF : 11 12 13 | 22 33 23 +// AS : 11 22 33 12 +// +#include +#include +#include +#include +#include +#include +#include +#include + +extern Tcl_CmdProc TclCommand_addPlaneWrapper; +extern Tcl_CmdProc TclCommand_newJ2Material; +extern Tcl_CmdProc TclCommand_newJ2Simplified; +extern Tcl_CmdProc TclCommand_newPlasticMaterial; +extern Tcl_CmdProc TclCommand_newConcreteMaterial; +extern Tcl_CmdProc TclCommand_newElasticMaterial; +extern Tcl_CmdProc TclCommand_addWrappingMaterial; +extern Tcl_CmdProc TclCommand_newPlateRebar; +extern Tcl_CmdProc TclCommand_newPlateFiber; + +extern OPS_Routine OPS_ElasticOrthotropicPlaneStress; +extern OPS_Routine OPS_OrthotropicMaterial; +extern OPS_Routine OPS_Series3DMaterial; +extern OPS_Routine OPS_Parallel3DMaterial; +extern OPS_Routine OPS_J2PlateFibreMaterial; +extern OPS_Routine OPS_J2CyclicBoundingSurfaceMaterial; +extern OPS_Routine OPS_ASDConcrete3DMaterial; +extern OPS_Routine OPS_ReinforcedConcretePlaneStressMaterial; +extern OPS_Routine OPS_FAReinforcedConcretePlaneStressMaterial; +extern OPS_Routine OPS_FAFourSteelRCPlaneStressMaterial; +extern OPS_Routine OPS_RAFourSteelRCPlaneStressMaterial; +extern OPS_Routine OPS_PrestressedConcretePlaneStressMaterial; +extern OPS_Routine OPS_FAPrestressedConcretePlaneStressMaterial; +extern OPS_Routine OPS_FAFourSteelPCPlaneStressMaterial; +extern OPS_Routine OPS_RAFourSteelPCPlaneStressMaterial; +// extern OPS_Routine OPS_MaterialCMM; +// extern OPS_Routine OPS_NewMaterialCMM; +extern OPS_Routine OPS_NewPlasticDamageConcretePlaneStress; +extern OPS_Routine OPS_ElasticIsotropicMaterial; +extern OPS_Routine OPS_IncrementalElasticIsotropicThreeDimensional; +extern OPS_Routine OPS_ElasticOrthotropicMaterial; +extern OPS_Routine OPS_BoundingCamClayMaterial; +extern OPS_Routine OPS_ContactMaterial2DMaterial; +extern OPS_Routine OPS_ContactMaterial3DMaterial; +extern OPS_Routine OPS_InitialStateAnalysisWrapperMaterial; +extern OPS_Routine OPS_ManzariDafaliasMaterial; +extern OPS_Routine OPS_ManzariDafaliasMaterialRO; +extern OPS_Routine OPS_PM4SandMaterial; +extern OPS_Routine OPS_PM4SiltMaterial; +extern OPS_Routine OPS_CycLiqCPMaterial; +extern OPS_Routine OPS_CycLiqCPSPMaterial; +extern OPS_Routine OPS_InitStressNDMaterial; +extern OPS_Routine OPS_StressDensityMaterial; +extern OPS_Routine OPS_PlaneStressLayeredMaterial; +extern OPS_Routine OPS_LinearCap; +extern OPS_Routine OPS_AcousticMedium; +extern OPS_Routine OPS_UVCmultiaxial; +extern OPS_Routine OPS_UVCplanestress; +extern OPS_Routine OPS_SAniSandMSMaterial; +extern OPS_Routine OPS_OrthotropicRotatingAngleConcreteT2DMaterial01; // M. J. Nunez - UChile +extern OPS_Routine OPS_SmearedSteelDoubleLayerT2DMaterial01; // M. J. Nunez - UChile + +extern OPS_Routine OPS_ElasticIsotropicMaterialThermal; // L.Jiang [SIF] +extern OPS_Routine OPS_DruckerPragerMaterialThermal; // L.Jiang [SIF] +extern OPS_Routine OPS_PlasticDamageConcretePlaneStressThermal; // L.Jiang [SIF] + +extern OPS_Routine OPS_AllASDPlasticMaterials; + +#ifdef _HAVE_Faria1998 +extern OPS_Routine OPS_NewFaria1998Material; +extern OPS_Routine OPS_NewConcreteMaterial; +#endif + +extern OPS_Routine OPS_FSAMMaterial; // K Kolozvari + +#ifdef _HAVE_Damage2p +extern OPS_Routine OPS_Damage2p; +#endif + + +extern "C" +int OPS_ResetInputNoBuilder(ClientData, Tcl_Interp *, int cArg, + int mArg, TCL_Char ** const argv, Domain *); + + +template static int +dispatch(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char** const argv) +{ + BasicModelBuilder *builder = static_cast(clientData); + + OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, 0); + + G3_Runtime *rt = G3_getRuntime(interp); + NDMaterial* theMaterial = (NDMaterial*)fn( rt, argc, argv ); + if (theMaterial == nullptr) { + return TCL_ERROR; + } + + if (builder->addTaggedObject(*theMaterial) != TCL_OK) { + opserr << OpenSees::PromptValueError << "Failed to add material to the model builder.\n"; + delete theMaterial; + return TCL_ERROR; + } + return TCL_OK; +} + +template +static int +dispatch(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char** const argv) +{ + assert(clientData != nullptr); + return fn( clientData, interp, argc, argv ); +} + +namespace OpenSees { +static std::unordered_map MaterialLibrary = { +// +// Elastic +// +// Isotropic + {"ElasticIsotropic3D", dispatch}, + {"ElasticIsotropic", dispatch}, + {"ElasticIsotropic3DThermal", dispatch}, +// Orthotropic + {"ElasticOrthotropic", dispatch}, + {"ElasticOrthotropicPlaneStress", dispatch}, +// +// Plasticity +// + {"J2", dispatch}, + {"J2Plasticity", dispatch}, + {"J2N", dispatch}, + {"J2L", dispatch}, + {"J2Thermal", dispatch}, + {"J2PlasticityThermal", dispatch}, + {"J2BeamFiber", dispatch}, + + {"SimplifiedJ2", dispatch}, + {"J2Simplified", dispatch}, + {"Simplified3DJ2", dispatch}, + {"3DJ2", dispatch}, + {"PlaneStressSimplifiedJ2", dispatch}, + {"DruckerPrager", dispatch}, + + {"UVCplanestress", dispatch }, + {"UVCmultiaxial", dispatch }, + {"J2PlateFibre", dispatch}, +// + {"ManzariDafalias", dispatch}, + {"ManzariDafaliasRO", dispatch}, + + + {"DruckerPragerThermal", dispatch }, + {"TruncatedDP", dispatch }, + {"FSAM", dispatch }, + {"AcousticMedium", dispatch }, + {"CycLiqCP", dispatch}, + {"CycLiqCPSP", dispatch}, + {"BoundingCamClay", dispatch}, +// +// Wrapper +// + {"InitStrainMaterial", dispatch}, + {"InitStrain", dispatch}, + {"InitialStrain", dispatch}, + {"InitStressMaterial", dispatch}, + {"OrthotropicMaterial", dispatch}, + {"Series3DMaterial", dispatch}, + {"Parallel3DMaterial", dispatch}, + {"Parallel3D", dispatch}, + // Beam fiber ( 22, 33, and 23 == 0) + {"BeamFiber", dispatch}, + {"BeamFiber2d", dispatch}, + {"BeamFiber2dPS", dispatch}, + // Plane + {"PlaneStressMaterial", dispatch}, + {"PlaneStress", dispatch}, + {"PlaneStrainMaterial", dispatch}, + {"PlaneStrain", dispatch}, + {"PlaneStressRebarMaterial", dispatch}, + // Plate (constrain stress 33 == 13 == 23 == 0) + {"PlateRebarMaterial", dispatch}, + {"PlateRebar", dispatch}, + {"PlateFiberMaterial", dispatch}, + {"PlateFiber", dispatch}, +// +// Other +// + {"ReinforcedConcretePlaneStress", dispatch}, + {"PlaneStressLayeredMaterial", dispatch}, + {"ASDConcrete3D", dispatch}, + {"PlasticDamageConcrete", dispatch}, + {"FariaPlasticDamage", dispatch}, + {"PlasticDamageConcretePlaneStress", dispatch}, +}; + +static std::unordered_map OldMaterialCommands = { +#ifdef OPS_USE_ASDPlasticMaterials + {"ASDPlasticMaterial", OPS_AllASDPlasticMaterials}, +#endif +#if 0 + {"CDPPlaneStressThermal", OPS_PlasticDamageConcretePlaneStressThermal}, +#endif +#ifdef _HAVE_Faria1998 + {"Faria1998", OPS_NewFaria1998Material}, + {"Concrete", OPS_NewConcreteMaterial}, +#endif +#ifdef _HAVE_Damage2p + {"Damage2p", OPS_Damage2p}, +#endif + + {"FAReinforcedConcretePlaneStress", OPS_FAReinforcedConcretePlaneStressMaterial}, + {"RAFourSteelRCPlaneStress", OPS_RAFourSteelRCPlaneStressMaterial}, + {"FAFourSteelRCPlaneStress", OPS_FAFourSteelRCPlaneStressMaterial}, + + + {"PrestressedConcretePlaneStress", OPS_PrestressedConcretePlaneStressMaterial}, + {"FAPrestressedConcretePlaneStress", OPS_FAPrestressedConcretePlaneStressMaterial}, + {"RAFourSteetPCPlaneStress", OPS_RAFourSteelPCPlaneStressMaterial}, + {"FAFourSteelPCPlaneStress", OPS_FAFourSteelPCPlaneStressMaterial}, + +//{"MaterialCMM", OPS_MaterialCMM}, + + {"PM4Sand", OPS_PM4SandMaterial}, + {"J2CyclicBoundingSurface", OPS_J2CyclicBoundingSurfaceMaterial}, + {"PM4Silt", OPS_PM4SiltMaterial}, + {"ContactMaterial2D", OPS_ContactMaterial2DMaterial}, + {"ContactMaterial3D", OPS_ContactMaterial3DMaterial}, + {"InitialStateAnalysisWrapper", OPS_InitialStateAnalysisWrapperMaterial}, + {"stressDensity", OPS_StressDensityMaterial}, + {"IncrementalElasticIsotropic3D", OPS_IncrementalElasticIsotropicThreeDimensional}, + {"OrthotropicRAConcrete", OPS_OrthotropicRotatingAngleConcreteT2DMaterial01}, + {"SmearedSteelDoubleLayer", OPS_SmearedSteelDoubleLayerT2DMaterial01}, + {"SAniSandMS", OPS_SAniSandMSMaterial}, +}; +} // namespace OpenSees diff --git a/SRC/runtime/commands/modeling/material/nDMaterial.cpp b/SRC/runtime/commands/modeling/material/nDMaterial.cpp new file mode 100644 index 0000000000..2783c0e8e7 --- /dev/null +++ b/SRC/runtime/commands/modeling/material/nDMaterial.cpp @@ -0,0 +1,1286 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Description: This file contains the function invoked when the user +// invokes the nDMaterial command in the interpreter. +// +// Developed by: +// Frank McKenna (fmckenna@ce.berkeley.edu) +// Gregory L. Fenves (fenves@ce.berkeley.edu) +// Filip C. Filippou (filippou@ce.berkeley.edu) +// +// With extensive contributions from +// Boris Jeremic (jeremic@ucdavis.edu) +// Zaohui Yang (zhyang@ucdavis.edu) +// Zhao Cheng (zcheng@ucdavis.edu) +// +//===----------------------------------------------------------------------===// +#include "material.hpp" +#include +#include +#include +#include +#include + +#include +#include +#include // Gang Wang + + +// start Yuli Huang & Xinzheng Lu +#include +#include +#include +// end Yuli Huang & Xinzheng Lu + +#include +#include // Quan Gu & ZhiJian Qiu 2013 + +#include +#include +#include + +#include +#include +#include +#include +#include + + +#include + +#if 0 +extern NDMaterial *Tcl_addWrapperNDMaterial(matObj *, ClientData, Tcl_Interp *, + int, TCL_Char **); +#endif + +#if defined(OPSDEF_Material_FEAP) +NDMaterial *TclBasicBuilder_addFeapMaterial(ClientData clientData, + Tcl_Interp *interp, int argc, + TCL_Char ** const argv); +#endif // _OPS_Material_FEAP + + +typedef struct ndMaterialPackageCommand { + char *funcName; + void *(*funcPtr)(); + struct ndMaterialPackageCommand *next; +} NDMaterialPackageCommand; + +static NDMaterialPackageCommand *theNDMaterialPackageCommands = nullptr; + + + +int +TclCommand_addNDMaterial(ClientData clientData, Tcl_Interp *interp, + Tcl_Size argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = static_cast(clientData); + + + if (argc < 2) { + opserr << OpenSees::PromptValueError + << "missing argument type" + << "\n"; + return TCL_ERROR; + } + + + { + auto tcl_cmd = OpenSees::MaterialLibrary.find(std::string(argv[1])); + if (tcl_cmd != OpenSees::MaterialLibrary.end()) { + return (*tcl_cmd->second)(clientData, interp, argc, &argv[0]); + } + } + + G3_Runtime *rt = G3_getRuntime(interp); + OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, 0); + + // Pointer to an ND material that will be added to the model builder + NDMaterial *theMaterial = nullptr; + + if (argc < 3) { + opserr << OpenSees::PromptValueError + << "missing argument tag" + << "\n"; + return TCL_ERROR; + } + auto tcl_cmd = OpenSees::OldMaterialCommands.find(std::string(argv[1])); + if (tcl_cmd != OpenSees::OldMaterialCommands.end()) { + void* theMat = (*tcl_cmd->second)(rt, argc, &argv[0]); + if (theMat != nullptr) + theMaterial = (NDMaterial *)theMat; + else + return TCL_ERROR; + } + + else if (strcmp(argv[1], "PressureDependentElastic3D") == 0) { + if (argc < 6) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PressureDependentElastic3D tag? E? v? rho?" + << "\n"; + return TCL_ERROR; + } + + int tag = 0; + double E = 0.0; + double v = 0.0; + double rho = 0.0; + double expp = 0.0; + double prp = 0.0; + double pop = 0.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid PressureDependentElastic3D tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { + opserr << "WARNING invalid E\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &v) != TCL_OK) { + opserr << "WARNING invalid v\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &rho) != TCL_OK) { + opserr << "WARNING invalid rho\n"; + return TCL_ERROR; + } + + if (argc == 6) { + theMaterial = new PressureDependentElastic3D(tag, E, v, rho); + } + + else if (argc == 7) { + // get the exponent of the pressure sensitive elastic material) + if (Tcl_GetDouble(interp, argv[6], &expp) != TCL_OK) { + opserr << "WARNING invalid expp\n"; + return TCL_ERROR; + } + theMaterial = new PressureDependentElastic3D(tag, E, v, rho, expp); + } + + else if (argc == 8) { + // get the exponent pressure of the pressure sensitive elastic material) + if (Tcl_GetDouble(interp, argv[6], &expp) != TCL_OK) { + opserr << "WARNING invalid expp\n"; + return TCL_ERROR; + } + // get the reference pressure of the pressure sensitive elastic material) + if (Tcl_GetDouble(interp, argv[7], &prp) != TCL_OK) { + opserr << "WARNING invalid prp\n"; + return TCL_ERROR; + } + theMaterial = new PressureDependentElastic3D(tag, E, v, rho, expp, prp); + } + + else if (argc >= 9) { + // get the exponent of the pressure sensitive elastic material) + if (Tcl_GetDouble(interp, argv[6], &expp) != TCL_OK) { + opserr << "WARNING invalid expp\n"; + return TCL_ERROR; + } + // get the reference pressure of the pressure sensitive elastic material) + if (Tcl_GetDouble(interp, argv[7], &prp) != TCL_OK) { + opserr << "WARNING invalid prp\n"; + return TCL_ERROR; + } + // get the cutoff pressure po of the pressure sensitive elastic material) + if (Tcl_GetDouble(interp, argv[8], &pop) != TCL_OK) { + opserr << "WARNING invalid pop\n"; + return TCL_ERROR; + } + theMaterial = + new PressureDependentElastic3D(tag, E, v, rho, expp, prp, pop); + } + } + + + // + // MultiAxialCyclicPlasticity Model by Gang Wang + // + // nDMaterial MultiaxialCyclicPlasticity $tag, $rho, $K, $G, + // $Su , $Ho , $h, $m, $beta, $KCoeff + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + else if ((strcmp(argv[1], "MultiaxialCyclicPlasticity") == 0) || + (strcmp(argv[1], "MCP") == 0)) { + if (argc < 12) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial MultiaxialCyclicPlasticity tag? rho? K? G? " + "Su? Ho? h? m? beta? KCoeff? " + << "\n"; + return TCL_ERROR; + } + + int tag; + double K, G, rho, Su, Ho, h, m, beta, Kcoeff; + double eta = 0.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid MultiaxialCyclicPlasticity tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &rho) != TCL_OK) { + opserr << "WARNING invalid rho\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &K) != TCL_OK) { + opserr << "WARNING invalid K\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &G) != TCL_OK) { + opserr << "WARNING invalid G\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &Su) != TCL_OK) { + opserr << "WARNING invalid alpha1\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[7], &Ho) != TCL_OK) { + opserr << "WARNING invalid Ho\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[8], &h) != TCL_OK) { + opserr << "WARNING invalid h\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[9], &m) != TCL_OK) { + opserr << "WARNING invalid m\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10], &beta) != TCL_OK) { + opserr << "WARNING invalid beta\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[11], &Kcoeff) != TCL_OK) { + opserr << "WARNING invalid Kcoeff\n"; + return TCL_ERROR; + } + + if (argc > 12 && Tcl_GetDouble(interp, argv[12], &eta) != TCL_OK) { + opserr << "WARNING invalid eta\n"; + return TCL_ERROR; + } + + theMaterial = new MultiaxialCyclicPlasticity(tag, 0, rho, K, G, Su, Ho, h, + m, beta, Kcoeff, eta); + } + + // Pressure Independent Multi-yield, by ZHY + else if (strcmp(argv[1], "PressureIndependMultiYield") == 0) { + const int numParam = 6; + const int totParam = 10; + int tag; + double param[totParam]; + param[6] = 0.0; + param[7] = 100.; + param[8] = 0.0; + param[9] = 20; + + const char *arg[] = {"nd", + "rho", + "refShearModul", + "refBulkModul", + "cohesi", + "peakShearStra", + "frictionAng (=0)", + "refPress (=100)", + "pressDependCoe (=0.0)", + "numberOfYieldSurf (=20)"}; + if (argc < (3 + numParam)) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PressureIndependMultiYield tag? " << arg[0]; + opserr << "? " + << "\n"; + opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " + << "\n"; + opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " + << "\n"; + opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid PressureIndependMultiYield tag" << "\n"; + return TCL_ERROR; + } + + for (int i = 3; (i < argc && i < 13); ++i) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + + static double *gredu = 0; + // user defined yield surfaces + if (param[9] < 0 && param[9] > -40) { + param[9] = -int(param[9]); + gredu = new double[int(2 * param[9])]; + for (int i = 0; i < 2 * param[9]; ++i) + if (Tcl_GetDouble(interp, argv[i + 13], &gredu[i]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + } + + PressureIndependMultiYield *temp = new PressureIndependMultiYield( + tag, param[0], param[1], param[2], param[3], param[4], param[5], + param[6], param[7], param[8], param[9], gredu); + theMaterial = temp; + + if (gredu != 0) { + delete[] gredu; + gredu = 0; + } + } + + // Pressure Independent Multi-yield, by Quan Gu + else if (strcmp(argv[1], "MultiYieldSurfaceClay") == 0) { + const int numParam = 6; + const int totParam = 10; + int tag; + double param[totParam]; + param[6] = 0.0; + param[7] = 100.; + param[8] = 0.0; + param[9] = 20; + + const char *arg[] = {"nd", + "rho", + "refShearModul", + "refBulkModul", + "cohesi", + "peakShearStra", + "frictionAng (=0)", + "refPress (=100)", + "pressDependCoe (=0.0)", + "numberOfYieldSurf (=20)"}; + if (argc < (3 + numParam)) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial MultiYieldSurfaceClay tag? " << arg[0]; + opserr << "? " + << "\n"; + opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " + << "\n"; + opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " + << "\n"; + opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid MultiYieldSurfaceClay tag" << "\n"; + return TCL_ERROR; + } + + for (int i = 3; (i < argc && i < 13); ++i) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial MultiYieldSurfaceClay: " << tag << "\n"; + return TCL_ERROR; + } + + static double *gredu = 0; + // user defined yield surfaces + if (param[9] < 0 && param[9] > -40) { + param[9] = -int(param[9]); + gredu = new double[int(2 * param[9])]; + for (int i = 0; i < 2 * param[9]; ++i) + if (Tcl_GetDouble(interp, argv[i + 13], &gredu[i]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial MultiYieldSurfaceClay: " << tag << "\n"; + return TCL_ERROR; + } + } + + MultiYieldSurfaceClay *temp = new MultiYieldSurfaceClay( + tag, param[0], param[1], param[2], param[3], param[4], param[5], + param[6], param[7], param[8], param[9], gredu); + theMaterial = temp; + + if (gredu != 0) { + delete[] gredu; + gredu = 0; + } + } + // ============ + + // Pressure Dependent Multi-yield, by ZHY + else if (strcmp(argv[1], "PressureDependMultiYield") == 0) { + const int numParam = 15; + const int totParam = 24; + int tag; + double param[totParam]; + param[15] = 20; + param[16] = 0.6; + param[17] = 0.9; + param[18] = 0.02; + param[19] = 0.7; + param[20] = 101.; + param[21] = .3; + param[22] = 0.; + param[23] = 1.; + + const char *arg[] = {"nd", + "rho", + "refShearModul", + "refBulkModul", + "frictionAng", + "peakShearStra", + "refPress", + "pressDependCoe", + "phaseTransformAngle", + "contractionParam1", + "dilationParam1", + "dilationParam2", + "liquefactionParam1", + "liquefactionParam2", + "liquefactionParam4", + "numberOfYieldSurf (=20)", + "e (=0.6)", + "volLimit1 (=0.9)", + "volLimit2 (=0.02)", + "volLimit3 (=0.7)", + "Atmospheric pressure (=101)", + "cohesi (=.5)", + "Hv (=0)", + "Pv (=1.)"}; + if (argc < (3 + numParam)) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PressureDependMultiYield tag? " << arg[0]; + opserr << "? " + << "\n"; + opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " + << "\n"; + opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " + << "\n"; + opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " + << "\n"; + opserr << arg[10] << "? " << arg[11] << "? " << arg[12] << "? " + << "\n"; + opserr << arg[13] << "? " << arg[14] << "? " << arg[15] << "? " + << "\n"; + opserr << arg[16] << "? " << arg[17] << "? " << arg[18] << "? " + << "\n"; + opserr << arg[19] << "? " << arg[20] << "? " << arg[21] << "? " << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid PressureDependMultiYield tag" << "\n"; + return TCL_ERROR; + } + + for (int i = 3; (i < argc && i < 19); ++i) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial PressureDependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + + static double *gredu = 0; + // user defined yield surfaces + if (param[15] < 0 && param[15] > -40) { + param[15] = -int(param[15]); + gredu = new double[int(2 * param[15])]; + + for (int i = 0; i < 2 * param[15]; ++i) + if (Tcl_GetDouble(interp, argv[i + 19], &gredu[i]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + } + + if (gredu != 0) { + for (int i = 19 + int(2 * param[15]); i < argc; ++i) + if (Tcl_GetDouble(interp, argv[i], + ¶m[i - 3 - int(2 * param[15])]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[15])] + << "\n"; + opserr << "nDMaterial PressureDependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + } else { + for (int i = 19; i < argc; ++i) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[15])] + << "\n"; + opserr << "nDMaterial PressureDependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + } + + PressureDependMultiYield *temp = new PressureDependMultiYield( + tag, param[0], param[1], param[2], param[3], param[4], param[5], + param[6], param[7], param[8], param[9], param[10], param[11], param[12], + param[13], param[14], param[15], gredu, param[16], param[17], param[18], + param[19], param[20], param[21], param[22], param[23]); + + theMaterial = temp; + if (gredu != 0) { + delete[] gredu; + gredu = 0; + } + } + + // Pressure Dependent Multi-yield, by ZHY + else if (strcmp(argv[1], "PressureDependMultiYield02") == 0) { + const int numParam = 13; + const int totParam = 26; + int tag; + double param[totParam]; + param[numParam] = 20; + param[numParam + 1] = 5.0; + param[numParam + 2] = 3.; + param[numParam + 3] = 1.; + param[numParam + 4] = 0.; + param[numParam + 5] = 0.6; + param[numParam + 6] = 0.9; + param[numParam + 7] = 0.02; + param[numParam + 8] = 0.7; + param[numParam + 9] = 101.; + param[numParam +10] = 0.1; + param[numParam +11] = 0.; + param[numParam +12] = 1.; + + const char *arg[] = {"nd", + "rho", + "refShearModul", + "refBulkModul", + "frictionAng", + "peakShearStra", + "refPress", + "pressDependCoe", + "phaseTransformAngle", + "contractionParam1", + "contractionParam3", + "dilationParam1", + "dilationParam3", + "numberOfYieldSurf (=20)", + "contractionParam2=5.0", + "dilationParam2=3.0", + "liquefactionParam1=1.0", + "liquefactionParam2=0.0", + "e (=0.6)", + "volLimit1 (=0.9)", + "volLimit2 (=0.02)", + "volLimit3 (=0.7)", + "Atmospheric pressure (=101)", + "cohesi (=.1)", + "Hv (=0)", + "Pv (=1.)"}; + if (argc < (3 + numParam)) { + opserr << "WARNING insufficient arguments\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid PressureDependMultiYield02 tag" << "\n"; + return TCL_ERROR; + } + + int in = 17; + for (int i = 3; (i < argc && i < in); ++i) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial PressureDependMultiYield02: " << tag << "\n"; + return TCL_ERROR; + } + + static double *gredu = 0; + + // user defined yield surfaces + if (param[numParam] < 0 && param[numParam] > -100) { + param[numParam] = -int(param[numParam]); + gredu = new double[int(2 * param[numParam])]; + + for (int i = 0; i < 2 * param[numParam]; ++i) + if (Tcl_GetDouble(interp, argv[i + in], &gredu[i]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; + return TCL_ERROR; + } + } + + if (gredu != 0) { + for (int i = in + int(2 * param[numParam]); i < argc; ++i) + if (Tcl_GetDouble(interp, argv[i], + ¶m[i - 3 - int(2 * param[numParam])]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[numParam])] + << "\n"; + opserr << "nDMaterial PressureDependMultiYield02: " << tag << "\n"; + return TCL_ERROR; + } + } else { + for (int i = in; i < argc; ++i) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[numParam])] + << "\n"; + opserr << "nDMaterial PressureDependMultiYield02: " << tag << "\n"; + return TCL_ERROR; + } + } + + PressureDependMultiYield02 *temp = new PressureDependMultiYield02( + tag, param[0], param[1], param[2], param[3], param[4], param[5], + param[6], param[7], param[8], param[9], param[10], param[11], param[12], + param[13], gredu, param[14], param[15], param[16], param[17], param[18], + param[19], param[20], param[21], param[22], param[23], param[24], + param[25]); + + theMaterial = temp; + if (gredu != 0) { + delete[] gredu; + gredu = 0; + } + } + + // nDMaterial PressureDependMultiYield03 $tag $nd $rho $refShearModul + // $refBulkModul $frictionAng $peakShearStra $refPress $pressDependCoe + // $PTAng $mType $ca $cb $cc $cd $ce $da $db $dc <$noYieldSurf=20 + // <$r1 $Gs1 …> $liquefac1=1. $liquefac2=0. $pa=101 <$c=1.73>> + // PressureDependMultiYield03 (based on PressureDependMultiYield02). + else if (strcmp(argv[1], "PressureDependMultiYield03") == 0) { + const int numParam = 18; + const int totParam = 23; + int tag; + double param[totParam]; + param[numParam] = 20; + param[numParam + 1] = 1.; + param[numParam + 2] = 0.; + param[numParam + 3] = 101.; + param[numParam + 4] = 1.73; + + const char *arg[] = {"nd", + "rho", + "refShearModul", + "refBulkModul", + "frictionAng", + "peakShearStra", + "refPress", + "pressDependCoe", + "phaseTransformAngle", + "mType", + "ca", + "cb", + "cc", + "cd", + "ce", + "da", + "db", + "dc", + "numberOfYieldSurf (=20)", + "liquefactionParam1=1.0", + "liquefactionParam2=0.0", + "Atmospheric pressure (=101)", + "cohesi (=1.73)"}; + + if (argc < (3 + numParam)) { // 3 refers to "nDMaterial + // PressureDependMultiYield03 $tag" + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PressureDependMultiYield03 tag? " << arg[0]; + opserr << "? " + << "\n"; + opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " + << "\n"; + opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " + << "\n"; + opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " + << "\n"; + opserr << arg[10] << "? " << arg[11] << "? " << arg[12] << "? " + << "\n"; + opserr << arg[13] << "? " << arg[14] << "? " << arg[15] << "? " + << "\n"; + opserr << arg[16] << "? " << arg[17] << "? " << arg[18] << "? " + << "\n"; + opserr << arg[19] << "? " << arg[20] << "? " << arg[21] << "? " << arg[22] + << "? " << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid PressureDependMultiYield03 tag" << "\n"; + return TCL_ERROR; + } + + int in = 22; + for (int i = 3; (i < argc && i < in); ++i) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + return TCL_ERROR; + } + + static double *gredu = 0; + + // user defined yield surfaces + if (param[numParam] < 0 && param[numParam] > -100) { + param[numParam] = -int(param[numParam]); + gredu = new double[int(2 * param[numParam])]; + + for (int i = 0; i < 2 * param[numParam]; ++i) + if (Tcl_GetDouble(interp, argv[i + in], &gredu[i]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + return TCL_ERROR; + } + } + + if (gredu != 0) { + for (int i = in + int(2 * param[numParam]); i < argc; ++i) + if (Tcl_GetDouble(interp, argv[i], + ¶m[i - 3 - int(2 * param[numParam])]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[numParam])] + << "\n"; + opserr << "nDMaterial PressureDependMultiYield03: " << tag << "\n"; + return TCL_ERROR; + } + } else { + for (int i = in; i < argc; ++i) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[numParam])] + << "\n"; + opserr << "nDMaterial PressureDependMultiYield03: " << tag << "\n"; + return TCL_ERROR; + } + } + + PressureDependMultiYield03 *temp = new PressureDependMultiYield03( + tag, param[0], param[1], param[2], param[3], param[4], param[5], + param[6], param[7], param[8], param[9], param[10], param[11], param[12], + param[13], param[14], param[15], param[16], param[17], param[18], gredu, + param[19], param[20], param[21], param[22]); + + theMaterial = temp; + if (gredu != 0) { + delete[] gredu; + gredu = 0; + } + } + + // Fluid Solid Porous, by ZHY + else if (strcmp(argv[1], "FluidSolidPorous") == 0) { + + int tag; + double param[4]; + const char *arg[] = {"nd", "soilMatTag", "combinedBulkModul", + "Atmospheric pressure"}; + if (argc < 6) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial FluidSolidPorous tag? " << arg[0]; + opserr << "? " + << "\n"; + opserr << arg[1] << "? " << arg[2] << "? " << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid FluidSolidPorous tag" << "\n"; + return TCL_ERROR; + } + + for (int i = 3; i < 6; ++i) + if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[i - 3] << "\n"; + opserr << "nDMaterial FluidSolidPorous: " << tag << "\n"; + return TCL_ERROR; + } + + NDMaterial *soil = builder->getTypedObject(param[1]); + if (soil == nullptr) + return TCL_ERROR; + + + param[3] = 101.; + if (argc == 7) { + if (Tcl_GetDouble(interp, argv[6], ¶m[3]) != TCL_OK) { + opserr << "WARNING invalid " << arg[3] << "\n"; + opserr << "nDMaterial FluidSolidPorous: " << tag << "\n"; + return TCL_ERROR; + } + } + + theMaterial = + new FluidSolidPorousMaterial(tag, param[0], *soil, param[2], param[3]); + } + + // ----- Cap plasticity model ------ // Quan Gu & ZhiJian Qiu 2013 + + // format nDmaterial CapPlasticity $tag $ndm $rho $G $K $X $D $W $R $lambda + // $theta $beta $alpha $T $tol + else if (strcmp(argv[1], "CapPlasticity") == 0) { + + int tag; + int ndm = 3; + double rho = 0.0; + double G = 1.0e10; + double K = 1.1e10; + double X = 1.1032e8; + double D = 4.6412e-10; + double W = 0.42; + double R = 4.43; + double lambda = 7.9979e6; + double theta = 0.11; + double beta = 6.3816e-8; + double alpha = 2.6614e7; + double T = -2.0684e6; + double tol = 1.0e-10; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &ndm) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity nd" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &rho) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity rho" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &G) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity G" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &K) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity K" << "\n"; + return TCL_ERROR; + } + + if (argc > 7) { + + if (Tcl_GetDouble(interp, argv[7], &X) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity X" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[8], &D) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity D" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[9], &W) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity W" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10], &R) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity R" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[11], &lambda) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity lambda" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[12], &theta) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity theta" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[13], &beta) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity beta" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[14], &alpha) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity alpha" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[15], &T) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity T" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[16], &tol) != TCL_OK) { + opserr << "WARNING invalid CapPlasticity tol" << "\n"; + return TCL_ERROR; + } + } + + theMaterial = new CapPlasticity(tag, G, K, rho, X, D, W, R, lambda, theta, + beta, alpha, T, ndm, tol); + + } + + // start Yuli Huang & Xinzheng Lu PlateFromPlaneStressMaterial + else if (strcmp(argv[1], "PlateFromPlaneStressMaterial") == 0 || + strcmp(argv[1], "PlateFromPlaneStress") == 0) { + if (argc < 5) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PlateFromPlaneStress tag? matTag? gmod?" + << "\n"; + return TCL_ERROR; + } + + int tag, matTag; + double gmod; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid nDMaterial PlateFromPlaneStress tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { + opserr << "WARNING invalid matTag" << "\n"; + opserr << "PlateFromPlaneStress: " << tag << "\n"; + return TCL_ERROR; + } + + NDMaterial *theMat = builder->getTypedObject(matTag); + if (theMat == nullptr) + return TCL_ERROR; + + if (Tcl_GetDouble(interp, argv[4], &gmod) != TCL_OK) { + opserr << "WARNING invalid gmod" << "\n"; + opserr << "PlateFromPlaneStress: " << tag << "\n"; + return TCL_ERROR; + } + + theMaterial = new PlateFromPlaneStressMaterial(tag, *theMat, gmod); + } + + // start Yuli Huang & Xinzheng Lu ConcreteS + else if (strcmp(argv[1], "ConcreteS") == 0) { + if (argc < 8) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial ConcreteS tag? E? nu? fc? ft? Es?" << "\n"; + return TCL_ERROR; + } + + int tag; + double E, nu, fc, ft, Es; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid nDMaterial ConcreteS tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { + opserr << "WARNING invalid E" << "\n"; + opserr << "ConcreteS: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &nu) != TCL_OK) { + opserr << "WARNING invalid nu" << "\n"; + opserr << "ConcreteS: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &fc) != TCL_OK) { + opserr << "WARNING invalid fc" << "\n"; + opserr << "ConcreteS: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &ft) != TCL_OK) { + opserr << "WARNING invalid ft" << "\n"; + opserr << "ConcreteS: " << tag << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[7], &Es) != TCL_OK) { + opserr << "WARNING invalid Es" << "\n"; + opserr << "ConcreteS: " << tag << "\n"; + return TCL_ERROR; + } + + theMaterial = new ConcreteS(tag, E, nu, fc, ft, Es); + } + // end Yuli Huang & Xinzheng Lu ConcreteS + + // start Yuli Huang & Xinzheng Lu PlaneStressUserMaterial + else if (strcmp(argv[1], "PlaneStressUserMaterial") == 0) { + if (argc < 6) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PlaneStressUserMaterial tag? nstatevs? " + "nprops? prop1? ... propn?" + << "\n"; + return TCL_ERROR; + } + + int tag, nstatevs, nprops; + double *props, p; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid nDMaterial PlaneStressUserMaterial tag" + << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &nstatevs) != TCL_OK) { + opserr << "WARNING invalid nDMaterial PlaneStressUserMaterial nstatevs" + << "\n"; + return TCL_ERROR; + } + + if (nstatevs < 1) + nstatevs = 1; + + if (Tcl_GetInt(interp, argv[4], &nprops) != TCL_OK) { + opserr << "WARNING invalid nDMaterial PlaneStressUserMaterial nprops" + << "\n"; + return TCL_ERROR; + } + + if (nprops < 1) + nprops = 1; + + props = new double[nprops]; + for (int i = 0; i < nprops; ++i) { + if (Tcl_GetDouble(interp, argv[5 + i], &p) != TCL_OK) { + opserr << "WARNING invalid prop" << "\n"; + opserr << "PlaneStressUserMaterial: " << tag << "\n"; + return TCL_ERROR; + } + props[i] = p; + } + + theMaterial = new PlaneStressUserMaterial(tag, nstatevs, nprops, props); + + if (props != nullptr) + delete [] props; + } + // end Yuli Huang & Xinzheng Lu PlaneStressUserMaterial + + else if (strcmp(argv[1], "ConcreteMcftNonLinear7") == 0 || + strcmp(argv[1], "ConcreteMcftNonLinear5") == 0) { + if (argc < 11) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial ConcreteMcftNonlinear7 tag? fcu? ecu? Ec? " + "fcr? Esv? fyv? alphaV? RoV?" + << "\n"; + return TCL_ERROR; + } + + int tag = 0; + double fcu = 0.0; + double ecu = 0.0; + double Ec = 0.0; + double fcr = 0.0; + double Esv = 0.0; + double fyv = 0.0; + double alphaV = 0.0; + double RoV = 0.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid ConcreteMcftNonlinear7: tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &fcu) != TCL_OK) { + opserr << "WARNING invalid fcu\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &ecu) != TCL_OK) { + opserr << "WARNING invalid ecu\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &Ec) != TCL_OK) { + opserr << "WARNING invalid Ec\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &fcr) != TCL_OK) { + opserr << "WARNING invalid fcr\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[7], &Esv) != TCL_OK) { + opserr << "WARNING invalid Esv\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[8], &fyv) != TCL_OK) { + opserr << "WARNING invalid fyv\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[9], &alphaV) != TCL_OK) { + opserr << "WARNING invalid alphaV\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10], &RoV) != TCL_OK) { + opserr << "WARNING invalid RoV\n"; + return TCL_ERROR; + } + + if (strcmp(argv[1], "ConcreteMcftNonLinear7") == 0) + theMaterial = new ConcreteMcftNonLinear7(tag, fcu, ecu, Ec, fcr, Esv, fyv, + alphaV, RoV); + else + theMaterial = new ConcreteMcftNonLinear5(tag, fcu, ecu, Ec, fcr, Esv, fyv, + alphaV, RoV); + } + + else if (strcmp(argv[1], "Bidirectional") == 0) { + opserr << "nDMaterial Bidirectional is now a section model, please " + << "change to \'section Bidirectional\'" << "\n"; + return TCL_ERROR; + } + + //------------------------------------------------------------- + else if (strcmp(argv[1], "PlateFromPlaneStressThermal") == 0) { + if (argc < 5) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PlateFromPlaneStress tag? matTag? gmod?" + << "\n"; + return TCL_ERROR; + } + + int tag, matTag; + double gmod; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid nDMaterial PlateFromPlaneStress tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { + opserr << "WARNING invalid matTag" << "\n"; + opserr << "PlateFromPlaneStress: " << tag << "\n"; + return TCL_ERROR; + } + + NDMaterial *theMat = builder->getTypedObject(matTag); + if (theMat == nullptr) + return TCL_ERROR; + + if (Tcl_GetDouble(interp, argv[4], &gmod) != TCL_OK) { + opserr << "WARNING invalid gmod" << "\n"; + return TCL_ERROR; + } + + theMaterial = new PlateFromPlaneStressMaterialThermal(tag, *theMat, gmod); + } + + +#if defined(OPSDEF_Material_FEAP) + else { + theMaterial = TclBasicBuilder_addFeapMaterial(clientData, interp, argc, argv); + } +#endif // _OPS_Material_FEAP + + if (theMaterial == 0) { + // + // maybe element in a class package already loaded + // loop through linked list of loaded functions comparing names & if find + // call it + // + + NDMaterialPackageCommand *matCommands = theNDMaterialPackageCommands; + bool found = false; + while (matCommands != NULL && found == false) { + if (strcmp(argv[1], matCommands->funcName) == 0) { + theMaterial = (NDMaterial *)(*(matCommands->funcPtr))(); + found = true; + ; + } else + matCommands = matCommands->next; + } + } + + // + // check to see if element is a procedure + // the proc may already have been loaded from a package or may exist in a + // package yet to be loaded + // + if (theMaterial == nullptr) { +#if 0 + // maybe material in a routine + // + + char *matType = new char[strlen(argv[1]) + 1]; + strcpy(matType, argv[1]); + matObj *matObject = OPS_GetMaterialType(matType, strlen(matType)); + + delete[] matType; + + if (matObject != 0) { + + theMaterial = Tcl_addWrapperNDMaterial(matObject, clientData, interp, + argc, argv); + + if (theMaterial == 0) + delete matObject; + } +#endif + } + + // + // maybe material class exists in a package yet to be loaded + // + + if (theMaterial == 0) { + + void *libHandle; + void *(*funcPtr)(); + + int matNameLength = strlen(argv[1]); + char *tclFuncName = new char[matNameLength + 12]; + strcpy(tclFuncName, "OPS_"); + strcpy(&tclFuncName[4], argv[1]); + int res = + getLibraryFunction(argv[1], tclFuncName, &libHandle, (void **)&funcPtr); + + delete[] tclFuncName; + + if (res == 0) { + // + // add loaded function to list of functions + // + char *matName = new char[matNameLength + 1]; + strcpy(matName, argv[1]); + NDMaterialPackageCommand *theMatCommand = new NDMaterialPackageCommand; + theMatCommand->funcPtr = funcPtr; + theMatCommand->funcName = matName; + theMatCommand->next = theNDMaterialPackageCommands; + theNDMaterialPackageCommands = theMatCommand; + + theMaterial = (NDMaterial *)(*funcPtr)(); + } + } + + if (theMaterial == nullptr) { + opserr << "WARNING could not create nDMaterial " << argv[1]; + return TCL_ERROR; + } + + // Now add the material to the modelBuilder + if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { + + opserr << "WARNING could not add material to the domain\n"; + opserr << *theMaterial << "\n"; + delete theMaterial; + return TCL_ERROR; + } + + return TCL_OK; +} diff --git a/SRC/runtime/commands/modeling/material/plastic.cpp b/SRC/runtime/commands/modeling/material/plastic.cpp new file mode 100644 index 0000000000..a2b73363f9 --- /dev/null +++ b/SRC/runtime/commands/modeling/material/plastic.cpp @@ -0,0 +1,1009 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// +// Description: This file implements a unified parser for plasticity materials. +// +// Written: cmp +// April 2025 +// +#include +#include +#include +#include +#include +#include +#include + +#include "isotropy.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +template +static inline int +TclCommand_newPlasticParser(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + + assert(clientData != nullptr); + + ArgumentTracker tracker; + std::set positional; + + + // Count the number of required isotropic parameters. + // This is needed to accommodate uniaxial materials, which generally + // only require one isotropic parameter (ie, E). + int niso = ( + (Position::E < Position::EndRequired) + + (Position::G < Position::EndRequired) + + (Position::Nu < Position::EndRequired) + + (Position::K < Position::EndRequired) + + (Position::Lambda < Position::EndRequired) + ); + + // + // Values we're parsing for + // + int tag; + double density = 0.0; + // Isotropy + IsotropicConstants consts {}; + // Plasticity + double Fy, Fsat = 0, Fo = 0; + // Hardening + double Hiso=0, + Hkin=0; + struct { + double theta = 1.0; + double Hsat = 0; + double Hmix = 0; + } hard{}; + bool mix = Position::Theta < Position::End; + // Viscosity + double eta=0; + // Drucker-Prager + double rho = 0, rho_bar = 0; + double atm = 101.0; + double delta2 = 0.0; + + // + // 1. Keyword arguments + // + + // Isotropy + IsotropicParse iso {consts, niso}; + if (TclCommand_setIsotropicParameters((ClientData)&iso, interp, argc, argv) == TCL_OK) { + tracker.consume(Position::E); + tracker.consume(Position::G); + tracker.consume(Position::Nu); + tracker.consume(Position::K); + tracker.consume(Position::Lambda); + } + + // Other arguments + for (int i=2; i= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &density) != TCL_OK) { + opserr << "Invalid density value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + } + // Yielding + else if (strcmp(argv[i], "-Fy") == 0 || + strcmp(argv[i], "-fy") == 0 || + strcmp(argv[i], "-yield-stress") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Fy) != TCL_OK) { + opserr << "Invalid yield stress value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::YieldStress); + } + else if ((strcmp(argv[i], "-Fo") == 0) || + (strcmp(argv[i], "-Ko") == 0)) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Fo) != TCL_OK) { + opserr << "Invalid initial saturation stress value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::SatStress0); + } + else if ((strcmp(argv[i], "-Fs") == 0) || + (strcmp(argv[i], "-Fsat") == 0) || + (strcmp(argv[i], "-fsat") == 0)) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Fsat) != TCL_OK) { + opserr << "Invalid saturation stress value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::SatStress); + } + // + // Hardening + // + else if (strcmp(argv[i], "-Hiso") == 0 || strcmp(argv[i], "-isotropic-hardening") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Hiso) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + mix = false; + tracker.consume(Position::Hiso); + } + else if (strcmp(argv[i], "-Hkin") == 0 || strcmp(argv[i], "-kinematic-hardening") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &Hkin) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + mix = false; + tracker.consume(Position::Hkin); + } + else if (strcmp(argv[i], "-H") == 0 || strcmp(argv[i], "-Hmix") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &hard.Hmix) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + mix = true; + tracker.consume(Position::Hmix); + tracker.consume(Position::Hiso); + tracker.consume(Position::Hkin); + } + + else if (strcmp(argv[i], "-theta") == 0 || strcmp(argv[i], "-mix") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &hard.theta) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Theta); + } + else if (strcmp(argv[i], "-Hsat") == 0 || + strcmp(argv[i], "-delta") == 0 || + strcmp(argv[i], "-delta1") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &hard.Hsat) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Hsat); + } + // Drucker-Prager + else if (strcmp(argv[i], "-delta2") == 0 || + strcmp(argv[i], "-Hten") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &delta2) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Delta2); + } + else if (strcmp(argv[i], "-atm") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &atm) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Atm); + } + else if (strcmp(argv[i], "-Rvol") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &rho) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Rho); + } + else if (strcmp(argv[i], "-Rbar") == 0 || + strcmp(argv[i], "-rhoBar") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &rho_bar) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::RhoBar); + } + // Viscosity + else if (strcmp(argv[i], "-eta") == 0 || strcmp(argv[i], "-viscosity") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &eta) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Position::Eta); + } + else + positional.insert(i); + } + + // + // 2) Positional arguments + // + for (int i : positional) { + + if (tracker.current() == Position::EndRequired) + tracker.increment(); + + switch (tracker.current()) { + // General + case Position::Tag : + if (Tcl_GetInt(interp, argv[i], &tag) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid section Elastic tag.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::Density: + if (Tcl_GetDouble (interp, argv[i], &density) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid density.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + // Isotropy + case Position::E: + if (Tcl_GetDouble (interp, argv[i], &consts.E) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid E.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::G: + if (Tcl_GetDouble (interp, argv[i], &consts.G) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid G.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::K: + if (Tcl_GetDouble (interp, argv[i], &consts.K) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid K.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::Nu: + if (Tcl_GetDouble (interp, argv[i], &consts.nu) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid nu.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::Lambda: + if (Tcl_GetDouble (interp, argv[i], &consts.lambda) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Lame lambda.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + // Yielding + case Position::YieldStress: + if (Tcl_GetDouble(interp, argv[i], &Fy) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid yield stress.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::SatStress: + if (Tcl_GetDouble (interp, argv[i], &Fsat) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid saturation stress.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::SatStress0: + if (Tcl_GetDouble (interp, argv[i], &Fo) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid initial saturation stress.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + // Hardening + case Position::Hiso: + if (Tcl_GetDouble (interp, argv[i], &Hiso) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Hiso.\n"; + return TCL_ERROR; + } else { + tracker.consume(Position::Hiso); + tracker.consume(Position::Theta); + break; + } + case Position::Hkin: + if (Tcl_GetDouble (interp, argv[i], &Hkin) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Hkin.\n"; + return TCL_ERROR; + } else { + tracker.consume(Position::Hkin); + tracker.consume(Position::Theta); + break; + } + case Position::Hsat: + if (Tcl_GetDouble (interp, argv[i], &hard.Hsat) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Hsat.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::Hmix: + if (Tcl_GetDouble (interp, argv[i], &hard.Hmix) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Hmix.\n"; + return TCL_ERROR; + } else { + mix = true; + tracker.consume(Position::Hmix); + tracker.consume(Position::Hiso); + tracker.consume(Position::Hkin); + break; + } + case Position::Theta: + if (Tcl_GetDouble (interp, argv[i], &hard.theta) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid hardening theta.\n"; + return TCL_ERROR; + } else { + tracker.consume(Position::Theta); + break; + } + + // Drucker + case Position::Delta2: + if (Tcl_GetDouble (interp, argv[i], &delta2) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid delta2.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::Rho: + if (Tcl_GetDouble (interp, argv[i], &rho) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Rvol.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::Atm: + if (Tcl_GetDouble (interp, argv[i], &atm) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid atm.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + case Position::RhoBar: + if (Tcl_GetDouble (interp, argv[i], &rho_bar) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid Rbar.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + // Viscosity + case Position::Eta: + if (Tcl_GetDouble (interp, argv[i], &eta) != TCL_OK) { + opserr << OpenSees::PromptParseError << "invalid eta.\n"; + return TCL_ERROR; + } else { + tracker.increment(); + break; + } + + case Position::EndRequired: + // This will not be reached + break; + + case Position::End: + opserr << OpenSees::PromptParseError << "unexpected argument " << argv[i] << ".\n"; + return TCL_ERROR; + } + } + + if (mix) { + Hiso = hard.theta * hard.Hmix; + Hkin = (1.0 - hard.theta) * hard.Hmix; + } + + // + // 3. Check for required arguments + // + if (tracker.current() < Position::EndRequired) { + opserr << OpenSees::PromptParseError + << "missing required arguments: "; + while (tracker.current() != Position::EndRequired) { + switch (tracker.current()) { + case Position::Tag : + opserr << "tag "; + break; + // Isotropy + case Position::E: + opserr << "E "; + break; + case Position::G: + opserr << "G "; + break; + case Position::K: + opserr << "K "; + break; + case Position::Nu: + opserr << "nu "; + break; + case Position::Lambda: + opserr << "lambda "; + break; + // Yielding + case Position::YieldStress: + opserr << "Fy "; + break; + case Position::SatStress: + opserr << "Fsat "; + break; + case Position::SatStress0: + opserr << "Fo "; + break; + // Hardening + case Position::Hiso: + opserr << "Hiso "; + break; + case Position::Hkin: + opserr << "Hkin "; + break; + case Position::Hmix: + opserr << "Hmix "; + break; + case Position::Theta: + opserr << "theta "; + break; + + // Drucker-Prager + case Position::Delta2: + opserr << "Hten "; + break; + case Position::Rho: + opserr << "Rvol "; + break; + case Position::RhoBar: + opserr << "Rbar "; + break; + + // Viscosity + case Position::Eta: + opserr << "eta "; + break; + + case Position::EndRequired: + case Position::End: + default: + break; + } + + if (tracker.current() == Position::EndRequired) + break; + + tracker.consume(tracker.current()); + } + + opserr << "\n"; + + return TCL_ERROR; + } + + // + // Create the material (TODO) + // + BasicModelBuilder *builder = static_cast(clientData); + if ((strcmp(argv[1], "Hardening") == 0) || + (strcmp(argv[1], "Steel") == 0)) { + + UniaxialMaterial* theMaterial = new HardeningMaterial(tag, consts.E, Fy, Hiso, Hkin, eta); + if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { + delete theMaterial; + return TCL_ERROR; + } + return TCL_OK; + } + + else if (strcmp(argv[1], "J2BeamFiber") == 0) { + NDMaterial* theMaterial = nullptr; + if (builder->getNDM() == 2) + theMaterial = new J2BeamFiber2d(tag, consts.E, consts.G, Fy, Hkin, Hiso); + else + theMaterial = new J2BeamFiber3d(tag, consts.E, consts.G, Fy, Hkin, Hiso); + + if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { + delete theMaterial; + return TCL_ERROR; + } + return TCL_OK; + } + + else if ((strcmp(argv[1], "Simplified3DJ2") == 0) || + (strcmp(argv[1], "SimplifiedJ2") == 0) || + (strcmp(argv[1], "J2Simplified") == 0) || + (strcmp(argv[1], "J2L") == 0) || + (strcmp(argv[1], "PlaneStressSimplifiedJ2") == 0) || + (strcmp(argv[1], "3DJ2") == 0)) { + + NDMaterial* theMaterial = new SimplifiedJ2(tag, 3, consts.G, consts.K, Fy, Hkin, Hiso, density); + if (strcmp(argv[1], "PlaneStressSimplifiedJ2") == 0) { + theMaterial = new PlaneStressSimplifiedJ2(tag, 2, *theMaterial); + } + if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { + delete theMaterial; + return TCL_ERROR; + } + return TCL_OK; + } + + else if ((strcmp(argv[1], "J2") == 0) || + (strcmp(argv[1], "J2N") == 0) || + (strcmp(argv[1], "J2Plasticity") == 0)) { + + NDMaterial* theMaterial = new J2Plasticity(tag, 0, consts.K, consts.G, + Fy, Fsat, hard.Hsat, Hiso, eta, density); + if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { + delete theMaterial; + return TCL_ERROR; + } + return TCL_OK; + } + + else if ((strcmp(argv[1], "J2PlasticityThermal") == 0) || + (strcmp(argv[1], "J2Thermal") == 0)) { + NDMaterial* theMaterial = new J2PlasticityThermal(tag, 0, consts.K, consts.G, + Fy, Fsat, hard.Hsat, Hiso, eta, density); + if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { + delete theMaterial; + return TCL_ERROR; + } + return TCL_OK; + } + else if (strcmp(argv[1], "DruckerPrager") == 0 || + strcmp(argv[1], "DP") == 0) { + + NDMaterial* theMaterial = new DruckerPrager(tag, 0, consts.K, consts.G, + Fy, rho, rho_bar, Fsat, Fo, + hard.Hsat, delta2, hard.Hmix, hard.theta, density, atm); + if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { + delete theMaterial; + return TCL_ERROR; + } + return TCL_OK; + } + return TCL_ERROR; +} + + +int +TclCommand_newPlasticMaterial(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + // + if (strcmp(argv[1], "Simplified3DJ2") == 0 || + strcmp(argv[1], "SimplifiedJ2") == 0 || + strcmp(argv[1], "J2Simplified") == 0 || + strcmp(argv[1], "J2L") == 0 || + strcmp(argv[1], "3DJ2") == 0 || + strcmp(argv[1], "PlaneStressSimplifiedJ2") == 0) { + + // "SimplifiedJ2" tag? G? K? Fy? Hkin? Hiso? + enum class Position : int { + Tag, G, K, YieldStress, EndRequired, + Hkin, Hiso, + End, + E, Nu, Lambda, Eta, Theta, Hmix, Hsat, + SatStress, SatStress0, + Delta2, Rho, RhoBar, Atm, + Density + }; + return TclCommand_newPlasticParser(clientData, interp, argc, argv); + } + else if (strcmp(argv[1], "J2BeamFiber") == 0) { + // J2BeamFiber $tag $E $v $sigmaY $Hiso $Hkin <$rho> + enum class Position : int { + Tag, E, G, YieldStress, EndRequired, + Hkin, Hiso, + Density, + End, + Nu, K, Eta, Lambda, Theta, Hmix, Hsat, + SatStress, SatStress0, + Delta2, Rho, RhoBar, Atm + }; + return TclCommand_newPlasticParser(clientData, interp, argc, argv); + } + + // "UniaxialJ2Plasticity" tag? E? sigmaY? Hkin? + else if (strcmp(argv[1], "UniaxialJ2Plasticity") == 0) { + } + + else if (strcmp(argv[1], "HardeningMaterial") == 0 || + strcmp(argv[1], "Hardening") == 0 || + strcmp(argv[1], "Hardening2") == 0 || + strcmp(argv[1], "Steel") == 0) { + + // "Hardening" tag? E? Y? Hiso? Hkin? + enum class Position : int { + Tag, E, YieldStress, Hiso, EndRequired, + Hkin, + End, + // Keyword-only arguments + Density, + // Unused + Eta, G, K, Nu, Lambda, Theta, Hmix, Hsat, + SatStress, SatStress0, + Delta2, Rho, RhoBar, Atm, + }; + return TclCommand_newPlasticParser(clientData, interp, argc, argv); + } + + else if (strcmp(argv[1], "J2") == 0 || + strcmp(argv[1], "J2N") == 0 || + strcmp(argv[1], "J2Plasticity") == 0) { + + // "J2Plasticity" tag? K? G? sig0? sigInf? delta? Hiso? + enum class Position : int { + Tag, K, G, YieldStress, SatStress, Hsat, Hiso, EndRequired, + Eta, End, + E, Nu, Lambda, Hkin, Theta, Hmix, SatStress0, + Delta2, Rho, RhoBar, Atm, + Density + }; + return TclCommand_newPlasticParser(clientData, interp, argc, argv); + } + else if (strcmp(argv[1], "DP") == 0 || + strcmp(argv[1], "DruckerPrager") == 0) { + + // DruckerPrager tag? K? G? sigma_y? rho? rho_bar? Kinf? Ko? delta1? delta2? H? theta? + enum class Position : int { + Tag, K, G, YieldStress, Rho, RhoBar, + SatStress, SatStress0, Hsat, Delta2, Hmix, Theta, EndRequired, + Density, Atm, End, + Eta, E, Nu, Lambda, Hiso, Hkin + }; + return TclCommand_newPlasticParser(clientData, interp, argc, argv); + } + return TCL_ERROR; +} + + +#include +int +TclCommand_newUniaxialJ2Plasticity(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char** const argv) +{ + // ----- 1D J2 Plasticity ---- + if (argc < 7) { + opserr << "WARNING invalid number of arguments\n"; + opserr << "Want: uniaxialMaterial UniaxialJ2Plasticity tag? E? sigmaY? Hkin? " + << endln; + return TCL_ERROR; + } + + int tag; + double E, sigmaY, Hkin, Hiso; + Hiso = 0.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid uniaxialMaterial UniaxialJ2Plasticity tag" + << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { + opserr << "WARNING invalid E\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &sigmaY) != TCL_OK) { + opserr << "WARNING invalid sigmaY\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &Hkin) != TCL_OK) { + opserr << "WARNING invalid Hkin\n"; + return TCL_ERROR; + } + + if (argc >= 7) + if (Tcl_GetDouble(interp, argv[6], &Hiso) != TCL_OK) { + opserr << "WARNING invalid Hiso\n"; + return TCL_ERROR; + } + + // Parsing was successful, allocate the material + UniaxialMaterial* theMaterial = new UniaxialJ2Plasticity(tag, E, sigmaY, Hkin, Hiso); + + assert(clientData != nullptr); + BasicModelBuilder *builder = static_cast(clientData); + builder->addTaggedObject(*theMaterial); + return TCL_OK; +} + + +int +TclCommand_newJ2Simplified(ClientData clientData, Tcl_Interp* interp, int argc, const char** const argv) +{ + + BasicModelBuilder* builder = static_cast(clientData); + + if (argc < 8) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDmaterial Simplified3DJ2 $matTag $G $K $sig0 $Hkin $Hiso" + << "\n"; + return TCL_ERROR; + } + + int tag; + double K, G, sig0, H_kin, H_iso; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &G) != TCL_OK) { + opserr << "WARNING invalid G\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &K) != TCL_OK) { + opserr << "WARNING invalid K\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &sig0) != TCL_OK) { + opserr << "WARNING invalid sig0\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &H_kin) != TCL_OK) { + opserr << "WARNING invalid Hkin\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[7], &H_iso) != TCL_OK) { + opserr << "WARNING invalid Hiso\n"; + return TCL_ERROR; + } + + NDMaterial* theMaterial = nullptr; + + if ((strcmp(argv[1], "Simplified3DJ2") == 0) || + (strcmp(argv[1], "3DJ2") == 0) || + (strcmp(argv[1], "SimplifiedJ2") == 0) || + (strcmp(argv[1], "PlaneStressSimplifiedJ2") == 0)) { + double density = 0.0; + theMaterial = new SimplifiedJ2(tag, 3, G, K, sig0, H_kin, H_iso, density); + + if (strcmp(argv[1], "PlaneStressSimplifiedJ2") == 0) { + theMaterial = new PlaneStressSimplifiedJ2(tag, 2, *theMaterial); + } + } + + // + if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { + delete theMaterial; + return TCL_ERROR; + } + return TCL_OK; +} + + +#if 0 + +int +TclCommand_newJ2Material(ClientData clientData, + Tcl_Interp* interp, + int argc, + const char** const argv) +{ + BasicModelBuilder* builder = static_cast(clientData); + + if (argc < 9) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial J2Plasticity tag? K? G? sig0? sigInf? delta? H? " << "\n"; + return TCL_ERROR; + } + + int tag; + double K, G, sig0, sigInf, delta, H; + double eta = 0.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid J2Plasticity tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &K) != TCL_OK) { + opserr << "WARNING invalid K\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &G) != TCL_OK) { + opserr << "WARNING invalid G\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &sig0) != TCL_OK) { + opserr << "WARNING invalid sig0\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &sigInf) != TCL_OK) { + opserr << "WARNING invalid sigInf\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[7], &delta) != TCL_OK) { + opserr << "WARNING invalid delta\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[8], &H) != TCL_OK) { + opserr << "WARNING invalid H\n"; + return TCL_ERROR; + } + if (argc > 9 && Tcl_GetDouble(interp, argv[9], &eta) != TCL_OK) { + opserr << "WARNING invalid eta\n"; + return TCL_ERROR; + } + + + // + NDMaterial* theMaterial = nullptr; + + if ((strcmp(argv[1], "J2Plasticity") == 0) || + (strcmp(argv[1], "J2") == 0)) { + theMaterial = new J2Plasticity(tag, 0, K, G, sig0, sigInf, delta, H, eta); + } + + if (theMaterial == nullptr) + return TCL_ERROR; + + if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { + delete theMaterial; + return TCL_ERROR; + } + return TCL_OK; +} + +int +TclCommand_newPlasticMaterial(ClientData clientData, Tcl_Interp* interp, int argc, const char**const argv) +{ + if ((strcmp(argv[1], "J2Plasticity") == 0) || (strcmp(argv[1], "J2") == 0)) + { + if (argc < 9) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial J2Plasticity tag? K? G? sig0? sigInf? delta? H? " << "\n"; + return TCL_ERROR; + } + + int tag; + double K, G, sig0, sigInf, delta, H; + double eta = 0.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid J2Plasticity tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &K) != TCL_OK) { + opserr << "WARNING invalid K\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &G) != TCL_OK) { + opserr << "WARNING invalid G\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &sig0) != TCL_OK) { + opserr << "WARNING invalid sig0\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[6], &sigInf) != TCL_OK) { + opserr << "WARNING invalid sigInf\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[7], &delta) != TCL_OK) { + opserr << "WARNING invalid delta\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[8], &H) != TCL_OK) { + opserr << "WARNING invalid H\n"; + return TCL_ERROR; + } + if (argc > 9 && Tcl_GetDouble(interp, argv[9], &eta) != TCL_OK) { + opserr << "WARNING invalid eta\n"; + return TCL_ERROR; + } + + theMaterial = new J2Plasticity(tag, 0, K, G, sig0, sigInf, delta, H, eta); + } +} +#endif diff --git a/SRC/runtime/commands/modeling/material/shell.cpp b/SRC/runtime/commands/modeling/material/shell.cpp new file mode 100644 index 0000000000..8b2ad71555 --- /dev/null +++ b/SRC/runtime/commands/modeling/material/shell.cpp @@ -0,0 +1,252 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// +// Written: rms, MHS, cmp +// Created: 07/99 +// +// Description: This file contains the function invoked when the user invokes +// the section command in the interpreter. +// +// +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +typedef SectionForceDeformation ShellSection; + + +int +TclCommand_addElasticShellSection(ClientData clientData, Tcl_Interp* interp, + int argc, TCL_Char** const argv) +{ + + BasicModelBuilder* builder = static_cast(clientData); + + if (argc < 5) { + opserr << OpenSees::PromptValueError + << "insufficient arguments\n"; + opserr << "Want: section ElasticMembranePlateSection tag? E? nu? h? " + " " + << endln; + return TCL_ERROR; + } + + int tag; + double E, nu, h; + double rho = 0.0; + double Ep_mod = 1.0; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid section ElasticMembranePlateSection tag" + << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid E" << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &nu) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid nu" << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[5], &h) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid h" << endln; + return TCL_ERROR; + } + + if (argc > 6 && Tcl_GetDouble(interp, argv[6], &rho) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid rho" << endln; + return TCL_ERROR; + } + + if (argc > 7 && Tcl_GetDouble(interp, argv[7], &Ep_mod) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid Ep_mod" << endln; + return TCL_ERROR; + } + + builder->addTaggedObject(*new ElasticMembranePlateSection(tag, E, nu, h, rho, Ep_mod)); + return TCL_OK; +} + + +int +TclCommand_ShellSection(ClientData clientData, Tcl_Interp* interp, + Tcl_Size argc, TCL_Char** const argv) +{ + // Pointer to a section that will be added to the model builder + SectionForceDeformation* theSection = nullptr; + BasicModelBuilder *builder = static_cast(clientData); + + if ((strcmp(argv[1], "PlateFiber") == 0) || + (strcmp(argv[1], "PlateFiberThermal") == 0)) { // TODO: add thermal + + if (argc < 5) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: section PlateFiber tag? matTag? h? \n"; + return TCL_ERROR; + } + + int tag; + double h; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid section PlateFiber tag\n"; + return TCL_ERROR; + } + + int matTag; + if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { + opserr << "WARNING invalid material tag " << argv[3] << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[4], &h) != TCL_OK) { + opserr << "WARNING invalid h\n"; + return TCL_ERROR; + } + + NDMaterial* theMaterial = builder->getTypedObject(matTag); + if (theMaterial == nullptr) + return TCL_ERROR; + + theSection = new MembranePlateFiberSection(tag, h, *theMaterial); + } + + else if ((strcmp(argv[1], "LayeredShell") == 0) || + (strcmp(argv[1], "LayeredShellThermal") == 0)) { // TODO: add thermal + + // section LayeredShell tag? nLayers? -or- + + int status = TCL_ERROR; + if (argc < 6) { + opserr << OpenSees::PromptValueError + << "insufficient arguments " << "\n"; + opserr << "Want: section LayeredShell tag? nLayers? mat1? h1? ... matn? hn? " + << endln; + return TCL_ERROR; + } + + int tag, nLayers; // , matTag; + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid section tag" << "\n"; + return TCL_ERROR; + } + + double h, *thickness; + NDMaterial **theMats; + if (Tcl_GetInt(interp, argv[3], &nLayers) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid nLayers" << "\n"; + opserr << "LayeredShell section: " << tag << "\n"; + return TCL_ERROR; + } + + if (nLayers < 3) { + opserr << "ERROR number of layers must be larger than 2" << endln; + return TCL_ERROR; + } + + if (argc < 3+2*nLayers) { + opserr << OpenSees::PromptValueError << "Must provide " << 2*nLayers << " layers\n"; + return TCL_ERROR; + } + + theMats = new NDMaterial *[nLayers]; + thickness = new double[nLayers]; + + for (int iLayer = 0; iLayer < nLayers; iLayer++) { + int mat; + if (Tcl_GetInt(interp, argv[4 + 2 * iLayer], &mat) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid material tag" << endln; + status = TCL_ERROR; + goto cleanup; + } + + NDMaterial* material = builder->getTypedObject(mat); + if (material == nullptr) { + status = TCL_ERROR; + goto cleanup; + } + + theMats[iLayer] = material->getCopy("PlateFiber"); + if (theMats[iLayer] == nullptr) { + theMats[iLayer] = new PlateFiberMaterial(mat, *material); + } + + if (Tcl_GetDouble(interp, argv[5 + 2 * iLayer], &h) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid h at layer " << iLayer << "\n"; + status = TCL_ERROR; + goto cleanup; + } + + if (h <= 0) { + opserr << OpenSees::PromptValueError + << "invalid h at layer " << iLayer << "\n"; + status = TCL_ERROR; + goto cleanup; + } + + thickness[iLayer] = h; + } + + theSection = new LayeredShellFiberSection(tag, nLayers, thickness, theMats); + + + if (builder->addTaggedObject(*theSection) == TCL_OK) { + status = TCL_OK; + } + +cleanup: + if (thickness != nullptr) + delete[] thickness; + + if (theMats != 0) { + for (int iLayer = 0; iLayer < nLayers; iLayer++) { + if (theMats[iLayer] != nullptr) + delete theMats[iLayer]; + } + delete[] theMats; + } + return status; + } + + + // Now add the material to the modelBuilder + if (builder->addTaggedObject(*theSection) < 0) { + opserr << "WARNING could not add section to the domain\n"; + opserr << *theSection << "\n"; + delete theSection; + return TCL_ERROR; + } + + return TCL_OK; +} + diff --git a/SRC/runtime/commands/modeling/material/wrapper.cpp b/SRC/runtime/commands/modeling/material/wrapper.cpp new file mode 100644 index 0000000000..c80bc76851 --- /dev/null +++ b/SRC/runtime/commands/modeling/material/wrapper.cpp @@ -0,0 +1,476 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include + + +int +TclCommand_addWrappingMaterial(ClientData clientData, Tcl_Interp* interp, + int argc, TCL_Char** const argv) +{ + // + // + // + BasicModelBuilder *builder = static_cast(clientData); + + if (argc < 4) { + opserr << OpenSees::PromptValueError << " insufficient arguments\n"; + return TCL_ERROR; + } + + int tago, tagi; + if (Tcl_GetInt(interp, argv[2], &tago) != TCL_OK) { + opserr << OpenSees::PromptValueError << "failed to read tag\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[3], &tagi) != TCL_OK) { + opserr << OpenSees::PromptValueError << "failed to read tag\n"; + return TCL_ERROR; + } + + if (strcmp(argv[1], "ContinuumWrapper") == 0 || strcmp(argv[1], "Continuum") == 0) { + NDMaterial* inside = builder->getTypedObject(tagi); + if (inside == nullptr) + return TCL_ERROR; + + return builder->addTypedObject(tago, new ContinuumUniaxial(tago, *inside)); + } + + else if (strcmp(argv[0], "uniaxialMaterial") == 0 && ( + strstr(argv[1], "InitStress") != 0 || + strstr(argv[1], "InitialStress") != 0 || + strstr(argv[1], "InitialStrain") != 0 || + strstr(argv[1], "InitStrain") != 0)) { + + double initial; + if (Tcl_GetDouble(interp, argv[4], &initial) != TCL_OK) { + opserr << OpenSees::PromptValueError << "failed to read initial value\n"; + return TCL_ERROR; + } + UniaxialMaterial* inside = builder->getTypedObject(tagi); + if (inside == nullptr) + return TCL_ERROR; + + if (strstr(argv[1], "Stress") != 0) + return builder->addTypedObject(tago, new InitStressMaterial(tago, *inside, initial)); + else if (strstr(argv[1], "Strain") != 0) + return builder->addTypedObject(tago, new InitStrainMaterial(tago, *inside, initial)); + } + + else if (strcmp(argv[0], "nDMaterial") == 0 && ( + strstr(argv[1], "InitStress") != 0 || + strstr(argv[1], "InitialStress") != 0 || + strstr(argv[1], "InitialStrain") != 0 || + strstr(argv[1], "InitStrain") != 0)) { + + Vector initial(6); + NDMaterial* inside = builder->getTypedObject(tagi); + if (inside == nullptr) + return TCL_ERROR; + + inside = inside->getCopy("ThreeDimensional"); + if (!inside || strcmp(inside->getType(), "ThreeDimensional") != 0) { + opserr << OpenSees::PromptValueError << "InitStressNDMaterial only works with 3D materials\n"; + return TCL_ERROR; + } + + if (argc == 5) { + double evol; + if (Tcl_GetDouble(interp, argv[4], &evol) != TCL_OK) { + opserr << OpenSees::PromptValueError << "failed to read initial value\n"; + return TCL_ERROR; + } + for (int i = 0; i < 3; ++i) + initial(i) = evol; + + } else { + for (int i=0; i<6; ++i) { + if (Tcl_GetDouble(interp, argv[4+i], &initial(i)) != TCL_OK) { + opserr << OpenSees::PromptValueError << "failed to read initial value\n"; + return TCL_ERROR; + } + } + } + + if (strstr(argv[1], "Strain") != 0) + return builder->addTypedObject(tago, new InitStrainNDMaterial(tago, *inside, initial)); + } + + + return TCL_ERROR; +} + + +int +TclCommand_newParallelMaterial(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char ** const argv) +{ + if (argc < 4) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: uniaxialMaterial Parallel tag? tag1? tag2? ..."; + opserr << " <-min min?> <-max max?>" << endln; + return TCL_ERROR; + } + + int tag; + UniaxialMaterial* theMaterial = nullptr; + BasicModelBuilder* builder = static_cast(clientData); + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid uniaxialMaterial Parallel tag" << endln; + return TCL_ERROR; + } + + int numMaterials = argc-3; + + if (numMaterials == 0) { + opserr << "WARNING no component material(s) provided\n"; + opserr << "uniaxialMaterial Parallel: " << tag << endln; + return TCL_ERROR; + } + + // Create an array to hold pointers to component materials + UniaxialMaterial **theMats = new UniaxialMaterial *[numMaterials]; + + // For each material get the tag and ensure it exists in model already + for (int i=0; igetTypedObject(tagI); + + if (theMat == nullptr) { + delete [] theMats; + return TCL_ERROR; + } else + theMats[i] = theMat; + } + + // Parsing was successful, allocate the material + theMaterial = new ParallelMaterial(tag, numMaterials, theMats); + builder->addTaggedObject(*theMaterial); + + delete [] theMats; + return TCL_OK; +} + +// material type? tag? nd_tag? +int +TclCommand_newPlateFiber(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char ** const argv) +{ + BasicModelBuilder *builder = static_cast(clientData); + + if (argc < 4) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial " << argv[1] << " tag? matTag?" << "\n"; + return TCL_ERROR; + } + + int tag, matTag; + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid nDMaterial tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { + opserr << "WARNING invalid matTag " << argv[3] << "\n"; + return TCL_ERROR; + } + + NDMaterial *threeDMaterial = builder->getTypedObject(matTag); + if (threeDMaterial == nullptr) + return TCL_ERROR; + + // Check if the material is a 3D material + threeDMaterial = threeDMaterial->getCopy("ThreeDimensional"); + if (threeDMaterial == nullptr) { + opserr << "a ThreeDimensional material was expected\n"; + return TCL_ERROR; + } + + NDMaterial *theMaterial = nullptr; + if (strcmp(argv[1], "PlateFiberMaterial") == 0 || + strcmp(argv[1], "PlateFiber") == 0) { + theMaterial = new PlateFiberMaterial(tag, *threeDMaterial); + } + // else if (strcmp(argv[1], "PlateFiberMaterialThermal") == 0 || + // strcmp(argv[1], "PlateFiberThermal") == 0) { + // theMaterial = new PlateFiberMaterialThermal(tag, *threeDMaterial); + // } + else if (strcmp(argv[1], "BeamFiberMaterial") == 0 || + strcmp(argv[1], "BeamFiber") == 0) { + theMaterial = new BeamFiberMaterial(tag, *threeDMaterial); + } + else if (strcmp(argv[1], "BeamFiberMaterial2d") == 0 || + strcmp(argv[1], "BeamFiber2d") == 0) { + theMaterial = new BeamFiberMaterial2d(tag, *threeDMaterial); + } + else if (strcmp(argv[1], "BeamFiberMaterial2dPS") == 0 || + strcmp(argv[1], "BeamFiber2dPS") == 0) { + theMaterial = new BeamFiberMaterial2dPS(tag, *threeDMaterial); + } + + else { + opserr << "WARNING invalid material type " << "\n"; + return TCL_ERROR; + } + + if (builder->addTaggedObject(*theMaterial) != TCL_OK) { + delete theMaterial; + return TCL_ERROR; + } + + delete threeDMaterial; + return TCL_OK; +} + +// nDMaterial type? tag? uni_tag? angle? +int +TclCommand_newPlateRebar(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char ** const argv) +{ + // + // nDMaterial type? tag? uni_tag? angle? + // + BasicModelBuilder *builder = static_cast(clientData); + if (argc < 5) { + opserr << "WARNING insufficient arguments\n"; + return TCL_ERROR; + } + + int tag, matTag; + double angle; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid nDMaterial PlateRebar tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { + opserr << "WARNING invalid matTag " << argv[3] << "\n"; + return TCL_ERROR; + } + + UniaxialMaterial *theMat = builder->getTypedObject(matTag); + if (theMat == nullptr) + return TCL_ERROR; + + if (Tcl_GetDouble(interp, argv[4], &angle) != TCL_OK) { + opserr << "WARNING invalid angle" << "\n"; + return TCL_ERROR; + } + + if (strcmp(argv[1], "PlateRebarMaterial") == 0 || + strcmp(argv[1], "PlateRebar") == 0) { + if (builder->addTaggedObject(*new PlateRebarMaterial(tag, *theMat, angle)) != TCL_OK) { + return TCL_ERROR; + } + } + + else if (strcmp(argv[1], "PlaneStressRebarMaterial") == 0 || + strcmp(argv[1], "PlaneStressRebar") == 0) { + if (builder->addTaggedObject(*new PlaneStressRebarMaterial(tag, *theMat, angle)) != TCL_OK) { + return TCL_ERROR; + } + } + + else { + opserr << "WARNING invalid material type " << "\n"; + return TCL_ERROR; + } + return TCL_OK; +} + + + +int +TclCommand_newFatigueMaterial(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char ** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder *builder = static_cast(clientData); + + if (argc < 4) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: uniaxialMaterial Fatigue tag? matTag?"; + opserr << " <-D_max dmax?> <-e0 e0?> <-m m?>" << "\n"; + opserr << " <-min min?> <-max max?>" << "\n"; + return TCL_ERROR; + } + + int tag, matTag; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid uniaxialMaterial Fatigue tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid component tag\n"; + return TCL_ERROR; + } + + double Dmax = 1.0; + double E0 = 0.191; + double m = -0.458; + double epsmin = NEG_INF_STRAIN; + double epsmax = POS_INF_STRAIN; + + for (int j = 4; j < argc; j++) { + if (strcmp(argv[j], "-Dmax") == 0) { + if ((j + 1 >= argc) || + (Tcl_GetDouble(interp, argv[++j], &Dmax) != TCL_OK)) { + opserr << OpenSees::PromptValueError << "invalid -Dmax"; + return TCL_ERROR; + } + } else if (strcmp(argv[j], "-E0") == 0) { + if ((j + 1 >= argc) || (Tcl_GetDouble(interp, argv[++j], &E0) != TCL_OK)) { + opserr << OpenSees::PromptValueError << "invalid -E0"; + return TCL_ERROR; + } + } else if (strcmp(argv[j], "-m") == 0) { + if ((j + 1 >= argc) || + (Tcl_GetDouble(interp, argv[++j], &m) != TCL_OK)) { + opserr << OpenSees::PromptValueError << "invalid -m"; + return TCL_ERROR; + } + } else if (strcmp(argv[j], "-min") == 0) { + if ((j + 1 >= argc) || + (Tcl_GetDouble(interp, argv[++j], &epsmin) != TCL_OK)) { + opserr << OpenSees::PromptValueError << "invalid -min "; + return TCL_ERROR; + } + } else if (strcmp(argv[j], "-max") == 0) { + if ((j + 1 >= argc) || + (Tcl_GetDouble(interp, argv[++j], &epsmax) != TCL_OK)) { + opserr << OpenSees::PromptValueError << "invalid -max"; + return TCL_ERROR; + } + } + } + + UniaxialMaterial *theMat = builder->getTypedObject(matTag); + + if (theMat == nullptr) { + opserr << OpenSees::PromptValueError << "component material does not exist\n"; + return TCL_ERROR; + } + + // Parsing was successful, allocate the material + UniaxialMaterial *theMaterial = + new FatigueMaterial(tag, *theMat, Dmax, E0, m, epsmin, epsmax); + + if (builder->addTaggedObject(*theMaterial) != TCL_OK) { + delete theMaterial; + return TCL_ERROR; + } + return TCL_OK; + +} + + +int +TclCommand_addPlaneWrapper(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) +{ + + BasicModelBuilder *builder = static_cast(clientData); + + NDMaterial * theMaterial = nullptr; + + if (strcmp(argv[1], "PlaneStressMaterial") == 0 || + strcmp(argv[1], "PlaneStress") == 0) { + if (argc < 4) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PlaneStress tag? matTag?" << "\n"; + return TCL_ERROR; + } + + int tag, matTag; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid nDMaterial PlaneStress tag" << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { + opserr << "WARNING invalid matTag" << "\n"; + opserr << "PlaneStress: " << matTag << "\n"; + return TCL_ERROR; + } + + NDMaterial *threeDMaterial = builder->getTypedObject(matTag); + if (threeDMaterial == nullptr) + return TCL_ERROR; + + theMaterial = new PlaneStressMaterial(tag, *threeDMaterial); + } + + // PlaneStrainMaterial + else if (strcmp(argv[1], "PlaneStrainMaterial") == 0 || + strcmp(argv[1], "PlaneStrain") == 0) { + if (argc < 4) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: nDMaterial PlaneStrain tag? matTag?" << "\n"; + return TCL_ERROR; + } + + int tag, matTag; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid nDMaterial tag " << argv[2] << "\n"; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { + opserr << "WARNING invalid matTag " << argv[3] << "\n"; + return TCL_ERROR; + } + + NDMaterial *threeDMaterial = builder->getTypedObject(matTag); + if (threeDMaterial == nullptr) + return TCL_ERROR; + + theMaterial = new PlaneStrainMaterial(tag, *threeDMaterial); + } + + // Done parsing + if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { + delete theMaterial; + return TCL_ERROR; + } + + return TCL_OK; + +} diff --git a/SRC/runtime/commands/modeling/mesh.cpp b/SRC/runtime/commands/modeling/mesh.cpp index 207d1d1475..6784d419a3 100644 --- a/SRC/runtime/commands/modeling/mesh.cpp +++ b/SRC/runtime/commands/modeling/mesh.cpp @@ -13,7 +13,6 @@ int TclCommand_mesh(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { - // ensure the destructor has not been called - assert(clientData != nullptr); // make sure corect number of arguments on command line @@ -48,7 +47,6 @@ int TclCommand_remesh(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { - // ensure the destructor has not been called - if (theTclBuilder == nullptr) { opserr << "WARNING builder has been destroyed" << endln; return TCL_ERROR; diff --git a/SRC/runtime/commands/modeling/model.cpp b/SRC/runtime/commands/modeling/model.cpp index e09106f4e0..c8c0005def 100644 --- a/SRC/runtime/commands/modeling/model.cpp +++ b/SRC/runtime/commands/modeling/model.cpp @@ -1,11 +1,12 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file implements commands that configure a -// `ModelBuider`. +// `ModelBuider`, including "model" // // Author: cmp // @@ -15,6 +16,7 @@ #include #include +#include #include #include #include @@ -31,16 +33,22 @@ bool builtModel = false; FE_Datastore *theDatabase = nullptr; -extern int G3_AddTclAnalysisAPI(Tcl_Interp *, Domain*); +extern int G3_AddTclAnalysisAPI(Tcl_Interp *, BasicModelBuilder&); extern int G3_AddTclDomainCommands(Tcl_Interp *, Domain*); + +// int TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char *argv[]) { G3_Runtime *rt = G3_getRuntime(interp); - BasicModelBuilder *theNewBuilder = nullptr; Domain *theNewDomain = (Domain*)clientData; + BasicModelBuilder *theNewBuilder = nullptr; + + // + // + // if (clientData == nullptr) { theNewDomain = new Domain(); @@ -50,17 +58,12 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL Tcl_CreateCommand(interp, "model", &TclCommand_specifyModel, theNewDomain, nullptr); G3_AddTclDomainCommands(interp, theNewDomain); - - const char* analysis_option; - if (!(analysis_option = Tcl_GetVar(interp,"opensees::pragma::analysis",TCL_GLOBAL_ONLY)) || - (strcmp(analysis_option, "off") != 0)) { - G3_AddTclAnalysisAPI(interp, theNewDomain); - } } + // make sure at least one other argument to contain model builder type given if (argc < 2) { - opserr << G3_ERROR_PROMPT << "need to specify a model type, valid types:\n"; + opserr << OpenSees::PromptValueError << "need to specify a model type, valid types:\n"; opserr << "\tBasicBuilder\n"; return TCL_ERROR; } @@ -73,8 +76,8 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL (strcmp(argv[1], "basicBuilder") == 0)) { if (argc < 3) { - opserr << G3_ERROR_PROMPT << "incorrect number of command arguments, expected:\n"; - opserr << "\tmodel modelBuilderType -ndm ndm? <-ndf ndf?> \n"; + opserr << OpenSees::PromptValueError + << "incorrect number of arguments\n"; return TCL_ERROR; } int ndm = 0; @@ -88,8 +91,8 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL argPos++; if (argPos < argc) { if (Tcl_GetInt(interp, argv[argPos], &ndm) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "error reading ndm, got '" << argv[argPos]; - opserr << "' but expected:\n\tmodel modelBuilderType -ndm ndm? <-ndf ndf?>\n"; + opserr << OpenSees::PromptValueError + << "error reading ndm, got '" << argv[argPos] << "'\n"; return TCL_ERROR; } } @@ -101,8 +104,7 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL argPos++; if (argPos < argc) if (Tcl_GetInt(interp, argv[argPos], &ndf) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid parameter ndf, expected:"; - opserr << "\n\tmodel modelBuilderType -ndm ndm? <-ndf ndf?>\n"; + opserr << OpenSees::PromptValueError << "invalid parameter ndf"; return TCL_ERROR; } argPos++; @@ -110,8 +112,7 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL } else if (posArg == 1) { if (Tcl_GetInt(interp, argv[argPos], &ndm) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid parameter ndm, expected:"; - opserr << "\n\tmodel modelBuilderType -ndm ndm? <-ndf ndf?>\n"; + opserr << OpenSees::PromptValueError << "invalid parameter ndm"; return TCL_ERROR; } argPos++; @@ -119,8 +120,7 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL } else if (posArg == 2) { if (Tcl_GetInt(interp, argv[argPos], &ndf) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "error reading ndf: " << argv[argPos]; - opserr << "\nmodel modelBuilderType -ndm ndm? <-ndf ndf?>\n"; + opserr << OpenSees::PromptValueError << "error reading ndf: " << argv[argPos] << "\n"; return TCL_ERROR; } argPos++; @@ -134,8 +134,7 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL // check that ndm was specified if (ndm == 0) { - opserr << G3_ERROR_PROMPT << "need to specify ndm\n"; - opserr << " model modelBuilderType -ndm ndm? <-ndf ndf?>\n"; + opserr << OpenSees::PromptValueError << "missing required argument ndm\n"; return TCL_ERROR; } @@ -148,7 +147,7 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL else if (ndm == 3) ndf = 6; else { - opserr << G3_ERROR_PROMPT << "specified ndm, " << ndm << ", will not work\n"; + opserr << OpenSees::PromptValueError << "specified ndm, " << ndm << ", will not work\n"; opserr << " with any elements in BasicBuilder\n"; return TCL_ERROR; } @@ -160,6 +159,12 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL // create the model builder theNewBuilder = new BasicModelBuilder(*theNewDomain, interp, ndm, ndf); G3_setModelBuilder(rt, theNewBuilder); + + const char* analysis_option; + if (!(analysis_option = Tcl_GetVar(interp,"opensees::pragma::analysis",TCL_GLOBAL_ONLY)) || + (strcmp(analysis_option, "off") != 0)) { + G3_AddTclAnalysisAPI(interp, *theNewBuilder); + } } #if 0 @@ -176,7 +181,7 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL } theNewBuilder = new TclUniaxialMaterialTester(*theNewDomain, interp, count); if (theNewBuilder == 0) { - opserr << G3_ERROR_PROMPT << "ran out of memory in creating " + opserr << OpenSees::PromptValueError << "ran out of memory in creating " "TclUniaxialMaterialTester model\n"; return TCL_ERROR; } else { @@ -197,7 +202,7 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL theNewBuilder = new TclPlaneStressMaterialTester(theDomain, interp, count); if (theNewBuilder == 0) { - opserr << G3_ERROR_PROMPT << "ran out of memory in creating " + opserr << OpenSees::PromptValueError << "ran out of memory in creating " "TclUniaxialMaterialTester model\n"; return TCL_ERROR; } @@ -215,7 +220,7 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL } theNewBuilder = new TclSectionTestBuilder(theDomain, interp, count); if (theNewBuilder == 0) { - opserr << G3_ERROR_PROMPT << "ran out of memory in creating " + opserr << OpenSees::PromptValueError << "ran out of memory in creating " "TclUniaxialMAterialTester model\n"; return TCL_ERROR; } @@ -223,7 +228,9 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL #endif else { - opserr << G3_ERROR_PROMPT << "unknown model builder type '" << argv[1] << "' not supported\n"; + opserr << OpenSees::PromptValueError + << "unknown model builder type '" << argv[1] << "' not supported" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -267,7 +274,7 @@ TclCommand_wipeModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Ch // command invoked to build the model, i.e. to invoke buildFE_Model() // on the ModelBuilder int -buildModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char *argv[]) +buildModel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char *argv[]) { G3_Runtime *rt = G3_getRuntime(interp); BasicModelBuilder* builder = (BasicModelBuilder*)G3_getModelBuilder(rt); @@ -279,12 +286,12 @@ buildModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char *argv[] builtModel = true; return builder->buildFE_Model(); - } else if (builder != 0 && builtModel == true) { - opserr << G3_ERROR_PROMPT << "Model has already been built - not built again \n"; + } else if (builder != nullptr && builtModel == true) { + opserr << OpenSees::PromptValueError << "Model has already been built - not built again \n"; return TCL_ERROR; } else { - opserr << G3_ERROR_PROMPT << "No ModelBuilder type has been specified \n"; + opserr << OpenSees::PromptValueError << "No ModelBuilder type has been specified \n"; return TCL_ERROR; } } diff --git a/SRC/runtime/commands/modeling/nodes.cpp b/SRC/runtime/commands/modeling/nodes.cpp index c8f3be9360..20cd636168 100644 --- a/SRC/runtime/commands/modeling/nodes.cpp +++ b/SRC/runtime/commands/modeling/nodes.cpp @@ -1,14 +1,17 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// +// // Description: This file implements commands that configure Node objects // for an analysis. // // Author: cmp // +#include #include #include #include @@ -18,9 +21,12 @@ #include #include #include +#include #include -#define G3_MAX_NUM_DOFS 1000000000000 +#define HeapNode Node + +// #define G3_MAX_NUM_DOFS 1000000000000 #define G3_NUM_DOF_BUFFER 20 int @@ -37,71 +43,62 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, int ndf = builder->getNDF(); // make sure corect number of arguments on command line - if (argc < 2 + ndm) { - opserr << G3_ERROR_PROMPT << "insufficient arguments, expected:\n"; - opserr << " node nodeTag? [ndm coordinates?] <-mass [ndf values?]>\n"; + if (argc < 2 + 1) { // ndm) { + opserr << OpenSees::PromptValueError + << "insufficient arguments" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } - Node *theNode = 0; + Node *theNode = nullptr; // read the node id int nodeId; if (Tcl_GetInt(interp, argv[1], &nodeId) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodeTag\n"; + opserr << OpenSees::PromptValueError << "invalid nodeTag\n"; opserr << " Want: node nodeTag? [ndm coordinates?] <-mass [ndf values?]>\n"; return TCL_ERROR; } + + Parameter* coord_params[3] = {nullptr, nullptr, nullptr}; + using namespace OpenSees::Parsing; + // read in the coordinates and create the node - double xLoc, yLoc, zLoc; - if (ndm == 1) { + double xLoc=0, yLoc=0, zLoc=0; + if (ndm >= 1 && argc >= 3) { // create a node in 1d space - if (Tcl_GetDouble(interp, argv[2], &xLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid coordinate\n"; + if (GetDoubleParam(interp, *theTclDomain, argv[2], &xLoc, coord_params[0]) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid coordinate " << argv[2] + << OpenSees::SignalMessageEnd; return TCL_ERROR; } } - else if (ndm == 2) { - // create a node in 2d space - if (Tcl_GetDouble(interp, argv[2], &xLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid 1st coordinate\n"; - opserr << "node: " << nodeId << "\n"; - return TCL_ERROR; - } + if (ndm >= 2 && argc >= 4) { if (Tcl_GetDouble(interp, argv[3], &yLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid 2nd coordinate\n"; - opserr << "node: " << nodeId << "\n"; + opserr << OpenSees::PromptValueError + << "invalid 2nd coordinate " << argv[3] + << OpenSees::SignalMessageEnd; return TCL_ERROR; } } - else if (ndm == 3) { - // create a node in 3d space - if (Tcl_GetDouble(interp, argv[2], &xLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid 1st coordinate\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[3], &yLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid 2nd coordinate\n"; - return TCL_ERROR; - } + if (ndm >= 3 && argc >= 5) { if (Tcl_GetDouble(interp, argv[4], &zLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid 3rd coordinate\n"; + opserr << OpenSees::PromptValueError + << "invalid 3rd coordinate " << argv[4] + << OpenSees::SignalMessageEnd; return TCL_ERROR; } - - } else { - opserr << G3_ERROR_PROMPT << "unsupported model dimension\n"; - return TCL_ERROR; } // check for -ndf override option int currentArg = 2 + ndm; if (currentArg < argc && strcmp(argv[currentArg], "-ndf") == 0) { if (Tcl_GetInt(interp, argv[currentArg + 1], &ndf) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodal ndf given for node " << nodeId << "\n"; + opserr << OpenSees::PromptValueError << "invalid nodal ndf given for node " << nodeId << "\n"; return TCL_ERROR; } currentArg += 2; @@ -112,12 +109,13 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, // switch (ndm) { case 1: - theNode = new Node(nodeId, ndf, xLoc); + theNode = new HeapNode(nodeId, ndf, xLoc); break; case 2: - theNode = new Node(nodeId, ndf, xLoc, yLoc); + theNode = new HeapNode(nodeId, ndf, xLoc, yLoc); break; case 3: +#if 0 if (getenv("NODE")) { switch (ndf) { case 3: @@ -127,11 +125,12 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, theNode = new NodeND<3, 6>(nodeId, xLoc, yLoc, zLoc); break; default: - theNode = new Node(nodeId, ndf, xLoc, yLoc, zLoc); + theNode = new HeapNode(nodeId, ndf, xLoc, yLoc, zLoc); break; } } else - theNode = new Node(nodeId, ndf, xLoc, yLoc, zLoc); +#endif + theNode = new HeapNode(nodeId, ndf, xLoc, yLoc, zLoc); break; } @@ -139,7 +138,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, if (strcmp(argv[currentArg], "-mass") == 0) { currentArg++; if (argc < currentArg + ndf) { - opserr << G3_ERROR_PROMPT << "incorrect number of nodal mass terms\n"; + opserr << OpenSees::PromptValueError << "incorrect number of nodal mass terms\n"; opserr << "node: " << nodeId << "\n"; return TCL_ERROR; } @@ -148,7 +147,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, Matrix mass(ndf, ndf); for (int i = 0; i < ndf; ++i) { if (Tcl_GetDouble(interp, argv[currentArg++], &theMass) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodal mass term"; + opserr << OpenSees::PromptValueError << "invalid nodal mass term"; opserr << " at dof " << i + 1 << "\n"; return TCL_ERROR; } @@ -159,7 +158,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, } else if (strcmp(argv[currentArg], "-dispLoc") == 0) { currentArg++; if (argc < currentArg + ndm) { - opserr << G3_ERROR_PROMPT << "incorrect number of nodal display location terms, " + opserr << OpenSees::PromptValueError << "incorrect number of nodal display location terms, " "need ndm\n"; return TCL_ERROR; } @@ -167,7 +166,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, double theCrd; for (int i = 0; i < ndm; ++i) { if (Tcl_GetDouble(interp, argv[currentArg++], &theCrd) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodal mass term\n"; + opserr << OpenSees::PromptValueError << "invalid nodal mass term\n"; opserr << "node: " << nodeId << ", dof: " << i + 1 << "\n"; return TCL_ERROR; } @@ -178,7 +177,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, } else if (strcmp(argv[currentArg], "-disp") == 0) { currentArg++; if (argc < currentArg + ndf) { - opserr << G3_ERROR_PROMPT << "incorrect number of nodal disp terms\n"; + opserr << OpenSees::PromptValueError << "incorrect number of nodal disp terms\n"; opserr << "node: " << nodeId << "\n"; return TCL_ERROR; } @@ -186,7 +185,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, double theDisp; for (int i = 0; i < ndf; ++i) { if (Tcl_GetDouble(interp, argv[currentArg++], &theDisp) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodal disp term\n"; + opserr << OpenSees::PromptValueError << "invalid nodal disp term\n"; opserr << "node: " << nodeId << ", dof: " << i + 1 << "\n"; return TCL_ERROR; } @@ -198,7 +197,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, } else if (strcmp(argv[currentArg], "-vel") == 0) { currentArg++; if (argc < currentArg + ndf) { - opserr << G3_ERROR_PROMPT << "incorrect number of nodal vel terms, "; + opserr << OpenSees::PromptValueError << "incorrect number of nodal vel terms, "; opserr << "expected " << ndf << "\n"; return TCL_ERROR; } @@ -207,7 +206,7 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, Vector disp(ndf); for (int i = 0; i < ndf; ++i) { if (Tcl_GetDouble(interp, argv[currentArg++], &theDisp) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodal vel term at "; + opserr << OpenSees::PromptValueError << "invalid nodal vel term at "; opserr << " dof " << i + 1 << "\n"; return TCL_ERROR; } @@ -220,11 +219,25 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, currentArg++; } + + // + // Setup parameters for coordinates + // + for (int i=0; i<3; ++i) { + if (coord_params[i] == nullptr) + continue; + char index[20]; + snprintf(index, sizeof(index), "%d", i + 1); + std::string idx = std::to_string(i + 1); + const char* args[2] = { "coord", index }; + coord_params[i]->addComponent(theNode, args, 2); + } + // // add the node to the domain // if (theTclDomain->addNode(theNode) == false) { - opserr << G3_ERROR_PROMPT << "failed to add node to the domain\n"; + opserr << OpenSees::PromptValueError << "failed to add node to the domain\n"; delete theNode; return TCL_ERROR; } @@ -244,7 +257,7 @@ TclCommand_addNodalMass(ClientData clientData, Tcl_Interp *interp, int argc, // make sure at least one other argument if (argc < (1 + ndf)) { - opserr << G3_ERROR_PROMPT << "insufficient arguments, expected:\n" + opserr << OpenSees::PromptValueError << "insufficient arguments, expected:\n" " mass nodeId <" << ndf << " mass values>\n"; return TCL_ERROR; } @@ -252,7 +265,7 @@ TclCommand_addNodalMass(ClientData clientData, Tcl_Interp *interp, int argc, // get the id of the node int nodeId; if (Tcl_GetInt(interp, argv[1], &nodeId) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nodeId: " << argv[1]; + opserr << OpenSees::PromptValueError << "invalid nodeId: " << argv[1]; opserr << " - mass nodeId " << ndf << " forces\n"; return TCL_ERROR; } @@ -262,7 +275,7 @@ TclCommand_addNodalMass(ClientData clientData, Tcl_Interp *interp, int argc, for (int i=0; isetMass(mass, nodeId) != 0) { - opserr << G3_ERROR_PROMPT << "failed to set mass at node " << nodeId << "\n"; + opserr << OpenSees::PromptValueError << "failed to set mass at node " << nodeId << "\n"; return TCL_ERROR; } @@ -292,13 +305,13 @@ TclCommand_getNDM(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char if (argc > 1) { int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "ndm nodeTag? \n"; + opserr << OpenSees::PromptValueError << "ndm nodeTag? \n"; return TCL_ERROR; } Node *theNode = the_domain->getNode(tag); if (theNode == nullptr) { - opserr << G3_ERROR_PROMPT << "nodeTag " << tag << " does not exist \n"; + opserr << OpenSees::PromptValueError << "nodeTag " << tag << " does not exist \n"; return TCL_ERROR; } const Vector &coords = theNode->getCrds(); @@ -323,12 +336,12 @@ TclCommand_getNDF(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char if (argc > 1) { int tag; if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "ndf nodeTag? \n"; + opserr << OpenSees::PromptValueError << "ndf nodeTag? \n"; return TCL_ERROR; } Node *theNode = the_domain->getNode(tag); if (theNode == nullptr) { - opserr << G3_ERROR_PROMPT << "nodeTag " << tag << " does not exist \n"; + opserr << OpenSees::PromptValueError << "nodeTag " << tag << " does not exist \n"; return TCL_ERROR; } ndf = theNode->getNumberDOF(); diff --git a/SRC/runtime/commands/modeling/printing.cpp b/SRC/runtime/commands/modeling/printing.cpp index 4176425a54..461bd7f0a6 100644 --- a/SRC/runtime/commands/modeling/printing.cpp +++ b/SRC/runtime/commands/modeling/printing.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: Commands that are used to print out the domain // // Author: cmp @@ -17,7 +18,7 @@ #endif #include #include -#include +#include #include #include @@ -32,6 +33,9 @@ #include #include +#include +#include + #include #include #include @@ -47,7 +51,10 @@ #include #include -#include +#include +#include + +#include int printElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, OPS_Stream &output); @@ -62,7 +69,8 @@ int printAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, OPS_Stream &output); -int TclCommand_classType(ClientData clientData, Tcl_Interp *interp, int argc, +int +TclCommand_classType(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char** const argv) { @@ -78,7 +86,7 @@ int TclCommand_classType(ClientData clientData, Tcl_Interp *interp, int argc, MovableObject* theObject = nullptr; int tag; if (Tcl_GetInt(interp, argv[2], &tag) < 0) { - opserr << G3_ERROR_PROMPT << "classType objectType tag? - unable to read tag" << "\n"; + opserr << OpenSees::PromptValueError << "classType objectType tag? - unable to read tag" << "\n"; return TCL_ERROR; } @@ -92,7 +100,7 @@ int TclCommand_classType(ClientData clientData, Tcl_Interp *interp, int argc, theObject = builder->getTypedObject(tag); #endif else { - opserr << G3_ERROR_PROMPT << "classType - " << type.c_str() << " not yet supported" << "\n"; + opserr << OpenSees::PromptValueError << "classType - " << type.c_str() << " not yet supported" << "\n"; return TCL_ERROR; } @@ -103,6 +111,15 @@ int TclCommand_classType(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_OK; } +template +static int +printRegistryObject(const BasicModelBuilder& builder, int tag, int flag, OPS_Stream *output) +{ + TaggedObject* object = builder.getTypedObject(tag); + object->Print(*output, flag); + return TCL_OK; +} + static int printRegistry(const BasicModelBuilder& builder, TCL_Char* type, int flag, OPS_Stream *output) { @@ -118,7 +135,7 @@ printDomain(OPS_Stream &s, BasicModelBuilder* builder, int flag) Domain* theDomain = builder->getDomain(); - const char* tab = " "; + const char* tab = " "; // TODO: maybe add a method called countRegistry<> // to BasicModelBuilder @@ -139,46 +156,79 @@ printDomain(OPS_Stream &s, BasicModelBuilder* builder, int flag) builder->printRegistry(s, flag); } s << "\n" << tab << tab << "]"; - s << ",\n"; } // - s << tab << tab << "\"nDMaterials\": [\n"; - builder->printRegistry(s, flag); - s << "\n" << tab << tab << "]"; s << ",\n"; // - s << tab << tab << "\"uniaxialMaterials\": [\n"; - builder->printRegistry(s, flag); - s << "\n" << tab << tab << "]"; + { + s << tab << tab << "\"nDMaterials\": [\n"; + builder->printRegistry(s, flag); + s << "\n" << tab << tab << "]"; + } + // + s << ",\n"; + // + { + s << tab << tab << "\"uniaxialMaterials\": [\n"; + builder->printRegistry(s, flag); + s << "\n" << tab << tab << "]"; + } s << ",\n"; // s << tab << tab << "\"crdTransformations\": [\n"; { - int n = builder->printRegistry(s, flag); + int n = builder->printRegistry(s, flag); DummyStream dummy; - if (builder->printRegistry(dummy, flag) > 0) { + if (builder->printRegistry(dummy, flag) > 0) { if (n > 0) s << ",\n"; - builder->printRegistry(s, flag); + builder->printRegistry(s, flag); } + s << "\n" << tab << tab << "]"; } - s << "\n" << tab << tab << "]"; -// builder->printRegistry(s, flag); + // + s << ",\n"; + // + { + s << tab << tab << "\"patterns\": [\n"; + LoadPatternIter &patterns = theDomain->getLoadPatterns(); + LoadPattern *p; + bool first_mp = true; + while ((p = patterns()) != nullptr) { + if (!first_mp) + s << ",\n"; + + p->Print(s, flag); + first_mp = false; + } + s << "\n" << tab << tab << "]"; + } + // + s << ",\n"; + // + { + s << tab << tab << "\"parameters\": [\n"; + ParameterIter ¶ms = theDomain->getParameters(); + Parameter *param; + bool first_mp = true; + while ((param = params()) != nullptr) { + if (!first_mp) + s << ",\n"; - // s << ",\n"; - // // - // s << tab << tab << "\"constraints\": [\n"; - // theDomain->Print(s, flag); - // s << "\n" << tab << tab << "]"; + param->Print(s, flag); + first_mp = false; + } + s << "\n" << tab << tab << "]\n"; + } + // s << "\n"; // + // s << tab << "},\n"; - // // s << tab << "\"geometry\": {\n"; - int numPrinted = 0; int numToPrint = theDomain->getNumNodes(); NodeIter &theNodess = theDomain->getNodes(); @@ -190,22 +240,53 @@ printDomain(OPS_Stream &s, BasicModelBuilder* builder, int flag) if (numPrinted < numToPrint) s << ",\n"; } - s << "\n" << tab << tab << "],\n"; - + s << "\n" << tab << tab << "]"; + // + s << ",\n"; + // + { + s << tab << tab << "\"elements\": [\n"; + Element *theEle; + ElementIter &theElementss = theDomain->getElements(); + numToPrint = theDomain->getNumElements(); + numPrinted = 0; + while ((theEle = theElementss()) != nullptr) { + theEle->Print(s, flag); + numPrinted += 1; + if (numPrinted < numToPrint) + s << ",\n"; + } + s << "\n" << tab << tab << "]"; + } + // + s << ",\n"; + // + { + s << tab << tab << "\"constraints\": [\n"; + MP_ConstraintIter &theMPs = theDomain->getMPs(); + MP_Constraint *theMP; + bool first_mp = true; + while ((theMP = theMPs()) != nullptr) { + if (!first_mp) + s << ",\n"; + theMP->Print(s, flag); + first_mp = false; + } - Element *theEle; - ElementIter &theElementss = theDomain->getElements(); - numToPrint = theDomain->getNumElements(); - numPrinted = 0; - s << tab << tab << "\"elements\": [\n"; - while ((theEle = theElementss()) != nullptr) { - theEle->Print(s, flag); - numPrinted += 1; - if (numPrinted < numToPrint) - s << ",\n"; + SP_ConstraintIter &theSPs = theDomain->getSPs(); + SP_Constraint *theSP; + bool first_sp = true; + while ((theSP = theSPs()) != nullptr) { + if (!first_sp || !first_mp) + s << ",\n"; + theSP->Print(s, flag); + first_sp = false; + } + s << "\n" << tab << tab << "]"; } - s << "\n" << tab << tab << "]\n"; + // END + s << "\n"; s << tab << "}\n"; s << "}\n"; @@ -292,6 +373,26 @@ TclCommand_print(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char * done = true; } + // if 'print material i j k ..' print out some nodes + else if ((strcmp(argv[currentArg], "-material") == 0)) { + currentArg++; + if (currentArg == argc) { + opserr << OpenSees::PromptValueError << "print -material .. - no tag specified\n"; + return TCL_ERROR; + } + for (int i = currentArg; i < argc; i++) { + int tag; + if (Tcl_GetInt(interp, argv[i], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "print -material failed to get integer tag: " << argv[i] + << "\n"; + return TCL_ERROR; + } + res += printRegistryObject(*((BasicModelBuilder*)clientData), tag, OPS_PRINT_PRINTMODEL_JSON, output); + } + done = true; + } + + else if ((strcmp(argv[currentArg], "-registry") == 0)) { currentArg++; if (currentArg == argc) @@ -320,7 +421,7 @@ TclCommand_print(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char * res = printAlgorithm(info.clientData, interp, argc - currentArg, argv + currentArg, *output); } else { - opserr << G3_ERROR_PROMPT << "Cannot print algorithm\n"; + opserr << OpenSees::PromptValueError << "Cannot print algorithm\n"; } done = true; } @@ -400,11 +501,11 @@ printElement(ClientData clientData, Tcl_Interp *interp, int argc, if ((strcmp(argv[0], "flag") == 0) || (strcmp(argv[0], "-flag")) == 0) { // get the specified flag if (argc < 2) { - opserr << G3_ERROR_PROMPT << "print ele no int specified \n"; + opserr << OpenSees::PromptValueError << "print ele no int specified \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[1], &flag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "print ele failed to get integer flag: \n"; + opserr << OpenSees::PromptValueError << "print ele failed to get integer flag: \n"; opserr << argv[eleArg] << endln; return TCL_ERROR; } @@ -427,7 +528,7 @@ printElement(ClientData clientData, Tcl_Interp *interp, int argc, for (int i = 0; i < numEle; ++i) { int eleTag; if (Tcl_GetInt(interp, argv[i + eleArg], &eleTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "print -ele failed to get integer: " << argv[i] + opserr << OpenSees::PromptValueError << "print -ele failed to get integer: " << argv[i] << endln; return TCL_ERROR; } @@ -470,11 +571,11 @@ printNode(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const if ((strcmp(argv[0], "flag") == 0) || (strcmp(argv[0], "-flag") == 0)) { // get the specified flag if (argc <= nodeArg) { - opserr << G3_ERROR_PROMPT << "print node no int specified \n"; + opserr << OpenSees::PromptValueError << "print node no int specified \n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[1], &flag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "print node failed to get integer flag: \n"; + opserr << OpenSees::PromptValueError << "print node failed to get integer flag: \n"; opserr << argv[nodeArg] << endln; return TCL_ERROR; } @@ -498,7 +599,7 @@ printNode(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const for (int i = 0; i < numNodes; ++i) { int nodeTag; if (Tcl_GetInt(interp, argv[nodeArg], &nodeTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "print node failed to get integer: " << argv[nodeArg] + opserr << OpenSees::PromptValueError << "print node failed to get integer: " << argv[nodeArg] << "\n"; return TCL_ERROR; } @@ -537,7 +638,7 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, bool hasLinear = false; bool hasTri3 = false; bool hasQuad4 = false; - bool hasQuad8 = false; +//bool hasQuad8 = false; bool hasQuad9 = false; bool hasBrick = false; int startEle = 1; @@ -548,7 +649,7 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, FileStream outputFile; if (argc < 2) { - opserr << G3_ERROR_PROMPT << "printGID fileName? - no filename supplied\n"; + opserr << OpenSees::PromptValueError << "printGID fileName? - no filename supplied\n"; return TCL_ERROR; } openMode mode = openMode::OVERWRITE; @@ -561,12 +662,12 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, eleRange = 1; if (Tcl_GetInt(interp, argv[i + 1], &startEle) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "print node failed to get integer: " << argv[i + 1] + opserr << OpenSees::PromptValueError << "print node failed to get integer: " << argv[i + 1] << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[i + 2], &endEle) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "print node failed to get integer: " << argv[i + 2] + opserr << OpenSees::PromptValueError << "print node failed to get integer: " << argv[i + 2] << "\n"; return TCL_ERROR; } @@ -575,7 +676,7 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, } if (outputFile.setFile(argv[1], mode) < 0) { - opserr << G3_ERROR_PROMPT << "printGID " << argv[1] << " failed to set the file\n"; + opserr << OpenSees::PromptValueError << "printGID " << argv[1] << " failed to set the file\n"; return TCL_ERROR; } @@ -603,7 +704,7 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, if (strcmp(theElement->getClassType(), "Brick") == 0) { hasBrick = true; } else { - hasQuad8 = true; + ;// hasQuad8 = true; } } } diff --git a/SRC/runtime/commands/modeling/section.cpp b/SRC/runtime/commands/modeling/section.cpp index be7247a63b..7e7bf224cf 100644 --- a/SRC/runtime/commands/modeling/section.cpp +++ b/SRC/runtime/commands/modeling/section.cpp @@ -1,39 +1,46 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file contains the function invoked when the user invokes // the section command in the interpreter. +//===----------------------------------------------------------------------===// +// +// Membrane nxx nyy nxy +// MembranePlate nxx nyy nxy mxx myy mxy vxz vyz // // Written: rms, mhs, cmp // Created: 07/99 // +#include #include -#include -#include -#include -#include -#include - #include #include #include +#include +#include +#include +#include +#include +#include + #include +#include + +using namespace OpenSees; extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp *interp, int cArg, int mArg, TCL_Char ** const argv, Domain *domain); +#include +#include #include #include -#include -#include -#include -#include -#include // #include #include #include @@ -43,41 +50,26 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, #include #include #include +#include #include -//#include - - -#include // Yuli Huang & Xinzheng Lu - -#include -#include -#include // SectionBuilder #include #include -#include #include #include -#include -#include +#include // #include #include #include -//--- Adding Thermo-mechanical Sections:[BEGIN] by UoE OpenSees Group ---// #include #include //Added by L.Jiang [SIF] 2017 -#include //Added by Liming, [SIF] 2017 -#include //Added by Liming, [SIF] 2017 -//--- Adding Thermo-mechanical Sections: [END] by UoE OpenSees Group ---// //#include -extern OPS_Routine OPS_ElasticSection; -extern OPS_Routine OPS_ElasticWarpingShearSection2d; // extern OPS_Routine OPS_ElasticTubeSection3d; extern OPS_Routine OPS_UniaxialSection; extern OPS_Routine OPS_ParallelSection; @@ -94,6 +86,10 @@ Tcl_CmdProc TclCommand_addFiberSection; Tcl_CmdProc TclCommand_addFiberIntSection; Tcl_CmdProc TclCommand_addUCFiberSection; Tcl_CmdProc TclCommand_addSectionAggregator; +Tcl_CmdProc TclCommand_addPlaneSection; +Tcl_CmdProc TclCommand_addElasticShellSection; +Tcl_CmdProc TclCommand_addUniaxialSection; +Tcl_CmdProc TclCommand_ShellSection; // extern OPS_Routine OPS_WFSection2d; // extern OPS_Routine OPS_RCCircularSection; @@ -105,6 +101,116 @@ Tcl_CmdProc TclCommand_addSectionAggregator; SectionForceDeformation * TclBasicBuilderYS_SectionCommand(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv); + +#include +#include +#include +int +TclCommand_addTrussSection(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + + enum class Positions { + Tag, MaterialTag, Area, + EndRequired, End + }; + + ArgumentTracker tracker; + std::set positional; + int tag; + int matTag; + double area; + + for (int i=2; i= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[i], &matTag) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::MaterialTag); + } + else if (strcmp(argv[i], "-area") == 0) { + if (++i >= argc) { + opserr << "Missing value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[i], &area) != TCL_OK) { + opserr << "Invalid value for option " << argv[i-1] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Area); + } + else + positional.insert(i); + } + + // + // Positional arguments + // + for (int i: positional) { + if (tracker.current() == Positions::EndRequired) + tracker.increment(); + + switch (tracker.current()) { + case Positions::Tag : + if (Tcl_GetInt(interp, argv[i], &tag) != TCL_OK) { + opserr << "Invalid tag " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Tag); + break; + + case Positions::MaterialTag: + if (Tcl_GetInt(interp, argv[i], &matTag) != TCL_OK) { + opserr << "Invalid value for material tag " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::MaterialTag); + break; + + case Positions::Area: + if (Tcl_GetDouble(interp, argv[i], &area) != TCL_OK) { + opserr << "Invalid value for area " << argv[i] << "\n"; + return TCL_ERROR; + } + tracker.consume(Positions::Area); + break; + + case Positions::EndRequired: + case Positions::End: + break; + } + } + + // + if (tracker.current() < Positions::EndRequired) { + opserr << "Missing required arguments: "; + if (tracker.contains(Positions::Tag)) + opserr << "tag "; + if (tracker.contains(Positions::MaterialTag)) + opserr << "material "; + if (tracker.contains(Positions::Area)) + opserr << "area "; + opserr << "\n"; + return TCL_ERROR; + } + + BasicModelBuilder *builder = static_cast(clientData); + + UniaxialMaterial *material = builder->getTypedObject(matTag); + if (material == nullptr) { + return TCL_ERROR; + } + auto fiber_section = new FrameFiberSection3d(tag, 1, nullptr, true, 0.0, 0); + fiber_section->addFiber(*material, area, 0.0, 0.0); + return builder->addTaggedObject(*fiber_section); +} + + int TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) @@ -116,8 +222,7 @@ TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, // Make sure there is a minimum number of arguments if (argc < 3) { - opserr << G3_ERROR_PROMPT << "insufficient number of section arguments\n"; - opserr << "Want: section type? tag? " << endln; + opserr << OpenSees::PromptValueError << "insufficient number of arguments\n"; return TCL_ERROR; } @@ -130,9 +235,13 @@ TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, if (strcmp(argv[1], "Fiber") == 0 || strcmp(argv[1], "fiberSec") == 0 || + strcmp(argv[1], "FiberSec") == 0 || strcmp(argv[1], "FiberFrame") == 0 || strcmp(argv[1], "FrameFiber") == 0 || + strcmp(argv[1], "AxialFiber") == 0 || strcmp(argv[1], "FiberSection") == 0 || + // + strcmp(argv[1], "ShearFiber") == 0 || // Shear strcmp(argv[1], "NDFiber") == 0 || strcmp(argv[1], "NDFiberWarping") == 0 || @@ -145,66 +254,49 @@ TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, return TclCommand_addFiberSection(clientData, interp, argc, argv); + + else if (strcmp(argv[1], "Truss") == 0 || + strcmp(argv[1], "TrussSection") == 0 || + strcmp(argv[1], "TrussSection2d") == 0 || + strcmp(argv[1], "TrussSection3d") == 0) { + return TclCommand_addTrussSection(clientData, interp, argc, argv); + } + + + else if (strcmp(argv[1], "FiberInt") == 0) { // TODO + // return TclCommand_addFiberIntSection(clientData, interp, argc, argv); opserr << "FiberInt is currently broken\n"; return TCL_ERROR; - // return TclCommand_addFiberIntSection(clientData, interp, argc, argv); } + else if ((strcmp(argv[1], "PlaneStrain") == 0) || + (strcmp(argv[1], "PlaneStress") == 0)) + return TclCommand_addPlaneSection(clientData, interp, argc, argv); + else if (strcmp(argv[1], "UCFiber") == 0) return TclCommand_addUCFiberSection(clientData, interp, argc, argv); - else if (strcmp(argv[1], "Parallel") == 0) { - SectionForceDeformation *theSection = - (SectionForceDeformation*)OPS_ParallelSection(rt, argc, argv); - - if (theSection == nullptr || builder->addTaggedObject(*theSection) < 0) { - if (theSection != nullptr) - delete theSection; - return TCL_ERROR; - } else - return TCL_OK; - } - - else if ((strcmp(argv[1], "FrameElastic") == 0) || - (strcmp(argv[1], "ElasticFrame") == 0)) { + else if ((strcmp(argv[1], "Elastic") == 0) || + (strcmp(argv[1], "ElasticShear") == 0) || + (strcmp(argv[1], "ElasticWarpingShear") == 0) || + (strcmp(argv[1], "FrameElastic") == 0) || + (strcmp(argv[1], "ElasticFrame") == 0)) { return TclCommand_newElasticSection(clientData, interp, argc, argv); } - else if (strcmp(argv[1], "Elastic") == 0) { - if (getenv("SEC")) - return TclCommand_newElasticSection(clientData, interp, argc, argv); - - else { - FrameSection *theSection = (FrameSection *)OPS_ElasticSection(rt, argc, argv); - // Now add the section to the modelBuilder - if (theSection == nullptr || builder->addTaggedObject(*theSection) < 0) { - if (theSection != nullptr) - delete theSection; - return TCL_ERROR; - } else - return TCL_OK; - } + else if (strcmp(argv[1], "Generic1D") == 0 || + strcmp(argv[1], "Generic1d") == 0 || + strcmp(argv[1], "Uniaxial") == 0) { + return TclCommand_addUniaxialSection(clientData, interp, argc, argv); } - else if (strcmp(argv[1], "ElasticWarpingShear") == 0) { - FrameSection *theSection = (FrameSection *)OPS_ElasticWarpingShearSection2d(rt, argc, argv); - // Now add the section to the modelBuilder - if (theSection == nullptr || builder->addTaggedObject(*theSection) < 0) { - if (theSection != nullptr) - delete theSection; - return TCL_ERROR; - } else - return TCL_OK; - } + else if (strcmp(argv[1], "Parallel") == 0) { + SectionForceDeformation *theSection = + (SectionForceDeformation*)OPS_ParallelSection(rt, argc, argv); - else if (strcmp(argv[1], "Generic1D") == 0 || - strcmp(argv[1], "Generic1d") == 0 || - strcmp(argv[1], "Uniaxial") == 0) { - FrameSection *theSection = (FrameSection *)OPS_UniaxialSection(rt, argc, argv); - // Now add the section to the modelBuilder - if (theSection == nullptr || builder->addTaggedObject(*theSection) < 0) { + if (theSection == nullptr || builder->addTaggedObject(*theSection) < 0) { if (theSection != nullptr) delete theSection; return TCL_ERROR; @@ -244,6 +336,28 @@ TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, #endif } + else if (strcmp(argv[1], "AddDeformation") == 0 || + strcmp(argv[1], "Aggregator") == 0 || + strcmp(argv[1], "Aggregate") == 0) + return TclCommand_addSectionAggregator(clientData, interp, argc, argv); + + + // + // Shell + // + else if ((strcmp(argv[1], "ElasticMembranePlateSection") == 0) || + (strcmp(argv[1], "ElasticShell") == 0) || + (strcmp(argv[1], "ElasticPlateSection") == 0) || + (strcmp(argv[1], "ElasticMembraneSection") == 0)) { + return TclCommand_addElasticShellSection(clientData, interp, argc, argv); + } + + else if ((strcmp(argv[1], "LayeredShell") == 0) || + (strcmp(argv[1], "LayeredShellThermal") == 0) || + (strcmp(argv[1], "PlateFiber") == 0) || + (strcmp(argv[1], "PlateFiberThermal") == 0)) { + return TclCommand_ShellSection(clientData, interp, argc, argv); + } // // Membrane @@ -266,372 +380,12 @@ TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, return TCL_ERROR; } - else if (strcmp(argv[1], "ElasticMembraneSection") == 0) { - void* theMat = OPS_ElasticMembraneSection(); - if (theMat != 0) - theSection = (SectionForceDeformation*)theMat; - else - return TCL_ERROR; - } - - else if (strcmp(argv[1], "AddDeformation") == 0 || - strcmp(argv[1], "Aggregator") == 0 || - strcmp(argv[1], "Aggregate") == 0) - return TclCommand_addSectionAggregator(clientData, interp, argc, argv); - - - else if (strcmp(argv[1], "ElasticPlateSection") == 0) { - - if (argc < 5) { - opserr << G3_ERROR_PROMPT << "insufficient arguments\n"; - opserr << "Want: section ElasticPlateSection tag? E? nu? h? " << endln; - return TCL_ERROR; - } - - int tag; - double E, nu, h; - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid section ElasticPlateSection tag" << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid E" << endln; - opserr << "ElasticPlateSection section: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &nu) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nu" << endln; - opserr << "ElasticPlateSection section: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &h) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid h" << endln; - opserr << "ElasticPlateSection section: " << tag << endln; - return TCL_ERROR; - } - - theSection = new ElasticPlateSection(tag, E, nu, h); - // Now add the material to the modelBuilder - if (builder->addTaggedObject(*theSection) < 0) { - delete theSection; // invoke the material objects destructor, otherwise mem leak - return TCL_ERROR; - } else - return TCL_OK; - } - - else if (strcmp(argv[1], "ElasticMembranePlateSection") == 0) { - if (argc < 5) { - opserr << G3_ERROR_PROMPT << "insufficient arguments\n"; - opserr << "Want: section ElasticMembranePlateSection tag? E? nu? h? " - " " - << endln; - return TCL_ERROR; - } - - int tag; - double E, nu, h; - double rho = 0.0; - double Ep_mod = 1.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid section ElasticMembranePlateSection tag" - << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid E" << endln; - opserr << "ElasticMembranePlateSection section: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &nu) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nu" << endln; - opserr << "ElasticMembranePlateSection section: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &h) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid h" << endln; - opserr << "ElasticMembranePlateSection section: " << tag << endln; - return TCL_ERROR; - } - - if (argc > 6 && Tcl_GetDouble(interp, argv[6], &rho) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid rho" << endln; - opserr << "ElasticMembranePlateSection section: " << tag << endln; - return TCL_ERROR; - } - - if (argc > 7 && Tcl_GetDouble(interp, argv[7], &Ep_mod) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Ep_mod" << endln; - opserr << "ElasticMembranePlateSection section: " << tag << endln; - return TCL_ERROR; - } - - theSection = new ElasticMembranePlateSection(tag, E, nu, h, rho, Ep_mod); - } - - else if (strcmp(argv[1], "PlateFiber") == 0) { - if (argc < 5) { - opserr << G3_ERROR_PROMPT << "insufficient arguments\n"; - opserr << "Want: section PlateFiber tag? matTag? h? " << endln; - return TCL_ERROR; - } - - double h; - int tag, matTag; - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid section PlateFiber tag" << endln; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid matTag" << endln; - opserr << "PlateFiber section: " << matTag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &h) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid h" << endln; - opserr << "PlateFiber section: " << tag << endln; - return TCL_ERROR; - } - - NDMaterial *theMaterial = builder->getTypedObject(matTag); - if (theMaterial == nullptr) { - opserr << G3_ERROR_PROMPT << "nD material does not exist\n"; - opserr << "nD material: " << matTag; - opserr << "\nPlateFiber section: " << tag << endln; - return TCL_ERROR; - } - - theSection = new MembranePlateFiberSection(tag, h, *theMaterial); - // Now add the material to the modelBuilder - if (builder->addTaggedObject(*theSection) < 0) { - delete theSection; - return TCL_ERROR; - } else - return TCL_OK; - } - - // start Yuli Huang & Xinzheng Lu LayeredShellFiberSection - else if (strcmp(argv[1], "LayeredShell") == 0) { - if (argc < 6) { - opserr << G3_ERROR_PROMPT << "insufficient arguments" << endln; - opserr << "Want: section LayeredShell tag? nLayers? matTag1? h1? ... " - "matTagn? hn? " - << endln; - return TCL_ERROR; - } - - int tag, nLayers, matTag; - double h, *thickness; - NDMaterial **theMats; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid section LayeredShell tag" << endln; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &nLayers) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nLayers" << endln; - opserr << "LayeredShell section: " << tag << endln; - return TCL_ERROR; - } - - if (nLayers < 3) { - opserr << "ERROR number of layers must be larger than 2" << endln; - opserr << "LayeredShell section: " << tag << endln; - return TCL_ERROR; - } - - theMats = new NDMaterial *[nLayers]; - thickness = new double[nLayers]; - - if (argc < 3+2*nLayers) { - opserr << G3_ERROR_PROMPT << "Must provide " << 2*nLayers << " layers\n"; - return TCL_ERROR; - } - - for (int iLayer = 0; iLayer < nLayers; iLayer++) { - - if (Tcl_GetInt(interp, argv[4 + 2 * iLayer], &matTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid matTag" << endln; - opserr << "LayeredShell section: " << tag << endln; - return TCL_ERROR; - } - - theMats[iLayer] = builder->getTypedObject(matTag); - if (theMats[iLayer] == 0) { - opserr << G3_ERROR_PROMPT << "nD material does not exist" << endln; - opserr << "nD material: " << matTag; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5 + 2 * iLayer], &h) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid h" << endln; - opserr << "LayeredShell section: " << tag << endln; - return TCL_ERROR; - } - - if (h < 0) { - opserr << G3_ERROR_PROMPT << "invalid h" << endln; - opserr << "PlateFiber section: " << tag << endln; - return TCL_ERROR; - } - - thickness[iLayer] = h; - } - - theSection = new LayeredShellFiberSection(tag, nLayers, thickness, theMats); - if (thickness != nullptr) - delete[] thickness; - if (theMats != 0) - delete[] theMats; - - // Now add the material to the modelBuilder - if (builder->addTaggedObject(*theSection) < 0) { - delete theSection; - return TCL_ERROR; - } else - return TCL_OK; - } - // end Yuli Huang & Xinzheng Lu LayeredShellFiberSection - - //-----Thermo-mechanical shell sections added by L.Jiang [SIF] - else if (strcmp(argv[1], "PlateFiberThermal") == 0) { - if (argc < 5) { - opserr << G3_ERROR_PROMPT << "insufficient arguments\n"; - opserr << "Want: section PlateFiberThermal tag? matTag? h? " << endln; - return TCL_ERROR; - } - - int tag, matTag; - double h; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid section PlateFiberThermal tag" << endln; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid matTag" << endln; - opserr << "PlateFiberThermal section: " << matTag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &h) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid h" << endln; - opserr << "PlateFiberThermal section: " << tag << endln; - return TCL_ERROR; - } - - NDMaterial *theMaterial = builder->getTypedObject(matTag); - if (theMaterial == nullptr) { - opserr << G3_ERROR_PROMPT << "nD material does not exist\n"; - opserr << "nD material: " << matTag; - opserr << "\nPlateFiberThermal section: " << tag << endln; - return TCL_ERROR; - } - - theSection = new MembranePlateFiberSectionThermal(tag, h, *theMaterial); - // Now add the material to the modelBuilder - if (builder->addTaggedObject(*theSection) < 0) { - delete theSection; // invoke the material objects destructor, otherwise mem leak - return TCL_ERROR; - } else - return TCL_OK; - } - - // LayeredShellFiberSectionThermal based on the - // LayeredShellFiberSectionThermal by Yuli Huang & Xinzheng Lu - else if (strcmp(argv[1], "LayeredShellThermal") == 0) { - if (argc < 6) { - opserr << G3_ERROR_PROMPT << "insufficient arguments" << endln; - opserr << "Want: section LayeredShellThermal tag? nLayers? matTag1? h1? " - "... matTagn? hn? " - << endln; - return TCL_ERROR; - } - - int tag, nLayers, matTag; - double h, *thickness; - NDMaterial **theMats; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid section LayeredShellThermal tag" << endln; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &nLayers) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nLayers" << endln; - opserr << "LayeredShellThermal section: " << tag << endln; - return TCL_ERROR; - } - - if (nLayers < 3) { - opserr << "ERROR number of layers must be larger than 2" << endln; - opserr << "LayeredShellThermal section: " << tag << endln; - return TCL_ERROR; - } - - theMats = new NDMaterial *[nLayers]; - thickness = new double[nLayers]; - - for (int iLayer = 0; iLayer < nLayers; iLayer++) { - if (Tcl_GetInt(interp, argv[4 + 2 * iLayer], &matTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid matTag" << endln; - opserr << "LayeredShellThermal section: " << tag << endln; - return TCL_ERROR; - } - - theMats[iLayer] = builder->getTypedObject(matTag); - if (theMats[iLayer] == 0) { - opserr << G3_ERROR_PROMPT << "nD material does not exist" << endln; - ; - opserr << "nD material: " << matTag; - opserr << "LayeredShellThermal section: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5 + 2 * iLayer], &h) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid h" << endln; - opserr << "LayeredShellThermal section: " << tag << endln; - return TCL_ERROR; - } - - if (h < 0) { - opserr << G3_ERROR_PROMPT << "invalid h" << endln; - opserr << "LayeredShellThermal section: " << tag << endln; - return TCL_ERROR; - } - - thickness[iLayer] = h; - } - - theSection = - new LayeredShellFiberSectionThermal(tag, nLayers, thickness, theMats); - if (thickness != 0) - delete[] thickness; - if (theMats != 0) - delete[] theMats; - - // Now add the material to the modelBuilder - if (builder->addTaggedObject(*theSection) < 0) { - delete theSection; // invoke the material objects destructor, otherwise mem leak - return TCL_ERROR; - } else - return TCL_OK; - } - // end L.Jiang [SIF] added based on LayeredShellFiberSectionThermal section + // + // // else if (strcmp(argv[1], "Iso2spring") == 0) { if (argc < 10) { - opserr << G3_ERROR_PROMPT << "insufficient arguments\n"; + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; opserr << "Want: section Iso2spring tag? tol? k1? Fy? k2? kv? hb? Pe? " << endln; @@ -643,53 +397,46 @@ TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, double Po = 0.0; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Iso2spring tag" << endln; + opserr << OpenSees::PromptValueError << "invalid Iso2spring tag" << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3], &tol) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid tol\n"; - opserr << "section Iso2spring: " << tag << endln; + opserr << OpenSees::PromptValueError << "invalid tol\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &k1) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid k1\n"; - opserr << "section Iso2spring: " << tag << endln; + opserr << OpenSees::PromptValueError << "invalid k1\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &Fy) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Fy\n"; - opserr << "section Iso2spring: " << tag << endln; + opserr << OpenSees::PromptValueError << "invalid Fy\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[6], &kb) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid k2\n"; - opserr << "section Iso2spring: " << tag << endln; + opserr << OpenSees::PromptValueError << "invalid k2\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[7], &kvo) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid kv\n"; - opserr << "section Iso2spring: " << tag << endln; + opserr << OpenSees::PromptValueError << "invalid kv\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[8], &hb) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid hb\n"; - opserr << "section Iso2spring: " << tag << endln; + opserr << OpenSees::PromptValueError << "invalid hb\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[9], &Pe) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Pe\n"; - opserr << "section Iso2spring: " << tag << endln; + opserr << OpenSees::PromptValueError << "invalid Pe\n"; return TCL_ERROR; } if (argc > 10) { if (Tcl_GetDouble(interp, argv[10], &Po) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Po\n"; + opserr << OpenSees::PromptValueError << "invalid Po\n"; opserr << "section Iso2spring: " << tag << endln; return TCL_ERROR; } @@ -712,7 +459,7 @@ TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, // Ensure we have created the Material, out of memory if got here and no // section if (theSection == nullptr) { - opserr << G3_ERROR_PROMPT << "could not create section " << argv[1] << endln; + opserr << OpenSees::PromptValueError << "could not create section " << argv[1] << endln; return TCL_ERROR; } @@ -747,7 +494,7 @@ findSectionBuilder(BasicModelBuilder* builder, Tcl_Interp *interp, int argc, con for (int i = 0; i(clientData); - // dimension of the structure (1d, 2d, or 3d) + // Dimension of the structure int ndm = builder->getNDM(); SectionBuilder *sbuilder = nullptr; FrameSection *section = nullptr; - // create 2d section + // Create 2d section if (ndm == 2) { if (options.isND) { - if (options.isWarping) { + if (options.isNew) { + auto sec = new FrameSolidSection3d(secTag, 30); + sbuilder = new FiberSectionBuilder<2, NDMaterial, FrameSolidSection3d>(*builder, *sec); + section = sec; + } + else if (options.isWarping) { auto sec = new NDFiberSectionWarping2d(secTag, 30, alpha); sbuilder = new FiberSectionBuilder<2, NDMaterial, NDFiberSectionWarping2d>(*builder, *sec); section = sec; - } else { + } + else { auto sec = new NDFiberSection2d(secTag, options.computeCentroid); sbuilder = new FiberSectionBuilder<2, NDMaterial, NDFiberSection2d>(*builder, *sec); section = sec; @@ -807,33 +563,55 @@ initSectionCommands(ClientData clientData, Tcl_Interp *interp, section = sec; } } - } else if (ndm == 3) { - // This function is not called when torsion is NULL and num==3 - assert(theTorsion != nullptr); + } - if (options.isND) { - auto sec = new NDFiberSection3d(secTag, - options.computeCentroid); - sbuilder = new FiberSectionBuilder<3, NDMaterial, NDFiberSection3d>(*builder, *sec); - section = sec; + else if (ndm == 3) { + if (options.isND) { + if (options.isNew) { + auto sec = new FrameSolidSection3d(secTag, 30); + sbuilder = new FiberSectionBuilder<3, NDMaterial, FrameSolidSection3d>(*builder, *sec); + section = sec; + } + else { + auto sec = new NDFiberSection3d(secTag, + options.computeCentroid); + sbuilder = new FiberSectionBuilder<3, NDMaterial, NDFiberSection3d>(*builder, *sec); + section = sec; + } } else { + + if (options.isThermal) { - auto sec = new FiberSection3dThermal(secTag, /* TODO: torsion */ - options.computeCentroid); + if (theTorsion == nullptr) { + opserr << OpenSees::PromptValueError + << "FiberThermal section requires torsion\n"; + return TCL_ERROR; + } + auto sec = new FiberSection3dThermal(secTag, 30, *theTorsion, + options.computeCentroid); sbuilder = new FiberSectionBuilder<3, UniaxialMaterial, FiberSection3dThermal>(*builder, *sec); section = sec; - } else if (options.isAsym) { + + } + else if (options.isAsym) { auto sec = new FiberSectionAsym3d(secTag, 30, theTorsion, Ys, Zs); sbuilder = new FiberSectionBuilder<3, UniaxialMaterial, FiberSectionAsym3d>(*builder, *sec); section = sec; - } else { + + } + else { if (options.isNew) { - auto sec = new FrameFiberSection3d(secTag, 30, *theTorsion, options.computeCentroid, + auto sec = new FrameFiberSection3d(secTag, 30, theTorsion, options.computeCentroid, options.density, options.use_density); sbuilder = new FiberSectionBuilder<3, UniaxialMaterial, FrameFiberSection3d>(*builder, *sec); section = sec; } else { + if (theTorsion == nullptr) { + opserr << OpenSees::PromptValueError + << "FiberThermal section requires torsion\n"; + return TCL_ERROR; + } auto sec = new FiberSection3d(secTag, 30, *theTorsion, options.computeCentroid); sbuilder = new FiberSectionBuilder<3, UniaxialMaterial, FiberSection3d>(*builder, *sec); section = sec; @@ -842,16 +620,24 @@ initSectionCommands(ClientData clientData, Tcl_Interp *interp, } } else { - opserr << G3_ERROR_PROMPT << "Model dimension (ndm = " << ndm + opserr << OpenSees::PromptValueError << "Model dimension (ndm = " << ndm << ") is incompatible with available frame elements\n"; return TCL_ERROR; } + + // In 2D truss elements still look for FrameSections if (builder->addTaggedObject(*section) < 0) { return TCL_ERROR; } + // if (ndm == 2) { + // if (builder->addTaggedObject(*section->getCopy()) < 0) { + // return TCL_ERROR; + // } + // } + if (builder->addTypedObject(secTag, sbuilder) < 0) { - opserr << G3_ERROR_PROMPT << "cannot add section\n"; + opserr << OpenSees::PromptValueError << "Faled to add section\n"; return TCL_ERROR; } @@ -887,15 +673,17 @@ TclCommand_addFiberSection(ClientData clientData, Tcl_Interp *interp, int argc, int secTag; if (Tcl_GetInt(interp, argv[2], &secTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "bad command - want: \nsection fiberSec secTag { " - "\n\tpatch \n\tlayer \n}\n"; + opserr << OpenSees::PromptValueError + << "failed to parse section tag \"" << argv[2] << "\"" + << OpenSees::SignalMessageEnd; return TCL_ERROR; } builder->setCurrentSectionBuilder(secTag); FiberSectionConfig options; - if (strcmp(argv[1], "NDFiber") == 0) + if (strcmp(argv[1], "NDFiber") == 0 || + strcmp(argv[1], "ShearFiber") == 0) options.isND = true; if (strcmp(argv[1], "NDFiberWarping") == 0) { @@ -903,7 +691,10 @@ TclCommand_addFiberSection(ClientData clientData, Tcl_Interp *interp, int argc, options.isWarping = true; } else if (strcmp(argv[1], "FrameFiber") == 0 || - strcmp(argv[1], "FiberFrame") == 0) + strcmp(argv[1], "FiberFrame") == 0 || + strcmp(argv[1], "AxialFiber") == 0 || + strcmp(argv[1], "ShearFiber") == 0 + ) options.isNew = true; else if (strcmp(argv[1], "FiberThermal") == 0 || @@ -935,11 +726,11 @@ TclCommand_addFiberSection(ClientData clientData, Tcl_Interp *interp, int argc, else if (strcmp(argv[iarg], "-mass") == 0 && iarg + 1 < argc) { if (argc < iarg + 2) { - opserr << G3_ERROR_PROMPT << "not enough -mass args need -mass mass?\n"; + opserr << OpenSees::PromptValueError << "not enough -mass args need -mass mass?\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[iarg + 1], &options.density) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid density"; + opserr << OpenSees::PromptValueError << "invalid density"; return TCL_ERROR; } options.use_density = true; @@ -949,7 +740,7 @@ TclCommand_addFiberSection(ClientData clientData, Tcl_Interp *interp, int argc, else if (strcmp(argv[iarg], "-GJ") == 0 && iarg + 1 < argc) { if (Tcl_GetDouble(interp, argv[iarg + 1], &GJ) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid GJ"; + opserr << OpenSees::PromptValueError << "invalid GJ"; return TCL_ERROR; } deleteTorsion = true; @@ -961,13 +752,13 @@ TclCommand_addFiberSection(ClientData clientData, Tcl_Interp *interp, int argc, else if (strcmp(argv[iarg], "-torsion") == 0 && iarg + 1 < argc) { int torsionTag = 0; if (Tcl_GetInt(interp, argv[iarg + 1], &torsionTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid torsionTag"; + opserr << OpenSees::PromptValueError << "invalid torsionTag"; return TCL_ERROR; } torsion = builder->getTypedObject(torsionTag); if (torsion == nullptr) { - opserr << G3_ERROR_PROMPT << "uniaxial material does not exist\n"; + opserr << OpenSees::PromptValueError << "uniaxial material does not exist\n"; opserr << "uniaxial material: " << torsionTag; opserr << "\nFiberSection3d: " << secTag << endln; return TCL_ERROR; @@ -978,15 +769,15 @@ TclCommand_addFiberSection(ClientData clientData, Tcl_Interp *interp, int argc, else if (strstr(argv[1], "Asym") != nullptr && !shearParsed) { if (iarg + 1 >= argc) { - opserr << G3_ERROR_PROMPT << "Asym sections require shear center before fiber block.\n"; + opserr << OpenSees::PromptValueError << "Asym sections require shear center before fiber block.\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[iarg], &Ys) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Ys"; + opserr << OpenSees::PromptValueError << "invalid Ys"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[iarg+1], &Zs) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Zs"; + opserr << OpenSees::PromptValueError << "invalid Zs"; return TCL_ERROR; } shearParsed = true; @@ -995,21 +786,20 @@ TclCommand_addFiberSection(ClientData clientData, Tcl_Interp *interp, int argc, else { // braces; skip and handle later -// iarg += 1; break; } } - if (torsion == nullptr && ndm == 3) { - opserr << G3_ERROR_PROMPT << "- no torsion specified for 3D fiber section, use -GJ or " + if (torsion == nullptr && ndm == 3 && !options.isNew) { + opserr << OpenSees::PromptValueError + << "missing required torsion for 3D fiber section, use -GJ or " "-torsion\n"; - opserr << "\nFiberSection3d: " << secTag << endln; return TCL_ERROR; } - // initialize the fiber section (for building) // TODO, alpha + // initialize the fiber section (for building) // TODO, pass alpha if (initSectionCommands(clientData, interp, secTag, torsion, Ys, Zs, 1.0, options) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "error constructing the section\n"; + opserr << OpenSees::PromptValueError << "error constructing the section\n"; return TCL_ERROR; } @@ -1040,21 +830,21 @@ TclCommand_addFiberIntSection(ClientData clientData, Tcl_Interp *interp, int secTag; if (Tcl_GetInt(interp, argv[2], &secTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "bad command - want: \nsection fiberInt secTag -GJ { " + opserr << OpenSees::PromptValueError << "bad command - want: \nsection fiberInt secTag -GJ { " "\n\tpatch \n\tlayer \n}\n"; return TCL_ERROR; } builder->setCurrentSectionBuilder(secTag); - - int brace = 3; // Start of recursive parse + // + int brace = 3; double GJ = 1.0; bool deleteTorsion = false; - UniaxialMaterial *torsion = 0; + UniaxialMaterial *torsion = nullptr; if (strcmp(argv[3], "-GJ") == 0) { if (Tcl_GetDouble(interp, argv[4], &GJ) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid GJ"; + opserr << OpenSees::PromptValueError << "invalid GJ\n"; return TCL_ERROR; } torsion = new ElasticMaterial(0, GJ); // Is this gonna be a memory leak? MHS @@ -1064,17 +854,13 @@ TclCommand_addFiberIntSection(ClientData clientData, Tcl_Interp *interp, int torsionTag = 0; if (strcmp(argv[3], "-torsion") == 0) { if (Tcl_GetInt(interp, argv[4], &torsionTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid torsionTag"; + opserr << OpenSees::PromptValueError << "invalid torsionTag\n"; return TCL_ERROR; } torsion = builder->getTypedObject(torsionTag); - if (torsion == 0) { - opserr << G3_ERROR_PROMPT << "uniaxial material does not exist\n"; - opserr << "uniaxial material: " << torsionTag; - opserr << "\nFiberSection3d: " << secTag << endln; + if (torsion == 0) return TCL_ERROR; - } brace = 5; } @@ -1085,32 +871,32 @@ TclCommand_addFiberIntSection(ClientData clientData, Tcl_Interp *interp, if (strcmp(argv[3], "-NStrip") == 0) { if (Tcl_GetInt(interp, argv[4], &NStrip1) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid NStrip1"; + opserr << OpenSees::PromptValueError << "invalid NStrip1\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &t1) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid t1"; + opserr << OpenSees::PromptValueError << "invalid t1"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[6], &NStrip2) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid NStrip2"; + opserr << OpenSees::PromptValueError << "invalid NStrip2"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[7], &t2) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid t2"; + opserr << OpenSees::PromptValueError << "invalid t2"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[8], &NStrip3) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid NStrip3"; + opserr << OpenSees::PromptValueError << "invalid NStrip3"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[9], &t3) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid t3"; + opserr << OpenSees::PromptValueError << "invalid t3"; return TCL_ERROR; } @@ -1120,7 +906,7 @@ TclCommand_addFiberIntSection(ClientData clientData, Tcl_Interp *interp, #if 0 // init the fiber section (for building) // TODO, alpha if (initSectionCommands(clientData, interp, secTag, *torsion, Ys, Zs, 1.0) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "- error constructing the section\n"; + opserr << OpenSees::PromptValueError << "- error constructing the section\n"; return TCL_ERROR; } #endif @@ -1128,12 +914,12 @@ TclCommand_addFiberIntSection(ClientData clientData, Tcl_Interp *interp, // parse the information inside the braces (patches and reinforcing layers) if (Tcl_Eval(interp, argv[brace]) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "- error reading information in { } \n"; + opserr << OpenSees::PromptValueError << "- error reading information in { } \n"; return TCL_ERROR; } - if (NDM == 3 && torsion == 0) { - opserr << G3_ERROR_PROMPT << "- no torsion specified for 3D fiber section, use -GJ or " + if (NDM == 3 && torsion == nullptr) { + opserr << OpenSees::PromptValueError << "- no torsion specified for 3D fiber section, use -GJ or " "-torsion\n"; opserr << "\nFiberSectionInt3d: " << secTag << endln; return TCL_ERROR; @@ -1143,7 +929,7 @@ TclCommand_addFiberIntSection(ClientData clientData, Tcl_Interp *interp, // build the fiber section (for analysis) if (buildSectionInt(clientData, interp, secTag, *torsion, NStrip1, t1, NStrip2, t2, NStrip3, t3) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "- error constructing the section\n"; + opserr << OpenSees::PromptValueError << "- error constructing the section\n"; return TCL_ERROR; } #endif @@ -1168,14 +954,14 @@ TclCommand_addPatch(ClientData clientData, SectionBuilder* fiberSectionRepr = findSectionBuilder(builder, interp, argc, argv); if (fiberSectionRepr == nullptr) { - opserr << G3_ERROR_PROMPT << "cannot retrieve section\n"; + opserr << OpenSees::PromptValueError << "cannot retrieve section\n"; return TCL_ERROR; } // make sure at least one other argument to contain patch type if (argc < 2) { - opserr << G3_ERROR_PROMPT << "need to specify a patch type \n"; + opserr << OpenSees::PromptValueError << "need to specify a patch type \n"; return TCL_ERROR; } @@ -1183,10 +969,10 @@ TclCommand_addPatch(ClientData clientData, if (strcmp(argv[1], "quad") == 0 || strcmp(argv[1], "quadr") == 0) { int numSubdivIJ, numSubdivJK, matTag; double vertexCoordY, vertexCoordZ; - Matrix vertexCoords(4, 2); + MatrixND<4,2> vertexCoords{}; if (argc < 13) { - opserr << G3_ERROR_PROMPT << "invalid number of parameters: patch quad matTag " + opserr << OpenSees::PromptValueError << "invalid number of parameters: patch quad matTag " "numSubdivIJ numSubdivJK yVertI zVertI yVertJ zVertJ yVertK " "zVertK yVertL zVertL\n"; return TCL_ERROR; @@ -1195,21 +981,21 @@ TclCommand_addPatch(ClientData clientData, int argi = 2; if (Tcl_GetInt(interp, argv[argi++], &matTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid matTag: patch quad matTag numSubdivIJ " + opserr << OpenSees::PromptValueError << "invalid matTag: patch quad matTag numSubdivIJ " "numSubdivJK yVertI zVertI yVertJ zVertJ yVertK zVertK yVertL " "zVertL\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[argi++], &numSubdivIJ) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid numSubdivIJ: patch quad matTag numSubdivIJ " + opserr << OpenSees::PromptValueError << "invalid numSubdivIJ: patch quad matTag numSubdivIJ " "numSubdivJK yVertI zVertI yVertJ zVertJ yVertK zVertK yVertL " "zVertL\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[argi++], &numSubdivJK) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid numSubdivJK: patch quad matTag numSubdivIJ " + opserr << OpenSees::PromptValueError << "invalid numSubdivJK: patch quad matTag numSubdivIJ " "numSubdivJK yVertI zVertI yVertJ zVertJ yVertK zVertK yVertL " "zVertL\n"; return TCL_ERROR; @@ -1217,13 +1003,13 @@ TclCommand_addPatch(ClientData clientData, for (int j = 0; j < 4; j++) { if (Tcl_GetDouble(interp, argv[argi++], &vertexCoordY) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Coordinate y: ...yVertI zVertI yVertJ " + opserr << OpenSees::PromptValueError << "invalid Coordinate y: ...yVertI zVertI yVertJ " "zVertJ yVertK zVertK yVertL zVertL\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &vertexCoordZ) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Coordinate z: ...yVertI zVertI yVertJ " + opserr << OpenSees::PromptValueError << "invalid Coordinate z: ...yVertI zVertI yVertJ " "zVertJ yVertK zVertK yVertL zVertL\n"; return TCL_ERROR; } @@ -1246,31 +1032,31 @@ TclCommand_addPatch(ClientData clientData, int numSubdivIJ, numSubdivJK, matTag; double vertexCoordY, vertexCoordZ; - Matrix vertexCoords(4, 2); + MatrixND<4,2> vertexCoords; if (argc < 9) { - opserr << G3_ERROR_PROMPT << "invalid number of parameters: patch quad matTag " + opserr << OpenSees::PromptValueError << "invalid number of parameters: patch quad matTag " "numSubdivIJ numSubdivJK yVertI zVertI yVertK zVertK\n"; return TCL_ERROR; } int argi = 2; if (Tcl_GetInt(interp, argv[argi++], &matTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid matTag: patch quad matTag numSubdivIJ " + opserr << OpenSees::PromptValueError << "invalid matTag: patch quad matTag numSubdivIJ " "numSubdivJK yVertI zVertI yVertJ zVertJ yVertK zVertK yVertL " "zVertL\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[argi++], &numSubdivIJ) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid numSubdivIJ: patch quad matTag numSubdivIJ " + opserr << OpenSees::PromptValueError << "invalid numSubdivIJ: patch quad matTag numSubdivIJ " "numSubdivJK yVertI zVertI yVertJ zVertJ yVertK zVertK yVertL " "zVertL\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[argi++], &numSubdivJK) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid numSubdivJK: patch quad matTag numSubdivIJ " + opserr << OpenSees::PromptValueError << "invalid numSubdivJK: patch quad matTag numSubdivIJ " "numSubdivJK yVertI zVertI yVertJ zVertJ yVertK zVertK yVertL " "zVertL\n"; return TCL_ERROR; @@ -1278,13 +1064,13 @@ TclCommand_addPatch(ClientData clientData, for (int j = 0; j < 2; j++) { if (Tcl_GetDouble(interp, argv[argi++], &vertexCoordY) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Coordinate y: ...yVertI zVertI yVertJ " + opserr << OpenSees::PromptValueError << "invalid Coordinate y: ...yVertI zVertI yVertJ " "zVertJ yVertK zVertK yVertL zVertL\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &vertexCoordZ) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Coordinate z: ...yVertI zVertI yVertJ " + opserr << OpenSees::PromptValueError << "invalid Coordinate z: ...yVertI zVertI yVertJ " "zVertJ yVertK zVertK yVertL zVertL\n"; return TCL_ERROR; } @@ -1317,63 +1103,63 @@ TclCommand_addPatch(ClientData clientData, int argi = 2; if (argc < 11) { - opserr << G3_ERROR_PROMPT << "invalid number of parameters: patch circ matTag " + opserr << OpenSees::PromptValueError << "invalid number of parameters: patch circ matTag " "numSubdivCirc numSubdivRad yCenter zCenter intRad extRad " "startAng endAng\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[argi++], &matTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid matTag: patch circ matTag numSubdivCirc " + opserr << OpenSees::PromptValueError << "invalid matTag: patch circ matTag numSubdivCirc " "numSubdivRad yCenter zCenter intRad extRad startAng endAng\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[argi++], &numSubdivCirc) != TCL_OK) { opserr - << G3_ERROR_PROMPT << "invalid numSubdivCirc: patch circ matTag numSubdivCirc " + << OpenSees::PromptValueError << "invalid numSubdivCirc: patch circ matTag numSubdivCirc " "numSubdivRad yCenter zCenter intRad extRad startAng endAng\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[argi++], &numSubdivRad) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid numSubdivRad: patch circ matTag numSubdivCirc " + opserr << OpenSees::PromptValueError << "invalid numSubdivRad: patch circ matTag numSubdivCirc " "numSubdivRad yCenter zCenter intRad extRad startAng endAng\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &yCenter) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid yCenter: patch circ matTag numSubdivCirc " + opserr << OpenSees::PromptValueError << "invalid yCenter: patch circ matTag numSubdivCirc " "numSubdivRad yCenter zCenter intRad extRad startAng endAng\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &zCenter) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid zCenter: patch circ matTag numSubdivCirc " + opserr << OpenSees::PromptValueError << "invalid zCenter: patch circ matTag numSubdivCirc " "numSubdivRad yCenter zCenter intRad extRad startAng endAng\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &intRad) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid intRad: patch circ matTag numSubdivCirc " + opserr << OpenSees::PromptValueError << "invalid intRad: patch circ matTag numSubdivCirc " "numSubdivRad yCenter zCenter intRad extRad startAng endAng\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &extRad) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid extRad: patch circ matTag numSubdivCirc " + opserr << OpenSees::PromptValueError << "invalid extRad: patch circ matTag numSubdivCirc " "numSubdivRad yCenter zCenter intRad extRad startAng endAng\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &startAng) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid startAng: patch circ matTag numSubdivCirc " + opserr << OpenSees::PromptValueError << "invalid startAng: patch circ matTag numSubdivCirc " "numSubdivRad yCenter zCenter intRad extRad startAng endAng\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &endAng) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid endAng: patch circ matTag numSubdivCirc " + opserr << OpenSees::PromptValueError << "invalid endAng: patch circ matTag numSubdivCirc " "numSubdivRad yCenter zCenter intRad extRad startAng endAng\n"; return TCL_ERROR; } @@ -1393,73 +1179,222 @@ TclCommand_addPatch(ClientData clientData, } else { - opserr << G3_ERROR_PROMPT << "patch type is not available\n"; + opserr << OpenSees::PromptValueError << "patch type is not available\n"; return TCL_ERROR; } return TCL_OK; } -// add fiber to fiber section +// Add a fiber to a fiber section int TclCommand_addFiber(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { + enum class Position : int { + Y, Z, Area, Material, End + }; + ArgumentTracker tracker; + std::set positional; + assert(clientData != nullptr); BasicModelBuilder* builder = static_cast(clientData); - if (argc < 5) { - opserr << G3_ERROR_PROMPT << "invalid num args: fiber yLoc zLoc area matTag\n"; - return TCL_ERROR; - } - SectionBuilder* fiberSectionRepr = findSectionBuilder(builder, interp, argc, argv); if (fiberSectionRepr == nullptr) { - opserr << G3_ERROR_PROMPT << "cannot retrieve a section builder\n"; + opserr << OpenSees::PromptValueError << "cannot retrieve a section builder\n"; return TCL_ERROR; } -//int numFibers = fiberSectionRepr->getNumFibers(); - - - double yLoc, zLoc, area; - if (Tcl_GetDouble(interp, argv[1], &yLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid yLoc: fiber yLoc zLoc area matTag\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[2], &zLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid zLoc: fiber yLoc zLoc area matTag\n"; - return TCL_ERROR; + double yLoc, zLoc=0, area; + int matTag; + bool warn_2d_z = false; + static constexpr int WarpModeCount = 3; + double warp[WarpModeCount][3]{}; + int warp_arg = -1; + for (int i=1; i= argc) { + opserr << OpenSees::PromptValueError << "missing warp argument\n"; + return TCL_ERROR; + } + warp_arg = i+1; + i++; + } + else if (strcmp(argv[i], "-warn-2d-z") == 0) { + warn_2d_z = true; + i++; + } + else if (strcmp(argv[i], "-material") == 0) { + if (argc == ++i || Tcl_GetInt(interp, argv[i], &matTag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid material tag\n"; + return TCL_ERROR; + } + tracker.consume(Position::Material); + } + else if (strcmp(argv[i], "-area") == 0) { + if (argc == ++i || Tcl_GetDouble(interp, argv[i], &area) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid area\n"; + return TCL_ERROR; + } + tracker.consume(Position::Area); + } + else if (strcmp(argv[i], "-y") == 0) { + if (argc == ++i || Tcl_GetDouble(interp, argv[i], &yLoc) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid y coordinate\n"; + return TCL_ERROR; + } + tracker.consume(Position::Y); + } + else if (strcmp(argv[i], "-z") == 0) { + if (argc == ++i || Tcl_GetDouble(interp, argv[i], &zLoc) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid z coordinate\n"; + return TCL_ERROR; + } + tracker.consume(Position::Z); + } + else { + positional.insert(i); + } } - if (Tcl_GetDouble(interp, argv[3], &area) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid area: fiber yLoc zLoc area matTag\n"; - return TCL_ERROR; + + for (int i: positional) { + switch (tracker.current()) { + case Position::Y: + if (Tcl_GetDouble(interp, argv[i], &yLoc) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid y coordinate\n"; + return TCL_ERROR; + } + tracker.consume(Position::Y); + break; + case Position::Z: + if (Tcl_GetDouble(interp, argv[i], &zLoc) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid z coordinate\n"; + return TCL_ERROR; + } + tracker.consume(Position::Z); + break; + case Position::Area: + if (Tcl_GetDouble(interp, argv[i], &area) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid area\n"; + return TCL_ERROR; + } + tracker.consume(Position::Area); + break; + case Position::Material: + if (Tcl_GetInt(interp, argv[i], &matTag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid material tag\n"; + return TCL_ERROR; + } + tracker.consume(Position::Material); + break; + default: + opserr << OpenSees::PromptValueError << "unexpected argument at position " << i << "\n"; + return TCL_ERROR; + } } - int matTag; - if (Tcl_GetInt(interp, argv[4], &matTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid matTag: fiber yLoc zLoc area matTag\n"; + + if (builder->getNDM() == 2) { + if (warn_2d_z && zLoc != 0.0) { + opswrn << OpenSees::SignalWarning << "z coordinate ignored in 2D\n"; + } + } + if (tracker.current() != Position::End) { + opserr << OpenSees::PromptValueError << "missing required arguments: "; + while (tracker.current() != Position::End) { + switch (tracker.current()) { + case Position::Y: + opserr << "y "; + break; + case Position::Z: + opserr << "z "; + break; + case Position::Area: + opserr << "area "; + break; + case Position::Material: + opserr << "material "; + break; + case Position::End: + break; + } + if (tracker.current() == Position::End) + break; + tracker.consume(tracker.current()); + } + opserr << "\n"; return TCL_ERROR; } + // + // process warping + // + int i_warp = 0; + int split_1_argc; + const char **split_1_argv; + if (warp_arg >= 0 && Tcl_SplitList(interp, argv[warp_arg], &split_1_argc, &split_1_argv) == TCL_OK) { + int argi = 0; + for (; i_warp= split_1_argc) + break; + + // + int split_argc; + const char **split_argv; + if (Tcl_SplitList(interp, split_1_argv[argi], &split_argc, &split_argv) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid warp\n"; + return TCL_ERROR; + } + + if (split_argc != 3) { + opserr << "WARNING warp parameter expected list of 3 floats\n"; + Tcl_Free((char *) split_argv); + return TCL_ERROR; + } + + for (int j = 0; j < 3; j++) { + if (Tcl_GetDouble(interp, split_argv[j], &warp[i_warp][j]) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid warp\n"; + Tcl_Free((char *) split_argv); + return TCL_ERROR; + } + } + + // Free memory allocated by Tcl_SplitList. + Tcl_Free((char *) split_argv); + argi++; + } +} // // Add fiber to section builder // int ndm = builder->getNDM(); - int error = 0; + int id = 0; if (ndm == 2) { Vector pos(2); pos(0) = yLoc; pos(1) = zLoc; - error = fiberSectionRepr->addFiber(0, matTag, area, pos); + id = fiberSectionRepr->addFiber(0, matTag, area, pos); } else if (ndm == 3) { Vector pos(2); pos(0) = yLoc; pos(1) = zLoc; - error = fiberSectionRepr->addFiber(0, matTag, area, pos); + id = fiberSectionRepr->addFiber(0, matTag, area, pos); + } + // set warping + while (i_warp > 0) { + if (0 > fiberSectionRepr->setWarping(id, i_warp-1, warp[i_warp-1])) { + opserr << OpenSees::PromptValueError << "failed to set warping for fiber\n"; + return TCL_ERROR; + } + i_warp--; } - if (error) { - opserr << G3_ERROR_PROMPT << "cannot add patch to section\n"; + if (id < 0) { + opserr << OpenSees::PromptValueError << "Failed to add fiber to section\n"; return TCL_ERROR; } @@ -1477,13 +1412,13 @@ TclCommand_addHFiber(ClientData clientData, Tcl_Interp *interp, int argc, SectionBuilder* fiberSectionRepr = findSectionBuilder(builder, interp, argc, argv); if (fiberSectionRepr == nullptr) { - opserr << G3_ERROR_PROMPT << "cannot retrieve section\n"; + opserr << OpenSees::PromptValueError << "cannot retrieve section\n"; return TCL_ERROR; } // make sure at least one other argument to contain patch type if (argc < 5) { - opserr << G3_ERROR_PROMPT << "invalid num args: Hfiber yLoc zLoc area matTag\n"; + opserr << OpenSees::PromptValueError << "invalid num args: Hfiber yLoc zLoc area matTag\n"; return TCL_ERROR; } @@ -1492,20 +1427,20 @@ TclCommand_addHFiber(ClientData clientData, Tcl_Interp *interp, int argc, double yHLoc, zHLoc, Harea; if (Tcl_GetDouble(interp, argv[1], &yHLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid yLoc: Hfiber yLoc zLoc area matTag\n"; + opserr << OpenSees::PromptValueError << "invalid yLoc: Hfiber yLoc zLoc area matTag\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[2], &zHLoc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid zLoc: Hfiber yLoc zLoc area matTag\n"; + opserr << OpenSees::PromptValueError << "invalid zLoc: Hfiber yLoc zLoc area matTag\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3], &Harea) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid area: Hfiber yLoc zLoc area matTag\n"; + opserr << OpenSees::PromptValueError << "invalid area: Hfiber yLoc zLoc area matTag\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[4], &matHTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid matTag: Hfiber yLoc zLoc area matTag\n"; + opserr << OpenSees::PromptValueError << "invalid matTag: Hfiber yLoc zLoc area matTag\n"; return TCL_ERROR; } @@ -1533,13 +1468,13 @@ TclCommand_addReinfLayer(ClientData clientData, Tcl_Interp *interp, int argc, SectionBuilder* fiberSectionRepr = findSectionBuilder(builder, interp, argc, argv); if (fiberSectionRepr == nullptr) { - opserr << G3_ERROR_PROMPT << "cannot retrieve section\n"; + opserr << OpenSees::PromptValueError << "cannot retrieve section\n"; return TCL_ERROR; } // make sure at least one other argument to contain layer type if (argc < 2) { - opserr << G3_ERROR_PROMPT << "need to specify a layer type \n"; + opserr << OpenSees::PromptValueError << "need to specify a layer type \n"; return TCL_ERROR; } @@ -1547,7 +1482,7 @@ TclCommand_addReinfLayer(ClientData clientData, Tcl_Interp *interp, int argc, if (strcmp(argv[1], "straight") == 0 || strcmp(argv[1], "line") == 0) { if (argc < 9) { - opserr << G3_ERROR_PROMPT << "invalid number of parameters: layer straight matTag " + opserr << OpenSees::PromptValueError << "invalid number of parameters: layer straight matTag " "numReinfBars reinfBarArea yStartPt zStartPt yEndPt zEndPt\n"; return TCL_ERROR; } @@ -1559,43 +1494,43 @@ TclCommand_addReinfLayer(ClientData clientData, Tcl_Interp *interp, int argc, int argi = 2; if (Tcl_GetInt(interp, argv[argi++], &matTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid matTag: layer straight matTag numReinfBars " + opserr << OpenSees::PromptValueError << "invalid matTag: layer straight matTag numReinfBars " "reinfBarArea yStartPt zStartPt yEndPt zEndPt\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[argi++], &numReinfBars) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid numReinfBars: layer straight matTag " + opserr << OpenSees::PromptValueError << "invalid numReinfBars: layer straight matTag " "numReinfBars reinfBarArea yStartPt zStartPt yEndPt zEndPt\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &reinfBarArea) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid reinfBarArea: layer straight matTag " + opserr << OpenSees::PromptValueError << "invalid reinfBarArea: layer straight matTag " "numReinfBars reinfBarArea yStartPt zStartPt yEndPt zEndPt\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &yStartPt) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid yStartPt: layer straight matTag numReinfBars " + opserr << OpenSees::PromptValueError << "invalid yStartPt: layer straight matTag numReinfBars " "reinfBarArea yStartPt zStartPt yEndPt zEndPt\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &zStartPt) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid zStartPt: layer straight matTag numReinfBars " + opserr << OpenSees::PromptValueError << "invalid zStartPt: layer straight matTag numReinfBars " "reinfBarArea yStartPt zStartPt yEndPt zEndPt\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &yEndPt) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid yEndPt: layer straight matTag numReinfBars " + opserr << OpenSees::PromptValueError << "invalid yEndPt: layer straight matTag numReinfBars " "reinfBarArea yStartPt zStartPt yEndPt zEndPt\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &zEndPt) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid zEndPt: layer straight matTag numReinfBars " + opserr << OpenSees::PromptValueError << "invalid zEndPt: layer straight matTag numReinfBars " "reinfBarArea yStartPt zStartPt yEndPt zEndPt\n"; return TCL_ERROR; } @@ -1619,7 +1554,7 @@ TclCommand_addReinfLayer(ClientData clientData, Tcl_Interp *interp, int argc, } else if (strcmp(argv[1], "circ") == 0) { if (argc < 8) { - opserr << G3_ERROR_PROMPT << "invalid number of parameters: layer circ matTag " + opserr << OpenSees::PromptValueError << "invalid number of parameters: layer circ matTag " "numReinfBars reinfBarArea yCenter zCenter arcRadius \n"; return TCL_ERROR; @@ -1632,38 +1567,32 @@ TclCommand_addReinfLayer(ClientData clientData, Tcl_Interp *interp, int argc, int argi = 2; if (Tcl_GetInt(interp, argv[argi++], &matTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid matTag: layer circ matTag numReinfBars " - "reinfBarArea yCenter zCenter radius startAng endAng\n"; + opserr << OpenSees::PromptValueError << "invalid matTag\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[argi++], &numReinfBars) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid numReinfBars: layer circ matTag numReinfBars " - "reinfBarArea yCenter zCenter radius startAng endAng\n"; + opserr << OpenSees::PromptValueError << "invalid numReinfBars\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &reinfBarArea) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid reinfBarArea: layer circ matTag numReinfBars " - "reinfBarArea yCenter zCenter radius startAng endAng\n"; + opserr << OpenSees::PromptValueError << "invalid reinfBarArea\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &yCenter) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid yCenter: layer circ matTag numReinfBars " - "reinfBarArea yCenter zCenter radius startAng endAng\n"; + opserr << OpenSees::PromptValueError << "invalid yCenter\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &zCenter) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid zCenter: layer circ matTag numReinfBars " - "reinfBarArea yCenter zCenter radius startAng endAng\n"; + opserr << OpenSees::PromptValueError << "invalid zCenter\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &radius) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid radius: layer circ matTag numReinfBars " - "reinfBarArea yCenter zCenter radius startAng endAng\n"; + opserr << OpenSees::PromptValueError << "invalid radius\n"; return TCL_ERROR; } @@ -1671,14 +1600,12 @@ TclCommand_addReinfLayer(ClientData clientData, Tcl_Interp *interp, int argc, if (argc > 9) { if (Tcl_GetDouble(interp, argv[argi++], &startAng) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid startAng: layer circ matTag numReinfBars " - "reinfBarArea yCenter zCenter radius startAng endAng\n"; + opserr << OpenSees::PromptValueError << "invalid startAng\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argi++], &endAng) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid endAng: layer circ matTag numReinfBars " - "reinfBarArea yCenter zCenter radius startAng endAng\n"; + opserr << OpenSees::PromptValueError << "invalid endAng\n"; return TCL_ERROR; } @@ -1692,24 +1619,25 @@ TclCommand_addReinfLayer(ClientData clientData, Tcl_Interp *interp, int argc, center(0) = yCenter; center(1) = zCenter; - CircReinfLayer *reinfLayer = nullptr; - if (anglesSpecified) + int error = -1; + // construct and add to section + if (anglesSpecified) { // Construct arc - reinfLayer = new CircReinfLayer(matTag, numReinfBars, reinfBarArea, - center, radius, startAng, endAng); - else + CircReinfLayer reinfLayer(matTag, numReinfBars, reinfBarArea, + center, radius, startAng, endAng); + error = fiberSectionRepr->addLayer(reinfLayer); + } else { // Construct circle - reinfLayer = new CircReinfLayer(matTag, numReinfBars, reinfBarArea, - center, radius); + CircReinfLayer reinfLayer(matTag, numReinfBars, reinfBarArea, + center, radius); + error = fiberSectionRepr->addLayer(reinfLayer); + } - // add reinfLayer to section - int error = fiberSectionRepr->addLayer(*reinfLayer); - delete reinfLayer; if (error) return TCL_ERROR; } else { - opserr << G3_ERROR_PROMPT << "reinforcing layer type is not available\n"; + opserr << OpenSees::PromptValueError << "reinforcing layer type is not available\n"; return TCL_ERROR; } @@ -1761,7 +1689,7 @@ TclCommand_addUCFiberSection(ClientData clientData, Tcl_Interp *interp, } // - // now parse the output file containing the fiber data, + // Now parse the output file containing the fiber data, // create fibers and add them to the section // @@ -1832,7 +1760,7 @@ buildSectionInt(ClientData clientData, Tcl_Interp *interp, TclBasicBuilder *theT SectionRepres *sectionRepres = theTclBasicBuilder->getSectionRepres(secTag); if (sectionRepres == nullptr) { - opserr << G3_ERROR_PROMPT << "cannot retrieve section\n"; + opserr << OpenSees::PromptValueError << "cannot retrieve section\n"; return TCL_ERROR; } @@ -1891,7 +1819,7 @@ buildSectionInt(ClientData clientData, Tcl_Interp *interp, TclBasicBuilder *theT for (int j = 0; j < numCells; j++) { fibersMaterial(k) = matTag; fibersArea(k) = cell[j]->getArea(); - fiberPosition = cell[j]->getCentroidPosition(); + fiberPosition = cell[j]->getPosition(); fibersPosition(0, k) = fiberPosition(0); fibersPosition(1, k) = fiberPosition(1); k++; @@ -1945,7 +1873,7 @@ buildSectionInt(ClientData clientData, Tcl_Interp *interp, TclBasicBuilder *theT for (int i = numSectionRepresFibers; i < numFibers; ++i) { material = builder->getUniaxialMaterial(fibersMaterial(k)); if (material == nullptr) { - opserr << G3_ERROR_PROMPT << "invalid material ID for patch\n"; + opserr << OpenSees::PromptValueError << "invalid material ID for patch\n"; return TCL_ERROR; } @@ -1967,12 +1895,12 @@ buildSectionInt(ClientData clientData, Tcl_Interp *interp, TclBasicBuilder *theT delete Hfiber[i]; if (section == nullptr) { - opserr << G3_ERROR_PROMPT << "cannot construct section\n"; + opserr << OpenSees::PromptValueError << "cannot construct section\n"; return TCL_ERROR; } if (theTclBasicBuilder->addSection (*section) < 0) { - opserr << G3_ERROR_PROMPT << "- cannot add section\n"; + opserr << OpenSees::PromptValueError << "- cannot add section\n"; return TCL_ERROR; } @@ -1983,7 +1911,7 @@ buildSectionInt(ClientData clientData, Tcl_Interp *interp, TclBasicBuilder *theT for (i = numSectionRepresFibers; i < numFibers; ++i) { material = builder->getUniaxialMaterial(fibersMaterial(k)); if (material == nullptr) { - opserr << G3_ERROR_PROMPT << "invalid material ID for patch\n"; + opserr << OpenSees::PromptValueError << "invalid material ID for patch\n"; return TCL_ERROR; } @@ -2007,17 +1935,17 @@ buildSectionInt(ClientData clientData, Tcl_Interp *interp, TclBasicBuilder *theT delete fiber[i]; if (section == 0) { - opserr << G3_ERROR_PROMPT << "- cannot construct section\n"; + opserr << OpenSees::PromptValueError << "- cannot construct section\n"; return TCL_ERROR; } if (theTclBasicBuilder->addSection (*section) < 0) { - opserr << G3_ERROR_PROMPT << "- cannot add section\n"; + opserr << OpenSees::PromptValueError << "- cannot add section\n"; return TCL_ERROR; } } else { - opserr << G3_ERROR_PROMPT << "NDM = " << NDM + opserr << OpenSees::PromptValueError << "NDM = " << NDM << " is incompatible with available frame elements\n"; return TCL_ERROR; } @@ -2027,7 +1955,7 @@ buildSectionInt(ClientData clientData, Tcl_Interp *interp, TclBasicBuilder *theT // delete [] Hfiber; } else { - opserr << G3_ERROR_PROMPT << "section invalid: can only build fiber sections\n"; + opserr << OpenSees::PromptValueError << "section invalid: can only build fiber sections\n"; return TCL_ERROR; } @@ -2043,7 +1971,7 @@ G3Parse_newTubeSection(G3_Runtime* rt, int argc, G3_Char ** const argv) SectionForceDeformation *theSection = nullptr; if (strcmp(argv[1], "Tube") == 0) { if (argc < 8) { - opserr << G3_ERROR_PROMPT << "insufficient arguments\n"; + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; opserr << "Want: section Tube tag? matTag? D? t? nfw? nfr?" << endln; return nullptr; } @@ -2053,35 +1981,35 @@ G3Parse_newTubeSection(G3_Runtime* rt, int argc, G3_Char ** const argv) int nfw, nfr; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid section Tube tag" << endln; + opserr << OpenSees::PromptValueError << "invalid section Tube tag" << endln; return nullptr; } if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid section Tube matTag" << endln; + opserr << OpenSees::PromptValueError << "invalid section Tube matTag" << endln; return nullptr; } if (Tcl_GetDouble(interp, argv[4], &D) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid D" << endln; + opserr << OpenSees::PromptValueError << "invalid D" << endln; opserr << "Tube section: " << tag << endln; return nullptr; } if (Tcl_GetDouble(interp, argv[5], &t) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid t" << endln; + opserr << OpenSees::PromptValueError << "invalid t" << endln; opserr << "Tube section: " << tag << endln; return nullptr; } if (Tcl_GetInt(interp, argv[6], &nfw) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nfw" << endln; + opserr << OpenSees::PromptValueError << "invalid nfw" << endln; opserr << "Tube section: " << tag << endln; return nullptr; } if (Tcl_GetInt(interp, argv[7], &nfr) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nfr" << endln; + opserr << OpenSees::PromptValueError << "invalid nfr" << endln; opserr << "Tube section: " << tag << endln; return nullptr; } @@ -2095,7 +2023,7 @@ G3Parse_newTubeSection(G3_Runtime* rt, int argc, G3_Char ** const argv) double shape = 1.0; if (argc > 9) { if (Tcl_GetDouble(interp, argv[9], &shape) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid shape" << endln; + opserr << OpenSees::PromptValueError << "invalid shape" << endln; opserr << "WFSection2d section: " << tag << endln; return nullptr; } diff --git a/SRC/runtime/commands/modeling/section/PlaneSection.h b/SRC/runtime/commands/modeling/section/PlaneSection.h new file mode 100644 index 0000000000..69433b1a5a --- /dev/null +++ b/SRC/runtime/commands/modeling/section/PlaneSection.h @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// +// Written: cmp +// +#pragma once +#include + + +template +class PlaneSection: public TaggedObject { + + public: + + PlaneSection(int tag, MatT& material, double thickness) + : TaggedObject(tag) + , material(&material) + , thickness(thickness) + { + } + + double getThickness() const + { + return thickness; + } + + MatT* getMaterial() const + { + return material; + } + + private: + const double thickness; + MatT* material; +}; + diff --git a/SRC/runtime/commands/modeling/section/frame.cpp b/SRC/runtime/commands/modeling/section/frame.cpp new file mode 100644 index 0000000000..d6f49441f6 --- /dev/null +++ b/SRC/runtime/commands/modeling/section/frame.cpp @@ -0,0 +1,641 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// +// Written: cmp +// +#include +#include +#include +#include +#include +#include +#include +#include +// +#include +#include +#include +#include +#include +#include + + +// section ElasticFrame tag E? A? Iz? +// E A I +// E A I G J +// -E $E +// -G $G +// +// -A $A +// {$A $Ay} if ndm == 2 +// {$A $Ay $Az} +// -Ay $Ay +// -Az $Az +// -I/B $Iz +// {$Iy $Iz} +// {$Iy $Iz $Iyz} +// -J $J +// -Cw $Cw +// {$Cw $Ca} +// -Q {$Qy $Qz <$Qyx $Qyz>} +// -R {$Qy $Qz} +// +template +static inline int +TclCommand_newElasticSectionTemplate(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + + assert(clientData != nullptr); + BasicModelBuilder *builder = static_cast(clientData); + FrameSectionConstants consts {}; + + Domain& domain = *builder->getDomain(); + + ArgumentTracker tracker; + std::set positional; + + using namespace OpenSees::Parsing; + + Parameter* parameters[int(Position::Max)] = {}; + + bool construct_full = false; + + if (argc < 5) { + opserr << OpenSees::PromptParseError << "insufficient arguments\n"; + opserr << "Want: section Elastic tag? E? A? Iz? .\n"; + return TCL_ERROR; + } + + int tag; + double E, + G = 0, + J = 0; + + bool use_mass = false; + double mass=0.0; + + // All 3D elements have been refactored to select shear themselves, but + // in 2D the element may check the section for shear. + bool use_shear = false ; // NDM == 3; + + int i; + for (i=2; iaddTaggedObject(*theSection) < 0) { + if (theSection != nullptr) + delete theSection; + return TCL_ERROR; + } + + // For the elastic elements + // builder->addTaggedObject(*new ElasticLinearFrameSection3d(tag,E,G,consts,mass,use_mass)); + + return TCL_OK; + + } else { + + FrameSection* theSection = nullptr; + + consts.Ca = consts.Iy + consts.Iz - J; + consts.Sa = -(consts.Iy + consts.Iz - J); + if (construct_full) { + theSection = new ElasticLinearFrameSection3d(tag, + E, G, + consts, + mass, use_mass + ); + } + + else if (strcmp(argv[1], "Elastic") == 0) { + if (use_shear) + theSection = new ElasticShearSection3d(tag, E, consts.A, consts.Iz, consts.Iy, G, J, + consts.A/consts.Ay, consts.A/consts.Az); + else + theSection = new ElasticSection3d(tag, E, consts.A, consts.Iz, consts.Iy, G, J); + + } + else + theSection = new ElasticLinearFrameSection3d(tag, + E, G, + consts, + mass, use_mass + ); + + if (theSection == nullptr || builder->addTaggedObject(*theSection) < 0) { + if (theSection != nullptr) + delete theSection; + return TCL_ERROR; + } else + return TCL_OK; + } + +} + +int +TclCommand_newElasticSection(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = static_cast(clientData); + + int ndm = builder->getNDM(); + + if (ndm==2) { + enum class Position : int { + Tag, E, A, Iz, EndRequired, G, ky, End, Iy, J, kz, Max + }; + return TclCommand_newElasticSectionTemplate(clientData, interp, argc, argv); + + } else { + enum class Position : int { + Tag, E, A, Iz, Iy, G, J, EndRequired, ky, kz, End, Max + }; + return TclCommand_newElasticSectionTemplate(clientData, interp, argc, argv); + } +} + +int +TclCommand_addSectionAggregator(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char**const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder *builder = static_cast(clientData); + + if (argc < 5) { + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; + opserr << "Want: section Aggregator tag? uniTag1? code1? ... <-section " + "secTag?>" + << endln; + return TCL_ERROR; + } + + int status = TCL_ERROR; + + int tag; + int secTag; + FrameSection *theSec = nullptr; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid Aggregator tag" << endln; + return TCL_ERROR; + } + + int nArgs = argc - 3; + + for (int ii = 5; ii < argc; ii++) { + if (strcmp(argv[ii], "-section") == 0 && ++ii < argc) { + if (Tcl_GetInt(interp, argv[ii], &secTag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid Aggregator tag" << endln; + return TCL_ERROR; + } + + theSec = builder->getTypedObject(secTag); + if (theSec == 0) + return TCL_ERROR; + + nArgs -= 2; + } + } + + int nMats = nArgs / 2; + + if (nArgs % 2 != 0) { + opserr << OpenSees::PromptValueError << "improper number of arguments for Aggregator" << endln; + return TCL_ERROR; + } + + ID codes(nMats); + UniaxialMaterial **theMats = new UniaxialMaterial *[nMats]; + + int i, j; + for (i = 3, j = 0; j < nMats; i++, j++) { + int tagI; + if (Tcl_GetInt(interp, argv[i], &tagI) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid Aggregator matTag" << endln; + status = TCL_ERROR; + goto cleanup; + } + + theMats[j] = builder->getTypedObject(tagI); + if (theMats[j] == 0) { + status = TCL_ERROR; + goto cleanup; + } + + i++; + + if (strcmp(argv[i], "Mz") == 0) + codes(j) = SECTION_RESPONSE_MZ; + else if (strcmp(argv[i], "P") == 0) + codes(j) = SECTION_RESPONSE_P; + else if (strcmp(argv[i], "Vy") == 0) + codes(j) = SECTION_RESPONSE_VY; + else if (strcmp(argv[i], "My") == 0) + codes(j) = SECTION_RESPONSE_MY; + else if (strcmp(argv[i], "Vz") == 0) + codes(j) = SECTION_RESPONSE_VZ; + else if (strcmp(argv[i], "T") == 0) + codes(j) = SECTION_RESPONSE_T; + else { + opserr << OpenSees::PromptValueError << "invalid code" << endln; + opserr << "\nsection Aggregator: " << tag << endln; + status = TCL_ERROR; + goto cleanup; + } + } + + { + FrameSection* theSection = nullptr; + if (theSec) + theSection = new SectionAggregator(tag, *theSec, nMats, theMats, codes); + else + theSection = new SectionAggregator(tag, nMats, theMats, codes); + + // Now add the material to the modelBuilder + if (builder->addTaggedObject(*theSection) < 0) { + delete theSection; + status = TCL_ERROR; + } else + status = TCL_OK; + } + +cleanup: + delete[] theMats; + return status; +} diff --git a/SRC/runtime/commands/modeling/section/plane.cpp b/SRC/runtime/commands/modeling/section/plane.cpp new file mode 100644 index 0000000000..c31610cd3e --- /dev/null +++ b/SRC/runtime/commands/modeling/section/plane.cpp @@ -0,0 +1,141 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// +// Written: cmp +// +#include +#include +#include +#include +#include +#include "PlaneSection.h" +#include +#include +#include + +int +TclCommand_addPlaneSection(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = static_cast(clientData); + enum class Positions : int { + Material, Thickness, End + }; + ArgumentTracker tracker; + std::set positional; + + // section Plane[Strain|Stress] $tag $material $thickness + if (argc < 5) { + opserr << OpenSees::PromptValueError + << "incorrect number of arguments\n"; + return TCL_ERROR; + } + + int tag; + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read integer tag\n"; + return TCL_ERROR; + } + int mtag; + double thickness; + for (int i=3; igetTypedObject(mtag); + if (mptr == nullptr) + return TCL_ERROR; + + NDMaterial* pptr = nullptr; + if (strcmp(argv[1], "PlaneStrain") == 0) { + if (!(pptr = mptr->getCopy("PlaneStrain"))) { + pptr = new PlaneStrainMaterial(tag, *mptr); + } + } + else if (strcmp(argv[1], "PlaneStress") == 0) { + if (!(pptr = mptr->getCopy("PlaneStress"))) { + pptr = new PlaneStressMaterial(tag, *mptr); + } + } + else { + opserr << OpenSees::PromptValueError + << "unknown plane section\n"; + return TCL_ERROR; + } + + builder->addTaggedObject>(*(new PlaneSection(tag, *pptr, thickness))); + + return TCL_OK; +} diff --git a/SRC/runtime/commands/modeling/section/truss.cpp b/SRC/runtime/commands/modeling/section/truss.cpp new file mode 100644 index 0000000000..12b3a739ac --- /dev/null +++ b/SRC/runtime/commands/modeling/section/truss.cpp @@ -0,0 +1,202 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// +// Description: This file implements a command to add a uniaxial section. +// Written: cmp +// +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int +TclCommand_addUniaxialSection(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = static_cast(clientData); + + // section Uniaxial tag? material? code? + if (argc < 5) { + opserr << "WARNING insufficient arguments\n"; + return TCL_ERROR; + } + + int tag; + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid section tag\n"; + return TCL_ERROR; + } + + int mat; + if (Tcl_GetInt(interp, argv[3], &mat) != TCL_OK) { + opserr << "WARNING invalid uniaxial material tag\n"; + return TCL_ERROR; + } + + + UniaxialMaterial* material = builder->getTypedObject(mat); + if (material == nullptr) + return TCL_ERROR; + + UniaxialMaterial *theMats[1] = {material}; + + // + int code; + const char* type = argv[4]; + if (strcmp(type,"Mz") == 0) + code = SECTION_RESPONSE_MZ; + else if (strcmp(type,"P") == 0) + code = SECTION_RESPONSE_P; + else if (strcmp(type,"Vy") == 0) + code = SECTION_RESPONSE_VY; + else if (strcmp(type,"My") == 0) + code = SECTION_RESPONSE_MY; + else if (strcmp(type,"Vz") == 0) + code = SECTION_RESPONSE_VZ; + else if (strcmp(type,"T") == 0) + code = SECTION_RESPONSE_T; + else { + opserr << "WARNING invalid code " << type << "\n"; + return TCL_ERROR; + } + + ID codeID(1); + codeID(0) = code; + return builder->addTaggedObject(*new SectionAggregator(tag, 1, theMats, codeID)); +} + + +#if 0 + +int +TclCommand_addTrussSection(ClientData clientData, Tcl_Interp *interp, + int argc, TCL_Char ** const argv) +{ + BasicModelBuilder *builder = static_cast(clientData); + enum class Positions : int { + Material, Area, End + }; + ArgumentTracker tracker; + std::set positional; + + + // section Type? $tag $material $area + if (argc < 5) { + opserr << OpenSees::PromptValueError + << "incorrect number of arguments\n"; + return TCL_ERROR; + } + + int tag; + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "failed to read integer tag\n"; + return TCL_ERROR; + } + + int mtag; + double area; + for (int i=3; igetTypedObject(mtag); + if (mptr == nullptr) + return TCL_ERROR; + + UniaxialMaterial* pptr = nullptr; + if (strcmp(argv[1], "Uniaxial") == 0) { + area = 1.0; + } + else if (strcmp(argv[1], "PlaneStress") == 0) { + if (!(pptr = mptr->getCopy("PlaneStress"))) { + pptr = new PlaneStressMaterial(tag, *mptr); + } + } + else { + opserr << OpenSees::PromptValueError + << "unknown plane section\n"; + return TCL_ERROR; + } + + builder->addTaggedObject>(*(new TrussSection(tag, *pptr, area))); + + return TCL_OK; +} +#endif \ No newline at end of file diff --git a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp index 5fdd5f10e3..c41852bbbf 100644 --- a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp +++ b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp @@ -38,7 +38,9 @@ class FrameTransformBuilder : public TaggedObject { : ndm(ndm), TaggedObject(t), vz{{0, 0, 0}}, offsets{}, offset_flags(0) { + // strncpy(name, n, 128); snprintf(name, sizeof(name), "%s", n); + // offset_flags |= LogIter; } virtual ~FrameTransformBuilder() {} @@ -84,6 +86,13 @@ class FrameTransformBuilder : public TaggedObject { else return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); } + else if (strcmp(name, "Corotational03") == 0) + { + if (getenv("Crisfield02")) + return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); + + return new EuclidFrameTransf> (tag, vz, offset_array, offset_flags); + } return nullptr; } diff --git a/SRC/runtime/commands/modeling/uniaxial.cpp b/SRC/runtime/commands/modeling/uniaxial.cpp index ca2b931324..5f61bafa86 100644 --- a/SRC/runtime/commands/modeling/uniaxial.cpp +++ b/SRC/runtime/commands/modeling/uniaxial.cpp @@ -1,8 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // // Description: This file contains the function invoked when the user invokes // the uniaxialMaterial command in the interpreter. @@ -10,23 +12,17 @@ // Written: fmk, MHS, cmp // Created: 07/99 // - -#include +#include #include #include #include "uniaxial.hpp" #include #include // MHS -#include // Won Lee #include // Won Lee -#include // MHS #include // Mackie -#include // ZHY -#include // Patxi #include // MHS #include // MHS -#include // NM #include // KM #include //JAE @@ -38,7 +34,6 @@ #include #include -#include // Quan class G3_Runtime; @@ -46,21 +41,25 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp *interp, int cArg, int mArg, TCL_Char ** const argv, Domain *domain); -// extern void *OPS_PlateBearingConnectionThermal(G3_Runtime*); - -// extern int TclCommand_ConfinedConcrete02(ClientData clientData, Tcl_Interp -// *interp, int argc, TCL_Char ** const argv, TclBasicBuilder -// *theTclBuilder); -// extern UniaxialMaterial *Tcl_AddLimitStateMaterial(ClientData clientData, -// Tcl_Interp *interp, int argc, -// TCL_Char **arg); #if 0 +extern void *OPS_PlateBearingConnectionThermal(G3_Runtime*); + +extern int TclCommand_ConfinedConcrete02(ClientData clientData, Tcl_Interp +*interp, int argc, TCL_Char ** const argv, TclBasicBuilder +*theTclBuilder); + +extern UniaxialMaterial *Tcl_AddLimitStateMaterial(ClientData clientData, + Tcl_Interp *interp, int argc, + TCL_Char **arg); + + extern UniaxialMaterial * Tcl_addWrapperUniaxialMaterial(matObj *, ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv); #endif + typedef struct uniaxialPackageCommand { char *funcName; void *(*funcPtr)(); @@ -69,25 +68,18 @@ typedef struct uniaxialPackageCommand { static UniaxialPackageCommand *theUniaxialPackageCommands = NULL; -static void printCommand(int argc, TCL_Char ** const argv) { - opserr << "Input command: "; - for (int i = 0; i < argc; ++i) - opserr << argv[i] << " "; - opserr << "\n"; -} - // // external functions // -UniaxialMaterial *TclBasicBuilder_addPyTzQzMaterial(ClientData clientData, - Tcl_Interp *interp, +UniaxialMaterial *TclBasicBuilder_addPyTzQzMaterial(ClientData, + Tcl_Interp *, int argc, TCL_Char ** const argv, - Domain *theDomain); + Domain *); -UniaxialMaterial *TclBasicBuilder_FRPCnfinedConcrete(ClientData clientData, - Tcl_Interp *interp, +UniaxialMaterial *TclBasicBuilder_FRPCnfinedConcrete(ClientData, + Tcl_Interp *, int argc, TCL_Char ** const argv, - Domain *theDomain); + Domain *); UniaxialMaterial *TclBasicBuilder_addDegradingMaterial(ClientData, Tcl_Interp *, int, TCL_Char **); @@ -103,7 +95,7 @@ TclCommand_addUniaxialMaterial(ClientData clientData, Tcl_Interp *interp, // Make sure there is a minimum number of arguments if (argc < 3) { - opserr << G3_ERROR_PROMPT + opserr << OpenSees::PromptValueError << "insufficient number of uniaxial material arguments\n" << "Want: uniaxialMaterial type? tag? \n"; return TCL_ERROR; @@ -240,13 +232,13 @@ TclCommand_addUniaxialMaterial(ClientData clientData, Tcl_Interp *interp, // if still here the element command does not exist // if (theMaterial == nullptr) { - opserr << G3_ERROR_PROMPT << "Could not create uniaxialMaterial " << argv[1] << "\n"; + opserr << OpenSees::PromptValueError << "Could not create uniaxialMaterial " << argv[1] << "\n"; return TCL_ERROR; } // Now add the material to the modelBuilder if (builder->addTaggedObject(*theMaterial) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "Could not add uniaxialMaterial to the model builder.\n"; + opserr << OpenSees::PromptValueError << "Could not add uniaxialMaterial to the model builder.\n"; delete theMaterial; return TCL_ERROR; } @@ -255,770 +247,9 @@ TclCommand_addUniaxialMaterial(ClientData clientData, Tcl_Interp *interp, } -int -TclCommand_newFatigueMaterial(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder *builder = static_cast(clientData); - - if (argc < 4) { - opserr << G3_ERROR_PROMPT << "insufficient arguments\n"; - printCommand(argc, argv); - opserr << "Want: uniaxialMaterial Fatigue tag? matTag?"; - opserr << " <-D_max dmax?> <-e0 e0?> <-m m?>" << "\n"; - opserr << " <-min min?> <-max max?>" << "\n"; - return TCL_ERROR; - } - - int tag, matTag; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid uniaxialMaterial Fatigue tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid component tag\n"; - opserr << "uniaxialMaterial Fatigue: " << tag << "\n"; - return TCL_ERROR; - } - - double Dmax = 1.0; - double E0 = 0.191; - double m = -0.458; - double epsmin = NEG_INF_STRAIN; - double epsmax = POS_INF_STRAIN; - - for (int j = 4; j < argc; j++) { - if (strcmp(argv[j], "-Dmax") == 0) { - if ((j + 1 >= argc) || - (Tcl_GetDouble(interp, argv[j + 1], &Dmax) != TCL_OK)) { - opserr << G3_ERROR_PROMPT << "invalid -Dmax"; - opserr << "uniaxialMaterial Fatigue: " << tag << "\n"; - return TCL_ERROR; - } - } else if (strcmp(argv[j], "-E0") == 0) { - if ((j + 1 >= argc) || - (Tcl_GetDouble(interp, argv[j + 1], &E0) != TCL_OK)) { - opserr << G3_ERROR_PROMPT << "invalid -E0"; - opserr << "uniaxialMaterial Fatigue: " << tag << "\n"; - return TCL_ERROR; - } - } else if (strcmp(argv[j], "-m") == 0) { - if ((j + 1 >= argc) || - (Tcl_GetDouble(interp, argv[j + 1], &m) != TCL_OK)) { - opserr << G3_ERROR_PROMPT << "invalid -m"; - opserr << "uniaxialMaterial Fatigue: " << tag << "\n"; - return TCL_ERROR; - } - } else if (strcmp(argv[j], "-min") == 0) { - if ((j + 1 >= argc) || - (Tcl_GetDouble(interp, argv[j + 1], &epsmin) != TCL_OK)) { - opserr << G3_ERROR_PROMPT << "invalid -min "; - opserr << "uniaxialMaterial Fatigue: " << tag << "\n"; - return TCL_ERROR; - } - } else if (strcmp(argv[j], "-max") == 0) { - if ((j + 1 >= argc) || - (Tcl_GetDouble(interp, argv[j + 1], &epsmax) != TCL_OK)) { - opserr << G3_ERROR_PROMPT << "invalid -max"; - opserr << "uniaxialMaterial Fatigue: " << tag << "\n"; - return TCL_ERROR; - } - } - j++; - } - - UniaxialMaterial *theMat = builder->getTypedObject(matTag); - - if (theMat == nullptr) { - opserr << G3_ERROR_PROMPT << "component material does not exist\n"; - opserr << "Component material: " << matTag; - opserr << "\nuniaxialMaterial Fatigue: " << tag << "\n"; - return TCL_ERROR; - } - - // Parsing was successful, allocate the material - UniaxialMaterial *theMaterial = - new FatigueMaterial(tag, *theMat, Dmax, E0, m, epsmin, epsmax); - - if (builder->addTaggedObject(*theMaterial) != TCL_OK) { - delete theMaterial; - return TCL_ERROR; - } - return TCL_OK; - -} - - -static int -TclDispatch_LegacyUniaxials(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char**const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder *builder = static_cast(clientData); - UniaxialMaterial *theMaterial = nullptr; - - if (strcmp(argv[1], "Elastic2") == 0) { - if (argc < 4 || argc > 5) { - opserr << G3_ERROR_PROMPT << "invalid number of arguments\n"; - printCommand(argc, argv); - opserr << "Want: uniaxialMaterial Elastic tag? E? " << "\n"; - return TCL_ERROR; - } - - int tag; - double E; - double eta = 0.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid uniaxialMaterial Elastic tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid E\n"; - opserr << "uniaxiaMaterial Elastic: " << tag << "\n"; - return TCL_ERROR; - } - - if (argc == 5) { - if (Tcl_GetDouble(interp, argv[4], &eta) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid eta\n"; - opserr << "uniaxialMaterial Elastic: " << tag << "\n"; - return TCL_ERROR; - } - } - - // Parsing was successful, allocate the material - theMaterial = new Elastic2Material(tag, E, eta); - - } else if (strcmp(argv[1], "ENT") == 0) { - if (argc < 4) { - opserr << G3_ERROR_PROMPT << "invalid number of arguments\n"; - printCommand(argc, argv); - opserr << "Want: uniaxialMaterial ENT tag? E?" << "\n"; - return TCL_ERROR; - } - - int tag; - double E; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid uniaxialMaterial ENT tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid E\n"; - opserr << "uniaxiaMaterial ENT: " << tag << "\n"; - return TCL_ERROR; - } - - // Parsing was successful, allocate the material - theMaterial = new ENTMaterial(tag, E); - - } - - else if (strcmp(argv[1], "BarSlip") == 0) { - if (argc != 17 && argc != 15) { - opserr << G3_ERROR_PROMPT << "insufficient arguments\n"; - printCommand(argc, argv); - opserr << "Want: uniaxialMaterial BarSlip tag? fc? fy? Es? fu? Eh? db? " - "ld? nb? width? depth? bsflag? type? " - << "\n"; - return TCL_ERROR; - } - - int tag, nb, bsf, typ, dmg=1, unt=1; - double fc, fy, Es, fu, Eh, ld, width, depth, db; - - int argStart = 2; - - if (Tcl_GetInt(interp, argv[argStart++], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid tag\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[argStart++], &fc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid fc\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[argStart++], &fy) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid fy\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[argStart++], &Es) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Es\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[argStart++], &fu) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid fu\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[argStart++], &Eh) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid Eh\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[argStart++], &db) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid db\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[argStart++], &ld) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid ld\n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[argStart++], &nb) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid nbars\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[argStart++], &width) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid width\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[argStart++], &depth) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid depth\n"; - return TCL_ERROR; - } - - int y; - y = argStart; - - if ((strcmp(argv[y], "strong") == 0) || - (strcmp(argv[y], "Strong") == 0) || (strcmp(argv[y], "weak") == 0) || - (strcmp(argv[y], "Weak") == 0)) { - if ((strcmp(argv[y], "strong") == 0) || - (strcmp(argv[y], "Strong") == 0)) { - bsf = 0; - } - - if ((strcmp(argv[y], "weak") == 0) || (strcmp(argv[y], "Weak") == 0)) { - bsf = 1; - } - } else { - opserr << G3_ERROR_PROMPT << "invalid bond strength specified\n"; - return TCL_ERROR; - } - y++; - - if ((strcmp(argv[y], "beamtop") == 0) || - (strcmp(argv[y], "beamTop") == 0) || - (strcmp(argv[y], "beambot") == 0) || - (strcmp(argv[y], "beamBot") == 0) || - (strcmp(argv[y], "beambottom") == 0) || - (strcmp(argv[y], "beamBottom") == 0) || - (strcmp(argv[y], "beam") == 0) || (strcmp(argv[y], "Beam") == 0) || - (strcmp(argv[y], "Column") == 0) || - (strcmp(argv[y], "column") == 0)) { - if ((strcmp(argv[y], "beamtop") == 0) || - (strcmp(argv[y], "beamTop") == 0) || - (strcmp(argv[y], "beam") == 0) || (strcmp(argv[y], "Beam") == 0)) { - typ = 0; - } - - if ((strcmp(argv[y], "beambot") == 0) || - (strcmp(argv[y], "beamBot") == 0) || - (strcmp(argv[y], "beambottom") == 0) || - (strcmp(argv[y], "beamBottom") == 0)) { - typ = 1; - } - - if ((strcmp(argv[y], "column") == 0) || - (strcmp(argv[y], "Column") == 0)) { - typ = 2; - } - } else { - opserr << G3_ERROR_PROMPT << "invalid location of bar specified\n"; - return TCL_ERROR; - } - if (argc == 17) { - y++; - - if ((strcmp(argv[y], "damage1") == 0) || - (strcmp(argv[y], "Damage1") == 0) || - (strcmp(argv[y], "damage2") == 0) || - (strcmp(argv[y], "Damage2") == 0) || - (strcmp(argv[y], "nodamage") == 0) || - (strcmp(argv[y], "Nodamage") == 0) || - (strcmp(argv[y], "NoDamage") == 0) || - (strcmp(argv[y], "noDamage") == 0)) { - if ((strcmp(argv[y], "damage1") == 0) || - (strcmp(argv[y], "Damage1") == 0)) { - dmg = 1; - } else if ((strcmp(argv[y], "damage2") == 0) || - (strcmp(argv[y], "Damage2") == 0)) { - dmg = 2; - } else if ((strcmp(argv[y], "nodamage") == 0) || - (strcmp(argv[y], "Nodamage") == 0) || - (strcmp(argv[y], "NoDamage") == 0) || - (strcmp(argv[y], "noDamage") == 0)) { - dmg = 0; - } - - } else { - opserr << G3_ERROR_PROMPT << "invalid damage specified\n"; - return TCL_ERROR; - } - - y++; - - if ((strcmp(argv[y], "mpa") == 0) || (strcmp(argv[y], "MPa") == 0) || - (strcmp(argv[y], "mPa") == 0) || (strcmp(argv[y], "Mpa") == 0) || - (strcmp(argv[y], "psi") == 0) || (strcmp(argv[y], "Psi") == 0) || - (strcmp(argv[y], "PSI") == 0) || (strcmp(argv[y], "Pa") == 0) || - (strcmp(argv[y], "pa") == 0) || (strcmp(argv[y], "psf") == 0) || - (strcmp(argv[y], "Psf") == 0) || (strcmp(argv[y], "PSF") == 0) || - (strcmp(argv[y], "ksi") == 0) || (strcmp(argv[y], "Ksi") == 0) || - (strcmp(argv[y], "KSI") == 0) || (strcmp(argv[y], "ksf") == 0) || - (strcmp(argv[y], "Ksf") == 0) || (strcmp(argv[y], "KSF") == 0)) { - if ((strcmp(argv[y], "mpa") == 0) || (strcmp(argv[y], "MPa") == 0) || - (strcmp(argv[y], "mPa") == 0) || (strcmp(argv[y], "Mpa") == 0)) { - unt = 1; - } else if ((strcmp(argv[y], "psi") == 0) || - (strcmp(argv[y], "Psi") == 0) || - (strcmp(argv[y], "PSI") == 0)) { - unt = 2; - } else if ((strcmp(argv[y], "Pa") == 0) || - (strcmp(argv[y], "pa") == 0)) { - unt = 3; - } else if ((strcmp(argv[y], "psf") == 0) || - (strcmp(argv[y], "Psf") == 0) || - (strcmp(argv[y], "PSF") == 0)) { - unt = 4; - } else if ((strcmp(argv[y], "ksi") == 0) || - (strcmp(argv[y], "Ksi") == 0) || - (strcmp(argv[y], "KSI") == 0)) { - unt = 5; - } else if ((strcmp(argv[y], "ksf") == 0) || - (strcmp(argv[y], "Ksf") == 0) || - (strcmp(argv[y], "KSF") == 0)) { - unt = 6; - } - } else { - opserr << G3_ERROR_PROMPT << "invalid unit specified\n"; - return TCL_ERROR; - } - } - - // allocate the material - if (argc == 15) { - theMaterial = new BarSlipMaterial(tag, fc, fy, Es, fu, Eh, db, ld, nb, - width, depth, bsf, typ); - } - - if (argc == 17) { - theMaterial = new BarSlipMaterial(tag, fc, fy, Es, fu, Eh, db, ld, nb, - width, depth, bsf, typ, dmg, unt); - } - - } - - else if (strcmp(argv[1], "ShearPanel") == 0) { - if (argc != 42 && argc != 31) { - opserr << G3_ERROR_PROMPT << "insufficient arguments\n"; - printCommand(argc, argv); - opserr << "Want: uniaxialMaterial ShearPanel tag? stress1p? strain1p? " - "stress2p? strain2p? stress3p? strain3p? stress4p? strain4p? " - << "\n rDispP? rForceP? uForceP? " - << "\n gammaK1? gammaK2? gammaK3? " - "gammaK4? gammaKLimit? gammaD1? gammaD2? gammaD3? gammaD4? " - << "\ngammaDLimit? gammaF1? gammaF2? gammaF3? gammaF4? " - "gammaFLimit? gammaE? YieldStress? "; - return TCL_ERROR; - } - - int tag; - double stress1p, stress2p, stress3p, stress4p; - double strain1p, strain2p, strain3p, strain4p; - double stress1n, stress2n, stress3n, stress4n; - double strain1n, strain2n, strain3n, strain4n; - double rDispP, rForceP, uForceP, rDispN, rForceN, uForceN; - double gammaK1, gammaK2, gammaK3, gammaK4, gammaKLimit; - double gammaD1, gammaD2, gammaD3, gammaD4, gammaDLimit; - double gammaF1, gammaF2, gammaF3, gammaF4, gammaFLimit; - double gammaE, yStr; - - int i = 2; - - if (Tcl_GetInt(interp, argv[i++], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid uniaxialMaterial ShearPanel tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &stress1p) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid stress1p\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &strain1p) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid strain1p\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &stress2p) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid stress2p\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &strain2p) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid strain2p\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &stress3p) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid stress3p\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &strain3p) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid strain3p\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &stress4p) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid stress4p\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &strain4p) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid strain4p\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (argc == 42) { - if (Tcl_GetDouble(interp, argv[i++], &stress1n) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid stress1n\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &strain1n) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid strain1n\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &stress2n) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid stress2n\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &strain2n) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid strain2n\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &stress3n) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid stress3n\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &strain3n) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid strain3n\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &stress4n) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid stress4n\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &strain4n) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid strain4n\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - } - - if (Tcl_GetDouble(interp, argv[i++], &rDispP) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid rDispP\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &rForceP) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid rForceP\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &uForceP) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid uForceP\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (argc == 42) { - if (Tcl_GetDouble(interp, argv[i++], &rDispN) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid rDispN\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &rForceN) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid rForceN\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &uForceN) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid uForceN\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - } - - if (Tcl_GetDouble(interp, argv[i++], &gammaK1) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaK1\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaK2) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaK2\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaK3) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaK3\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaK4) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaK4\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaKLimit) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaKLimit\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaD1) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaD1\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaD2) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaD2\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaD3) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaD3\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaD4) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaD4\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaDLimit) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaDLimit\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaF1) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaF1\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaF2) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaF2\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaF3) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaF3\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaF4) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaF4\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[i++], &gammaFLimit) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaFLimit\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &gammaE) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid gammaE\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[i++], &yStr) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid yield stress\n"; - opserr << "ShearPanel material: " << tag << "\n"; - return TCL_ERROR; - } - - // allocate the pinching material - if (argc == 42) { - theMaterial = new ShearPanelMaterial( - tag, stress1p, strain1p, stress2p, strain2p, stress3p, strain3p, - stress4p, strain4p, stress1n, strain1n, stress2n, strain2n, - stress3n, strain3n, stress4n, strain4n, rDispP, rForceP, uForceP, - rDispN, rForceN, uForceN, gammaK1, gammaK2, gammaK3, gammaK4, - gammaKLimit, gammaD1, gammaD2, gammaD3, gammaD4, gammaDLimit, - gammaF1, gammaF2, gammaF3, gammaF4, gammaFLimit, gammaE, yStr); - } - if (argc == 31) { - theMaterial = new ShearPanelMaterial( - tag, stress1p, strain1p, stress2p, strain2p, stress3p, strain3p, - stress4p, strain4p, rDispP, rForceP, uForceP, gammaK1, gammaK2, - gammaK3, gammaK4, gammaKLimit, gammaD1, gammaD2, gammaD3, gammaD4, - gammaDLimit, gammaF1, gammaF2, gammaF3, gammaF4, gammaFLimit, - gammaE, yStr); - } - } - - else if (strcmp(argv[1], "Concrete01WithSITC") == 0) { - if (argc < 7) { - opserr << G3_ERROR_PROMPT << "insufficient arguments\n"; - printCommand(argc, argv); - opserr << "Want: uniaxialMaterial Concrete01 tag? fpc? epsc0? fpcu? " - "epscu? " - << "\n"; - return TCL_ERROR; - } - - int tag; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid uniaxialMaterial Concrete01 tag" << "\n"; - return TCL_ERROR; - } - - // Read required Concrete01 material parameters - double fpc, epsc0, fpcu, epscu; - - if (Tcl_GetDouble(interp, argv[3], &fpc) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid fpc\n"; - opserr << "Concrete01 material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &epsc0) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid epsc0\n"; - opserr << "Concrete01 material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &fpcu) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid fpcu\n"; - opserr << "Concrete01 material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &epscu) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid epscu\n"; - opserr << "Concrete01 material: " << tag << "\n"; - return TCL_ERROR; - } - - if (argc == 7) - // Parsing was successful, allocate the material - theMaterial = new Concrete01WithSITC(tag, fpc, epsc0, fpcu, epscu); - else { - double endStrainSITC; - if (Tcl_GetDouble(interp, argv[7], &endStrainSITC) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid epscu\n"; - opserr << "Concrete01 material: " << tag << "\n"; - return TCL_ERROR; - } - theMaterial = - new Concrete01WithSITC(tag, fpc, epsc0, fpcu, epscu, endStrainSITC); - } - } - - if (theMaterial == nullptr) - return TCL_ERROR; - - if (builder->addTaggedObject(*theMaterial) != TCL_OK) { - delete theMaterial; - return TCL_ERROR; - } - - return TCL_OK; -} - -#include -static int -TclCommand_newUniaxialJ2Plasticity(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char** const argv) -{ - // ----- 1D J2 Plasticity ---- - if (argc < 7) { - opserr << "WARNING invalid number of arguments\n"; - printCommand(argc, argv); - opserr << "Want: uniaxialMaterial UniaxialJ2Plasticity tag? E? sigmaY? " - "Hkin? " - << endln; - return TCL_ERROR; - } - - int tag; - double E, sigmaY, Hkin, Hiso; - Hiso = 0.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial UniaxialJ2Plasticity tag" - << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { - opserr << "WARNING invalid E\n"; - opserr << "uniaxiaMaterial UniaxialJ2Plasticity: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &sigmaY) != TCL_OK) { - opserr << "WARNING invalid sigmaY\n"; - opserr << "uniaxiaMaterial UniaxialJ2Plasticity: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &Hkin) != TCL_OK) { - opserr << "WARNING invalid Hkin\n"; - opserr << "uniaxiaMaterial SmoothPSConcrete: " << tag << endln; - return TCL_ERROR; - } - - if (argc >= 7) - if (Tcl_GetDouble(interp, argv[6], &Hiso) != TCL_OK) { - opserr << "WARNING invalid Hiso\n"; - opserr << "uniaxialMaterial UniaxialJ2Plasticity: " << tag << endln; - return TCL_ERROR; - } - - // Parsing was successful, allocate the material - UniaxialMaterial* theMaterial = new UniaxialJ2Plasticity(tag, E, sigmaY, Hkin, Hiso); - - assert(clientData != nullptr); - BasicModelBuilder *builder = static_cast(clientData); - builder->addTaggedObject(*theMaterial); - return TCL_OK; - -} -#include // NM +#include // NM static int TclDispatch_newUniaxialPinching4(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char ** const argv) { @@ -1028,7 +259,7 @@ TclDispatch_newUniaxialPinching4(ClientData clientData, Tcl_Interp* interp, int if (strcmp(argv[1], "Pinching4") == 0) { if (argc != 42 && argc != 31) { - opserr << G3_ERROR_PROMPT << "insufficient arguments\n"; + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; opserr << "Want: uniaxialMaterial Pinching4 tag? stress1p? strain1p? " "stress2p? strain2p? stress3p? strain3p? stress4p? strain4p? " << "\n #include #include +#include #include #include -#include +#include + +// Viscous +extern OPS_Routine OPS_Maxwell; +extern OPS_Routine OPS_ViscousDamper; +extern OPS_Routine OPS_ViscousMaterial; +extern OPS_Routine OPS_ViscoelasticGap; +extern OPS_Routine OPS_DamperMaterial; + extern OPS_Routine OPS_ASD_SMA_3K; +extern OPS_Routine OPS_ASDConcrete1DMaterial; extern OPS_Routine OPS_APDFMD; extern OPS_Routine OPS_APDMD; extern OPS_Routine OPS_APDVFD; -extern OPS_Routine OPS_BWBN; extern OPS_Routine OPS_Bilin02; extern OPS_Routine OPS_Bilin; extern OPS_Routine OPS_BilinearOilDamper; extern OPS_Routine OPS_Bond_SP01; -extern OPS_Routine OPS_BoucWenOriginal; extern OPS_Routine OPS_CFSSSWP; extern OPS_Routine OPS_CFSWSWP; extern OPS_Routine OPS_CableMaterial; extern OPS_Routine OPS_Cast; extern OPS_Routine OPS_CreepMaterial; - +// Concrete extern OPS_Routine OPS_Concrete01; extern OPS_Routine OPS_Concrete02; extern OPS_Routine OPS_Concrete02IS; @@ -42,13 +51,11 @@ extern OPS_Routine OPS_ConcreteL01Material; extern OPS_Routine OPS_ConcreteSakaiKawashima; extern OPS_Routine OPS_ConcreteZ01Material; extern OPS_Routine OPS_ConfinedConcrete01Material; -extern OPS_Routine OPS_DamperMaterial; -extern OPS_Routine OPS_DegradingPinchedBW; + extern OPS_Routine OPS_DoddRestr; extern OPS_Routine OPS_Dodd_Restrepo; extern OPS_Routine OPS_EPPGapMaterial; extern OPS_Routine OPS_ElasticBilin; -extern OPS_Routine OPS_ElasticMaterial; extern OPS_Routine OPS_ElasticMaterialThermal; extern OPS_Routine OPS_ElasticMultiLinear; extern OPS_Routine OPS_ElasticPPMaterial; @@ -59,10 +66,8 @@ extern OPS_Routine OPS_FRPConfinedConcrete; extern OPS_Routine OPS_GMG_CyclicReinforcedConcrete; extern OPS_Routine OPS_FRCC; extern OPS_Routine OPS_GNGMaterial; -extern OPS_Routine OPS_HardeningMaterial; extern OPS_Routine OPS_HoehlerStanton; extern OPS_Routine OPS_HookGap; -extern OPS_Routine OPS_HyperbolicGapMaterial; extern OPS_Routine OPS_HystereticMaterial; extern OPS_Routine OPS_HystereticPoly; extern OPS_Routine OPS_HystereticAsym; @@ -73,18 +78,14 @@ extern OPS_Routine OPS_IMKPeakOriented; extern OPS_Routine OPS_IMKPinching; extern OPS_Routine OPS_JankowskiImpact; extern OPS_Routine OPS_ImpactMaterial; -extern OPS_Routine OPS_InitStrainMaterial; -extern OPS_Routine OPS_InitStressMaterial; extern OPS_Routine OPS_Masonry; extern OPS_Routine OPS_Masonryt; -extern OPS_Routine OPS_Maxwell; extern OPS_Routine OPS_MinMaxMaterial; extern OPS_Routine OPS_ModIMKPeakOriented02; extern OPS_Routine OPS_ModIMKPeakOriented; extern OPS_Routine OPS_ModIMKPinching; extern OPS_Routine OPS_ModIMKPinching02; extern OPS_Routine OPS_MultiLinear; -extern OPS_Routine OPS_OOHystereticMaterial; extern OPS_Routine OPS_OriginCentered; extern OPS_Routine OPS_PinchingLimitState; extern OPS_Routine OPS_PinchingLimitStateMaterial; @@ -98,21 +99,17 @@ extern OPS_Routine OPS_SAWSMaterial; extern OPS_Routine OPS_SLModel; extern OPS_Routine OPS_SMAMaterial; extern OPS_Routine OPS_SPSW02; // SAJalali -extern OPS_Routine OPS_SeriesMaterial; extern OPS_Routine OPS_SimpleFractureMaterial; + extern OPS_Routine OPS_StainlessECThermal; -extern OPS_Routine OPS_Steel01; -extern OPS_Routine OPS_Steel01Thermal; -extern OPS_Routine OPS_Steel02; -extern OPS_Routine OPS_Steel02Fatigue; -extern OPS_Routine OPS_Steel02Thermal; -extern OPS_Routine OPS_Steel2; -extern OPS_Routine OPS_Steel4; extern OPS_Routine OPS_SteelBRB; extern OPS_Routine OPS_SteelECThermal; extern OPS_Routine OPS_SteelFractureDI; // galvisf extern OPS_Routine OPS_SteelMPF; extern OPS_Routine OPS_SteelZ01Material; +extern OPS_Routine OPS_Steel02Fatigue; +extern OPS_Routine OPS_Steel4; + extern OPS_Routine OPS_TDConcrete; // ntosic extern OPS_Routine OPS_TDConcreteEXP; // ntosic extern OPS_Routine OPS_TDConcreteMC10; // ntosic @@ -121,13 +118,23 @@ extern OPS_Routine OPS_TendonL01Material; extern OPS_Routine OPS_Trilinwp2; extern OPS_Routine OPS_Trilinwp; extern OPS_Routine OPS_UVCuniaxial; -extern OPS_Routine OPS_ViscousDamper; -extern OPS_Routine OPS_ViscousMaterial; -extern OPS_Routine OPS_ViscoelasticGap; extern OPS_Routine OPS_pyUCLA; +extern void *OPS_ConcretewBeta(); + +extern Tcl_CmdProc Create_OOHystereticMaterial; + -extern void *OPS_ConcretewBeta(void); +#if 0 +const char** DeprecatedUniaxialMaterials { + {"Bilin02", "This material is superceded by \"IMKBilin\" and \"HystereticSM\""}, + {"CFSSSWP", ""}, + {"CFSWSWP", ""}, + {"APDVFD", ""}, + {"APDMD", ""}, + {"APDFMD", ""}, +}; +#endif typedef UniaxialMaterial*(G3_TclUniaxialPackage)(ClientData, Tcl_Interp *, int, TCL_Char ** const); G3_TclUniaxialPackage TclBasicBuilder_addFedeasMaterial; @@ -143,27 +150,44 @@ std::unordered_map tcl_uniaxial_package_ta }; -typedef UniaxialMaterial* (TclDispatch_UniaxialMaterial)(G3_Runtime*, int, TCL_Char ** const); -TclDispatch_UniaxialMaterial TclCommand_ReinforcingSteel; - -static Tcl_CmdProc TclCommand_newFatigueMaterial; -static Tcl_CmdProc TclCommand_newUniaxialJ2Plasticity; - -Tcl_CmdProc TclCommand_newFedeasUniaxialDamage; -Tcl_CmdProc TclCommand_ContinuumUniaxialMaterial; +// Elastic +extern Tcl_CmdProc TclCommand_newElasticUniaxialMaterial; +// Plastic +extern Tcl_CmdProc TclCommand_newPlasticMaterial; +extern Tcl_CmdProc TclCommand_newUniaxialJ2Plasticity; +// Fedeas +extern Tcl_CmdProc TclCommand_newFedeasSteel; +extern Tcl_CmdProc TclCommand_newFedeasUniaxialDamage; +extern Tcl_CmdProc TclCommand_newFedeasConcrete; +// Wrapper +extern Tcl_CmdProc TclCommand_addWrappingMaterial; +extern Tcl_CmdProc TclCommand_newFatigueMaterial; +extern Tcl_CmdProc TclCommand_newParallelMaterial; +extern OPS_Routine OPS_SeriesMaterial; +// Bearing Tcl_CmdProc TclCommand_AxialSp; Tcl_CmdProc TclCommand_AxialSpHD; Tcl_CmdProc TclCommand_KikuchiAikenHDR; Tcl_CmdProc TclCommand_KikuchiAikenLRB; +// Concrete Tcl_CmdProc TclCommand_newUniaxialConcrete04; Tcl_CmdProc TclCommand_newUniaxialConcrete06; Tcl_CmdProc TclCommand_newUniaxialConcrete07; -Tcl_CmdProc TclCommand_newUniaxialBoucWen; -Tcl_CmdProc TclCommand_newParallelMaterial; - -// typedef int (TclCommand_UniaxialMaterial)(ClientData, Tcl_Interp*, int, TCL_Char ** const); +// Bouc-Wen +extern Tcl_CmdProc TclCommand_newBoucWen; +extern Tcl_CmdProc TclCommand_newUniaxialBoucWen; +extern Tcl_CmdProc TclCommand_newBoucWenMG; +extern OPS_Routine OPS_DegradingPinchedBW; +// Abutment +Tcl_CmdProc TclCommand_HyperbolicGapMaterial; +// Other static Tcl_CmdProc TclDispatch_newUniaxialPinching4; -static Tcl_CmdProc TclDispatch_LegacyUniaxials; +extern Tcl_CmdProc TclDispatch_LegacyUniaxials; + + +typedef UniaxialMaterial* (TclDispatch_UniaxialMaterial)(G3_Runtime*, int, TCL_Char ** const); +TclDispatch_UniaxialMaterial TclCommand_ReinforcingSteel; + template static int dispatch(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char** const argv) @@ -173,7 +197,7 @@ dispatch(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char** const ar UniaxialMaterial* theMaterial = (UniaxialMaterial*)fn( rt, argc, argv ); if (builder->addTaggedObject(*theMaterial) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "Could not add uniaxialMaterial to the model builder.\n"; + opserr << OpenSees::PromptValueError << "Failed to add UniaxialMaterial to the model builder.\n"; delete theMaterial; return TCL_ERROR; } @@ -189,7 +213,7 @@ dispatch(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const a UniaxialMaterial* theMaterial = fn( rt, argc, argv ); if (builder->addTaggedObject(*theMaterial) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "Could not add uniaxialMaterial to the model builder.\n"; + opserr << OpenSees::PromptValueError << "Could not add uniaxialMaterial to the model builder.\n"; delete theMaterial; return TCL_ERROR; } @@ -204,74 +228,40 @@ dispatch(ClientData clientData, Tcl_Interp* interp, int argc, G3_Char** const ar return fn( clientData, interp, argc, argv ); } -#if 0 -class broker_ { - Tcl_CmdProc* parse; - virtual UniaxialMaterial* alloc(); -}; - -template class broker: public broker_ { - broker(Tcl_CmdProc* parse_): parse(parse_) {}; -}; - -std::unordered_map uniaxial_dispatch_2 { - {"Concrete01", broker<>(dispatch) }, - {"Concrete02", dispatch }, -}; -#endif - std::unordered_map uniaxial_dispatch { - {"APDFMD", dispatch }, - {"APDMD", dispatch }, - {"APDVFD", dispatch }, - - {"FedeasUniaxialDamage", dispatch }, - {"KikuchiAikenHDR", dispatch }, - {"KikuchiAikenLRB", dispatch }, - - {"AxialSp", dispatch }, - {"AxialSpHD", dispatch }, - {"ContinuumUniaxial", dispatch}, - - {"Concrete04", dispatch }, - {"Concrete06", dispatch }, - {"Concrete07", dispatch }, -#if 0 - { "ConcretewBeta", dispatch } -#endif - {"Ratchet", dispatch }, -// {"ReinforcingSteel", dispatch }, - {"ReinforcingSteel", dispatch< OPS_ReinforcingSteel> }, - {"Parallel", dispatch }, - {"BoucWen", dispatch }, - - {"Elastic", dispatch }, - - {"Concrete01", dispatch }, - {"Concrete02", dispatch }, - - {"Bond_SP01", dispatch }, - {"Bond", dispatch }, - - {"Fatigue", dispatch }, -// Composites - {"MinMaxMaterial", dispatch }, - {"MinMax", dispatch }, - - {"Series", dispatch }, - -// Steels - - {"Steel01", dispatch }, - - {"Steel02", dispatch }, + {"Elastic", dispatch}, +// +// Plasticity +// + {"ElasticPP", dispatch }, + {"UniaxialJ2Plasticity", dispatch }, + {"UVCuniaxial", dispatch }, + {"Hardening", dispatch }, + {"Hardening2", dispatch }, +// +// Bouc +// + {"BWBF", dispatch }, + {"BWBN", dispatch }, + {"BoucWenOriginal", dispatch }, + {"BoucWen", dispatch }, + {"BoucWenMG", dispatch }, + {"DegradingPinchedBW", dispatch }, +// +// Steel +// + {"Steel", dispatch}, + {"Steel01", dispatch }, + {"Steel02", dispatch }, + {"Steel2", dispatch }, {"Steel4", dispatch }, - + {"RambergOsgood", dispatch }, + {"RambergOsgoodSteel", dispatch }, + {"ReinforcingSteel", dispatch }, +// {"ReinforcingSteel", dispatch }, {"SteelBRB", dispatch }, - {"SteelFractureDI", dispatch }, - {"Steel02Fatigue", dispatch }, {"Dodd_Restrepo", dispatch }, @@ -282,13 +272,87 @@ std::unordered_map uniaxial_dispatch { {"DoddRestr", dispatch }, #endif + {"SteelZ01Material", dispatch }, + {"SteelZ01", dispatch }, -// Piles - {"PySimple3", dispatch }, +// Concretes + {"Concrete01", dispatch }, + {"Concrete02", dispatch }, + {"Concrete04", dispatch }, + {"Concrete06", dispatch }, + {"Concrete07", dispatch }, + + {"Concrete02IS", dispatch }, + {"ConcreteCM", dispatch }, + {"ConfinedConcrete01", dispatch}, + {"ConfinedConcrete", dispatch}, + + {"ConcreteZ01Material", dispatch }, + {"ConcreteZ01", dispatch }, + + +#if 0 + { "ConcretewBeta", dispatch } +#endif +// +// Viscous +// + {"Maxwell", dispatch }, + {"MaxwellMaterial", dispatch }, + {"ViscousDamper", dispatch }, + {"DamperMaterial", dispatch }, + {"BilinearOilDamper", dispatch }, +// +// Multilinear +// + {"BilinMaterial", dispatch }, + {"Bilin", dispatch }, + {"MultiLinear", dispatch }, + {"IMKBilin", dispatch }, + {"IMKPeakOriented", dispatch }, + {"IMKPinching", dispatch }, + {"ModIMKPinching", dispatch }, + {"ModIMKPinching02", dispatch }, + {"ModIMKPeakOriented", dispatch }, + {"ModIMKPeakOriented02", dispatch }, + {"Bilin02", dispatch }, +// Piles + {"PySimple3", dispatch }, +// +// Wrappers +// + {"InitStrainMaterial", dispatch}, + {"InitialStrain", dispatch}, + {"InitStrain", dispatch}, + {"InitStressMaterial", dispatch}, + {"InitialStress", dispatch}, + {"InitStress", dispatch}, + {"ContinuumUniaxial", dispatch}, + {"MinMaxMaterial", dispatch }, + {"MinMax", dispatch }, + {"Series", dispatch }, + {"Parallel", dispatch}, + {"Ratchet", dispatch }, + {"Fatigue", dispatch }, + // Other + {"GNG", dispatch }, + {"Bond_SP01", dispatch }, + {"Bond", dispatch }, + {"APDFMD", dispatch }, + {"APDMD", dispatch }, + {"APDVFD", dispatch }, + + {"FedeasUniaxialDamage", dispatch }, + {"KikuchiAikenHDR", dispatch }, + {"KikuchiAikenLRB", dispatch }, + + {"AxialSp", dispatch }, + {"AxialSpHD", dispatch }, + /* {"PlateBearingConnectionThermal", OPS_PlateBearingConnectionThermal}, {"PinchingLimitStateMaterial", OPS_PinchingLimitState }, @@ -301,27 +365,9 @@ std::unordered_map uniaxial_dispatch { {"ImpactMaterial", dispatch }, {"Impact", dispatch }, - {"UVCuniaxial", dispatch }, - {"GNG", dispatch }, - {"SimpleFractureMaterial", dispatch }, {"SimpleFracture", dispatch }, - - {"Maxwell", dispatch }, - {"MaxwellMaterial", dispatch }, - - {"ViscousDamper", dispatch }, - - {"DamperMaterial", dispatch }, - -// Concretes - {"Concrete02IS", dispatch }, - {"ConcreteCM", dispatch }, - {"ConfinedConcrete01", dispatch}, - {"ConfinedConcrete", dispatch}, - - {"BilinearOilDamper", dispatch }, - +// {"Cast", dispatch }, {"CastFuse", dispatch }, @@ -330,22 +376,15 @@ std::unordered_map uniaxial_dispatch { /* {"HoehlerStanton", dispatch }, -*/ +*/ {"SLModel", dispatch }, - {"RambergOsgood", dispatch }, - {"RambergOsgoodSteel", dispatch }, - - {"ReinforcingSteel", dispatch }, - - {"Steel2", dispatch }, - {"OriginCentered", dispatch }, {"HookGap", dispatch }, - {"HyperbolicGapMaterial", dispatch }, + {"HyperbolicGapMaterial", dispatch}, {"FRPConfinedConcrete02", dispatch }, {"FRCC", dispatch }, @@ -353,43 +392,15 @@ std::unordered_map uniaxial_dispatch { {"PinchingLimitState", dispatch }, - {"InitStrainMaterial", dispatch }, - {"InitStrain", dispatch }, - - {"InitStressMaterial", dispatch }, - {"InitStress", dispatch }, - {"pyUCLA", dispatch }, {"PYUCLA", dispatch }, - {"MultiLinear", dispatch }, - - {"BWBN", dispatch }, - - {"DegradingPinchedBW", dispatch }, - - {"IMKBilin", dispatch }, - {"IMKPeakOriented", dispatch }, - - {"IMKPinching", dispatch }, {"JankowskiImpact", dispatch }, - {"ModIMKPinching", dispatch }, - {"ModIMKPinching02", dispatch }, - - {"ModIMKPeakOriented", dispatch }, - - {"ModIMKPeakOriented02", dispatch }, - - {"Bilin02", dispatch }, - - {"BoucWenOriginal", dispatch }, - // Thermal - {"Steel01Thermal", dispatch }, - - {"Steel02Thermal", dispatch }, + {"Steel01Thermal", dispatch }, + {"Steel02Thermal", dispatch }, {"SteelECThermal", dispatch }, @@ -400,7 +411,7 @@ std::unordered_map uniaxial_dispatch { {"ConcreteECThermal", dispatch }, {"Concrete02Thermal", dispatch }, - +// {"ConcreteD", dispatch }, {"ConcreteSakaiKawashima", dispatch }, @@ -412,7 +423,6 @@ std::unordered_map uniaxial_dispatch { {"ResilienceMaterialHR", dispatch }, {"CFSWSWP", dispatch }, - {"CFSSSWP", dispatch }, {"FRPConfinedConcrete", dispatch }, @@ -425,17 +435,8 @@ std::unordered_map uniaxial_dispatch { {"Masonryt", dispatch }, - {"ElasticPP", dispatch }, - {"UniaxialJ2Plasticity", dispatch }, - - {"Hardening", dispatch }, - {"Hardening2", dispatch }, - - {"BilinMaterial", dispatch }, - {"Bilin", dispatch }, {"Hysteretic", dispatch }, - {"HystereticAsym", dispatch }, {"HystereticSmooth", dispatch }, {"HystereticSMMaterial", dispatch }, @@ -443,7 +444,7 @@ std::unordered_map uniaxial_dispatch { {"ElasticPPGap", dispatch }, - {"OOHysteretic", dispatch }, + {"OOHysteretic", dispatch }, {"Viscous", dispatch }, {"ViscoelasticGap", dispatch }, @@ -451,17 +452,12 @@ std::unordered_map uniaxial_dispatch { {"SAWSMaterial", dispatch }, {"SAWS", dispatch }, - {"ConcreteZ01Material", dispatch }, - {"ConcreteZ01", dispatch }, {"ConcreteL01Material", dispatch }, {"ConcreteL01", dispatch }, {"Creep", dispatch }, - {"SteelZ01Material", dispatch }, - {"SteelZ01", dispatch }, - {"TendonL01Material", dispatch }, {"TendonL01", dispatch }, @@ -471,20 +467,20 @@ std::unordered_map uniaxial_dispatch { {"ASD_SMA_3K", dispatch }, + {"ASDConcrete1D", dispatch }, + {"HystereticPoly", dispatch }, {"SPSW02", dispatch }, {"TDConcreteEXP", dispatch }, - {"TDConcrete", dispatch }, - {"TDConcreteMC10", dispatch }, - {"TDConcreteMC10NL", dispatch }, - {"Pinching4", TclDispatch_newUniaxialPinching4 }, + {"Pinching4", TclDispatch_newUniaxialPinching4 }, +// Legacy {"Elastic2", TclDispatch_LegacyUniaxials }, {"ENT", TclDispatch_LegacyUniaxials }, {"BarSlip", TclDispatch_LegacyUniaxials }, diff --git a/SRC/runtime/commands/modeling/uniaxialMaterial.cpp b/SRC/runtime/commands/modeling/uniaxialMaterial.cpp index 20e36b8ecf..81b1cc0a72 100644 --- a/SRC/runtime/commands/modeling/uniaxialMaterial.cpp +++ b/SRC/runtime/commands/modeling/uniaxialMaterial.cpp @@ -1,15 +1,17 @@ -/* ****************************************************************** ** -** Opensee - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ****************************************************************** */ +//===----------------------------------------------------------------------===// // +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file contains the function invoked when the user invokes // the uniaxialMaterial command in the interpreter. +//===----------------------------------------------------------------------===// // // Written: fmk, MHS // Created: 07/99 // -// #include #include #include @@ -21,10 +23,12 @@ #include // KM #include // Won Lee #include // Won Lee + #include #include #include // LMS #include // JDW + #include // MHS #include // Mackie #include // MHS @@ -76,11 +80,9 @@ extern OPS_Routine OPS_Cast; extern OPS_Routine OPS_DoddRestr; extern OPS_Routine OPS_ElasticMultiLinear; extern OPS_Routine OPS_HookGap; -extern OPS_Routine OPS_HyperbolicGapMaterial; extern OPS_Routine OPS_FRPConfinedConcrete; extern OPS_Routine OPS_FRPConfinedConcrete02; extern OPS_Routine OPS_UVCuniaxial; -extern OPS_Routine OPS_Steel01Thermal; extern OPS_Routine OPS_Concrete02Thermal; extern OPS_Routine OPS_StainlessECThermal; // L.Jiang [SIF] extern OPS_Routine OPS_SteelECThermal; // L.Jiang [SIF] @@ -95,11 +97,10 @@ extern OPS_Routine OPS_ModIMKPeakOriented; extern OPS_Routine OPS_ModIMKPeakOriented02; extern OPS_Routine OPS_ModIMKPinching; extern OPS_Routine OPS_ModIMKPinching02; -extern void *OPS_ConcretewBeta(void); +extern void *OPS_ConcretewBeta(); extern OPS_Routine OPS_ConcreteD; extern OPS_Routine OPS_PinchingLimitState; extern OPS_Routine OPS_OriginCentered; -extern OPS_Routine OPS_Steel2; extern OPS_Routine OPS_ConcreteSakaiKawashima; extern OPS_Routine OPS_ResilienceMaterialHR; extern OPS_Routine OPS_CFSSSWP; @@ -108,7 +109,6 @@ extern OPS_Routine OPS_ResilienceLow; extern OPS_Routine OPS_ViscousMaterial; extern OPS_Routine OPS_SteelMPF; // K Kolozvari extern OPS_Routine OPS_Bond_SP01; // K Kolozvari -extern OPS_Routine OPS_OOHystereticMaterial; extern OPS_Routine OPS_ElasticPowerFunc; extern OPS_Routine OPS_UVCuniaxial; extern OPS_Routine OPS_DegradingPinchedBW; @@ -135,31 +135,12 @@ typedef struct uniaxialPackageCommand { static UniaxialPackageCommand *theUniaxialPackageCommands = NULL; -static void -printCommand(int argc, TCL_Char ** const argv) -{ - opserr << "Input command: "; - for (int i = 0; i < argc; ++i) - opserr << argv[i] << " "; - opserr << endln; -} - -// external functions - -Tcl_CmdProc TclCommand_KikuchiAikenHDR; -Tcl_CmdProc TclCommand_KikuchiAikenLRB; - -UniaxialMaterial *TclBasicBuilder_addDrainMaterial(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv); - -UniaxialMaterial *TclBasicBuilder_addSnapMaterial(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv); -UniaxialMaterial *TclBasicBuilder_addPyTzQzMaterial(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, - Domain *theDomain); - -UniaxialMaterial *TclBasicBuilder_FRPCnfinedConcrete(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, - Domain *theDomain); - -UniaxialMaterial *TclBasicBuilder_addDegradingMaterial(ClientData, Tcl_Interp *, int, TCL_Char **); +UniaxialMaterial *TclBasicBuilder_addDrainMaterial(ClientData, Tcl_Interp *, int argc, TCL_Char ** const argv); +UniaxialMaterial *TclBasicBuilder_addSnapMaterial(ClientData, Tcl_Interp *, int argc, TCL_Char ** const argv); +UniaxialMaterial *TclBasicBuilder_addPyTzQzMaterial(ClientData, Tcl_Interp *, int argc, TCL_Char ** const argv, Domain *); +UniaxialMaterial *TclBasicBuilder_FRPCnfinedConcrete(ClientData, Tcl_Interp *, int argc, TCL_Char ** const argv, Domain *); +UniaxialMaterial *TclBasicBuilder_adDegradingMaterial(ClientData, Tcl_Interp *, int, TCL_Char **); extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp *interp, int cArg, int mArg, TCL_Char ** const argv, Domain *domain); @@ -188,15 +169,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp return TCL_ERROR; -#if 0 - } else if (strcmp(argv[1],"HoehlerStanton") == 0) { - void *theMat = OPS_HoehlerStanton(rt, argc, argv); - if (theMat != 0) - theMaterial = (UniaxialMaterial *)theMat; - else - return TCL_ERROR; -#endif - } else if ((strcmp(argv[1], "BilinearOilDamper") == 0)) { void *theMat = OPS_BilinearOilDamper(rt, argc, argv); if (theMat != 0) @@ -283,14 +255,8 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp else return TCL_ERROR; - } else if (strcmp(argv[1], "Steel01Thermal") == 0) { - void *theMat = OPS_Steel01Thermal(rt, argc, argv); - if (theMat != 0) - theMaterial = (UniaxialMaterial *)theMat; - else - return TCL_ERROR; - - } else if (strcmp(argv[1], "ConcretewBeta") == 0) { + } + else if (strcmp(argv[1], "ConcretewBeta") == 0) { void *theMat = OPS_ConcretewBeta(); if (theMat != 0) theMaterial = (UniaxialMaterial *)theMat; @@ -309,7 +275,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp } else if (strcmp(argv[1], "Elastic2") == 0) { if (argc < 4 || argc > 5) { opserr << "WARNING invalid number of arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial Elastic tag? E? " << endln; return TCL_ERROR; } @@ -343,7 +308,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp } else if (strcmp(argv[1], "ENT") == 0) { if (argc < 4) { opserr << "WARNING invalid number of arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial ENT tag? E?" << endln; return TCL_ERROR; } @@ -379,7 +343,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp // Check that there is the minimum number of arguments if (argc < 9) { opserr << "WARNING insufficient arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial Steel03 tag? fy? E0? b? r? cR1 cR2?"; opserr << " " << endln; return TCL_ERROR; @@ -397,37 +360,31 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (Tcl_GetDouble(interp, argv[3], &fy) != TCL_OK) { opserr << "WARNING invalid fy\n"; - opserr << "uniaxialMaterial Steel03: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &E) != TCL_OK) { opserr << "WARNING invalid E0\n"; - opserr << "uniaxialMaterial Steel03: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &b) != TCL_OK) { opserr << "WARNING invalid b\n"; - opserr << "uniaxialMaterial Steel03: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[6], &r) != TCL_OK) { opserr << "WARNING invalid r\n"; - opserr << "uniaxialMaterial Steel03: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[7], &cR1) != TCL_OK) { opserr << "WARNING invalid cR1\n"; - opserr << "uniaxialMaterial Steel03: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[8], &cR2) != TCL_OK) { opserr << "WARNING invalid cR2\n"; - opserr << "uniaxialMaterial Steel03: " << tag << endln; return TCL_ERROR; } @@ -482,21 +439,10 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp } - else if (strcmp(argv[1], "OOHysteretic") == 0) { - - void *theMat = OPS_OOHystereticMaterial(rt, argc, argv); - if (theMat != 0) - theMaterial = (UniaxialMaterial *)theMat; - else - return TCL_ERROR; - - } - else if (strcmp(argv[1], "Concrete04") == 0) { // opserr << argc << endln; if (argc != 10 && argc != 9 && argc != 7) { opserr << "WARNING insufficient arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial Concrete04 tag? fpc? epsc0? epscu? " "Ec0? >" << endln; @@ -515,43 +461,36 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (Tcl_GetDouble(interp, argv[3], &fpc) != TCL_OK) { opserr << "WARNING invalid fpc\n"; - opserr << "Concrete04 material: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &epsc0) != TCL_OK) { opserr << "WARNING invalid epsc0\n"; - opserr << "Concrete04 material: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &epscu) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "Concrete04 material: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[6], &Ec0) != TCL_OK) { opserr << "WARNING invalid Ec0\n"; - opserr << "Concrete04 material: " << tag << endln; return TCL_ERROR; } if (argc == 9 || argc == 10) { if (Tcl_GetDouble(interp, argv[7], &ft) != TCL_OK) { opserr << "WARNING invalid ft\n"; - opserr << "Concrete04 material: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[8], &etu) != TCL_OK) { opserr << "WARNING invalid etu\n"; - opserr << "Concrete04 material: " << tag << endln; return TCL_ERROR; } } if (argc == 10) { if (Tcl_GetDouble(interp, argv[9], &beta) != TCL_OK) { opserr << "WARNING invalid beta\n"; - opserr << "Concrete04 material: " << tag << endln; return TCL_ERROR; } } @@ -569,7 +508,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp else if (strcmp(argv[1], "Concrete06") == 0) { if (argc < 12) { opserr << "WARNING insufficient arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial Concrete06 tag? fc? eo? r? k? alphaC? " "fcr? ecr? b? alphaT?" << endln; @@ -579,7 +517,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp int tag; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial Concrete06 tag" << endln; + opserr << "WARNING invalid uniaxialMaterial tag" << endln; return TCL_ERROR; } @@ -649,7 +587,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp // Check to see if there are enough arquements if (argc < 11) { opserr << "WARNING: Insufficient arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial Concrete07 tag? fpc? epsc0? Ec? fpt? " "epst0? xcrp? xcrn? r?\n"; return TCL_ERROR; @@ -667,57 +604,44 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (Tcl_GetDouble(interp, argv[3], &fpc) != TCL_OK) { opserr << "WARNING: Invalid peak compression stress\n"; - opserr << "uniaxialMaterial Concrete07: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &epsc0) != TCL_OK) { opserr << "WARNING: Invalid peak compression strain\n"; - opserr << "uniaxialMaterial Concrete07: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &Ec) != TCL_OK) { opserr << "WARNING: Invalid Young's Modulus\n"; - opserr << "uniaxialMaterial Concrete07: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[6], &fpt) != TCL_OK) { opserr << "WARNING: Invalid peak tension stress\n"; - opserr << "uniaxialMaterial Concrete07: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[7], &epst0) != TCL_OK) { opserr << "WARNING: Invalid peak tension strain\n"; - opserr << "uniaxialMaterial Concrete07: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[8], &xcrp) != TCL_OK) { opserr << "WARNING: Invalid critical nondimensional strain in tension\n"; - opserr << "uniaxialMaterial Concrete07: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[9], &xcrn) != TCL_OK) { opserr << "WARNING: Invalid critical nondimensional strain in compression\n"; - opserr << "uniaxialMaterial Concrete07: " << tag << endln; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[10], &r) != TCL_OK) { opserr << "WARNING: Invalid value for r\n"; - opserr << "uniaxialMaterial Concrete07: " << tag << endln; } - // opserr << "fpc: " << fpc << endln << "epsc0: " << epsc0 << endln << - //"Ec: " << Ec << endln; opserr << "fpt: " << fpt << endln << "epst0: " << - //epst0 << endln << "xcrp: " << xcrp << endln; opserr << "xcrn: " << xcrn << - //endln << "r: " << r << endln; - // Parsing was successful, allocate the material theMaterial = @@ -727,7 +651,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp else if (strcmp(argv[1], "PathIndependent") == 0) { if (argc < 4) { opserr << "WARNING insufficient arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial PathIndependent tag? matTag?" << endln; return TCL_ERROR; } @@ -752,11 +675,11 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp theMaterial = new PathIndependentMaterial(tag, *material); } + else if (strcmp(argv[1], "Backbone") == 0) { if (argc < 4) { opserr << "WARNING insufficient arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial Backbone tag? bbTag?" << endln; return TCL_ERROR; } @@ -790,7 +713,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp else if (strcmp(argv[1], "Fatigue") == 0) { if (argc < 4) { opserr << "WARNING insufficient arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial Fatigue tag? matTag?"; opserr << " <-D_max dmax?> <-e0 e0?> <-m m?>" << endln; opserr << " <-min min?> <-max max?>" << endln; @@ -930,7 +852,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp else if (strcmp(argv[1], "Pinching4") == 0) { if (argc != 42 && argc != 31) { opserr << "WARNING insufficient arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial Pinching4 tag? stress1p? strain1p? " "stress2p? strain2p? stress3p? strain3p? stress4p? strain4p? " << "\n" << endln; @@ -1424,7 +1344,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp else if (strcmp(argv[1], "ShearPanel") == 0) { if (argc != 42 && argc != 31) { opserr << "WARNING insufficient arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial ShearPanel tag? stress1p? strain1p? " "stress2p? strain2p? stress3p? strain3p? stress4p? strain4p? " << "\n" << endln; @@ -1760,7 +1678,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp else if (strcmp(argv[1], "ECC01") == 0) { if (argc < 16) { opserr << "WARNING insufficient arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial ECC01 TAG? SIGT0? EPST0? SIGT1? EPST1? " "EPST2? SIGC0? EPSC0? EPSC1? "; opserr << "ALPHAT1? ALPHAT2? ALPHAC? ALPHACU? BETAT? BETAC\n"; @@ -1867,7 +1784,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp else if (strcmp(argv[1], "SelfCentering") == 0) { if (argc < 7) { opserr << "WARNING insufficient arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial SelfCentering tag? k1? k2? ActF? beta? " "" << endln; @@ -1948,7 +1864,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp // Check that there is the minimum number of arguments if (argc < 4) { opserr << "WARNING insufficient arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial SteelMP tag? fy? E0? b? "; opserr << " " << endln; return TCL_ERROR; @@ -1984,7 +1899,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (argc < 5) { opserr << "WARNING insufficient number of hardening parameters\n"; - opserr << "uniaxialMaterial Steel03: " << tag << endln; return TCL_ERROR; } @@ -2034,7 +1948,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp else if (strcmp(argv[1], "SmoothPSConcrete") == 0) { if (argc < 6 || argc > 9) { opserr << "WARNING invalid number of arguments\n"; - printCommand(argc, argv); opserr << "Want: uniaxialMaterial SmoothPSConcrete tag? fc? fu? Ec? " " " << endln; @@ -2136,7 +2049,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp TclBasicBuilder_addDegradingMaterial(clientData, interp, argc, argv); #endif - if (theMaterial == 0) { + if (theMaterial == nullptr) { // // maybe element in a class package already loaded // loop through linked list of loaded functions comparing names & if find diff --git a/SRC/runtime/commands/modeling/utilities/Block2D.cpp b/SRC/runtime/commands/modeling/utilities/Block2D.cpp new file mode 100644 index 0000000000..95e797be80 --- /dev/null +++ b/SRC/runtime/commands/modeling/utilities/Block2D.cpp @@ -0,0 +1,236 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Description: This file contains the class definition for Block2D. +// +// Written: Ed Love +// Created: 07/99 +// +#include +#include +#include +#include "Block2D.h" + + +Block2D::Block2D(int numx, int numy, + const ID& nodeID, + const Matrix& coorArray, + int numNode) +: + element(numNode), + numNodesElement(numNode), + nx(numx), ny(numy), + errorFlag(0) +{ + + if (numNodesElement == 9) { + if (((numx % 2) != 0) || ((numy % 2) != 0)) { + opserr << "ERROR: Block2D::Block2D - numX & numY for nine noded elements must be even\n"; + errorFlag = 1; + } + } + + if (numNodesElement != 9 && numNodesElement != 4) { + opserr << "ERROR: Block2D::Block2D - numNode must be either 4 or 9\n"; + errorFlag = 1; + } + + if (this->setUpXl( nodeID, coorArray ) != 0) + errorFlag = 1; + +} + + +// set up xl array +int +Block2D::setUpXl( const ID &nodeID, const Matrix &coorArray ) +{ + + + for (int i=0; i<4; i++ ){ + if ( nodeID(i) == -1 ) { + opserr << "Warning : in Block2D, block node " + << i << " is not defined.\n"; + return -1; + } + } + + // local storage xl = transpose(coorArray) + for (int i=0; i<3; i++ ) { + for (int j=0; j<9; j++ ) + xl[i][j] = coorArray(j,i); + } + + + if ( nodeID(4) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][4] = 0.5*( xl[i][0] + xl[i][1] ); + } + + if ( nodeID(5) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][5] = 0.5*( xl[i][1] + xl[i][2] ); + } + + if ( nodeID(6) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][6] = 0.5*( xl[i][2] + xl[i][3] ); + } + + if ( nodeID(7) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][7] = 0.5*( xl[i][3] + xl[i][0] ); + } + + if ( nodeID(8) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][8] = 0.25*( xl[i][0] + xl[i][1] + xl[i][2] + xl[i][3] ) ; + } + + + return 0; +} + + +//generate node +Vector3D +Block2D::getNodalCoords( int i, int j ) +{ + + double hx = 2.0 / nx; + double hy = 2.0 / ny; + double x = -1.0 + (i*hx); + double y = -1.0 + (j*hy); + + Vector3D coor; + coor[0] = x; + coor[1] = y; + coor[2] = 0.0; + + this->transformNodalCoordinates(coor); + + return coor; +} + + +//generate element +const ID& +Block2D::getElementNodes( int i, int j ) +{ + + if (errorFlag == 1) + return element; + + else if (numNodesElement == 4) { + int nenx = nx + 1; + // int neny = ny + 1; + + + int node1 = i + j*nenx; + int node2 = node1 + 1; + + int node3 = node2 + nenx; + int node4 = node1 + nenx; + + element(0) = node1; + element(1) = node2; + element(2) = node3; + element(3) = node4; + + } else { + + int nenx = nx + 1; + // int neny = ny + 1; + + int node1, node2, node3, node4, node5, node6, node7, node8, node9; + + node1 = i*2 + j*2*nenx; + node5 = node1 + 1; + node2 = node1 + 2; + + node4 = node1 + 2*nenx; + node7 = node4 + 1; + node3 = node7 + 1; + + node8 = node1 + nenx; + node9 = node8 + 1; + node6 = node9 + 1; + + element(0) = node1; + element(1) = node2; + element(2) = node3; + element(3) = node4; + element(4) = node5; + element(5) = node6; + element(6) = node7; + element(7) = node8; + element(8) = node9; + + } + + return element; +} + + + +//transform to real coordiantes +void +Block2D::transformNodalCoordinates(Vector3D& coor ) +{ + + static double shape[9]; + static double natCoor[2]; + + natCoor[0] = coor[0]; + natCoor[1] = coor[1]; + + coor.zero( ); + + this->shape2d( natCoor[0], natCoor[1], shape ); + + for ( int j=0; j<9; j++ ) { + + for ( int dim=0; dim<3; dim++ ) + coor[dim] += shape[j]*xl[dim][j]; + + } + + return; + +} + + +// shape functions +void Block2D::shape2d( double x, double y, + double shape[9] ) +{ + static double Nx[3]; + static double Ny[3]; + + Nx[0] = 0.5 * x * ( x - 1.0 ); + Nx[1] = 1.0 - (x*x); + Nx[2] = 0.5 * x * ( x + 1.0 ); + + Ny[0] = 0.5 * y * ( y - 1.0 ); + Ny[1] = 1.0 - (y*y); + Ny[2] = 0.5 * y * ( y + 1.0 ); + + shape[0] = Nx[0]*Ny[0]; + shape[1] = Nx[2]*Ny[0]; + shape[2] = Nx[2]*Ny[2]; + shape[3] = Nx[0]*Ny[2]; + + shape[4] = Nx[1]*Ny[0]; + shape[5] = Nx[2]*Ny[1]; + shape[6] = Nx[1]*Ny[2]; + shape[7] = Nx[0]*Ny[1]; + + shape[8] = Nx[1]*Ny[1]; + + return; +} diff --git a/SRC/runtime/commands/modeling/utilities/Block2D.h b/SRC/runtime/commands/modeling/utilities/Block2D.h new file mode 100644 index 0000000000..9028ad2ee1 --- /dev/null +++ b/SRC/runtime/commands/modeling/utilities/Block2D.h @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Description: This file contains the implementation of Block2D. +// +// Written: Ed Love +// Created: 07/01 +// +#ifndef Block2D_h +#define Block2D_h + +#include +#include +#include +class Matrix; +class Vector; + +class Block2D { + +public: + + Block2D(int numx, int numy, + const ID& nodeID, + const Matrix& coorArray, + int numNodeElement); + + + // generate nodes + Vector3D getNodalCoords(int i, int j); + + // generate elements + const ID &getElementNodes(int i, int j); + + + private: + // set up xl array + int setUpXl(const ID &nodeID, const Matrix &coorArray); + + // transform to real coordiantes + void transformNodalCoordinates(Vector3D&); + + // shape functions + void shape2d(double x1, + double x2, + double shape[9]); + + int nx; // number of elements x-direction + int ny; // number of elements y-direction + + double xl[3][9]; //block coordinates + + ID element; //ID-array of an element + + + int numNodesElement; // 4 or 9 + int errorFlag; // flag indicating if odd nx and ny ok for 9-noded elements +}; + +#endif diff --git a/SRC/runtime/commands/modeling/utilities/Block3D.cpp b/SRC/runtime/commands/modeling/utilities/Block3D.cpp new file mode 100644 index 0000000000..f17d76d626 --- /dev/null +++ b/SRC/runtime/commands/modeling/utilities/Block3D.cpp @@ -0,0 +1,336 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// Description: This file contains the implementation of Block3D. +// +// Written: Ed Love +// Created: 07/01 +// +#include "Block3D.h" + + +Block3D::Block3D(int numx, int numy, int numz, + const ID& nodeID, + const Matrix& coorArray ) +: nx(numx), ny(numy), nz(numz), + coor(3), + element(8) +{ + this->setUpXl( nodeID, coorArray ); +} + + +// set up xl array +void Block3D::setUpXl( const ID &nodeID, const Matrix &coorArray ) +{ + + for (int i=0; i<8; i++ ){ + if ( nodeID(i) == -1 ) { + opserr << "Warning : in Block3D, block node " + << i + << " is not defined. No Generation will take place." + << endln; + break; + } + } + + + // xl = tranpose coorArray(27,3) + for (int i=0; i<3; i++ ) { + for (int j=0; j<27; j++ ) + xl[i][j] = coorArray(j,i); + } + + + if ( nodeID(8) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][8] = 0.5*( xl[i][0] + xl[i][4] ); + } + + if ( nodeID(9) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][9] = 0.5*( xl[i][1] + xl[i][5] ); + } + + if ( nodeID(10) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][10] = 0.5*( xl[i][2] + xl[i][6] ); + } + + if ( nodeID(11) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][11] = 0.5*( xl[i][3] + xl[i][7] ); + } + + + if ( nodeID(12) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][12] = 0.5*( xl[i][0] + xl[i][1] ); + } + + if ( nodeID(13) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][13] = 0.5*( xl[i][1] + xl[i][2] ); + } + + if ( nodeID(14) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][14] = 0.5*( xl[i][2] + xl[i][3] ); + } + + if ( nodeID(15) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][15] = 0.5*( xl[i][0] + xl[i][3] ); + } + + + if ( nodeID(16) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][16] = 0.25*( xl[i][0] + xl[i][1] + xl[i][2] + xl[i][3] ); + } + + + if ( nodeID(17) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][17] = 0.5*( xl[i][4] + xl[i][5] ); + } + + if ( nodeID(18) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][18] = 0.5*( xl[i][5] + xl[i][6] ); + } + + if ( nodeID(19) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][19] = 0.5*( xl[i][6] + xl[i][7] ); + } + + if ( nodeID(20) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][20] = 0.5*( xl[i][4] + xl[i][7] ); + } + + + if ( nodeID(21) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][21] = 0.25*( xl[i][4] + xl[i][5] + xl[i][6] + xl[i][7] ); + } + + + if ( nodeID(22) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][22] = 0.25*( xl[i][0] + xl[i][1] + xl[i][5] + xl[i][4] ); + } + + if ( nodeID(23) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][23] = 0.25*( xl[i][1] + xl[i][2] + xl[i][6] + xl[i][5] ); + } + + + if ( nodeID(24) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][24] = 0.25*( xl[i][3] + xl[i][2] + xl[i][6] + xl[i][7] ); + } + + if ( nodeID(25) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][25] = 0.25*( xl[i][0] + xl[i][3] + xl[i][7] + xl[i][4] ); + } + + + + if ( nodeID(26) == -1 ) { + for (int i=0; i<3; i++ ) + xl[i][26] = 0.125*( xl[i][0] + xl[i][1] + xl[i][2] + xl[i][3] + + xl[i][4] + xl[i][5] + xl[i][6] + xl[i][7] ); + } + + return; +} + + +//generate node +const Vector& +Block3D::getNodalCoords( int i, int j, int k ) +{ + + /* loop as follows (in pseudocode) + for ( k = 0, nz ) { + for ( j = 0, ny ) { + for ( i = 0, nx ) + call getNodalCoords(i,j,k); + } + } + */ + + double hx = 2.0 / nx; + + double hy = 2.0 / ny; + + double hhz = 2.0 / nz; + + double x = -1.0 + (i*hx); + + double y = -1.0 + (j*hy); + + double z = -1.0 + (k*hhz); + + coor(0) = x; + coor(1) = y; + coor(2) = z; + + this->transformNodalCoordinates( ); + + return coor; +} + + +//generate element +const ID& +Block3D::getElementNodes( int i, int j, int k ) +{ + + int nenx = nx + 1; + + int neny = ny + 1; + + int nInXYplane = nenx * neny; + + + int node1, node2, node3, node4; + int node5, node6, node7, node8; + + + node1 = i + (j*nenx) + (k*nInXYplane); + node2 = node1 + 1; + node3 = node2 + nenx; + node4 = node1 + nenx; + + node5 = node1 + nInXYplane; + node6 = node2 + nInXYplane; + node7 = node3 + nInXYplane; + node8 = node4 + nInXYplane; + + element(0) = node1; + element(1) = node2; + element(2) = node3; + element(3) = node4; + + element(4) = node5; + element(5) = node6; + element(6) = node7; + element(7) = node8; + + return element; +} + + + +//transform to real coordinates +void Block3D::transformNodalCoordinates( ) +{ + + double shape[27]; + static double natCoor[3]; + + natCoor[0] = coor(0); + natCoor[1] = coor(1); + natCoor[2] = coor(2); + + coor.Zero( ); + + this->shape3d( natCoor[0], natCoor[1], natCoor[2], shape ); + + for (int j=0; j<27; j++ ) { + + for (int dim=0; dim<3; dim++ ) + coor(dim) += shape[j]*xl[dim][j]; + + } + + return; + +} + + +void +Block3D::shape3d( double r, double s, double t, double shape[27]) +/* + * Adapted from: + subroutine shp04(shp,glu,glo,gu,eu,to,xjac,detj,r,s,t,xl,ul) +c----------------------------------------------------------------------- +c.....compute shape functions and their derivatives for linear,quadratic +c.....lagrangian and serendipity isoparametric 3-d hexahedral elements +c..... +c.....global coordinate system x,y,z +c.....local coordinate system xsi,eta,zeta +c----------------------------------------------------------------------- +*/ +{ + + static constexpr int ri[] = {-1, 1, 1,-1, -1, 1, 1,-1, -1, 1, 1,-1, 0, 1, 0,-1, 0, 0, 1, 0,-1, 0, 0, 1, 0,-1, 0}; + static constexpr int si[] = {-1,-1, 1, 1, -1,-1, 1, 1, -1,-1, 1, 1, -1, 0, 1, 0, 0, -1, 0, 1, 0, 0, -1, 0, 1, 0, 0}; + static constexpr int ti[] = {-1,-1,-1,-1, 1, 1, 1, 1, 0, 0, 0, 0, -1,-1,-1,-1,-1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}; + + + static const double d1 = 1.0; + static const double d2 = 0.5; // = 1.0/2.0; + static const double d4 = 0.25; // = 1.0/4.0; + static const double d8 = 0.125; // = 1.0/8.0; + + + double rr = r*r; + double ss = s*s; + double tt = t*t; + + int kk; + + // shape functions for 27-node element + for (int k=1; k<=27; k++ ) { + + kk = k-1; // C-style numbering + + double r0 = r*ri[kk]; + double s0 = s*si[kk]; + double t0 = t*ti[kk]; + + // corner nodes top/bottom + if ( k>=1 && k<=8 ) + shape[kk] = d8*(rr+r0) *(ss+s0) *(tt+t0); + + // corner nodes midside + if ( k>=9 && k<=12 ) + shape[kk] = d4*(rr+r0) *(ss+s0) *(d1-tt); + + // midside nodes top/bottom r-dir + if ( k==13 || k==15 || k==18 || k==20 ) + shape[kk] = d4*(d1-rr)*(ss+s0) *(tt+t0); + + // midside nodes top/bottom s-dir + if ( k==14 || k==16 || k==19 || k==21 ) + shape[kk] = d4*(rr+r0) *(d1-ss)*(tt+t0); + + // midside nodes mid plane r-dir + if ( k==23 || k==25 ) + shape[kk] = d2*(d1-rr)*(ss+s0) *(d1-tt); + + // midside nodes mid plane s-dir + if ( k==24 || k==26 ) + shape[kk] = d2*(rr+r0) *(d1-ss)*(d1-tt); + + // central nodes top/bottom + if ( k==17 || k==22 ) + shape[kk] = d2*(d1-rr)*(d1-ss)*(tt+t0); + + if ( k==27 ) + shape[kk] = (d1-rr)*(d1-ss)*(d1-tt); + } + + return; +} + diff --git a/SRC/runtime/commands/modeling/utilities/Block3D.h b/SRC/runtime/commands/modeling/utilities/Block3D.h new file mode 100644 index 0000000000..eb80fd5b95 --- /dev/null +++ b/SRC/runtime/commands/modeling/utilities/Block3D.h @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// Written: Ed Love +// Created: 07/01 +// +// Description: This file contains the implementation of Block3D. +// +#ifndef Block3D_h +#define Block3D_h +// + +#include +#include +#include +#include + +class Block3D { + +public: + + Block3D(int numx, int numy, int numz, + const ID& nodeID, + const Matrix& coorArray); + + // generate nodes + const Vector &getNodalCoords(int i, int j, int k); + + // generate elements + const ID &getElementNodes(int i, int j, int k); + + protected: + + private: + + int nx; // number of elements x-direction + int ny; // number of elements y-direction + int nz; // number of elements z-direction + + double xl[3][27]; //block coordinates + + Vector coor; //coordinates of a node + + ID element; //ID-array of an element + + // set up xl array + void setUpXl(const ID &nodeID, const Matrix &coorArray); + + // transform to real coordiantes + void transformNodalCoordinates(); + + // shape functions + void shape3d(double x1, + double x2, + double x3, + double shape[27]); + +}; + +#endif diff --git a/SRC/runtime/commands/modeling/utilities/blockND.cpp b/SRC/runtime/commands/modeling/utilities/blockND.cpp new file mode 100644 index 0000000000..279a329215 --- /dev/null +++ b/SRC/runtime/commands/modeling/utilities/blockND.cpp @@ -0,0 +1,442 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// NOTE: This doesnt really need access to the model builder, it would +// work with just the domain +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Block2D.h" +#include "Block3D.h" + +using OpenSees::MatrixND; + +int +TclCommand_doBlock2D(ClientData clientData, + Tcl_Interp *interp, + Tcl_Size argc, + TCL_Char ** const argv) +{ + assert(clientData != nullptr); + BasicModelBuilder* builder = static_cast(clientData); + Domain *theTclDomain = builder->getDomain(); + int ndm = builder->getNDM(); + int ndf = builder->getNDF(); + + if (ndm < 2) { + opserr << OpenSees::PromptValueError + << "model dimension (ndm) must be at leat 2 " + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } + + if (argc < 8) { + opserr << OpenSees::PromptValueError << "incorrect number of args, expected:" + "\n\tblock2D numX? numY? startNode? startEle? eleType? eleArgs?" + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } + int numX, numY, startNodeNum, startEleNum; + if (Tcl_GetInt(interp, argv[1], &numX) != TCL_OK) { + opserr << OpenSees::PromptValueError + << "invalid numX (" << argv[1] << ")" + << OpenSees::SignalMessageEnd; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[2], &numY) != TCL_OK) { + opserr << OpenSees::PromptValueError << "block2D numX? numY? startNode? startEle? eleType? eleArgs?"; + opserr << " : invalid numY: " << argv[2] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[3], &startNodeNum) != TCL_OK) { + opserr << OpenSees::PromptValueError << "block2D numX? numY? startNode? startEle? eleType? eleArgs?"; + opserr << " : invalid startNode: " << argv[3] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[4], &startEleNum) != TCL_OK) { + opserr << OpenSees::PromptValueError << "block2D numX? numY? startNode? startEle? eleType? eleArgs?"; + opserr << " : invalid startEle: " << argv[4] << "\n"; + return TCL_ERROR; + } + + + MatrixND<9,3> Coordinates; + Coordinates.zero(); + + static ID haveNode(9); + for (int k=0; k<9; k++) + haveNode(k) = -1; + + int numNodes = 4; + if (argc == 10) { + if (strcmp(argv[7],"-numEleNodes") == 0) + if (Tcl_GetInt(interp, argv[8], &numNodes) != TCL_OK) { + opserr << OpenSees::PromptValueError << "block2D numX? numY? startNode? startEle? eleType eleArgs?"; + opserr << " -numEleNodes numNodes?: invalid numNodes: " << argv[8] << "\n"; + return TCL_ERROR; + } + if (numNodes != 4 && numNodes != 9) { + opserr << OpenSees::PromptValueError << "block2D numX? numY? startNode? startEle? eleType? eleArgs? "; + opserr << "-numEleNodes numNodes?: invalid numNodes: " << argv[8] << " 4 or 9 only\n"; + return TCL_ERROR; + } + + if (numNodes == 9) { + if (((numX % 2) != 0) || ((numY % 2) != 0)) { + opserr << OpenSees::PromptValueError << "block2D numX? numY? startNode? startEle? eleType? eleArgs? "; + opserr << "numX and numY must both be even when using -numEleNodes 9\n"; + return TCL_ERROR; + } + } + } + + int nodalInfo = 9; + if (numNodes == 4) + nodalInfo = 7; + + TCL_Char ** argvNodes; + int argcNodes; + + Tcl_SplitList(interp, argv[nodalInfo], &argcNodes, &argvNodes); + + + int count = 0; + while (count < argcNodes) { + int nodeTag; + double value; + if ((count + ndm + 1) > argcNodes) { + opserr << OpenSees::PromptValueError << "block2D numX? numY? startNode? startEle? eleType? eleArgs?"; + opserr << " : invalid number of node args: " << argv[7] << "\n"; + Tcl_Free((char *)argvNodes); + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argvNodes[count], &nodeTag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "block2D numX? numY? startNode? startEle? eleType? eleArgs?"; + opserr << " : invalid node tag: " << argvNodes[count] << "\n"; + Tcl_Free((char *)argvNodes); + return TCL_ERROR; + } + if (nodeTag < 1 || nodeTag > 9) { + opserr << OpenSees::PromptValueError + << " : invalid node tag out of bounds [1,9]: " << argvNodes[count] << "\n"; + Tcl_Free((char *)argvNodes); + return TCL_ERROR; + } + for (int i=0; i(nodeID, nodeCoords(0), nodeCoords(1), nodeCoords(2)); + break; + case 6: + theNode = new NodeND<3, 6>(nodeID, nodeCoords(0), nodeCoords(1), nodeCoords(2)); + break; + default: + theNode = new HeapNode(nodeID, ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); + break; + } + } else +#endif +// theNode = new HeapNode(nodeID, ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); + theNode = new Node(nodeID,ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); + } + + if (theTclDomain->addNode(theNode) == false) { + opserr << OpenSees::PromptValueError << "failed to add node to the domain\n"; + opserr << "node: " << nodeID << "\n"; + delete theNode; + return TCL_ERROR; + } + nodeID++; + } + } + + // create the elements: numX*numY elements to be created if 4 node elements + // numX/2 * numY /2 nodes to be v=created if 9 node elements + TCL_Char *eleType = argv[5]; + TCL_Char *additionalEleArgs = argv[6]; + // const ID &nodeTags = theBlock.getElementNodes(0,0); + // int numNodes = nodeTags.Size(); + + // assumes 15 is largest string for individual nodeTags + count = int(10 + strlen(eleType) + strlen(additionalEleArgs) + 15 *(numNodes+1)); + char *eleCommand = new char[count]; + int initialCount = int(8 + strlen(eleType)); + + int eleID = startEleNum; + if (numNodes == 9) { + numX /= 2; + numY /= 2; + } + + for (int jj=0; jj(clientData); + Domain *theTclDomain = builder->getDomain(); + int ndm = builder->getNDM(); + int ndf = builder->getNDF(); + + if (ndm < 3) { + opserr << OpenSees::PromptValueError << "block3D numX? numY? startNode? startEle? eleType? eleArgs?"; + opserr << " : model dimension (ndm) must be at leat 2 " << "\n"; + return TCL_ERROR; + } + + int numX, numY, numZ, startNodeNum, startEleNum; + if (Tcl_GetInt(interp, argv[1], &numX) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid numX: " << argv[1] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[2], &numY) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid numY: " << argv[2] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[3], &numZ) != TCL_OK) { + opserr << OpenSees::PromptValueError << "block3D numX? numY? numZ? startNode? startEle? eleType? eleArgs?"; + opserr << " : invalid numZ: " << argv[3] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[4], &startNodeNum) != TCL_OK) { + opserr << OpenSees::PromptValueError << "block3D numX? numY? numZ? startNode? startEle? eleType? eleArgs?"; + opserr << " : invalid startNode: " << argv[4] << "\n"; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[5], &startEleNum) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid startEle: " << argv[5] << "\n"; + return TCL_ERROR; + } + + MatrixND<27,3> Coordinates; + static ID haveNode(27); + Coordinates.zero(); + for (int k=0; k<27; k++) + haveNode(k) = -1; + + TCL_Char *nodalInfo = argv[8]; + TCL_Char ** argvNodes; + int argcNodes; + + Tcl_SplitList(interp, nodalInfo, &argcNodes, &argvNodes); + + + int count = 0; + while (count < argcNodes) { + if ((count + ndm + 1) > argcNodes) { + opserr << OpenSees::PromptValueError << "invalid number of node args: " << argv[8] << "\n"; + Tcl_Free((char *)argvNodes); + return TCL_ERROR; + } + int nodeTag; + double value; + if (Tcl_GetInt(interp, argvNodes[count], &nodeTag) != TCL_OK) { + opserr << OpenSees::PromptValueError << "invalid node id in node args: " << argvNodes[count] << "\n"; + Tcl_Free((char *)argvNodes); + return TCL_ERROR; + } + if (nodeTag < 1 || nodeTag > 27) { + opserr << OpenSees::PromptValueError << "node tag out of bounds [1, 27]: " << argvNodes[count] << "\n"; + Tcl_Free((char *)argvNodes); + return TCL_ERROR; + } + for (int i=0; i(nodeID, nodeCoords(0), nodeCoords(1), nodeCoords(2)); + break; + case 6: + theNode = new NodeND<3, 6>(nodeID, nodeCoords(0), nodeCoords(1), nodeCoords(2)); + break; + default: + theNode = new HeapNode(nodeID, ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); + break; + } + } else +#endif +// theNode = new HeapNode(nodeID, ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); + theNode = new Node(nodeID,ndf,nodeCoords(0),nodeCoords(1),nodeCoords(2)); + + if (theTclDomain->addNode(theNode) == false) { + opserr << OpenSees::PromptValueError << "failed to add node to the domain\n"; + opserr << "node: " << nodeID << "\n"; + delete theNode; + return TCL_ERROR; + } + + nodeID++; + } + } + } + + // create the elements: numX*numY elements to be created + TCL_Char *eleType = argv[6]; + TCL_Char *additionalEleArgs = argv[7]; + const ID &nodeTags = theBlock.getElementNodes(0,0,0); + int numNodes = nodeTags.Size(); + + // TODO: assumes 15 is largest string for individual nodeTags + count = int(10 + strlen(eleType) + strlen(additionalEleArgs) + 15 * (numNodes+1)); + char *eleCommand = new char[count]; + int initialCount = int(8 + strlen(eleType)); + + int eleID = startEleNum; + for (kk=0; kk(clientData); + int ndm = builder->getNDM(); + + if (argc < 1) { + opserr << OpenSees::PromptValueError << "block {args}\n"; + return TCL_ERROR; + } + + if (ndm == 2) + return TclCommand_doBlock2D(clientData, interp, argc, argv); + + else if (strcmp(argv[1], "2d") == 0) + return TclCommand_doBlock2D(clientData, interp, argc-1, argv+1); + + else + return TclCommand_doBlock3D(clientData, interp, argc, argv); + + return TCL_OK; +} diff --git a/SRC/runtime/commands/packages.cpp b/SRC/runtime/commands/packages.cpp index cc3ad4d46c..2c7e291310 100644 --- a/SRC/runtime/commands/packages.cpp +++ b/SRC/runtime/commands/packages.cpp @@ -115,110 +115,6 @@ getLibraryFunction(const char *libName, const char *funcName, void **libHandle, typedef TransientIntegrator** (*OPS_GetTransientIntegratorPtrType)(); typedef ConvergenceTest** (*OPS_GetTestPtrType)(); typedef bool* (*OPS_builtModelPtrType)(); -#if 0 - typedef void(_cdecl* setGlobalPointersFunction)( - OPS_Stream*, - Domain*, - SimulationInformation*, - OPS_ErrorPtrType, - OPS_GetIntInputPtrType, - OPS_GetDoubleInputPtrType, - OPS_AllocateElementPtrType, - OPS_AllocateMaterialPtrType, - OPS_GetUniaxialMaterialPtrType, - OPS_GetNDMaterialPtrType, - OPS_GetSectionForceDeformationPtrType, - OPS_GetCrdTransfPtrType, - OPS_GetFrictionModelPtrType, - OPS_InvokeMaterialDirectlyPtrType, - OPS_GetNodeInfoPtrType, - OPS_GetNodeInfoPtrType, - OPS_GetNodeInfoPtrType, - OPS_GetNodeInfoPtrType, - OPS_GetNodeInfoPtrType, - OPS_GetNodeInfoPtrType, - OPS_GetNumRemainingInputArgsType, - OPS_ResetCurrentInputArgType, - //OPS_ResetInputType, - OPS_ResetInputNoBuilderType, - OPS_GetStringType, - OPS_GetStringCopyType, - OPS_GetIntPtrType, - OPS_GetIntPtrType, - OPS_GetFEDatastorePtrType, - OPS_GetInterpPWD_PtrType, - OPS_GetAnalysisModelPtrType, - OPS_GetAlgorithmPtrType, - OPS_GetHandlerPtrType, - OPS_GetNumbererPtrType, - OPS_GetSOEPtrType, - OPS_GetEigenSOEPtrType, - OPS_GetStaticAnalysisPtrType, - OPS_GetTransientAnalysisPtrType, - OPS_GetVariableTimeStepTransientAnalysisPtrType, - OPS_GetNumEigenPtrType, - OPS_GetStaticIntegratorPtrType, - OPS_GetTransientIntegratorPtrType, - OPS_GetTestPtrType, - OPS_builtModelPtrType, - OPS_GetDomainPointerType); - - setGlobalPointersFunction funcPtr; - // look for pointer function - funcPtr = (setGlobalPointersFunction)GetProcAddress((HMODULE)hLib, "setGlobalPointers"); - if (funcPtr == 0) { - FreeLibrary((HMODULE)hLib); - return -2; - } -#endif -#if 0 - // invoke pointer function - (funcPtr)(opserrPtr, - ops_TheActiveDomain, - nullptr, // theSimulationInfoPtr, - OPS_Error, - OPS_GetIntInput, - OPS_GetDoubleInput, - OPS_AllocateElement, - OPS_AllocateMaterial, - OPS_GetUniaxialMaterial, - OPS_GetNDMaterial, - OPS_GetSectionForceDeformation, - OPS_GetCrdTransf, - OPS_GetFrictionModel, - OPS_InvokeMaterialDirectly, - OPS_GetNodeCrd, - OPS_GetNodeDisp, - OPS_GetNodeVel, - OPS_GetNodeAccel, - OPS_GetNodeIncrDisp, - OPS_GetNodeIncrDeltaDisp, - OPS_GetNumRemainingInputArgs, - OPS_ResetCurrentInputArg, - //OPS_ResetInput, - OPS_ResetInputNoBuilder, - OPS_GetString, - OPS_GetStringCopy, - OPS_GetNDM, - OPS_GetNDF, - OPS_GetFEDatastore, - OPS_GetInterpPWD, - OPS_GetAnalysisModel, - OPS_GetAlgorithm, - OPS_GetHandler, - OPS_GetNumberer, - OPS_GetSOE, - OPS_GetEigenSOE, - OPS_GetStaticAnalysis, - OPS_GetTransientAnalysis, - OPS_GetVariableTimeStepTransientAnalysis, - OPS_GetNumEigen, - OPS_GetStaticIntegrator, - OPS_GetTransientIntegrator, - OPS_GetTest, - OPS_builtModel, - OPS_GetDomain); -# endif LocalInitPtrType initPtr; initPtr = (LocalInitPtrType)GetProcAddress((HMODULE)hLib, "localInit"); if (initPtr != 0) { diff --git a/SRC/runtime/commands/packages.h b/SRC/runtime/commands/packages.h index 2ee1d68c28..2f5c55d4f5 100644 --- a/SRC/runtime/commands/packages.h +++ b/SRC/runtime/commands/packages.h @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Written: fmk // #ifndef OPS_PACKAGES_H diff --git a/SRC/runtime/commands/parallel/CMakeLists.txt b/SRC/runtime/commands/parallel/CMakeLists.txt index 62099d954a..0990026221 100644 --- a/SRC/runtime/commands/parallel/CMakeLists.txt +++ b/SRC/runtime/commands/parallel/CMakeLists.txt @@ -1,18 +1,42 @@ +#============================================================================== +# +# OpenSees -- Open System For Earthquake Engineering Simulation +# Pacific Earthquake Engineering Research Center +# +#============================================================================== +# _PARALLEL_INTERPRETERS +# _PARALLEL_PROCESSING # OpenSeesSP -target_compile_definitions(OpenSeesRT_Parallel PRIVATE - _PARALLEL_INTERPRETERS - _PARALLEL_PROCESSING # OpenSeesSP +return() + +find_package(MPI) +if (NOT MPI_FOUND) + return() +endif() + + +add_library(OpenSeesRT_Parallel OBJECT) + +target_include_directories(OpenSeesRT_Parallel + PRIVATE + ${OPS_SRC_DIR}/domain/partitioner/ + ${OPS_SRC_DIR}/analysis/analysis/ ) -target_link_libraries(OpenSeesRT_Parallel PRIVATE OPS_Parallel OPS_Actor) -target_sources(OpenSeesRT_Parallel PRIVATE - parallel_commands.cpp + +target_link_libraries(OpenSeesRT_Parallel PRIVATE + OPS_Runtime + OPS_Parallel + OPS_Actor + MPI::MPI_CXX +# ${MPI_CXX_LIBRARIES} ) -add_executable(OpenSeesSP EXCLUDE_FROM_ALL ) -add_executable(OpenSeesMP EXCLUDE_FROM_ALL ) +target_sources(OpenSeesRT_Parallel PRIVATE + machine.cpp +) -if(MKL_FOUND) +if (MKL_FOUND) message(STATUS "MKL was found.") set(SCALAPACK_LIBRARIES ${MKL_LIBRARIES}) else() @@ -21,20 +45,55 @@ else() message(">>> ScaLAPACK: ${ScaLAPACK_LIBRARIES}") endif() -target_link_libraries(OpenSeesRT_Parallel PRIVATE OPS_Parallel OPS_Actor - ${MPI_CXX_LIBRARIES} - /usr/lib/libscalapack.so +target_link_libraries(OpenSeesRT_Parallel PRIVATE + OPS_Parallel + OPS_Actor + MPI::MPI_CXX +# /usr/lib/libscalapack.so ${MPI_Fortran_LIBRARIES} - ${MPI_CXX_LINK_FLAGS} ) -target_sources(OpenSeesMP PRIVATE mpiMain.cpp) -target_link_libraries(OpenSeesMP PRIVATE OPS_Parallel OPS_Actor OpenSeesRT ${MPI_LIBRARIES}) +# +# OpenSeesMP +# +add_library(LibOpenSeesMP SHARED EXCLUDE_FROM_ALL ) +set_property(TARGET LibOpenSeesMP PROPERTY POSITION_INDEPENDENT_CODE 1) + +target_link_libraries(LibOpenSeesMP PRIVATE + OpenSeesRT_Parallel + OPS_Parallel + OPS_Actor + OpenSeesRT + OPS_Runtime + MPI::MPI_CXX +) + +target_sources(LibOpenSeesMP PRIVATE + communicate.cpp + ${OPS_SRC_DIR}/parallel/OpenSeesMP.cpp +) + +# +# OpenSeesSP +# +add_library(LibOpenSeesSP SHARED EXCLUDE_FROM_ALL ) +set_property(TARGET LibOpenSeesSP PROPERTY POSITION_INDEPENDENT_CODE 1) + +target_sources(LibOpenSeesSP PRIVATE + partition.cpp + ${OPS_SRC_DIR}/parallel/OpenSeesSP.cpp +) -target_sources(OpenSeesSP PRIVATE mpiMain.cpp) -target_link_libraries(OpenSeesSP PRIVATE OPS_Parallel OPS_Actor OpenSeesRT ${MPI_LIBRARIES} - ${MPI_CXX_LIBRARIES} - /usr/lib/libscalapack.so - ${MPI_Fortran_LIBRARIES} - ${MPI_CXX_LINK_FLAGS} +target_link_libraries(LibOpenSeesSP + PRIVATE + OpenSeesRT_Parallel + OPS_Parallel + OPS_Partition + OPS_Analysis + OPS_Runtime + OPS_Actor + OpenSeesRT + MPI::MPI_CXX + METIS +# /usr/lib/libscalapack.so ) diff --git a/SRC/runtime/commands/parallel/communicate.cpp b/SRC/runtime/commands/parallel/communicate.cpp new file mode 100644 index 0000000000..959043925f --- /dev/null +++ b/SRC/runtime/commands/parallel/communicate.cpp @@ -0,0 +1,154 @@ + +#include +#include +#include +#include +#include +#include + + +static int opsBarrier(ClientData, Tcl_Interp *, int, TCL_Char ** const argv); +static int opsSend(ClientData, Tcl_Interp *, int, TCL_Char ** const argv); +static int opsRecv(ClientData, Tcl_Interp *, int,TCL_Char ** const argv); + +void +Init_Communication(Tcl_Interp* interp, MachineBroker* theMachineBroker) +{ + Tcl_CreateCommand(interp, "send", &opsSend, (ClientData)theMachineBroker, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "recv", &opsRecv, (ClientData)theMachineBroker, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "barrier", &opsBarrier, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); +} + + +static int +opsSend(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +{ + if (argc < 2) + return TCL_OK; + + int otherPID = -1; + MachineBroker* theMachineBroker = (MachineBroker*)clientData; + int myPID = theMachineBroker->getPID(); + int np = theMachineBroker->getNP(); + const char *dataToSend = argv[argc - 1]; + int msgLength = strlen(dataToSend) + 1; + + const char *gMsg = dataToSend; + + if (strcmp(argv[1], "-pid") == 0 && argc > 3) { + + if (Tcl_GetInt(interp, argv[2], &otherPID) != TCL_OK) { + opserr << "send -pid pid? data? - pid: " << argv[2] << " invalid\n"; + return TCL_ERROR; + } + + if (otherPID > -1 && otherPID != myPID && otherPID < np) { + + MPI_Send((void *)(&msgLength), 1, MPI_INT, otherPID, 0, MPI_COMM_WORLD); + MPI_Send((void *)gMsg, msgLength, MPI_CHAR, otherPID, 1, MPI_COMM_WORLD); + + } else { + opserr << "send -pid pid? data? - pid: " << otherPID << " invalid\n"; + return TCL_ERROR; + } + + } else { + if (myPID == 0) { + MPI_Bcast((void *)(&msgLength), 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast((void *)gMsg, msgLength, MPI_CHAR, 0, MPI_COMM_WORLD); + } else { + opserr << "send data - only process 0 can do a broadcast - you may need " + "to kill the application"; + return TCL_ERROR; + } + } + return TCL_OK; +} + +static int +opsRecv(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +{ + MachineBroker* theMachineBroker = (MachineBroker*)clientData; + if (argc < 2) + return TCL_OK; + + int otherPID = 0; + int myPID = theMachineBroker->getPID(); + int np = theMachineBroker->getNP(); + TCL_Char *varToSet = argv[argc - 1]; + + int msgLength = 0; + char *gMsg = 0; + + if (strcmp(argv[1], "-pid") == 0 && argc > 3) { + + bool fromAny = false; + + if ((strcmp(argv[2], "ANY") == 0) || (strcmp(argv[2], "ANY_SOURCE") == 0) || + (strcmp(argv[2], "MPI_ANY_SOURCE") == 0)) { + fromAny = true; + } else { + if (Tcl_GetInt(interp, argv[2], &otherPID) != TCL_OK) { + opserr << "recv -pid pid? data? - pid: " << argv[2] << " invalid\n"; + return TCL_ERROR; + } + } + + if (otherPID > -1 && otherPID < np) { + MPI_Status status; + + if (fromAny == false) + if (myPID != otherPID) + MPI_Recv((void *)(&msgLength), 1, MPI_INT, otherPID, 0, + MPI_COMM_WORLD, &status); + else { + opserr << "recv -pid pid? data? - " << otherPID + << " cant receive from self!\n"; + return TCL_ERROR; + } + else { + MPI_Recv((void *)(&msgLength), 1, MPI_INT, MPI_ANY_SOURCE, 0, + MPI_COMM_WORLD, &status); + otherPID = status.MPI_SOURCE; + } + + if (msgLength > 0) { + gMsg = new char[msgLength]; + + MPI_Recv((void *)gMsg, msgLength, MPI_CHAR, otherPID, 1, MPI_COMM_WORLD, + &status); + + Tcl_SetVar(interp, varToSet, gMsg, TCL_LEAVE_ERR_MSG); + } + + } else { + opserr << "recv -pid pid? data? - " << otherPID << " invalid\n"; + return TCL_ERROR; + } + } else { + if (myPID != 0) { + MPI_Bcast((void *)(&msgLength), 1, MPI_INT, 0, MPI_COMM_WORLD); + + if (msgLength > 0) { + gMsg = new char[msgLength]; + + MPI_Bcast((void *)gMsg, msgLength, MPI_CHAR, 0, MPI_COMM_WORLD); + + Tcl_SetVar(interp, varToSet, gMsg, TCL_LEAVE_ERR_MSG); + } + + } else { + opserr << "recv data - only process 0 can do a broadcast - you may need " + "to kill the application"; + return TCL_ERROR; + } + } + return TCL_OK; +} + +static int +opsBarrier(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +{ + return MPI_Barrier(MPI_COMM_WORLD); +} + diff --git a/SRC/runtime/commands/parallel/machine.cpp b/SRC/runtime/commands/parallel/machine.cpp new file mode 100644 index 0000000000..25c17d4403 --- /dev/null +++ b/SRC/runtime/commands/parallel/machine.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +#include +#include +#include +#include + +static int getPID(ClientData, Tcl_Interp *, int, TCL_Char ** const argv); +static int getNP( ClientData, Tcl_Interp *, int, TCL_Char ** const argv); + + +void +Init_MachineRuntime(Tcl_Interp* interp, MachineBroker* theMachineBroker) +{ + Tcl_CreateCommand(interp, "getNP", &getNP, (ClientData)theMachineBroker, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "getPID", &getPID, (ClientData)theMachineBroker, (Tcl_CmdDeleteProc *)NULL); +} + +static int +getPID(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +{ + int pid = 0; + + MachineBroker* theMachineBroker = (MachineBroker*)clientData; + + if (theMachineBroker != nullptr) + pid = theMachineBroker->getPID(); + + // now we copy the value to the tcl string that is returned + Tcl_SetObjResult(interp, Tcl_NewIntObj(pid)); + + return TCL_OK; +} + +static int +getNP(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +{ + int np = 1; + MachineBroker* theMachineBroker = (MachineBroker*)clientData; + + if (theMachineBroker != nullptr) + np = theMachineBroker->getNP(); + + // now we copy the value to the tcl string that is returned + Tcl_SetObjResult(interp, Tcl_NewIntObj(np)); + + return TCL_OK; +} + + diff --git a/SRC/runtime/commands/parallel/partition.cpp b/SRC/runtime/commands/parallel/partition.cpp new file mode 100644 index 0000000000..cf307b1484 --- /dev/null +++ b/SRC/runtime/commands/parallel/partition.cpp @@ -0,0 +1,184 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +#include +#include +#include +// #include +#include +#include + +// # include +// # include +// # include +// # include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// # define MPIPP_H +// # include +// # include + + struct PartitionRuntime { + MachineBroker *machine = nullptr; + FEM_ObjectBroker *broker = nullptr; + DomainPartitioner *DOMAIN_partitioner = nullptr; + GraphPartitioner *GRAPH_partitioner = nullptr; +// LoadBalancer *balancer = nullptr; + Channel **channels = nullptr; + int num_subdomains = 0; + bool partitioned = false; + bool using_main_domain = false; + bool setMPIDSOEFlag = false; + int main_partition = 0; + PartitionedDomain theDomain; + }; + + +static int partitionModel(PartitionRuntime& part, int eleTag); +static Tcl_CmdProc opsPartition; +static Tcl_CmdProc wipePP; +extern Tcl_CmdProc TclCommand_specifyModel; + +void +Init_PartitionRuntime(Tcl_Interp* interp, MachineBroker* theMachineBroker, FEM_ObjectBroker* theBroker) +{ + PartitionRuntime *part = new PartitionRuntime{theMachineBroker, theBroker}; + + // + // set some global parameters + // + if (theMachineBroker->getPID() == 0) { + + // always use p0 even if ODD number of partitions + part->num_subdomains = theMachineBroker->getNP(); + part->using_main_domain = true; + part->main_partition = 1; + + } else { + part->using_main_domain = false; + part->num_subdomains = 0; + part->partitioned = false; + + } + + + Tcl_CreateCommand(interp, "partition", &opsPartition, (ClientData)part, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "wipePP", &wipePP, (ClientData)part, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "model", &TclCommand_specifyModel, (ClientData)&part->theDomain, (Tcl_CmdDeleteProc *)NULL); +} + + + +int +opsPartition(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + PartitionRuntime& part = *static_cast(clientData); + + int eleTag; + if (argc == 2) { + if (Tcl_GetInt(interp, argv[1], &eleTag) != TCL_OK) { + ; + } + } + partitionModel(part, eleTag); + return TCL_OK; +} + +static int +partitionModel(PartitionRuntime& part, int eleTag) +{ + if (part.partitioned == true) + return 0; + + int result = 0; + + if (part.channels != nullptr) + delete[] part.channels; + + part.channels = new Channel *[part.num_subdomains]; + + // create some subdomains + for (int i = 1; i <= part.num_subdomains; i++) { + if (i != part.main_partition) { + ShadowSubdomain *theSubdomain = + new ShadowSubdomain(i, *part.machine, *part.broker); + part.theDomain.addSubdomain(theSubdomain); + part.channels[i - 1] = theSubdomain->getChannelPtr(); + } + } + + // create a partitioner & partition the domain + if (part.DOMAIN_partitioner == nullptr) { + // part.balancer = new ShedHeaviest(); + // OPS_DOMAIN_partitioner = new DomainPartitioner(*OPS_GRAPH_partitioner, *part.balancer); + part.GRAPH_partitioner = new Metis; + part.DOMAIN_partitioner = new DomainPartitioner(*part.GRAPH_partitioner); + part.theDomain.setPartitioner(part.DOMAIN_partitioner); + } + + result = part.theDomain.partition(part.num_subdomains, part.using_main_domain, + part.main_partition, eleTag); + + if (result < 0) + return result; + + part.partitioned = true; + + DomainDecompositionAnalysis *theSubAnalysis; + SubdomainIter &theSubdomains = part.theDomain.getSubdomains(); + Subdomain *theSub = nullptr; + + void* the_static_analysis = nullptr; +#if 0 + // create the appropriate domain decomposition analysis + while ((theSub = theSubdomains()) != nullptr) { + if (the_static_analysis != nullptr) { + theSubAnalysis = new StaticDomainDecompositionAnalysis( + *theSub, *theHandler, *theNumberer, *the_analysis_model, *theAlgorithm, + *theSOE, *theStaticIntegrator, theTest, false); + + } else { + theSubAnalysis = new TransientDomainDecompositionAnalysis( + *theSub, *theHandler, *theNumberer, *the_analysis_model, *theAlgorithm, + *theSOE, *theTransientIntegrator, theTest, false); + } + theSub->setDomainDecompAnalysis(*theSubAnalysis); + } +#endif + + return result; +} + + +static int +wipePP(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + PartitionRuntime& part = *static_cast(clientData); + + if (part.partitioned == true && part.num_subdomains > 1) { + SubdomainIter &theSubdomains = part.theDomain.getSubdomains(); + Subdomain *theSub =nullptr; + + // create the appropriate domain decomposition analysis + while ((theSub = theSubdomains()) != nullptr) + theSub->wipeAnalysis(); + } + return TCL_OK; +} + diff --git a/SRC/runtime/commands/parallel/sequential.cpp b/SRC/runtime/commands/parallel/sequential.cpp index 9fcbba337f..bffcab3444 100644 --- a/SRC/runtime/commands/parallel/sequential.cpp +++ b/SRC/runtime/commands/parallel/sequential.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This unit contains implementations of parallel commands // for use in non-parallel interpreters // diff --git a/SRC/runtime/commands/pragma.cpp b/SRC/runtime/commands/pragma.cpp index a442e832ad..1ca9a3a28b 100644 --- a/SRC/runtime/commands/pragma.cpp +++ b/SRC/runtime/commands/pragma.cpp @@ -1,17 +1,20 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // #include #include -#include +#include + +class Domain; int TclObjCommand_pragma([[maybe_unused]] ClientData clientData, - Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) + Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[]) { if (objc == 1) return TCL_OK; @@ -29,6 +32,7 @@ TclObjCommand_pragma([[maybe_unused]] ClientData clientData, "proc system {args} {}\n" "proc test {args} {}\n" "proc algorithm {args} {}\n" + "proc sensitivityAlgorithm {args} {}\n" "proc integrator {args} {}\n" "proc analysis {args} {}\n" "proc analyze {args} {return 0}\n" @@ -36,7 +40,24 @@ TclObjCommand_pragma([[maybe_unused]] ClientData clientData, "namespace eval opensees::pragma {set analysis off}\n" ); return TCL_OK; - } + } else if (argi < objc && strcmp(Tcl_GetString(objv[argi]), "on") == 0) { + Tcl_Eval(interp, + "proc loadConst {args} {return 0}\n" + "proc wipeAnalysis {args} {return 0}\n" + "proc constraints {args} {return 0}\n" + "proc numberer {args} {return 0}\n" + "proc system {args} {return 0}\n" + "proc test {args} {return 0}\n" + "proc algorithm {args} {return 0}\n" + "proc sensitivityAlgorithm {args} {return 0}\n" + "proc integrator {args} {return 0}\n" + "proc analysis {args} {return 0}\n" + "proc analyze {args} {}\n" + "proc eigen {args} {}\n" + "namespace eval opensees::pragma {set analysis on}\n" + ); + return TCL_OK; + } } else if (strcmp(pragma, "openseespy") == 0) { if (argi < objc && strcmp(Tcl_GetString(objv[argi]), "off") == 0) { diff --git a/SRC/runtime/commands/strings.cpp b/SRC/runtime/commands/strings.cpp index cf3bf6ea67..7ff0769c4e 100644 --- a/SRC/runtime/commands/strings.cpp +++ b/SRC/runtime/commands/strings.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // #if 0 static const char* diff --git a/SRC/runtime/commands/utilities/formats.cpp b/SRC/runtime/commands/utilities/formats.cpp index c636aed84a..147513132b 100644 --- a/SRC/runtime/commands/utilities/formats.cpp +++ b/SRC/runtime/commands/utilities/formats.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file provides basic file format handling commands, // such as naive XML processing and binary conversion. // @@ -11,7 +12,8 @@ #include #include #include -#include +#include +#include extern int binaryToText(const char *inputFile, const char *outputFile); extern int textToBinary(const char *inputFile, const char *outputFile); diff --git a/SRC/runtime/commands/utilities/linalg.hh b/SRC/runtime/commands/utilities/linalg.hh index d398e05697..7ad4ada106 100644 --- a/SRC/runtime/commands/utilities/linalg.hh +++ b/SRC/runtime/commands/utilities/linalg.hh @@ -1,7 +1,38 @@ const char *linalg[] = {R"END( -# https://wiki.tcl-lang.org/page/range +namespace eval OpenSees { +namespace export verify + +proc verify {cmd {value ""} {reference ""} {tolerance 1e-12} {about ""}} { + if {$cmd == "error"} { + set check [expr abs(($value - $reference)/$reference)] + if {$check > $tolerance} { + puts " \033\[31mFAIL\033\[0m: | $value - $reference | = $check > $tolerance" + error "$about" + } else { + puts " \033\[32mPASS\033\[0m "; # " $value $reference $about" + } + + } elseif {$cmd == "value"} { + if {abs($value - $reference) > $tolerance} { + set check [expr abs($value - $reference)] + puts " \033\[31mFAIL\033\[0m($about): | $value - $reference | = $check > $tolerance" + error "$about" + } else { + puts " \033\[32mPASS\033\[0m "; # "$value $reference $about" + } + } else { + # value or "about" + puts " $value" + } +} + +}; # namespace OpenSees + +namespace import OpenSees::verify + proc range args { + # https://wiki.tcl-lang.org/page/range foreach {start stop step} [switch -exact -- [llength $args] { 1 {concat 0 $args 1} 2 {concat $args 1} @@ -17,8 +48,9 @@ proc range args { return $range } -# https://opensource.apple.com/source/tcl/tcl-118.50.1/tcl_ext/tklib/tklib/examples/plotchart/rosenbrock.tcl.auto.htm proc linspace {min max num} { + # https://opensource.apple.com/source/tcl/tcl-118.50.1/tcl_ext/tklib/tklib/examples/plotchart/rosenbrock.tcl.auto.htm + #set opts { # {min.arg 0.0 "the minimum value in the range"} # {max.arg 1.0 "the maximum value in the range"} diff --git a/SRC/runtime/commands/utilities/progress.cpp b/SRC/runtime/commands/utilities/progress.cpp index 2920c37679..44d42b96e2 100644 --- a/SRC/runtime/commands/utilities/progress.cpp +++ b/SRC/runtime/commands/utilities/progress.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file provides progress bar functionality to the // interpreter. // diff --git a/SRC/runtime/commands/utilities/sdofResponse.cpp b/SRC/runtime/commands/utilities/sdofResponse.cpp index 42e6c246b5..80787eecc3 100644 --- a/SRC/runtime/commands/utilities/sdofResponse.cpp +++ b/SRC/runtime/commands/utilities/sdofResponse.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // ============= ==================================================== // m mass // zeta damping ratio diff --git a/SRC/runtime/parsing/CMakeLists.txt b/SRC/runtime/parsing/CMakeLists.txt new file mode 100644 index 0000000000..98e15ab310 --- /dev/null +++ b/SRC/runtime/parsing/CMakeLists.txt @@ -0,0 +1,9 @@ +#============================================================================== +# +# OpenSees -- Open System For Earthquake Engineering Simulation +# Pacific Earthquake Engineering Research Center +# +#============================================================================== + +target_sources(OPS_Runtime PRIVATE InterpreterAPI.cpp) + diff --git a/SRC/runtime/parsing/InputAPI.h b/SRC/runtime/parsing/InputAPI.h index 0b4a288c64..929e3018d7 100644 --- a/SRC/runtime/parsing/InputAPI.h +++ b/SRC/runtime/parsing/InputAPI.h @@ -4,7 +4,7 @@ #include #define G3_RUNTIME_H #endif - +#include #define G3_Char TCL_Char diff --git a/SRC/runtime/parsing/InterpreterAPI.cpp b/SRC/runtime/parsing/InterpreterAPI.cpp index c1518c986c..23be2d02d5 100644 --- a/SRC/runtime/parsing/InterpreterAPI.cpp +++ b/SRC/runtime/parsing/InterpreterAPI.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // #include #include @@ -11,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -26,8 +27,6 @@ #include #include -#include -#include #include @@ -75,24 +74,11 @@ OPS_ResetCurrentInputArg(int cArg) } -// extern "C" -#if 0 -int -OPS_ResetInput(ClientData clientData, Tcl_Interp *interp, int cArg, int mArg, - TCL_Char ** const argv, void*, void*) -{ - currentArgv = argv; - currentArg = cArg; - maxArg = mArg; - return 0; -} -#endif - - extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp *interp, int cArg, int mArg, TCL_Char ** const argv, Domain *domain) { + theInterp = interp; currentArgv = argv; currentArg = cArg; maxArg = mArg; @@ -175,31 +161,31 @@ OPS_GetStringCopy(char **arrayData) extern "C" int OPS_GetDoubleListInput(int* size, Vector* data) { - TCL_Char** strings; + TCL_Char** strings; - if (Tcl_SplitList(theInterp, currentArgv[currentArg], - size, &strings) != TCL_OK) { - opserr << "ERROR problem splitting list " << currentArgv[currentArg] << " \n"; - return -1; - } + if (Tcl_SplitList(theInterp, currentArgv[currentArg], + size, &strings) != TCL_OK) { + opserr << "ERROR problem splitting list " << currentArgv[currentArg] << " \n"; + return -1; + } - data->resize(*size); - for (int i = 0; i < *size; i++) { - double value; - if (Tcl_GetDouble(theInterp, strings[i], &value) != TCL_OK) { - opserr << "ERROR problem reading data value " << strings[i] << " \n"; - // free up the array of strings .. see tcl man pages as to why - Tcl_Free((char*)strings); - return -1; - } - (*data)(i) = value; - } - // free up the array of strings .. see tcl man pages as to why - Tcl_Free((char*)strings); + data->resize(*size); + for (int i = 0; i < *size; i++) { + double value; + if (Tcl_GetDouble(theInterp, strings[i], &value) != TCL_OK) { + opserr << "ERROR problem reading data value " << strings[i] << " \n"; + // free up the array of strings .. see tcl man pages as to why + Tcl_Free((char*)strings); + return -1; + } + (*data)(i) = value; + } + // free up the array of strings .. see tcl man pages as to why + Tcl_Free((char*)strings); - currentArg++; + currentArg++; - return 0; + return 0; } extern "C" @@ -309,7 +295,7 @@ G3_setModelBuilder(G3_Runtime *rt, BasicModelBuilder* builder) { theModelBuilder = builder; rt->m_builder = builder; - return 1; + return 0; } BasicModelBuilder * @@ -376,7 +362,10 @@ G3_getSectionForceDeformation(G3_Runtime* rt, int tag) { BasicModelBuilder* builder = G3_getSafeBuilder(rt); assert(builder); - SectionForceDeformation* theSection = builder->getTypedObject(tag); + SectionForceDeformation* theSection = nullptr; + + if (builder->getNDM() == 3) + theSection = builder->getTypedObject(tag); if (theSection != nullptr) return theSection; @@ -393,7 +382,8 @@ G3_getUniaxialMaterialInstance(G3_Runtime *rt, int tag) return builder->getTypedObject(tag); } -int G3_addUniaxialMaterial(G3_Runtime *rt, UniaxialMaterial *mat) { +int +G3_addUniaxialMaterial(G3_Runtime *rt, UniaxialMaterial *mat) { BasicModelBuilder* builder = G3_getSafeBuilder(rt); assert(builder != nullptr); assert(mat != nullptr); @@ -444,106 +434,52 @@ OPS_GetFEDatastore() {return theDatabase;} const char * OPS_GetInterpPWD() {return getInterpPWD(theInterp);} -#if 0 -EquiSolnAlgo ** -OPS_GetAlgorithm(void) {return &theAlgorithm;} - -EigenSOE ** -OPS_GetEigenSOE(void) {return &theEigenSOE;} - -LinearSOE ** -OPS_GetSOE(void) {return &theSOE;} - -StaticAnalysis ** -OPS_GetStaticAnalysis(void) {return &theStaticAnalysis;} -#endif - -#if 0 && !defined(OPS_USE_RUNTIME) -modelState theModelState; - -UniaxialMaterial * -OPS_GetUniaxialMaterial(int matTag) -{ - return OPS_getUniaxialMaterial(matTag); -} - -Domain * -OPS_GetDomain(void) {return theDomain;} - -AnalysisModel ** -OPS_GetAnalysisModel(void){return &theAnalysisModel;} - -CrdTransf * -OPS_GetCrdTransf(int crdTag) {return OPS_getCrdTransf(crdTag);} - -StaticIntegrator ** -OPS_GetStaticIntegrator(void) {return &theStaticIntegrator;} - -TransientIntegrator ** -OPS_GetTransientIntegrator(void) {return &theTransientIntegrator;} - -DirectIntegrationAnalysis ** -OPS_GetTransientAnalysis(void) {return &theTransientAnalysis;} - -ConvergenceTest ** -OPS_GetTest(void) {return &theTest;} - -ConstraintHandler ** -OPS_GetHandler(void) {return &theHandler;} - -DOF_Numberer ** -OPS_GetNumberer(void) {return &theGlobalNumberer;} - -extern "C" int -OPS_InvokeMaterialDirectly2(matObject *theMat, modelState *model, - double *strain, double *stress, double *tang, - int *isw) -{ - int error = 0; - if (theMat != nullptr) - theMat->matFunctPtr(theMat, model, strain, tang, stress, isw, &error); - else - error = -1; - - return error; -} -static void -OPS_InvokeMaterialObject(struct matObject *theMat, modelState *theModel, - double *strain, double *tang, double *stress, int *isw, - int *result) -{ - int matType = (int)theMat->theParam[0]; - - if (matType == 1) { - // UniaxialMaterial *theMaterial = theUniaxialMaterials[matCount]; - UniaxialMaterial *theMaterial = (UniaxialMaterial *)theMat->matObjectPtr; - if (theMaterial == 0) { - *result = -1; - return; - } - - if (*isw == ISW_COMMIT) { - *result = theMaterial->commitState(); - return; - } else if (*isw == ISW_REVERT) { - *result = theMaterial->revertToLastCommit(); - return; - } else if (*isw == ISW_REVERT_TO_START) { - *result = theMaterial->revertToStart(); - return; - } else if (*isw == ISW_FORM_TANG_AND_RESID) { - double matStress = 0.0; - double matTangent = 0.0; - int res = theMaterial->setTrial(strain[0], matStress, matTangent); - stress[0] = matStress; - tang[0] = matTangent; - *result = res; - return; +namespace OpenSees { + namespace Parsing { + + int + GetDoubleParam(Tcl_Interp *interp, Domain& domain, const char* arg, double* value, Parameter* ¶m) + { + if (Tcl_GetDouble(interp, arg, value) == TCL_OK) + return TCL_OK; + + // something like "parameter tag value" + int tag, argc; + const char **argv; + if (Tcl_SplitList(interp, arg, &argc, &argv) != TCL_OK) + return TCL_ERROR; + + if (argc != 3) { + Tcl_Free((char*)argv); + return TCL_ERROR; + } + + if (strcmp(argv[0], "Parameter") != 0) { + Tcl_Free((char*)argv); + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + Tcl_Free((char*)argv); + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[2], value) != TCL_OK) { + Tcl_Free((char*)argv); + return TCL_ERROR; + } + + Tcl_Free((char*)argv); + + param = domain.getParameter(tag); + + if (param == nullptr) { + opserr << OpenSees::PromptValueError << "parameter with tag " << tag << " not found\n"; + return TCL_ERROR; + } + + return TCL_OK; } } - - return; -} - -#endif +} \ No newline at end of file diff --git a/SRC/runtime/parsing/Parsing.h b/SRC/runtime/parsing/Parsing.h index 39d087e826..e1d5851240 100644 --- a/SRC/runtime/parsing/Parsing.h +++ b/SRC/runtime/parsing/Parsing.h @@ -1,9 +1,12 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// +#pragma once +#include #ifndef TCL_Char typedef const char TCL_Char; #endif @@ -13,3 +16,17 @@ typedef const char G3_Char; #endif #include "InputAPI.h" + +// As suggested by https://core.tcl-lang.org/tcl/wiki?name=Migrating+C+extensions+to+Tcl+9 +#ifndef TCL_SIZE_MAX +typedef int Tcl_Size; +#define TCL_SIZE_MAX INT_MAX +#endif + +class Parameter; +namespace OpenSees { +namespace Parsing { +int +GetDoubleParam(Tcl_Interp *, Domain& , const char* arg, double* value, Parameter*&); +} +} \ No newline at end of file diff --git a/SRC/runtime/python/OpenSeesPyRT.cpp b/SRC/runtime/python/OpenSeesPyRT.cpp index 2050406330..159df84ada 100644 --- a/SRC/runtime/python/OpenSeesPyRT.cpp +++ b/SRC/runtime/python/OpenSeesPyRT.cpp @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Author: cmp // #include @@ -29,9 +30,6 @@ namespace py = pybind11; // // ANALYSIS // -#include -#include -#include #include #include @@ -506,7 +504,7 @@ init_obj_module(py::module &m) py::class_(m, "_Runtime") ; - +#if 0 py::class_(m, "_StaticAnalysis") .def (py::init([](G3_Runtime *runtime, G3_Config conf) { return *((StaticAnalysis*)runtime->newStaticAnalysis(conf)); @@ -521,6 +519,7 @@ init_obj_module(py::module &m) })) .def ("analyze", &DirectIntegrationAnalysis::analyze) ; +#endif // // Module-Level Functions diff --git a/SRC/runtime/runtime/BasicAnalysisBuilder.cpp b/SRC/runtime/runtime/BasicAnalysisBuilder.cpp index 50038a815e..c03871607a 100644 --- a/SRC/runtime/runtime/BasicAnalysisBuilder.cpp +++ b/SRC/runtime/runtime/BasicAnalysisBuilder.cpp @@ -1,15 +1,17 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // // Written: Claudio Perez // #include #include #include - +#include "BasicModelBuilder.h" #include "BasicAnalysisBuilder.h" #include #include @@ -18,14 +20,13 @@ #include #include #include -#include -#include -#include +#include #include #include #include #include #include +#include // For eigen() #include @@ -52,29 +53,32 @@ #include -static std::unordered_map SolveFailedMessage { +static std::unordered_map AnalyzeFailedMessage { {SolutionAlgorithm::BadFormResidual, "Failed to form residual\n"}, {SolutionAlgorithm::BadFormTangent, "Failed to form tangent\n"}, {SolutionAlgorithm::BadLinearSolve, "Failed to solve system, tangent may be singular\n"}, // {SolutionAlgorithm::TestFailed, ""},// no output; information will have been printed by the test {SolutionAlgorithm::BadTestStart, "Failed to initialize the convergence test\n"}, + {SolutionAlgorithm::BadStepUpdate, "Failed to update the model\n"} }; -BasicAnalysisBuilder::BasicAnalysisBuilder(Domain* domain) +BasicAnalysisBuilder::BasicAnalysisBuilder(BasicModelBuilder& context) : - theDomain(domain), + context(context), + theDomain(context.getDomain()), theHandler(nullptr), theNumberer(nullptr), + theAnalysisModel(new AnalysisModel()), theAlgorithm(nullptr), theSOE(nullptr), theEigenSOE(nullptr), theStaticIntegrator(nullptr), theTransientIntegrator(nullptr), theTest(nullptr), - theVariableTimeStepTransientAnalysis(nullptr), - CurrentAnalysisFlag(EMPTY_ANALYSIS) + CurrentAnalysisFlag(EMPTY_ANALYSIS), + domainStamp(0) { - theAnalysisModel = new AnalysisModel(); + } BasicAnalysisBuilder::~BasicAnalysisBuilder() @@ -100,16 +104,16 @@ BasicAnalysisBuilder::wipe() theStaticIntegrator = nullptr; } if ((theTransientIntegrator != nullptr) && freeTI) { - delete theTransientIntegrator; - theTransientIntegrator = nullptr; + delete theTransientIntegrator; + theTransientIntegrator = nullptr; } if ((theSOE != nullptr) && freeSOE) { - delete theSOE; - theSOE = nullptr; + delete theSOE; + theSOE = nullptr; } if (theNumberer != nullptr) { - delete theNumberer; - theNumberer = nullptr; + delete theNumberer; + theNumberer = nullptr; } if (theHandler != nullptr) { delete theHandler; @@ -127,14 +131,14 @@ BasicAnalysisBuilder::wipe() delete theAnalysisModel; theAnalysisModel = new AnalysisModel(); } - theVariableTimeStepTransientAnalysis = nullptr; } + void BasicAnalysisBuilder::setLinks(CurrentAnalysis flag) { - if (theSOE && theAnalysisModel) - theSOE->setLinks(*theAnalysisModel); + // if (theSOE && theAnalysisModel) + // theSOE->setLinks(*theAnalysisModel); if (theDomain && theHandler && theAnalysisModel) theAnalysisModel->setLinks(*theDomain, *theHandler); @@ -147,51 +151,51 @@ BasicAnalysisBuilder::setLinks(CurrentAnalysis flag) switch (flag) { - case EMPTY_ANALYSIS: - break; + case EMPTY_ANALYSIS: + break; - case TRANSIENT_ANALYSIS: - if (theDomain && theAnalysisModel && theTransientIntegrator && theHandler) - theHandler->setLinks(*theDomain, *theAnalysisModel, *theTransientIntegrator); + case TRANSIENT_ANALYSIS: + if (theDomain && theAnalysisModel && theTransientIntegrator && theHandler) + theHandler->setLinks(*theDomain, *theAnalysisModel); - if (theAnalysisModel && theTransientIntegrator && theSOE && theTest && theAlgorithm) - theAlgorithm->setLinks(*theAnalysisModel, *theTransientIntegrator, *theSOE, theTest); + if (theTransientIntegrator && theSOE && theTest && theAlgorithm) + theAlgorithm->setLinks(*theTransientIntegrator, *theSOE, theTest); - if (theAnalysisModel && theSOE && theTest && theTransientIntegrator) { - theTransientIntegrator->setLinks(*theAnalysisModel, *theSOE, theTest); - } - // if (theTransientIntegrator && domainStamp != 0) - // theTransientIntegrator->domainChanged(); - // this->domainChanged(); + if (theAnalysisModel && theSOE && theTest && theTransientIntegrator) { + theTransientIntegrator->setLinks(*theAnalysisModel, *theSOE, theTest); + } + // if (theTransientIntegrator && domainStamp != 0) + // theTransientIntegrator->domainChanged(); + // this->domainChanged(); - // domainStamp = 0; - break; + // domainStamp = 0; + break; - case STATIC_ANALYSIS: - // opserr << "setLinks(STATIC)\n"; - if (theDomain && theAnalysisModel && theStaticIntegrator && theHandler) - theHandler->setLinks(*theDomain, *theAnalysisModel, *theStaticIntegrator); + case STATIC_ANALYSIS: + if (theDomain && theAnalysisModel && theStaticIntegrator && theHandler) + theHandler->setLinks(*theDomain, *theAnalysisModel); - if (theAnalysisModel && theSOE && theTest && theStaticIntegrator) - theStaticIntegrator->setLinks(*theAnalysisModel, *theSOE, theTest); + if (theAnalysisModel && theSOE && theTest && theStaticIntegrator) + theStaticIntegrator->setLinks(*theAnalysisModel, *theSOE, theTest); - if (theAnalysisModel && theStaticIntegrator && theSOE && theTest && theAlgorithm) - theAlgorithm->setLinks(*theAnalysisModel, *theStaticIntegrator, *theSOE, theTest); + if (theStaticIntegrator && theSOE && theTest && theAlgorithm) + theAlgorithm->setLinks(*theStaticIntegrator, *theSOE, theTest); - // domainStamp = 0; - break; + // domainStamp = 0; + break; } } int -BasicAnalysisBuilder::initialize(void) +BasicAnalysisBuilder::initialize() { // check if domain has undergone change int stamp = theDomain->hasDomainChanged(); if (stamp != domainStamp) { domainStamp = stamp; if (this->domainChanged() < 0) { - opserr << G3_ERROR_PROMPT << "initialize - domainChanged() failed\n"; + opserr << OpenSees::PromptValueError + << "initialize - domainChanged() failed\n"; return -1; } } @@ -202,17 +206,17 @@ BasicAnalysisBuilder::initialize(void) case STATIC_ANALYSIS: if (theStaticIntegrator->initialize() < 0) { - opserr << G3_WARN_PROMPT << "integrator initialize() failed\n"; - return -2; - } else + return -2; + } + else theStaticIntegrator->commit(); break; case TRANSIENT_ANALYSIS: if (theTransientIntegrator->initialize() < 0) { - opserr << "integrator initialize() failed\n"; - return -2; - } else + return -2; + } + else theTransientIntegrator->commit(); break; } @@ -222,7 +226,7 @@ BasicAnalysisBuilder::initialize(void) } int -BasicAnalysisBuilder::domainChanged(void) +BasicAnalysisBuilder::domainChanged() { Domain *domain = this->getDomain(); int stamp = domain->hasDomainChanged(); @@ -230,17 +234,18 @@ BasicAnalysisBuilder::domainChanged(void) opsdbg << G3_DEBUG_PROMPT << "Domain changed\n"; + theAnalysisModel->clearAll(); if (theHandler != nullptr) { theHandler->clearAll(); - // Invoke handle() on the constraint handler which - // causes the creation of FE_Element and DOF_Group objects - // and their addition to the AnalysisModel. + // Create FE_Element and DOF_Group objects + // and add to the AnalysisModel. if (theHandler->handle() < 0) { opserr << "BasicAnalysisBuilder::domainChange() - ConstraintHandler::handle() failed\n"; return -1; } + // Invoke number() on the numberer which causes // equation numbers to be assigned to all the DOFs in the // AnalysisModel. @@ -261,7 +266,7 @@ BasicAnalysisBuilder::domainChanged(void) if (theSOE != nullptr) { if (theSOE->setSize(theGraph) < 0) { - opserr << "BasicAnalysisBuilder::domainChange() - LinearSOE::setSize() failed\n"; + opserr << "BasicAnalysisBuilder::domainChange - LinearSOE::setSize() failed\n"; return -3; } } @@ -275,26 +280,25 @@ BasicAnalysisBuilder::domainChanged(void) theAnalysisModel->clearDOFGraph(); - // finally we invoke domainChanged on the Integrator and Algorithm - // objects .. informing them that the model has changed + // finally invoke domainChanged on the Integrator and Algorithm + // informing them that the model has changed switch (this->CurrentAnalysisFlag) { + case STATIC_ANALYSIS: + if (theStaticIntegrator->domainChanged() < 0) { + opserr << "BasicAnalysisBuilder::domainChange - Integrator::domainChanged() failed\n"; + return -4; + } + break; - case STATIC_ANALYSIS: - if (theStaticIntegrator->domainChanged() < 0) { - opserr << "BasicAnalysisBuilder::domainChange - Integrator::domainChanged() failed\n"; - return -4; - } - break; - - case TRANSIENT_ANALYSIS: + case TRANSIENT_ANALYSIS: - if (theTransientIntegrator->domainChanged() < 0) { - opserr << "BasicAnalysisBuilder::domainChange - Integrator::domainChanged() failed\n"; - return -4; - } - break; - default: - break; + if (theTransientIntegrator->domainChanged() < 0) { + opserr << "BasicAnalysisBuilder: Integrator failed in domainChanged()\n"; + return -4; + } + break; + default: + break; } // if (theAlgorithm && theAlgorithm->domainChanged() < 0) { @@ -306,80 +310,101 @@ BasicAnalysisBuilder::domainChanged(void) } int -BasicAnalysisBuilder::analyze(int num_steps, double size_steps) +BasicAnalysisBuilder::analyze(int num_steps, double size_steps, int flag) { - + int status = -1; switch (this->CurrentAnalysisFlag) { case STATIC_ANALYSIS: - return this->analyzeStatic(num_steps); + status = this->analyzeStatic(num_steps, flag); break; case TRANSIENT_ANALYSIS: { - // TODO: Set global timestep variable + // TODO: Need to remove global timestep variable; ops_Dt = size_steps; - return this->analyzeTransient(num_steps, size_steps); + status = this->analyzeTransient(num_steps, size_steps); break; } default: - opserr << G3_ERROR_PROMPT << "No Analysis type has been specified \n"; + opserr << OpenSees::PromptValueError << "No Analysis type has been specified \n"; return -1; } + + // TODO: This should be done when exact compatibility with upstream is needed; + // add an environment variable or flag to control it. + // theDomain->flushRecorders(); + return status; } int -BasicAnalysisBuilder::analyzeStatic(int numSteps) +BasicAnalysisBuilder::analyzeStatic(int numSteps, int flag) { int result = 0; for (int i=0; ianalysisStep(0.0); + if (result < 0) { + opserr << "The AnalysisModel failed\n"; + opserr << " at step: " << i << " with domain at load factor "; + opserr << theDomain->getCurrentTime() << "\n"; + theDomain->revertToLastCommit(); + return -2; + } - result = theAnalysisModel->analysisStep(); + // Check for change in Domain since last step. As a change can + // occur in a commit() in a domain decomp with load balancing + // this must now be inside the loop + int stamp = theDomain->hasDomainChanged(); + if (stamp != domainStamp) { + domainStamp = stamp; + result = this->domainChanged(); if (result < 0) { - opserr << "StaticAnalysis::analyze - the AnalysisModel failed\n"; - opserr << " at step: " << i << " with domain at load factor "; - opserr << theDomain->getCurrentTime() << "\n"; - theDomain->revertToLastCommit(); - return -2; - } - - // Check for change in Domain since last step. As a change can - // occur in a commit() in a domaindecomp with load balancing - // this must now be inside the loop - int stamp = theDomain->hasDomainChanged(); - - if (stamp != domainStamp) { - domainStamp = stamp; - result = this->domainChanged(); - if (result < 0) { - opserr << "domainChanged failed"; - opserr << " at step " << i << " of " << numSteps << "\n"; - return -1; - } + opserr << "domainChanged failed"; + opserr << " at step " << i << " of " << numSteps << "\n"; + return -1; } + } + if (flag & Increment) { result = theStaticIntegrator->newStep(); if (result < 0) { opserr << "The Integrator failed at step: " << i - << " with domain at load factor " << theDomain->getCurrentTime() << "\n"; + << " with domain at load factor " << theDomain->getCurrentTime() << "\n"; theDomain->revertToLastCommit(); theStaticIntegrator->revertToLastStep(); return -2; } + } + if (flag & Iterate) { result = theAlgorithm->solveCurrentStep(); if (result < 0) { // Print error message if we have one - if (SolveFailedMessage.find(result) != SolveFailedMessage.end()) { - opserr << OpenSees::PromptAnalysisFailure << SolveFailedMessage[result]; + if (AnalyzeFailedMessage.find(result) != AnalyzeFailedMessage.end()) { + opserr << OpenSees::PromptAnalysisFailure << AnalyzeFailedMessage[result]; } theDomain->revertToLastCommit(); theStaticIntegrator->revertToLastStep(); return -3; } + } + + if (theStaticIntegrator->shouldComputeAtEachStep()) { + result = theStaticIntegrator->computeSensitivities(); + if (result < 0) { + opserr << "StaticAnalysis::analyze() - the SensitivityAlgorithm failed"; + opserr << " at step: " << i << " with domain at load factor "; + opserr << theDomain->getCurrentTime() << "\n"; + theDomain->revertToLastCommit(); + theStaticIntegrator->revertToLastStep(); + return -5; + } + } + if (flag & Commit) { result = theStaticIntegrator->commit(); if (result < 0) { opserr << "StaticAnalysis::analyze - "; @@ -391,11 +416,14 @@ BasicAnalysisBuilder::analyzeStatic(int numSteps) theStaticIntegrator->revertToLastStep(); return -4; } + } } return 0; } + + int BasicAnalysisBuilder::analyzeTransient(int numSteps, double dT) { @@ -437,6 +465,7 @@ BasicAnalysisBuilder::analyzeSubLevel(int level, double dT) return result; } + // analyze a transient step int BasicAnalysisBuilder::analyzeStep(double dT) @@ -469,14 +498,24 @@ BasicAnalysisBuilder::analyzeStep(double dT) result = theAlgorithm->solveCurrentStep(); if (result < 0) { - if (SolveFailedMessage.find(result) != SolveFailedMessage.end()) { - opserr << OpenSees::PromptAnalysisFailure << SolveFailedMessage[result]; + if (AnalyzeFailedMessage.find(result) != AnalyzeFailedMessage.end()) { + opserr << OpenSees::PromptAnalysisFailure << AnalyzeFailedMessage[result]; } theDomain->revertToLastCommit(); theTransientIntegrator->revertToLastStep(); return -3; } + if (theTransientIntegrator->shouldComputeAtEachStep()) { + result = theTransientIntegrator->computeSensitivities(); + if (result < 0) { + opserr << "TransientAnalysis::analyze() - the SensitivityAlgorithm failed"; + opserr << " at time " << theDomain->getCurrentTime() << "\n"; + theDomain->revertToLastCommit(); + theTransientIntegrator->revertToLastStep(); + return -5; + } + } result = theTransientIntegrator->commit(); if (result < 0) { @@ -492,6 +531,121 @@ BasicAnalysisBuilder::analyzeStep(double dT) } +static double +determineDt(double dT, + double dtMin, + double dtMax, + int Jd, + ConvergenceTest *theTest) +{ + double newDt = dT; + + // get the number of trial steps in the last solveCurrentStep() + double numLastIter = 1.0; + if (theTest != 0) + numLastIter = theTest->getNumTests(); + + + // determine new dT based on last dT and Jd and #iter of last step + double factor = Jd/numLastIter; + newDt *= factor; + + // ensure: dtMin <~~ dT <= dtMax + if (newDt < dtMin) + newDt = dtMin - DBL_EPSILON; // to ensure we get out of the analysis + // loop if can't converge on next step + else if (newDt > dtMax) + newDt = dtMax; + + return newDt; +} + + +int +BasicAnalysisBuilder::analyzeVariable(int numSteps, double dT, double dtMin, double dtMax, int Jd) +{ + + // set some variables + int result = 0; + double totalTimeIncr = numSteps * dT; + double currentTimeIncr = 0.0; + double currentDt = dT; + + // loop until analysis has performed the total time incr requested + while (currentTimeIncr < totalTimeIncr) { + + if (theAnalysisModel->analysisStep(currentDt) < 0) { + opserr << "DirectIntegrationAnalysis::analyze() - the AnalysisModel failed in newStepDomain"; + opserr << " at time " << theDomain->getCurrentTime() << "\n"; + theDomain->revertToLastCommit(); + return -2; + } + + // check if domain has undergone change + int stamp = theDomain->hasDomainChanged(); + if (stamp != domainStamp) { + domainStamp = stamp; + if (this->domainChanged() < 0) { + opserr << "DirectIntegrationAnalysis::analyze() - domainChanged() failed\n"; + return -1; + } + } + + // + // do newStep(), solveCurrentStep() and commit() as in regular + // DirectINtegrationAnalysis - difference is we do not return + // if a failure - we stop the analysis & resize time step if failure + // + + if (theTransientIntegrator->newStep(currentDt) < 0) { + result = -2; + } + + + if (result >= 0) { + result = theAlgorithm->solveCurrentStep(); + if (result < 0) + result = -3; + } + + if (result >= 0) { + result = theTransientIntegrator->commit(); + if (result < 0) + result = -4; + } + + // if the time step was successful increment delta T for the analysis + // otherwise revert the Domain to last committed state & see if can go on + + if (result >= 0) + currentTimeIncr += currentDt; + + else { + + // invoke the revertToLastCommit + theDomain->revertToLastCommit(); + theTransientIntegrator->revertToLastStep(); + + // if last dT was <= min specified the analysis FAILS - return FAILURE + if (currentDt <= dtMin) { + opserr << "VariableTimeStepDirectIntegrationAnalysis::analyze() - "; + opserr << " failed at time " << theDomain->getCurrentTime() << endln; + return result; + } + + + // if still here reset result for next loop + result = 0; + } + + // now we determine a new delta T for next loop + currentDt = determineDt(currentDt, dtMin, dtMax, Jd, theTest); + } + + + return 0; +} + void BasicAnalysisBuilder::set(ConstraintHandler* obj) @@ -550,7 +704,6 @@ BasicAnalysisBuilder::set(LinearSOE* obj, bool free) if (theEigenSOE != nullptr) theEigenSOE->setLinearSOE(*theSOE); - domainStamp = 0; } @@ -613,7 +766,7 @@ BasicAnalysisBuilder::set(ConvergenceTest* obj) void BasicAnalysisBuilder::set(EigenSOE &theNewSOE) { - // invoke the destructor on the old one if not the same! + // destroy the old one if not the same type if (theEigenSOE != nullptr) { if (theEigenSOE->getClassTag() != theNewSOE.getClassTag()) { delete theEigenSOE; @@ -625,10 +778,8 @@ BasicAnalysisBuilder::set(EigenSOE &theNewSOE) theEigenSOE = &theNewSOE; theEigenSOE->setLinks(*theAnalysisModel); theEigenSOE->setLinearSOE(*theSOE); - domainStamp = 0; } - } void @@ -654,7 +805,7 @@ BasicAnalysisBuilder::fillDefaults(BasicAnalysisBuilder::CurrentAnalysis flag) theTest = new CTestNormUnbalance(1.0e-6, 25, ConvergenceTest::PrintFailure); if (theAlgorithm == nullptr) - theAlgorithm = new NewtonRaphson(*theTest); + theAlgorithm = new NewtonRaphson(CURRENT_TANGENT, CURRENT_TANGENT, 0.0, 1.0); if (theHandler == nullptr) { @@ -671,8 +822,7 @@ BasicAnalysisBuilder::fillDefaults(BasicAnalysisBuilder::CurrentAnalysis flag) if (theSOE == nullptr) // TODO: CHANGE TO MORE GENERAL SOE - theSOE = new ProfileSPDLinSOE(*(new ProfileSPDLinDirectSolver())); - + theSOE = new ProfileSPDLinSOE(*(new ProfileSPDLinDirectSolver())); } @@ -702,11 +852,11 @@ BasicAnalysisBuilder::setTransientAnalysis() int BasicAnalysisBuilder::newTransientAnalysis() { - assert(theDomain != nullptr); + assert(theDomain != nullptr); - this->fillDefaults(TRANSIENT_ANALYSIS); + this->fillDefaults(TRANSIENT_ANALYSIS); - return 1; + return 1; } @@ -718,11 +868,11 @@ BasicAnalysisBuilder::newEigenAnalysis(int typeSolver, double shift) if (theHandler == nullptr) theHandler = new TransformationConstraintHandler(); - // this->CurrentAnalysisFlag = TRANSIENT_ANALYSIS; if (this->CurrentAnalysisFlag == EMPTY_ANALYSIS) this->CurrentAnalysisFlag = TRANSIENT_ANALYSIS; - this->fillDefaults(this->CurrentAnalysisFlag); //TRANSIENT_ANALYSIS); - this->setLinks(this->CurrentAnalysisFlag); //TRANSIENT_ANALYSIS); + + this->fillDefaults(this->CurrentAnalysisFlag); + this->setLinks(this->CurrentAnalysisFlag); // create a new eigen system and solver if (theEigenSOE != nullptr) { @@ -754,6 +904,7 @@ BasicAnalysisBuilder::newEigenAnalysis(int typeSolver, double shift) } // theEigenSOE == 0 } + int BasicAnalysisBuilder::eigen(int numMode, bool generalized, bool findSmallest) { @@ -766,7 +917,7 @@ BasicAnalysisBuilder::eigen(int numMode, bool generalized, bool findSmallest) Domain *the_Domain = this->getDomain(); // for parallel processing, want all analysis doing an eigenvalue analysis - result = theAnalysisModel->eigenAnalysis(numMode, generalized, findSmallest); + result = the_Domain->eigenAnalysis(numMode, generalized, findSmallest); int stamp = the_Domain->hasDomainChanged(); @@ -856,8 +1007,8 @@ BasicAnalysisBuilder::eigen(int numMode, bool generalized, bool findSmallest) // Solve for the eigen values & vectors // if (theEigenSOE->solve(numMode, generalized, findSmallest) < 0) { - opserr << G3_WARN_PROMPT << "EigenSOE failed in solve()\n"; - return -4; + opserr << G3_WARN_PROMPT << "EigenSOE failed in solve()\n"; + return -4; } // @@ -881,8 +1032,8 @@ BasicAnalysisBuilder::getDomain() return theDomain; } -EquiSolnAlgo* -BasicAnalysisBuilder::getAlgorithm() +const EquiSolnAlgo* +BasicAnalysisBuilder::getAlgorithm() const { return theAlgorithm; } @@ -894,8 +1045,8 @@ BasicAnalysisBuilder::getStaticIntegrator() } TransientIntegrator* -BasicAnalysisBuilder::getTransientIntegrator() { - +BasicAnalysisBuilder::getTransientIntegrator() +{ return theTransientIntegrator; } @@ -908,12 +1059,55 @@ BasicAnalysisBuilder::getConvergenceTest() int BasicAnalysisBuilder::formUnbalance() { - if (theStaticIntegrator != nullptr) - return theStaticIntegrator->formUnbalance(); + if (theStaticIntegrator != nullptr) + return theStaticIntegrator->formUnbalance(); - else if (theTransientIntegrator != nullptr) - return theTransientIntegrator->formUnbalance(); + else if (theTransientIntegrator != nullptr) + return theTransientIntegrator->formUnbalance(); - return -1; + return -1; +} + + +int +BasicAnalysisBuilder::analyzeGradient() +{ + switch (this->CurrentAnalysisFlag) { + case EMPTY_ANALYSIS: + return -1; + + case STATIC_ANALYSIS: + if (theStaticIntegrator->computeSensitivities() < 0) { + return -2; + } + case TRANSIENT_ANALYSIS: + if (theTransientIntegrator->computeSensitivities() < 0) { + return -2; + } + } + return 0; } +int +BasicAnalysisBuilder::setGradientType(int flag) +{ + switch (this->CurrentAnalysisFlag) { + case EMPTY_ANALYSIS: + return -1; + + case STATIC_ANALYSIS: + if (theStaticIntegrator->setGradientType(flag) < 0) { + return -2; + } + theStaticIntegrator->activateSensitivity(); + break; + + case TRANSIENT_ANALYSIS: + if (theTransientIntegrator->setGradientType(flag) < 0) { + return -2; + } + theTransientIntegrator->activateSensitivity(); + break; + } + return 0; +} \ No newline at end of file diff --git a/SRC/runtime/runtime/BasicAnalysisBuilder.h b/SRC/runtime/runtime/BasicAnalysisBuilder.h index 30187c7469..27da80093f 100644 --- a/SRC/runtime/runtime/BasicAnalysisBuilder.h +++ b/SRC/runtime/runtime/BasicAnalysisBuilder.h @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // BasicAnalysisBuilder is an aggregate class which manages the analysis // objects: // @@ -28,6 +29,7 @@ #define BasicAnalysisBulider_h class Domain; +class BasicModelBuilder; class G3_Table; class ConstraintHandler; class DOF_Numberer; @@ -38,12 +40,11 @@ class EigenSOE; class StaticIntegrator; class TransientIntegrator; class ConvergenceTest; -class VariableTimeStepDirectIntegrationAnalysis; class BasicAnalysisBuilder { public: - BasicAnalysisBuilder(Domain* domain); + BasicAnalysisBuilder(BasicModelBuilder&); ~BasicAnalysisBuilder(); enum CurrentAnalysis { @@ -52,6 +53,12 @@ class BasicAnalysisBuilder TRANSIENT_ANALYSIS }; + enum Perform : int { + Increment = 1<<0, + Iterate = 1<<1, + Commit = 1<<2 + }; + void set(ConstraintHandler* obj); void set(DOF_Numberer* obj); void set(EquiSolnAlgo* obj); @@ -64,6 +71,8 @@ class BasicAnalysisBuilder LinearSOE* getLinearSOE(); Domain* getDomain(); + const BasicModelBuilder& getContext() const { return context; } + int initialize(); int newTransientAnalysis(); @@ -77,25 +86,29 @@ class BasicAnalysisBuilder int formUnbalance(); - VariableTimeStepDirectIntegrationAnalysis* getVariableTimeStepDirectIntegrationAnalysis() { - return theVariableTimeStepTransientAnalysis; - } - - EquiSolnAlgo* getAlgorithm(); + const EquiSolnAlgo* getAlgorithm() const; StaticIntegrator* getStaticIntegrator(); TransientIntegrator* getTransientIntegrator(); + + // for getCTestIter command ConvergenceTest* getConvergenceTest(); int domainChanged(); // Performing analysis - int analyze(int num_steps, double size_steps=0.0); - int analyzeStatic(int num_steps); + int analyze(int num_steps, double size_steps, int flag=Increment|Iterate|Commit); + int analyzeStatic(int num_steps, int flag); int analyzeTransient(int numSteps, double dT); + int analyzeVariable(int numSteps, double dT, double dtMin, double dtMax, int Jd); +private: int analyzeStep(double dT); int analyzeSubLevel(int level, double dT); +public: + int analyzeGradient(); + int setGradientType(int flag); + void wipe(); @@ -105,6 +118,7 @@ class BasicAnalysisBuilder void setLinks(CurrentAnalysis flag = EMPTY_ANALYSIS); void fillDefaults(enum CurrentAnalysis flag); + BasicModelBuilder& context; Domain *theDomain; ConstraintHandler *theHandler; DOF_Numberer *theNumberer; @@ -115,7 +129,6 @@ class BasicAnalysisBuilder StaticIntegrator *theStaticIntegrator; TransientIntegrator *theTransientIntegrator; ConvergenceTest *theTest; - VariableTimeStepDirectIntegrationAnalysis *theVariableTimeStepTransientAnalysis; int domainStamp; int numEigen = 0; diff --git a/SRC/runtime/runtime/BasicModelBuilder.cpp b/SRC/runtime/runtime/BasicModelBuilder.cpp index 7b1ec8f82c..d36ec62a3f 100644 --- a/SRC/runtime/runtime/BasicModelBuilder.cpp +++ b/SRC/runtime/runtime/BasicModelBuilder.cpp @@ -1,13 +1,14 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // -// Description: This file contains the class definition for BasicModelBuilder. -// A BasicModelBuilder adds the commands to create the model for the standard -// models that can be generated using the elements released with the g3 -// framework. +// A BasicModelBuilder stores intermediate "reference" objects like +// materials and sections that are used +// to construct other objects like elements. // // Written: cmp // @@ -32,31 +33,29 @@ #include // For TCL_OK/ERROR -// -// CLASS CONSTRUCTOR & DESTRUCTOR -// + BasicModelBuilder::BasicModelBuilder(Domain &domain, Tcl_Interp *interp, int NDM, int NDF) - : ndm(NDM), ndf(NDF), theInterp(interp), - section_builder_is_set(false), - theDomain(&domain), - tclEnclosingPattern(nullptr), - next_node_load(0), - next_elem_load(0) - + : ndm(NDM), ndf(NDF), theInterp(interp), + section_builder_is_set(false), + theDomain(&domain), + tclEnclosingPattern(nullptr), + next_node_load(0) + // , next_elem_load(0) { - static int ncmd = sizeof(tcl_char_cmds)/sizeof(char_cmd); + using namespace OpenSees; + + static int ncmd = sizeof(ModelBuilderCommands)/sizeof(decltype(ModelBuilderCommands[0])); // CommandTableEntry); Tcl_CreateCommand(interp, "wipe", TclCommand_wipeModel, (ClientData)this, nullptr); for (int i = 0; i < ncmd; i++) Tcl_CreateCommand(interp, - tcl_char_cmds[i].name, - tcl_char_cmds[i].func, + ModelBuilderCommands[i].name, + ModelBuilderCommands[i].func, (ClientData) this, nullptr); - + tclEnclosingPattern = nullptr; - // theTclMultiSupportPattern = 0; Tcl_SetAssocData(interp, "OPS::theTclBuilder", NULL, (ClientData)this); Tcl_SetAssocData(interp, "OPS::theBasicModelBuilder", NULL, (ClientData)this); @@ -74,44 +73,66 @@ BasicModelBuilder::~BasicModelBuilder() // set the pointers to 0 theDomain = nullptr; -//theTclBuilder = nullptr; tclEnclosingPattern = nullptr; - static int ncmd = sizeof(tcl_char_cmds)/sizeof(char_cmd); + using namespace OpenSees; + + static int ncmd = sizeof(ModelBuilderCommands)/sizeof(decltype(ModelBuilderCommands[0])); for (int i = 0; i < ncmd; i++) - Tcl_DeleteCommand(theInterp, tcl_char_cmds[i].name); + Tcl_DeleteCommand(theInterp, ModelBuilderCommands[i].name); } int -BasicModelBuilder::buildFE_Model() {return 0;} +BasicModelBuilder::buildFE_Model() +{ + return 0; +} -int -BasicModelBuilder::getNDM() const {return ndm;} int -BasicModelBuilder::getNDF() const {return ndf;} +BasicModelBuilder::getNDM() const +{ + return ndm; +} -LoadPattern* -BasicModelBuilder::getCurrentLoadPattern() +int +BasicModelBuilder::getNDF() const { - return m_current_load_pattern; + return ndf; } void -BasicModelBuilder::letClobber(bool let_clobber) { +BasicModelBuilder::letClobber(bool let_clobber) +{ no_clobber = !let_clobber; } bool -BasicModelBuilder::canClobber() { +BasicModelBuilder::canClobber() +{ return !no_clobber; } -int BasicModelBuilder::incrNodalLoadTag(){return ++next_node_load;}; -int BasicModelBuilder::decrNodalLoadTag(){return --next_node_load;}; -int BasicModelBuilder::getNodalLoadTag() {return next_node_load;}; +int +BasicModelBuilder::incrNodalLoadTag() +{ + return ++next_node_load; +} + +int +BasicModelBuilder::decrNodalLoadTag() +{ + return --next_node_load; +} + +int +BasicModelBuilder::getNodalLoadTag() +{ + return next_node_load; +} + int BasicModelBuilder::addSP_Constraint(int axisDirn, double axisValue, const ID &fixityCodes, double tol) @@ -177,10 +198,14 @@ BasicModelBuilder::printRegistry(const char *partition, OPS_Stream& stream, int } void* -BasicModelBuilder::getRegistryObject(const char* partition, int tag, int flags) const +BasicModelBuilder::getRegistryObject(const char* type, const char* specialize, int tag, int flags) const { - auto iter = m_registry.find(std::string{partition}); + std::string partition = std::string{type}; + if (specialize) + partition += std::string{specialize}; + + auto iter = m_registry.find(partition); if (iter == m_registry.end()) { if (flags == 0) opserr << "No objects of type \"" << partition @@ -191,7 +216,7 @@ BasicModelBuilder::getRegistryObject(const char* partition, int tag, int flags) auto iter_objs = iter->second.find(tag) ; if (iter_objs == iter->second.end()) { if (flags == 0) - opserr << "No object with tag \"" << tag << "\"in partition \"" + opserr << "No object with tag \"" << tag << "\" in partition \"" << partition << "\"\n"; return nullptr; } @@ -201,10 +226,13 @@ BasicModelBuilder::getRegistryObject(const char* partition, int tag, int flags) } int -BasicModelBuilder::addRegistryObject(const char* partition, int tag, void *obj) +BasicModelBuilder::addRegistryObject(const char* type, const char* specialize, int tag, void *obj) { - // TODO: Change void* obj to TaggedObject* - m_registry[std::string{partition}][tag] = (TaggedObject*)obj; + std::string partition = std::string{type}; + if (specialize) + partition += std::string{specialize}; + + m_registry[partition][tag] = (TaggedObject*)obj; return TCL_OK; } diff --git a/SRC/runtime/runtime/BasicModelBuilder.h b/SRC/runtime/runtime/BasicModelBuilder.h index b30f030631..ad2e48274e 100644 --- a/SRC/runtime/runtime/BasicModelBuilder.h +++ b/SRC/runtime/runtime/BasicModelBuilder.h @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Description: This file contains the class definition for // BasicModelBuilder. A BasicModelBuilder aims to be a threadsafe // alternative to the TclBasicBuilder class. This class adds the commands to @@ -51,28 +52,23 @@ class BasicModelBuilder { int getCurrentSectionBuilder(int&); void setCurrentSectionBuilder(int); - LoadPattern *getCurrentLoadPattern(); LoadPattern* getEnclosingPattern(); int setEnclosingPattern(LoadPattern*); int incrNodalLoadTag(); int decrNodalLoadTag(); int getNodalLoadTag(); - // newCount - // getCount - // // Managing tagged objects // template int addTypedObject(int tag, T* obj) { - return addRegistryObject(typeid(T).name(), tag, obj); + return addRegistryObject(typeid(T).name(), nullptr, tag, obj); } - template int addTaggedObject(T& obj) { + template int addTaggedObject(T& obj) { int tag = obj.getTag(); -// m_registry[typeid(T).name()][tag] = &obj; - return addRegistryObject(typeid(T).name(), tag, &obj); + return addRegistryObject(typeid(T).name(), specialize, tag, &obj); } constexpr static int SilentLookup = 1; @@ -81,11 +77,13 @@ class BasicModelBuilder { return printRegistry(typeid(T).name(), stream, flag); } - template T* getTypedObject(int tag, int flags=0) const { - return (T*)getRegistryObject(typeid(T).name(), tag, flags); + template T* + getTypedObject(int tag, int flags=0) const { + return (T*)getRegistryObject(typeid(T).name(), specialize, tag, flags); } - template int removeObject(int tag, int flags=0) { + template int + removeObject(int tag, int flags=0) { return removeRegistryObject(typeid(T).name(), tag, flags); } @@ -100,15 +98,13 @@ class BasicModelBuilder { int buildFE_Model(); -// +// private: - // find/remove/insert - // TODO: make private - int addRegistryObject(const char*, int tag, void* obj); - void* getRegistryObject(const char*, int tag, int flags) const; + int addRegistryObject(const char*, const char*, int tag, void* obj); + void* getRegistryObject(const char*, const char*, int tag, int flags) const; int removeRegistryObject(const char*, int tag, int flags); int findFreeTag(const char*, int& tag) const; - int printRegistry(const char *, OPS_Stream& stream, int flag) const ; + int printRegistry(const char *, OPS_Stream& stream, int flag) const ; int ndm; // space dimension of the mesh @@ -117,17 +113,14 @@ class BasicModelBuilder { Tcl_Interp *theInterp; Domain *theDomain = nullptr; -//int eleArgStart = 0; int next_node_load = 0; - int next_elem_load = 0; // Options bool no_clobber = true; -// previously extern variables + // previously extern variables LoadPattern *tclEnclosingPattern = nullptr; - LoadPattern* m_current_load_pattern = nullptr; - MultiSupportPattern *theTclMultiSupportPattern = nullptr; +//MultiSupportPattern *theTclMultiSupportPattern = nullptr; bool section_builder_is_set = false; int current_section_builder = 0; diff --git a/SRC/runtime/runtime/CMakeLists.txt b/SRC/runtime/runtime/CMakeLists.txt index 28e1713c69..b4ea5cea8a 100644 --- a/SRC/runtime/runtime/CMakeLists.txt +++ b/SRC/runtime/runtime/CMakeLists.txt @@ -17,7 +17,7 @@ target_sources(OPS_Runtime TclPackageClassBroker.h ) -add_subdirectory(SectionBuilder) -add_subdirectory(Renderer) +add_subdirectory(modeling/section) +add_subdirectory(legacy/Renderer) diff --git a/SRC/runtime/runtime/G3_Runtime.h b/SRC/runtime/runtime/G3_Runtime.h index 115298a059..b9b712b1ba 100644 --- a/SRC/runtime/runtime/G3_Runtime.h +++ b/SRC/runtime/runtime/G3_Runtime.h @@ -1,20 +1,16 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// // // written: cmp // +#pragma once #include -#include -#include -#include - #include -#include - -typedef std::unordered_map> G3_Config; class Domain; class BasicModelBuilder; @@ -24,9 +20,6 @@ class ConstraintHandler; class LinearSOE; class EigenSOE; class DOF_Numberer; -class ConvergenceTest; -class StaticIntegrator; -class TransientIntegrator; class G3_Runtime { @@ -37,25 +30,14 @@ class G3_Runtime { // MODEL BUILDING BasicModelBuilder *m_builder = nullptr; Domain *m_domain = nullptr; - bool model_is_built=false; // ANALYSIS AnalysisModel *m_analysis_model = nullptr; AnalysisModel **m_analysis_model_ptr = &m_analysis_model; - - void *newStaticAnalysis(G3_Config); - void *newTransientAnalysis(G3_Config); - // IO FILE* streams[3] = {stdin,stdout,stderr}; }; -class G3_ParallelRuntime : public G3_Runtime { - bool is_partitioned=false; - int num_subdomains = 0; - bool flag_MPID_SOE = false; -}; - diff --git a/SRC/runtime/runtime/Notes.md b/SRC/runtime/runtime/Notes.md new file mode 100644 index 0000000000..946c67fdc9 --- /dev/null +++ b/SRC/runtime/runtime/Notes.md @@ -0,0 +1,91 @@ + + +- `LibraryBroker` + + +``` + static library = G3_Library( + LibraryBroker(&uniaxial_material_library), + LibraryBroker(&multiaxial_material_library), + ); + +read +parse +build +define +broker +invoke call +create make new +insert save add +delete wipe del +update - +remove wipe clean + read build get + scan + show + load + dump + clear + count + erase + print + + +del +add +get +set +put +log +let +new + +->callObj(tag, task, resp) -> state +->callObj(obj, task, resp) +->makeObj(tag) +->readObj(argc, argv) -> Obj* + +->saveObj(obj) +->wipeObj(tag) + +->pullObj(obj) +->yankObj(obj) + + + static broker = G3_Broker(library); + + T* library->readNew(builder*, argc, argv); + library->makeNew(); + + +newObj(tag) +getObj(argc, argv); +addObj(getObj(argc, argv)); + + + G3_RuntimeBroker(library) + + + + + G3_ModelBuilder() + model_builder->makeNew(inst_tag) + model_builder->tag(X*) + model_builder->readNew(argc, argv); + + + runtime_broker->newEmpty(class_tag); +``` + + + + +ElemRoutine(rt, state, task, argc, argv) + + + + + + + + diff --git a/SRC/runtime/runtime/TclPackageClassBroker.cpp b/SRC/runtime/runtime/TclPackageClassBroker.cpp index 96fbf1770d..a15e0f3884 100644 --- a/SRC/runtime/runtime/TclPackageClassBroker.cpp +++ b/SRC/runtime/runtime/TclPackageClassBroker.cpp @@ -1,14 +1,16 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Purpose: This file contains the class definition for TclPackageClassBroker. // TclPackageClassBroker is is an object broker class that is meant to become // a threadsafe replacement for the BrokerAllClasses class. // All methods are virtual to allow for subclasses; which can be // used by programmers when introducing new subclasses of the main objects. +//===----------------------------------------------------------------------===// // #ifdef _PARALLEL_PROCESSING # include @@ -21,10 +23,9 @@ #include using namespace OpenSees::Hash; using namespace OpenSees::Hash::literals; + #define DISPATCH(symbol) case hasher()(#symbol): return new symbol(); -// -// case hasher()(Truss::class_name): return new Truss(); -// + #include "packages.h" #include @@ -81,8 +82,8 @@ using namespace OpenSees::Hash::literals; #include "ModIMKPeakOriented.h" #include "snap/Clough.h" #include "limitState/LimitStateMaterial.h" -#include "InitStressMaterial.h" -#include "InitStrainMaterial.h" +#include "wrapper/InitStressMaterial.h" +#include "wrapper/InitStrainMaterial.h" #include "Bond_SP01.h" #include "SimpleFractureMaterial.h" #include "ConfinedConcrete01.h" @@ -115,14 +116,12 @@ using namespace OpenSees::Hash::literals; #include "drain/DrainClough1Material.h" #include "drain/DrainClough2Material.h" #include "drain/DrainPinch1Material.h" -#include "HyperbolicGapMaterial.h" +#include "abutment/HyperbolicGapMaterial.h" #include "ImpactMaterial.h" // Sections #include "ElasticSection2d.h" #include "ElasticSection3d.h" -#include "ElasticShearSection2d.h" -#include "ElasticShearSection3d.h" #include "GenericSection1d.h" //#include "GenericSectionNd.h" #include "SectionAggregator.h" @@ -130,7 +129,6 @@ using namespace OpenSees::Hash::literals; #include "FiberSection2d.h" #include "FiberSection3d.h" #include "FiberSectionAsym3d.h" //Xinlong Du -#include "ElasticPlateSection.h" #include "ElasticMembranePlateSection.h" #include "MembranePlateFiberSection.h" #include "Bidirectional.h" @@ -249,15 +247,15 @@ using namespace OpenSees::Hash::literals; #include "Shell/ShellMITC4.h" #include "Shell/ShellMITC9.h" -#include "Shell/ShellDKGQ.h" // Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu -#include "Shell/ShellNLDKGQ.h" // Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu -#include "Shell/ASDShellQ4.h" // Massimo Petracca +#include "Shell/ShellDKGQ.h" +#include "Shell/ShellNLDKGQ.h" +#include "Shell/ASDShellQ4.h" #include "Brick/Brick.h" #include "Brick/BbarBrick.h" #include "Brick/BrickUP.h" #include "Brick/BBarBrickUP.h" #include "Brick/Twenty_Eight_Node_BrickUP.h" -#include "Joint/Joint2D.h" // Arash +#include "Joint/Joint2D.h" #include "Link/TwoNodeLink.h" #include "Link/LinearElasticSpring.h" #include "Link/Inerter.h" @@ -287,10 +285,10 @@ using namespace OpenSees::Hash::literals; #include "Bearing/friction/frictionModel/VelNormalFrcDep.h" -#include "mvlem/MVLEM.h" // Kristijan Kolozvari -#include "mvlem/SFI_MVLEM.h" // Kristijan Kolozvari -#include "mvlem/MVLEM_3D.h" // Kristijan Kolozvari -#include "mvlem/SFI_MVLEM_3D.h" // Kristijan Kolozvari +#include "mvlem/MVLEM.h" +#include "mvlem/SFI_MVLEM.h" +#include "mvlem/MVLEM_3D.h" +#include "mvlem/SFI_MVLEM_3D.h" #include "Boundary/RockingBC.h" @@ -324,7 +322,7 @@ using namespace OpenSees::Hash::literals; #include "quadrature/Frame/MidDistanceBeamIntegration.h" #include "quadrature/Frame/CompositeSimpsonBeamIntegration.h" -// node header files +// Node header files #include "Node.h" #ifdef HEAP_NODE #include "HeapNode.h" @@ -348,11 +346,6 @@ using namespace OpenSees::Hash::literals; #include "VTK_Recorder.h" #include "GmshRecorder.h" -#ifdef _H5DRM -#include "VTKHDF_Recorder.h" -#endif - - // mp_constraint header files #include "MP_Constraint.h" #include "Joint/MP_Joint2D.h" @@ -394,25 +387,15 @@ using namespace OpenSees::Hash::literals; #include "LagrangeConstraintHandler.h" #include "TransformationConstraintHandler.h" -// dof numberer header files -#include "DOF_Numberer.h" -#include "PlainNumberer.h" - -// analysis model header files -#include "AnalysisModel.h" -// equi soln algo header files +// equi soln algo #include "EquiSolnAlgo.h" #include "Linear.h" #include "NewtonRaphson.h" #include "Broyden.h" #include "NewtonLineSearch.h" -#include "KrylovNewton.h" -#include "AcceleratedNewton.h" #include "ModifiedNewton.h" -#include "accelerator/KrylovAccelerator.h" -#include "accelerator/RaphsonAccelerator.h" #include "BisectionLineSearch.h" #include "InitialInterpolatedLineSearch.h" @@ -429,13 +412,8 @@ using namespace OpenSees::Hash::literals; #include "DistributedDisplacementControl.h" #endif #include "LoadControl.h" -// #include "StagedLoadControl.h" #include "TransientIntegrator.h" -#include "AlphaOS.h" -#include "AlphaOS_TP.h" -#include "AlphaOSGeneralized.h" -#include "AlphaOSGeneralized_TP.h" #include "CentralDifference.h" #include "CentralDifferenceAlternative.h" #include "CentralDifferenceNoDamping.h" @@ -460,7 +438,6 @@ using namespace OpenSees::Hash::literals; #include "KRAlphaExplicit.h" #include "KRAlphaExplicit_TP.h" #include "Newmark.h" -// #include "StagedNewmark.h" #include "NewmarkExplicit.h" #include "NewmarkHSFixedNumIter.h" #include "NewmarkHSIncrLimit.h" @@ -541,6 +518,7 @@ using namespace OpenSees::Hash::literals; # include "DistributedDiagonalSOE.h" #endif +using namespace OpenSees; typedef struct uniaxialPackage { int classTag; @@ -621,19 +599,11 @@ TclPackageClassBroker::getNewElement(int classTag) { switch ((std::size_t)classTag) { - DISPATCH(Truss); DISPATCH(Truss2); DISPATCH(TrussSection); - DISPATCH(CorotTruss); DISPATCH(CorotTrussSection); DISPATCH(InertiaTruss); - // case ELE_TAG_ZeroLengthND: - // return new ZeroLengthND(); - - DISPATCH(FourNodeQuadUP); - DISPATCH(FourNodeQuad); - DISPATCH(Tri31); DISPATCH(ElasticBeam2d); DISPATCH(ModElasticBeam2d); DISPATCH(ModElasticBeam3d); @@ -648,6 +618,9 @@ TclPackageClassBroker::getNewElement(int classTag) DISPATCH(MixedBeamColumnAsym3d); // Quads + DISPATCH(FourNodeQuadUP); + DISPATCH(FourNodeQuad); + DISPATCH(Tri31); DISPATCH(EnhancedQuad); DISPATCH(NineNodeMixedQuad); DISPATCH(NineNodeQuad); @@ -666,7 +639,6 @@ TclPackageClassBroker::getNewElement(int classTag) DISPATCH(SSPbrickUP); #endif DISPATCH(PML2D); - DISPATCH(PML3D); // Bricks @@ -681,7 +653,7 @@ TclPackageClassBroker::getNewElement(int classTag) DISPATCH(ShellMITC9); DISPATCH(ShellDKGQ); DISPATCH(ShellNLDKGQ); - DISPATCH(ASDShellQ4); // Massimo Petracca + DISPATCH(ASDShellQ4); #if defined(OPSDEF_Elements_UW) DISPATCH(BeamContact2D); @@ -703,15 +675,15 @@ TclPackageClassBroker::getNewElement(int classTag) - DISPATCH(Joint2D); // Arash + DISPATCH(Joint2D); DISPATCH(TwoNodeLink); DISPATCH(LinearElasticSpring); DISPATCH(Inerter); - DISPATCH(MVLEM); // Kristijan Kolozvari - DISPATCH(SFI_MVLEM); // Kristijan Kolozvari - DISPATCH(MVLEM_3D); // Kristijan Kolozvari - DISPATCH(SFI_MVLEM_3D); // Kristijan Kolozvari + DISPATCH(MVLEM); + DISPATCH(SFI_MVLEM); + DISPATCH(MVLEM_3D); + DISPATCH(SFI_MVLEM_3D); DISPATCH(ElastomericBearingBoucWen2d); @@ -731,7 +703,6 @@ TclPackageClassBroker::getNewElement(int classTag) DISPATCH(SingleFPSimple3d); DISPATCH(TripleFrictionPendulum); - DISPATCH(RockingBC); DISPATCH(ASDEmbeddedNodeElement); DISPATCH(ASDAbsorbingBoundary2D); @@ -771,8 +742,8 @@ TclPackageClassBroker::getNewMP(int classTag) case CNSTRNT_TAG_MP_Constraint: return new MP_Constraint(classTag); - case CNSTRNT_TAG_MP_Joint2D: // Arash - return new MP_Joint2D(); // Arash + case CNSTRNT_TAG_MP_Joint2D: + return new MP_Joint2D(); default: opserr << "TclPackageClassBroker::getNewMP - "; @@ -971,6 +942,7 @@ TclPackageClassBroker::getNewUniaxialMaterial(int classTag) case MAT_TAG_ASD_SMA_3K: return new ASD_SMA_3K(); +// Concrete case MAT_TAG_Concrete01: return new Concrete01(); @@ -988,7 +960,7 @@ TclPackageClassBroker::getNewUniaxialMaterial(int classTag) case MAT_TAG_ConcretewBeta: return new ConcretewBeta(); - +// Steel case MAT_TAG_Steel01: return new Steel01(); @@ -1010,6 +982,7 @@ TclPackageClassBroker::getNewUniaxialMaterial(int classTag) case MAT_TAG_Hardening: return new HardeningMaterial(); +// Other case MAT_TAG_PySimple1: return new PySimple1(); @@ -1174,14 +1147,8 @@ TclPackageClassBroker::getNewSection(int classTag) case SEC_TAG_Elastic3d: return new ElasticSection3d(); - case SEC_TAG_ElasticShear2d: - return new ElasticShearSection2d(); - - case SEC_TAG_ElasticShear3d: - return new ElasticShearSection3d(); - - case SEC_TAG_Generic1d: - return new GenericSection1d(); + // case SEC_TAG_Generic1d: + // return new GenericSection1d(); // case SEC_TAG_GenericNd: // return new GenericSectionNd(); @@ -1201,9 +1168,6 @@ TclPackageClassBroker::getNewSection(int classTag) case SEC_TAG_FiberSectionAsym3d: return new FiberSectionAsym3d(); // Xinlong Du - case SEC_TAG_ElasticPlateSection: - return new ElasticPlateSection(); - case SEC_TAG_ElasticMembranePlateSection: return new ElasticMembranePlateSection(); @@ -1665,13 +1629,6 @@ TclPackageClassBroker::getPtrNewRecorder(int classTag) case RECORDER_TAGS_GmshRecorder: return new GmshRecorder(); -#ifdef _H5DRM - case RECORDER_TAGS_VTKHDF_Recorder(): - return new VTKHDF_Recorder(); -#endif - - - // case RECORDER_TAGS_MPCORecorder: // return new MPCORecorder(); @@ -1716,39 +1673,13 @@ TclPackageClassBroker::getNewConstraintHandler(int classTag) DOF_Numberer * TclPackageClassBroker::getNewNumberer(int classTag) { - switch (classTag) { - case NUMBERER_TAG_DOF_Numberer: - return new DOF_Numberer(); - - case NUMBERER_TAG_PlainNumberer: - return new PlainNumberer(); - -#ifdef _PARALLEL_PROCESSING - case NUMBERER_TAG_ParallelNumberer: - return new ParallelNumberer(); -#endif - - default: - opserr << "TclPackageClassBroker::getNewConstraintHandler - "; - opserr << " - no ConstraintHandler type exists for class tag "; - opserr << classTag << endln; - return 0; - } + return nullptr; } AnalysisModel * TclPackageClassBroker::getNewAnalysisModel(int classTag) { - switch (classTag) { - case AnaMODEL_TAGS_AnalysisModel: - return new AnalysisModel(); - - default: - opserr << "TclPackageClassBroker::getNewAnalysisModel - "; - opserr << " - no AnalysisModel type exists for class tag "; - opserr << classTag << endln; - return 0; - } + return nullptr; } EquiSolnAlgo * @@ -1764,12 +1695,6 @@ TclPackageClassBroker::getNewEquiSolnAlgo(int classTag) case EquiALGORITHM_TAGS_NewtonLineSearch: return new NewtonLineSearch(); - case EquiALGORITHM_TAGS_KrylovNewton: - return new KrylovNewton(); - - case EquiALGORITHM_TAGS_AcceleratedNewton: - return new AcceleratedNewton(); - case EquiALGORITHM_TAGS_ModifiedNewton: return new ModifiedNewton(CURRENT_TANGENT); @@ -1788,12 +1713,6 @@ Accelerator * TclPackageClassBroker::getAccelerator(int classTag) { switch (classTag) { - - case ACCELERATOR_TAGS_Krylov: - return new KrylovAccelerator; - case ACCELERATOR_TAGS_Raphson: - return new RaphsonAccelerator; - default: opserr << "TclPackageClassBroker::getAccelerator - "; opserr << " - no EquiSolnAlgo type exists for class tag "; @@ -1871,17 +1790,14 @@ TransientIntegrator * TclPackageClassBroker::getNewTransientIntegrator(int classTag) { switch (classTag) { - case INTEGRATOR_TAGS_AlphaOS: - return new AlphaOS(); - - case INTEGRATOR_TAGS_AlphaOS_TP: - return new AlphaOS_TP(); - - case INTEGRATOR_TAGS_AlphaOSGeneralized: - return new AlphaOSGeneralized(); - - case INTEGRATOR_TAGS_AlphaOSGeneralized_TP: - return new AlphaOSGeneralized_TP(); + // case INTEGRATOR_TAGS_AlphaOS: + // return new AlphaOS(); + // case INTEGRATOR_TAGS_AlphaOS_TP: + // return new AlphaOS_TP(); + // case INTEGRATOR_TAGS_AlphaOSGeneralized: + // return new AlphaOSGeneralized(); + // case INTEGRATOR_TAGS_AlphaOSGeneralized_TP: + // return new AlphaOSGeneralized_TP(); case INTEGRATOR_TAGS_CentralDifference: return new CentralDifference(); // must recvSelf @@ -1954,10 +1870,7 @@ TclPackageClassBroker::getNewTransientIntegrator(int classTag) case INTEGRATOR_TAGS_Newmark: return new Newmark(); -#if 0 - case INTEGRATOR_TAGS_StagedNewmark: - return new StagedNewmark(); -#endif + case INTEGRATOR_TAGS_NewmarkExplicit: return new NewmarkExplicit(); @@ -1969,10 +1882,7 @@ TclPackageClassBroker::getNewTransientIntegrator(int classTag) case INTEGRATOR_TAGS_NewmarkHSIncrReduct: return new NewmarkHSIncrReduct(); -#if 0 - case INTEGRATOR_TAGS_PFEMIntegrator: - return new PFEMIntegrator(); -#endif + case INTEGRATOR_TAGS_TRBDF2: return new TRBDF2(); @@ -2132,7 +2042,7 @@ TclPackageClassBroker::getPtrNewDDLinearSOE(int classTagSOE, DomainDecompositionAnalysis * TclPackageClassBroker::getNewDomainDecompAnalysis(int classTag, - Subdomain &theSubdomain) + [[maybe_unused]] Subdomain &theSubdomain) { switch (classTag) { //case DomDecompANALYSIS_TAGS_DomainDecompositionAnalysis: diff --git a/SRC/runtime/runtime/TclPackageClassBroker.h b/SRC/runtime/runtime/TclPackageClassBroker.h index f36614949f..2f1d483827 100644 --- a/SRC/runtime/runtime/TclPackageClassBroker.h +++ b/SRC/runtime/runtime/TclPackageClassBroker.h @@ -1,9 +1,10 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara // //===----------------------------------------------------------------------===// -// +// https://xara.so +//===----------------------------------------------------------------------===// // Written: cmp // Revision: A // diff --git a/SRC/runtime/runtime/modeling/section/CMakeLists.txt b/SRC/runtime/runtime/modeling/section/CMakeLists.txt new file mode 100644 index 0000000000..83c09d101c --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/CMakeLists.txt @@ -0,0 +1,14 @@ +#============================================================================== +# +# OpenSees -- Open System For Earthquake Engineering Simulation +# Pacific Earthquake Engineering Research Center +# +#============================================================================== +add_library(OPS_Section_Repres OBJECT) + +target_include_directories(OPS_Section_Repres PUBLIC ${CMAKE_CURRENT_LIST_DIR}) + +add_subdirectory(cell) +add_subdirectory(patch) +add_subdirectory(reinfLayer) + diff --git a/SRC/runtime/runtime/modeling/section/FiberSectionBuilder.h b/SRC/runtime/runtime/modeling/section/FiberSectionBuilder.h new file mode 100644 index 0000000000..dff4c0539f --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/FiberSectionBuilder.h @@ -0,0 +1,150 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// Written: cmp +// +#ifndef FiberSectionBuilder_h +#define FiberSectionBuilder_h +#include +#include +#include +#include +#include +#include + +#include + +// Inherit tagged object so that the model builder can delete +class SectionBuilder: public TaggedObject { +public: + SectionBuilder(int tag) : TaggedObject(tag) {} + + virtual int addFiber(int tag, int mat, double area, + const Vector& cPos) =0; + + virtual int addHFiber(int tag, int mat, double area, const Vector& cPos)=0; + virtual int setWarping(int tag, int field, double w[3]) =0; + + int addPatch(const Patch& patch) { + Cell** cells = patch.getCells(); + const int nc = patch.getNumCells(); + const int mat = patch.getMaterialID(); + Vector cPos(2); + for(int j=0; jgetArea(); + const VectorND<2>& x = cells[j]->getPosition(); + cPos(0) = x(0); + cPos(1) = x(1); + if (this->addFiber(j, mat, area, cPos) < 0) + return -1; + } + return 0; + } + + int addLayer(const ReinfLayer& layer) { + + int numReinfBars = layer.getNumReinfBars(); + std::vector bars = layer.getReinfBars(); + int mat = layer.getMaterialID(); + Vector cPos(2); + for(int j=0; j& x = bars[j].getPosition(); + cPos(0) = x(0); + cPos(1) = x(1); + if (this->addFiber(j, mat, area, cPos) < 0) + return -1; + } + return 0; + } + +}; + +template +class FiberSectionBuilder : public SectionBuilder { +public: + FiberSectionBuilder(BasicModelBuilder& builder_, SecT& section_) + : SectionBuilder(section_.getTag()), builder(builder_), section(section_) {} + + virtual int addHFiber(int tag, int mat, double area, const Vector& cPos); + + int setWarping(int tag, int field, double w[3]) { + // Warping is set using the setParameter interface + + std::string ts = std::to_string(tag); + + for (int i=0; i<3; i++) { + // Dont pass argv/argc in Parameters constructor because it cant + // signal errors that way. + Parameter p(-1, nullptr, nullptr, 0); + + std::string s = std::to_string(w[i]); + std::string v = std::to_string(field*3+i); + const char* argv[] {"warp", ts.c_str(), v.c_str()}; + + if (0 > section.setParameter(argv, 3, p)) + return -1; + + p.update(w[i]); + } + + return 0; + } + + int + addFiber(int tag, int mat, double area, const Vector& cPos) + { + if (area <= 0.0) { + opserr << OpenSees::PromptValueError + << "fiber area <= 0.0 for fiber " << tag << "\n"; + return -1; + } + + MatT * theMaterial = builder.getTypedObject(mat); + if (theMaterial == nullptr) { + opserr << OpenSees::PromptValueError + << "no material with tag " << mat << " for fiber " << tag << "\n"; + return -1; + } + + int id = -1; + if constexpr (ndm==2) { + id = section.addFiber(*theMaterial, area, cPos(0)); + } + else { + id = section.addFiber(*theMaterial, area, cPos(0), cPos(1)); + } + return id; + } + +private: + BasicModelBuilder& builder; + SecT& section; +}; + +template <> int +FiberSectionBuilder<2, UniaxialMaterial, FiberSection2dInt>::addHFiber(int tag, int mat, double area, const Vector& cPos) { + + UniaxialMaterial * theMaterial = builder.getTypedObject(mat); + if (theMaterial == nullptr) { + opserr << OpenSees::PromptValueError + << "no material with tag " << mat << " for fiber " << tag << "\n"; + return -1; + } + + section.addHFiber(*theMaterial, area, cPos(0)); + return 0; +} + +template int +FiberSectionBuilder::addHFiber(int tag, int mat, double area, const Vector& cPos) { + opserr << OpenSees::PromptValueError << "section does not support H fibers\n"; + return -1; +} + +#endif + diff --git a/SRC/runtime/runtime/modeling/section/cell/CMakeLists.txt b/SRC/runtime/runtime/modeling/section/cell/CMakeLists.txt new file mode 100644 index 0000000000..7b45854d29 --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/cell/CMakeLists.txt @@ -0,0 +1,18 @@ +#============================================================================== +# +# OpenSees -- Open System For Earthquake Engineering Simulation +# Pacific Earthquake Engineering Research Center +# +#============================================================================== + +target_sources(OPS_Section_Repres + PRIVATE + CircSectionCell.cpp + QuadCell.cpp + PUBLIC + Cell.h + CircSectionCell.h + QuadCell.h +) +target_include_directories(OPS_Section_Repres PUBLIC ${CMAKE_CURRENT_LIST_DIR}) + diff --git a/SRC/runtime/runtime/modeling/section/cell/Cell.h b/SRC/runtime/runtime/modeling/section/cell/Cell.h new file mode 100644 index 0000000000..6211cdb640 --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/cell/Cell.h @@ -0,0 +1,51 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// File: Cell.h +// +// Written by Remo M. de Souza +// December 1998 + +#ifndef Cell_h +#define Cell_h +#include + +using OpenSees::VectorND; +class Cell { +public: + Cell() : area(0.0) {} + Cell(int mat, double area, const VectorND<2>& loc) : area(area), location(loc) + { + } + // reinforcing bar inquiring functions + + double getArea() const {return area;}; + double getdValue() const {return 0.0;}; + const VectorND<2>& getPosition() const {return location;}; + int getMaterial() const {return matID;}; + +protected: + double area; + int matID; + VectorND<2> location; +private: +}; + +#endif diff --git a/SRC/runtime/runtime/modeling/section/cell/CircSectionCell.cpp b/SRC/runtime/runtime/modeling/section/cell/CircSectionCell.cpp new file mode 100644 index 0000000000..eeb2c0e198 --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/cell/CircSectionCell.cpp @@ -0,0 +1,46 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// Written: fmk +// March 2014 + +#include +#include +#include +#include + +#include + +CircSectionCell::CircSectionCell(double r1, double r2, double alpha, double theta, double offsetX, + double offsetY) +{ + + double a = alpha / 2.0; + double At = a * r2 * r2; + double ct = 2.0 * r2 * sin(a) / (3.0 * a); + double A1 = a * r1 * r1; + double c1 = 2.0 * r1 * sin(a) / (3.0 * a); + + area = At - A1; + double c = (At * ct - A1 * c1) / area; + + location[0] = std::cos(theta) * c + offsetX; + location[1] = std::sin(theta) * c + offsetY; +} \ No newline at end of file diff --git a/SRC/runtime/runtime/modeling/section/cell/CircSectionCell.h b/SRC/runtime/runtime/modeling/section/cell/CircSectionCell.h new file mode 100644 index 0000000000..84e9616963 --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/cell/CircSectionCell.h @@ -0,0 +1,38 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +#ifndef CircSectionCell_h +#define CircSectionCell_h + +#include +#include + +class Matrix; +class Vector; + +class CircSectionCell : public Cell { +public: + CircSectionCell(double r2, double r1, double alpha, double theta, double centerX, double centerY); + +protected: +private: +}; + +#endif diff --git a/SRC/runtime/runtime/modeling/section/cell/QuadCell.cpp b/SRC/runtime/runtime/modeling/section/cell/QuadCell.cpp new file mode 100644 index 0000000000..bc24a9047b --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/cell/QuadCell.cpp @@ -0,0 +1,92 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// File: QuadCell.C +// Written by Remo M. de Souza +// December 1998 +// +#include +#include +#include +using OpenSees::MatrixND; +using OpenSees::VectorND; +// QuadCell::QuadCell() : vertCoord{}, location{} {} + +QuadCell::QuadCell(const MatrixND<4,2>& vertCoord) + //: vertCoord(vertexCoords) +{ + + // double x0 = vertCoord(0, 0); + // double y0 = vertCoord(0, 1); + // double x1 = vertCoord(1, 0); + // double y1 = vertCoord(1, 1); + // double x2 = vertCoord(2, 0); + // double y2 = vertCoord(2, 1); + // double x3 = vertCoord(3, 0); + // double y3 = vertCoord(3, 1); + + // double area = ((x2 - x1) * (y0 - y1) - (x0 - x1) * (y2 - y1) + (x0 - x3) * (y2 - y3) - + // (x2 - x3) * (y0 - y3)) / + // 2.0; + + + area = 0; + + for (int i = 0; i < 4; i++) { + int i1 = (i + 1) % 4; + double yi = vertCoord(i, 0); + double zi = vertCoord(i, 1); + double yi1 = vertCoord(i1, 0); + double zi1 = vertCoord(i1, 1); + + area += (zi1 - zi) * (yi1 + yi); + } + area /= 2.0; + + // + // centroid + // + + double CGy = 0.0, CGz = 0.0; + + for (int i = 0; i < 4; i++) { + int i1 = (i + 1) % 4; + + double yi = vertCoord(i, 0); + double zi = vertCoord(i, 1); + double yi1 = vertCoord(i1, 0); + double zi1 = vertCoord(i1, 1); + + double dyi = yi1 - yi; + double dzi = zi1 - zi; + + double integ = yi * zi + (yi * dzi + zi * dyi) / 2.0 + dyi * dzi / 3.0; + + CGy -= dyi * integ; + CGz += dzi * integ; + } + + CGy /= area; + CGz /= area; + + location[0] = CGy; + location[1] = CGz; + +} diff --git a/SRC/runtime/runtime/modeling/section/cell/QuadCell.h b/SRC/runtime/runtime/modeling/section/cell/QuadCell.h new file mode 100644 index 0000000000..59cbbdb8b3 --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/cell/QuadCell.h @@ -0,0 +1,45 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// File: QuadCell.h +// +// Written by Remo M. de Souza +// December 1998 + +#ifndef QuadCell_h +#define QuadCell_h + +#include +#include +#include + +using OpenSees::MatrixND; +using OpenSees::VectorND; + + +class QuadCell : public Cell { +public: + QuadCell(const MatrixND<4,2>& vertexCoords); + +protected: +private: +}; + +#endif diff --git a/SRC/runtime/runtime/modeling/section/patch/CMakeLists.txt b/SRC/runtime/runtime/modeling/section/patch/CMakeLists.txt new file mode 100644 index 0000000000..280891a8c7 --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/patch/CMakeLists.txt @@ -0,0 +1,18 @@ +#============================================================================== +# +# OpenSees -- Open System For Earthquake Engineering Simulation +# Pacific Earthquake Engineering Research Center +# +#============================================================================== + +target_sources(OPS_Section_Repres + PRIVATE + CircPatch.cpp + QuadPatch.cpp + PUBLIC + CircPatch.h + Patch.h + QuadPatch.h +) +target_include_directories(OPS_Section_Repres PUBLIC ${CMAKE_CURRENT_LIST_DIR}) + diff --git a/SRC/runtime/runtime/modeling/section/patch/CircPatch.cpp b/SRC/runtime/runtime/modeling/section/patch/CircPatch.cpp new file mode 100644 index 0000000000..5a97ae4921 --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/patch/CircPatch.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// Adapted from CircPatch.C +// Written by Remo M. de Souza +// December 1998 +// +#include +#include +#include +#include +#include +#include +#include + +CircPatch::CircPatch(int materialID, int numSubdivCircunf, int numSubdivRadial, + const VectorND<2>& centerPosition, double internRadius, double externRadius, + double initialAngle, double finalAngle) + : matID(materialID), + nDivCirc(numSubdivCircunf), + nDivRad(numSubdivRadial), + centerPosit(centerPosition), + intRad(internRadius), + extRad(externRadius), + initAng(initialAngle), + finalAng(finalAngle) +{ +} + +CircPatch::~CircPatch() {} + +int +CircPatch::getMaterialID() const +{ + return matID; +} + +int +CircPatch::getNumCells() const +{ + return nDivCirc * nDivRad; +} + +Cell** +CircPatch::getCells() const +{ + double pi = acos(-1.0); + double deltaRad, deltaTheta; + double initAngRadians, finalAngRadians; + double theta_i, theta_i1; + Matrix cellVertCoord(4, 2); + + int numCells; + Cell** cells; + + if (nDivRad > 0 && nDivCirc > 0) { + numCells = this->getNumCells(); + + cells = new Cell*[numCells]; + + initAngRadians = pi * initAng / 180.0; + finalAngRadians = pi * finalAng / 180.0; + + deltaRad = (extRad - intRad) / nDivRad; + deltaTheta = (finalAngRadians - initAngRadians) / nDivCirc; + + int k = 0; + for (int j = 0; j < nDivRad; j++) { + double rad_j = intRad + deltaRad * j; + double rad_j1 = rad_j + deltaRad; + + for (int i = 0; i < nDivCirc; i++) { + + theta_i = initAngRadians + deltaTheta * i; + + theta_i1 = theta_i + deltaTheta / 2.0; + cells[k] = new CircSectionCell(rad_j, rad_j1, deltaTheta, theta_i1, centerPosit(0), centerPosit(1)); + + k++; + } + } + } else + return 0; + + return cells; +} diff --git a/SRC/runtime/runtime/modeling/section/patch/CircPatch.h b/SRC/runtime/runtime/modeling/section/patch/CircPatch.h new file mode 100644 index 0000000000..28936e077d --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/patch/CircPatch.h @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// OpenSees - Open System for Earthquake Engineering Simulation +// +//===----------------------------------------------------------------------===// +// +// Adapted from CircPatch.h +// Written by Remo M. de Souza +// December 1998 +// +#ifndef CircPatch_h +#define CircPatch_h + +#include +#include +#include +using OpenSees::VectorND; + +class Cell; +class Matrix; + +class CircPatch : public Patch { +public: + CircPatch(int material, + int numSubdivCircunf, int numSubdivRadial, + const VectorND<2>& centerPosition, + double internRadius, double externRadius, + double initialAngle, double finalAngle); + + ~CircPatch(); + + int getMaterialID() const; + int getNumCells() const; + Cell** getCells() const; + +protected: +private: + int matID; + int nDivCirc, nDivRad; + const VectorND<2> centerPosit; + double intRad, extRad; + double initAng, finalAng; +}; + +#endif diff --git a/SRC/runtime/runtime/modeling/section/patch/Patch.h b/SRC/runtime/runtime/modeling/section/patch/Patch.h new file mode 100644 index 0000000000..f20b751702 --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/patch/Patch.h @@ -0,0 +1,29 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ****************************************************************** */ +// +// File: Patch.h +// Written by Remo M. de Souza +// December 1998 +// +#ifndef Patch_h +#define Patch_h +class Cell; +class OPS_Stream; + +class Patch { +public: + + // inquiring functions + + virtual int getMaterialID() const = 0; + virtual int getNumCells() const = 0; + virtual Cell** getCells() const = 0; + +protected: +private: +}; + +#endif diff --git a/SRC/runtime/runtime/modeling/section/patch/QuadPatch.cpp b/SRC/runtime/runtime/modeling/section/patch/QuadPatch.cpp new file mode 100644 index 0000000000..605aa3fc22 --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/patch/QuadPatch.cpp @@ -0,0 +1,120 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// File: QuadPatch.C +// Written by Remo M. de Souza +// December 1998 +// +#include +#include +#include +#include +#include +#include +#include +#include + +using OpenSees::VectorND; + +QuadPatch::QuadPatch(int materialID, int numSubdivIJ, int numSubdivJK, + const MatrixND<4,2>& vertexCoords) + : matID(materialID), nDivIJ(numSubdivIJ), nDivJK(numSubdivJK), vertCoord(vertexCoords) + +{ +} + +QuadPatch::~QuadPatch() {} + +int +QuadPatch::getMaterialID() const +{ + return matID; +} + +int +QuadPatch::getNumCells() const +{ + return nDivIJ * nDivJK; +} + +Cell** +QuadPatch::getCells() const +{ + VectorND<4> N; + double xi, eta; + int numCells; + Cell** cells; + + if (nDivIJ > 0 && nDivJK > 0) { + numCells = this->getNumCells(); + + cells = new Cell*[numCells]; + + if (!cells) + return 0; + + double deltaXi = 2.0 / nDivIJ; + double deltaEta = 2.0 / nDivJK; + + int k = 0; + for (int j = 0; j < nDivJK; j++) + for (int i = 0; i < nDivIJ; i++) { + // compute natural coordinates + + MatrixND<4,2> cellVertCoord; + cellVertCoord(0, 0) = -1.0 + deltaXi * i; + cellVertCoord(0, 1) = -1.0 + deltaEta * j; + cellVertCoord(1, 0) = -1.0 + deltaXi * (i + 1); + cellVertCoord(1, 1) = cellVertCoord(0, 1); + cellVertCoord(2, 0) = cellVertCoord(1, 0); + cellVertCoord(2, 1) = -1.0 + deltaEta * (j + 1); + cellVertCoord(3, 0) = cellVertCoord(0, 0); + cellVertCoord(3, 1) = cellVertCoord(2, 1); + + // map to cartesian coordinates using bilinear + // shape functions + + for (int r = 0; r < 4; r++) { + xi = cellVertCoord(r, 0); + eta = cellVertCoord(r, 1); + + N(0) = (1.0 - xi) * (1.0 - eta) / 4.0; + N(1) = (1.0 + xi) * (1.0 - eta) / 4.0; + N(2) = (1.0 + xi) * (1.0 + eta) / 4.0; + N(3) = (1.0 - xi) * (1.0 + eta) / 4.0; + + cellVertCoord(r, 0) = 0.0; + cellVertCoord(r, 1) = 0.0; + + for (int s = 0; s < 4; s++) { + cellVertCoord(r, 0) += N(s) * vertCoord(s, 0); + cellVertCoord(r, 1) += N(s) * vertCoord(s, 1); + } + } + + cells[k] = new QuadCell(cellVertCoord); + k++; + } + } else + return nullptr; + + return cells; +} + diff --git a/SRC/runtime/runtime/modeling/section/patch/QuadPatch.h b/SRC/runtime/runtime/modeling/section/patch/QuadPatch.h new file mode 100644 index 0000000000..96b35a2240 --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/patch/QuadPatch.h @@ -0,0 +1,54 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// File: QuadPatch.h +// Written by Remo M. de Souza +// December 1998 +// +#ifndef QuadPatch_h +#define QuadPatch_h + +#include +#include +#include + +class Cell; +class Matrix; +using OpenSees::MatrixND; + +class QuadPatch : public Patch { +public: + QuadPatch(); + QuadPatch(int materialID, int numSubdivIJ, int numSubdivJK, const MatrixND<4,2>& vertexCoords); + + ~QuadPatch(); + + int getMaterialID() const; + int getNumCells() const; + Cell** getCells() const; + +protected: +private: + int matID; + int nDivIJ, nDivJK; + MatrixND<4,2> vertCoord; +}; + +#endif diff --git a/SRC/runtime/runtime/modeling/section/reinfLayer/CMakeLists.txt b/SRC/runtime/runtime/modeling/section/reinfLayer/CMakeLists.txt new file mode 100644 index 0000000000..4b7b1faca7 --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/reinfLayer/CMakeLists.txt @@ -0,0 +1,18 @@ +#============================================================================== +# +# OpenSees -- Open System For Earthquake Engineering Simulation +# Pacific Earthquake Engineering Research Center +# +#============================================================================== + +target_sources(OPS_Section_Repres + PRIVATE + CircReinfLayer.cpp + StraightReinfLayer.cpp + PUBLIC + CircReinfLayer.h + ReinfLayer.h + StraightReinfLayer.h +) +target_include_directories(OPS_Section_Repres PUBLIC ${CMAKE_CURRENT_LIST_DIR}) + diff --git a/SRC/runtime/runtime/modeling/section/reinfLayer/CircReinfLayer.cpp b/SRC/runtime/runtime/modeling/section/reinfLayer/CircReinfLayer.cpp new file mode 100644 index 0000000000..097acef42d --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/reinfLayer/CircReinfLayer.cpp @@ -0,0 +1,98 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// File: CircReinfLayer.C +// Written by Remo M. de Souza +// December 1998 + +#include +#include +#include +#include +#include + +#include +#include + + + +CircReinfLayer::CircReinfLayer(int material, int numReinfBars, double area, + const VectorND<2>& centerPosition, double arcRadius, double initialAngle, + double finalAngle) + : ReinfLayer(material, area), + nReinfBars(numReinfBars), + centerPosit(centerPosition), + arcRad(arcRadius), + initAng(initialAngle), + finalAng(finalAngle) +{ +} + +CircReinfLayer::CircReinfLayer(int material, int numReinfBars, double area, + const VectorND<2>& centerPosition, double radius) + : ReinfLayer(material, area), + nReinfBars(numReinfBars), + centerPosit(centerPosition), + arcRad(radius), + initAng(0.0), + finalAng(0.0) +{ + // Figure out final angle so that complete circle does not put + // two bars at the same location + if (nReinfBars > 0) + finalAng = 360.0 - 360.0 / nReinfBars; +} + +int +CircReinfLayer::getNumReinfBars() const +{ + return nReinfBars; +} + +std::vector +CircReinfLayer::getReinfBars() const +{ + std::vector bars(nReinfBars); + + double pi = acos(-1.0); + + if (nReinfBars > 0) { + double initAngRad = pi * initAng / 180.0; + double finalAngRad = pi * finalAng / 180.0; + + double dtheta; + if (nReinfBars > 1) + dtheta = (finalAngRad - initAngRad) / (nReinfBars - 1); + else + dtheta = 0.0; // Doesn't really matter what this is + + + for (int i = 0; i < nReinfBars; i++) { + double theta = initAngRad + dtheta * i; + VectorND<2> position { + centerPosit(0) + arcRad * cos(theta), + centerPosit(1) + arcRad * sin(theta) + }; + bars[i] = Cell(this->getMaterialID(), this->getCellArea(), position); + } + } + + return bars; +} diff --git a/SRC/runtime/runtime/modeling/section/reinfLayer/CircReinfLayer.h b/SRC/runtime/runtime/modeling/section/reinfLayer/CircReinfLayer.h new file mode 100644 index 0000000000..0a0d227e6e --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/reinfLayer/CircReinfLayer.h @@ -0,0 +1,60 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// File: CircReinfLayer.h +// Written by Remo M. de Souza +// December 1998 + +#ifndef CircReinfLayer_h +#define CircReinfLayer_h + +#include +#include +#include + +using OpenSees::VectorND; + +class CircReinfLayer : public ReinfLayer { +public: + // Constructor for an arc + CircReinfLayer(int material, int n, double area, + const VectorND<2>& center, double radius, + double initialAngle, + double finalAngle); + // Constructor for full circle + CircReinfLayer(int material, int n, double area, + const VectorND<2>& center, double radius); + + virtual ~CircReinfLayer() {}; + + int getNumReinfBars() const; + std::vector getReinfBars() const; + + +protected: +private: + int nReinfBars; + VectorND<2> centerPosit; + double arcRad; + double initAng; + double finalAng; +}; + +#endif diff --git a/SRC/runtime/runtime/modeling/section/reinfLayer/ReinfLayer.h b/SRC/runtime/runtime/modeling/section/reinfLayer/ReinfLayer.h new file mode 100644 index 0000000000..15774c083f --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/reinfLayer/ReinfLayer.h @@ -0,0 +1,52 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// File: ReinfLayer.h +// Written by Remo M. de Souza +// December 1998 +// +#ifndef ReinfLayer_h +#define ReinfLayer_h + +#include +#include + +class ReinfLayer { +public: + ReinfLayer(int material, double area) : material(material), area(area) {} + virtual ~ReinfLayer() {}; + + int getMaterialID() const { + return material; + }; + + virtual int getNumReinfBars() const = 0; + virtual std::vector getReinfBars() const = 0; + +protected: + double getCellArea() const { + return area; + }; +private: + int material; + double area; +}; + +#endif diff --git a/SRC/runtime/runtime/modeling/section/reinfLayer/StraightReinfLayer.cpp b/SRC/runtime/runtime/modeling/section/reinfLayer/StraightReinfLayer.cpp new file mode 100644 index 0000000000..2ed0ac63da --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/reinfLayer/StraightReinfLayer.cpp @@ -0,0 +1,87 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// File: StraightReinfLayer.C +// Written by Remo M. de Souza +// December 1998 +// +#include +#include +#include +#include +#include + +#include +#include + +StraightReinfLayer::StraightReinfLayer(int material, int n, double area, + const VectorND<2>& xi, + const VectorND<2>& xj) + : ReinfLayer(material, area), + nReinfBars(n), + initPosit(xi), + finalPosit(xj) +{ +} + +int +StraightReinfLayer::getNumReinfBars() const +{ + return nReinfBars; +} + +std::vector +StraightReinfLayer::getReinfBars() const +{ + VectorND<2> barPosit; + // ReinfBar* reinfBars; + std::vector bars(nReinfBars); + + if (nReinfBars == 1) { + VectorND<2> location { + barPosit(0) = (initPosit(0) + finalPosit(0)) / 2, + barPosit(1) = (initPosit(1) + finalPosit(1)) / 2 + }; + + // reinfBars = new ReinfBar[1]; + bars[0] = Cell(this->getMaterialID(), this->getCellArea(), location); + + // bars[0].setPosition(barPosit); + // bars[0].setArea(this->area); + } + + else if (nReinfBars > 1) { + double dy = (finalPosit(0) - initPosit(0)) / (nReinfBars - 1); + double dz = (finalPosit(1) - initPosit(1)) / (nReinfBars - 1); + + // reinfBars = new ReinfBar[nReinfBars]; + + for (int i = 0; i < nReinfBars; i++) { + VectorND<2> location { + initPosit(0) + dy * i, + initPosit(1) + dz * i + }; + + bars[i] = Cell(this->getMaterialID(), this->getCellArea(), location); + } + } + + return bars; +} diff --git a/SRC/runtime/runtime/modeling/section/reinfLayer/StraightReinfLayer.h b/SRC/runtime/runtime/modeling/section/reinfLayer/StraightReinfLayer.h new file mode 100644 index 0000000000..f7e847114f --- /dev/null +++ b/SRC/runtime/runtime/modeling/section/reinfLayer/StraightReinfLayer.h @@ -0,0 +1,51 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// File: StraightReinfLayer.h +// Written by Remo M. de Souza +// December 1998 +// +#ifndef StraightReinfLayer_h +#define StraightReinfLayer_h + +#include +#include +#include + +using OpenSees::VectorND; + +class StraightReinfLayer : public ReinfLayer { +public: + StraightReinfLayer(int materialID, int numReinfBars, double reinfBarArea, + const VectorND<2>& initialPosition, const VectorND<2>& finalPosition); + + virtual ~StraightReinfLayer() {}; + + int getNumReinfBars() const; + std::vector getReinfBars() const; + +protected: +private: + int nReinfBars; + VectorND<2> initPosit; + VectorND<2> finalPosit; +}; + +#endif From 5ba61c4a3cce39ccd7851737b724b3b878c9d472 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 28 Aug 2025 21:30:29 -0700 Subject: [PATCH 221/261] update banners --- SRC/runtime/CMakeLists.txt | 2 - SRC/runtime/OpenSeesRT.cpp | 12 +- SRC/runtime/commands/analysis/algorithm.cpp | 10 +- SRC/runtime/commands/analysis/itpack.cpp | 20 +++ SRC/runtime/commands/analysis/solver.cpp | 150 ++++-------------- SRC/runtime/commands/analysis/solver.hpp | 29 ++-- SRC/runtime/commands/domain/domain.cpp | 2 +- SRC/runtime/commands/domain/element.cpp | 2 +- .../commands/domain/loading/element_load.cpp | 10 +- SRC/runtime/commands/domain/recorder.cpp | 3 +- SRC/runtime/commands/modeling/commands.h | 11 +- SRC/runtime/commands/modeling/constraint.cpp | 5 +- SRC/runtime/commands/modeling/element.cpp | 2 +- SRC/runtime/commands/modeling/geomTransf.cpp | 9 +- .../commands/modeling/invoking/invoke.cpp | 2 +- .../modeling/invoking/invoke_section.cpp | 2 +- .../modeling/invoking/invoke_stress.cpp | 2 +- .../modeling/invoking/invoke_uniaxial.cpp | 2 +- .../commands/modeling/material/elastic.cpp | 11 +- .../commands/modeling/material/fedeas.cpp | 14 +- SRC/runtime/commands/modeling/nodes.cpp | 10 +- .../commands/modeling/section/frame.cpp | 38 +++-- SRC/runtime/commands/modeling/uniaxial.hpp | 14 +- .../commands/modeling/utilities/blockND.cpp | 2 +- SRC/runtime/parsing/ArgumentTracker.h | 12 +- SRC/runtime/parsing/InterpreterAPI.cpp | 6 +- SRC/runtime/parsing/Parsing.h | 10 +- SRC/runtime/runtime/BasicAnalysisBuilder.cpp | 2 +- SRC/runtime/runtime/BasicAnalysisBuilder.h | 12 +- SRC/runtime/runtime/BasicModelBuilder.cpp | 38 +++-- SRC/runtime/runtime/TclPackageClassBroker.cpp | 6 +- 31 files changed, 238 insertions(+), 212 deletions(-) create mode 100644 SRC/runtime/commands/analysis/itpack.cpp diff --git a/SRC/runtime/CMakeLists.txt b/SRC/runtime/CMakeLists.txt index a9e9f06592..66b46df859 100644 --- a/SRC/runtime/CMakeLists.txt +++ b/SRC/runtime/CMakeLists.txt @@ -14,8 +14,6 @@ target_compile_definitions(OpenSeesRT PUBLIC USE_TCL_STUBS _TCL85) set_property(TARGET OpenSeesRT PROPERTY POSITION_INDEPENDENT_CODE 1) target_compile_options(OPS_Runtime PRIVATE -# "$<$>:-Wextra>" -# "$<$>:-Wpedantic>" "$<$>:-Wno-unused-parameter>" "$<$:/W3>" "$<$:/bigobj>" diff --git a/SRC/runtime/OpenSeesRT.cpp b/SRC/runtime/OpenSeesRT.cpp index 114d8ed2a5..970418d6c3 100644 --- a/SRC/runtime/OpenSeesRT.cpp +++ b/SRC/runtime/OpenSeesRT.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // This file contains functions that are required by Tcl to load the // OpenSeesRT library. // @@ -14,7 +22,7 @@ // #include #include "runtime/G3_Runtime.h" -#include +#include #include #include #include "commands/strings.cpp" diff --git a/SRC/runtime/commands/analysis/algorithm.cpp b/SRC/runtime/commands/analysis/algorithm.cpp index 00ca755258..acd5a7ccc7 100644 --- a/SRC/runtime/commands/analysis/algorithm.cpp +++ b/SRC/runtime/commands/analysis/algorithm.cpp @@ -1,11 +1,19 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // +// // Description: This file implements commands that allow for construction // and interaction with Algorithm objects. Any command which requires // access to specific Algorithm types (from the standard library) should diff --git a/SRC/runtime/commands/analysis/itpack.cpp b/SRC/runtime/commands/analysis/itpack.cpp new file mode 100644 index 0000000000..5181c5a21a --- /dev/null +++ b/SRC/runtime/commands/analysis/itpack.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +LinearSOE* +TclDispatch_newItpackLinearSOE(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +{ + // now must determine the type of solver to create + // from rest of args + int method = 1; + if (argc == 3) { + if (Tcl_GetInt(interp, argv[2], &method) != TCL_OK) + return nullptr; + } + ItpackLinSolver *theSolver = new ItpackLinSolver(method); + return new ItpackLinSOE(*theSolver); +} + + + diff --git a/SRC/runtime/commands/analysis/solver.cpp b/SRC/runtime/commands/analysis/solver.cpp index 1abd16de83..9c8ce4c40c 100644 --- a/SRC/runtime/commands/analysis/solver.cpp +++ b/SRC/runtime/commands/analysis/solver.cpp @@ -1,12 +1,19 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// -// Description: This file implements commands that configure the linear -// solver. +// +// Description: This file implements commands that configure the linear solver. // #include #include @@ -21,7 +28,6 @@ #include #include #include -// #include "analysis.h" #include "solver.hpp" #include "BasicAnalysisBuilder.h" @@ -34,18 +40,6 @@ #include #include -#ifdef _CUDA -# include -# include -#endif - -#ifdef _CULAS4 -# include -#endif - -#ifdef _CULAS5 -# include -#endif #if defined(_PARALLEL_PROCESSING) // parallel soe & solvers @@ -64,10 +58,6 @@ # include #endif -// TODO: remove -// extern DirectIntegrationAnalysis *theTransientAnalysis; -// extern LinearSOE *theSOE; - LinearSOE* G3Parse_newLinearSOE(ClientData, Tcl_Interp* interp, int, G3_Char **const); @@ -92,6 +82,7 @@ TclCommand_systemSize(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C return TCL_OK; } + int specifySysOfEqnTable(ClientData clientData, Tcl_Interp *interp, int argc, G3_Char ** const argv) { @@ -114,6 +105,7 @@ specifySysOfEqnTable(ClientData clientData, Tcl_Interp *interp, int argc, G3_Cha } + LinearSOE* G3Parse_newLinearSOE(ClientData clientData, Tcl_Interp* interp, Tcl_Size argc, G3_Char ** const argv) @@ -129,9 +121,9 @@ G3Parse_newLinearSOE(ClientData clientData, Tcl_Interp* interp, Tcl_Size argc, if (ctor != soe_table.end()) { return ctor->second.ss(rt, argc, argv); - } -#ifdef XARA_USE_MUMPS + +#if 1 || defined(XARA_USE_MUMPS) else if (strcasecmp(argv[1], "mumps") == 0) { return TclDispatch_newMumpsLinearSOE(clientData, interp, argc, argv); } @@ -139,20 +131,21 @@ G3Parse_newLinearSOE(ClientData clientData, Tcl_Interp* interp, Tcl_Size argc, else if (strcasecmp(argv[1], "Umfpack")==0) { // TODO: if "umfpack" is in solver.hpp, this wont be reached return TclDispatch_newUmfpackLinearSOE(clientData, interp, argc, argv); - } + } + #if 0 else if (strcmp(argv[2],"Thread") == 0) { int blockSize = 4; int numThreads = 1; if (argc == 5) { - if (Tcl_GetInt(interp, argv[3], &blockSize) != TCL_OK) - return nullptr; //TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &numThreads) != TCL_OK) - return nullptr; //TCL_ERROR; - } - return new ProfileSPDLinSOE( - *new ProfileSPDLinDirectThreadSolver(numThreads,blockSize,1.0e-12) - ); + if (Tcl_GetInt(interp, argv[3], &blockSize) != TCL_OK) + return nullptr; //TCL_ERROR; + if (Tcl_GetInt(interp, argv[4], &numThreads) != TCL_OK) + return nullptr; //TCL_ERROR; + } + return new ProfileSPDLinSOE( + *new ProfileSPDLinDirectThreadSolver(numThreads,blockSize,1.0e-12) + ); } #endif @@ -182,7 +175,9 @@ G3Parse_newLinearSOE(ClientData clientData, Tcl_Interp* interp, Tcl_Size argc, #endif else { - opserr << OpenSees::PromptValueError << " system '" << argv[1] << "' is unknown or not installed\n"; + opserr << OpenSees::PromptValueError + << " system '" + << argv[1] << "' is unknown or not installed\n"; return nullptr; } @@ -263,7 +258,7 @@ specifySparseGen(G3_Runtime* rt, int argc, G3_Char ** const argv) count++; } - int permSpec = 0; + int permSpec = 1; int panelSize = 6; int relax = 6; @@ -286,7 +281,9 @@ specifySparseGen(G3_Runtime* rt, int argc, G3_Char ** const argv) char symmetric = 'N'; double drop_tol = 0.0; while (count < argc) { - if (strcmp(argv[count], "s") == 0 || strcmp(argv[count], "symmetric") || + if (strcmp(argv[count], "s") == 0 || + strcmp(argv[count], "symmetric") || + strcmp(argv[count], "-symmetric") || strcmp(argv[count], "-symm")) { symmetric = 'Y'; } @@ -304,7 +301,7 @@ specifySparseGen(G3_Runtime* rt, int argc, G3_Char ** const argv) } -#if 0 // Some misc solvers i play with +#if 0 // Some misc solvers else if (strcmp(argv[2],"Block") == 0) { int blockSize = 4; @@ -353,86 +350,3 @@ else theSolver = new ProfileSPDLinDirectSolver(); #endif // misc solvers - - -#if defined(_CULAS4) || defined(_CULAS5) -// CULA SPARSE -else if ((strcmp(argv[1], "CulaSparse") == 0)) { - double absTol = 1.0e-6; - double relTol = 1e-6; - - int maxInteration = 100000; - - int preCond = 5; // fainv -# ifdef _CULAS4 - preCond = 1; -# endif - int solver = 0; // cg - int count = 2; - int single = 0; - int host = 0; - - while (count < argc) { - - if (strcmp(argv[count], "-rTol") == 0) { - count++; - if (count < argc) - if (Tcl_GetDouble(interp, argv[count], &relTol) != TCL_OK) - return TCL_ERROR; - } else if ((strcmp(argv[count], "-mInt") == 0)) { - count++; - if (count < argc) - if (Tcl_GetInt(interp, argv[count], &maxInteration) != TCL_OK) - return TCL_ERROR; - } else if ((strcmp(argv[count], "-pre") == 0)) { - count++; - if (count < argc) - if ((strcmp(argv[count], "none") == 0)) - preCond = 0; - else if ((strcmp(argv[count], "jacobi") == 0)) - preCond = 1; - else if ((strcmp(argv[count], "blockjacobi") == 0)) - preCond = 2; - else if ((strcmp(argv[count], "ilu0") == 0)) - preCond = 3; - else if ((strcmp(argv[count], "ainv") == 0)) - preCond = 4; - else if ((strcmp(argv[count], "fainv") == 0)) - preCond = 5; - else - return TCL_ERROR; - } else if ((strcmp(argv[count], "-solver") == 0)) { - count++; - if (count < argc) - if ((strcmp(argv[count], "cg") == 0)) - solver = 0; - else if ((strcmp(argv[count], "bicg") == 0)) - solver = 1; - else if ((strcmp(argv[count], "blockstab") == 0)) - solver = 2; - else if ((strcmp(argv[count], "blockstabl") == 0)) - solver = 3; - else if ((strcmp(argv[count], "gmres") == 0)) - solver = 4; - else if ((strcmp(argv[count], "minres") == 0)) - solver = 5; - else - return TCL_ERROR; - } else if ((strcmp(argv[count], "-single") == 0)) { - single = 1; - } else if ((strcmp(argv[count], "-host") == 0)) { - host = 1; - } - count++; - } - -# ifdef _CULAS5 - CulaSparseSolverS5 *theSolver = new CulaSparseSolverS5( - relTol, maxInteration, preCond, solver, single, host); -# else - CulaSparseSolverS4 *theSolver = - new CulaSparseSolverS4(relTol, maxInteration, preCond, solver); -# endif - theSOE = new SparseGenRowLinSOE(*theSolver); -} -#endif diff --git a/SRC/runtime/commands/analysis/solver.hpp b/SRC/runtime/commands/analysis/solver.hpp index 6e4c7d4056..352fc3e283 100644 --- a/SRC/runtime/commands/analysis/solver.hpp +++ b/SRC/runtime/commands/analysis/solver.hpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // standard library #include #include @@ -43,22 +51,6 @@ // #include #include #include -#include -#include -#include -#include -// -#ifdef _CUSP -# include -#endif - -#ifdef _CULAS4 -#include -#endif - -#ifdef _CULAS5 -#include -#endif #if 1 || defined(_PETSC) LinearSOE *TclCommand_newPetscSOE(int, TCL_Char**); @@ -94,8 +86,7 @@ typedef LinearSOE*(G3_SysOfEqnSpecifier)(G3_Runtime*, int, G3_Char**); // Specifiers defined in solver.cpp G3_SysOfEqnSpecifier specify_SparseSPD; G3_SysOfEqnSpecifier specifySparseGen; -TclDispatch TclDispatch_newMumpsLinearSOE; -// TclDispatch TclDispatch_newUmfpackLinearSOE; +LinearSOE* TclDispatch_newMumpsLinearSOE(ClientData, Tcl_Interp*, Tcl_Size, const char** const); LinearSOE* TclDispatch_newUmfpackLinearSOE(ClientData, Tcl_Interp*, Tcl_Size, const char** const); LinearSOE* TclDispatch_newItpackLinearSOE(ClientData, Tcl_Interp*, Tcl_Size, const char** const); diff --git a/SRC/runtime/commands/domain/domain.cpp b/SRC/runtime/commands/domain/domain.cpp index abe498f879..30410f21ec 100644 --- a/SRC/runtime/commands/domain/domain.cpp +++ b/SRC/runtime/commands/domain/domain.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include diff --git a/SRC/runtime/commands/domain/element.cpp b/SRC/runtime/commands/domain/element.cpp index f3569c0b60..c4f9fccc0e 100644 --- a/SRC/runtime/commands/domain/element.cpp +++ b/SRC/runtime/commands/domain/element.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include namespace OpenSees { namespace DomainCommands { diff --git a/SRC/runtime/commands/domain/loading/element_load.cpp b/SRC/runtime/commands/domain/loading/element_load.cpp index 1d6d1999c4..28d5d82fc8 100644 --- a/SRC/runtime/commands/domain/loading/element_load.cpp +++ b/SRC/runtime/commands/domain/loading/element_load.cpp @@ -1,11 +1,19 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // +// #include #include #include diff --git a/SRC/runtime/commands/domain/recorder.cpp b/SRC/runtime/commands/domain/recorder.cpp index 38a33681a1..169061c68f 100644 --- a/SRC/runtime/commands/domain/recorder.cpp +++ b/SRC/runtime/commands/domain/recorder.cpp @@ -25,9 +25,8 @@ #define strcmp strcasecmp -// #include #include -#include +#include #include #include #include diff --git a/SRC/runtime/commands/modeling/commands.h b/SRC/runtime/commands/modeling/commands.h index f8f3aa97c8..0a02b98623 100644 --- a/SRC/runtime/commands/modeling/commands.h +++ b/SRC/runtime/commands/modeling/commands.h @@ -1,6 +1,15 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // //===----------------------------------------------------------------------===// // diff --git a/SRC/runtime/commands/modeling/constraint.cpp b/SRC/runtime/commands/modeling/constraint.cpp index 9955d56f2f..436e50564a 100644 --- a/SRC/runtime/commands/modeling/constraint.cpp +++ b/SRC/runtime/commands/modeling/constraint.cpp @@ -350,7 +350,8 @@ TclCommand_addSP(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, // check number of arguments if (argc < 4) { - opserr << OpenSees::PromptValueError << "bad command - want: sp nodeId dofID value"; + opserr << OpenSees::PromptValueError + << "bad command - want: sp nodeId dofID value"; return TCL_ERROR; } @@ -361,7 +362,7 @@ TclCommand_addSP(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, opserr << OpenSees::PromptValueError << "invalid nodeId: " << argv[1] << " - sp nodeId dofID value\n"; return TCL_ERROR; } - if (Tcl_GetInt(interp, argv[2], &dofId) != TCL_OK) { + if (Tcl_GetInt(interp, argv[2], &dofId) != TCL_OK || dofId < 1) { opserr << OpenSees::PromptValueError << "invalid dofId: " << argv[2] << " - sp "; opserr << nodeId << " dofID value\n"; return TCL_ERROR; diff --git a/SRC/runtime/commands/modeling/element.cpp b/SRC/runtime/commands/modeling/element.cpp index 13c37dd028..2283f6d61f 100644 --- a/SRC/runtime/commands/modeling/element.cpp +++ b/SRC/runtime/commands/modeling/element.cpp @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include #include diff --git a/SRC/runtime/commands/modeling/geomTransf.cpp b/SRC/runtime/commands/modeling/geomTransf.cpp index f05a91fc33..c437af44b8 100644 --- a/SRC/runtime/commands/modeling/geomTransf.cpp +++ b/SRC/runtime/commands/modeling/geomTransf.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Description: Geometric transformation command diff --git a/SRC/runtime/commands/modeling/invoking/invoke.cpp b/SRC/runtime/commands/modeling/invoking/invoke.cpp index 6f5a8d9b93..0ec4f4289d 100644 --- a/SRC/runtime/commands/modeling/invoking/invoke.cpp +++ b/SRC/runtime/commands/modeling/invoking/invoke.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include Tcl_CmdProc TclCommand_useUniaxialMaterial; Tcl_CmdProc TclCommand_useCrossSection; diff --git a/SRC/runtime/commands/modeling/invoking/invoke_section.cpp b/SRC/runtime/commands/modeling/invoking/invoke_section.cpp index 71c690838a..053d2cc53f 100644 --- a/SRC/runtime/commands/modeling/invoking/invoke_section.cpp +++ b/SRC/runtime/commands/modeling/invoking/invoke_section.cpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/SRC/runtime/commands/modeling/invoking/invoke_stress.cpp b/SRC/runtime/commands/modeling/invoking/invoke_stress.cpp index 82dae848b5..6c5360b37a 100644 --- a/SRC/runtime/commands/modeling/invoking/invoke_stress.cpp +++ b/SRC/runtime/commands/modeling/invoking/invoke_stress.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include typedef const char TCL_Char; diff --git a/SRC/runtime/commands/modeling/invoking/invoke_uniaxial.cpp b/SRC/runtime/commands/modeling/invoking/invoke_uniaxial.cpp index 4119addb1d..937d62c96a 100644 --- a/SRC/runtime/commands/modeling/invoking/invoke_uniaxial.cpp +++ b/SRC/runtime/commands/modeling/invoking/invoke_uniaxial.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/SRC/runtime/commands/modeling/material/elastic.cpp b/SRC/runtime/commands/modeling/material/elastic.cpp index b0c71a3abb..66e164eb9b 100644 --- a/SRC/runtime/commands/modeling/material/elastic.cpp +++ b/SRC/runtime/commands/modeling/material/elastic.cpp @@ -1,6 +1,15 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // //===----------------------------------------------------------------------===// // diff --git a/SRC/runtime/commands/modeling/material/fedeas.cpp b/SRC/runtime/commands/modeling/material/fedeas.cpp index 98ba2e8e84..885cc2b010 100644 --- a/SRC/runtime/commands/modeling/material/fedeas.cpp +++ b/SRC/runtime/commands/modeling/material/fedeas.cpp @@ -52,7 +52,7 @@ FedeasConcrParse(ClientData clientData, Tcl_Interp *interp, int tag; double fpc, epsc0, fpcu, epscu; - double rat, ft, Ets; + double rat=0.1, ft=0, Ets=0; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { opserr << "WARNING invalid uniaxialMaterial tag\n"; @@ -69,6 +69,8 @@ FedeasConcrParse(ClientData clientData, Tcl_Interp *interp, opserr << "Invalid value for option " << argv[i-1] << "\n"; return TCL_ERROR; } + if (tracker.contains(Positions::ft)) + ft = 0.1*fpc; tracker.consume(Positions::fpc); } else if ((strcasecmp(argv[i], "-epsc0") == 0) || (strcmp(argv[i], "-ec0") == 0)) { @@ -655,16 +657,16 @@ TclCommand_newFedeasConcrete(ClientData clientData, Tcl_Interp *interp, return FedeasConcrParse(clientData, interp, argc, argv); } - else if ((strcmp(argv[1], "Steel02") == 0) || - (strcmp(argv[1], "Steel2") == 0) || - (strcmp(argv[1], "Steel02Thermal") == 0) || - (strcmp(argv[1], "SteelMP") == 0) + else if ((strcmp(argv[1], "Concrete02") == 0) || + (strcmp(argv[1], "Concrete2") == 0) || + (strcmp(argv[1], "Concrete02Thermal") == 0) ) { // uniaxialMaterial Concrete02 tag? fpc? epsc0? fpcu? epscu? rat? ft? Ets? enum class Positions: int { Tag, - fpc, epsc0, fpcu, epscu, rat, ft, Ets, EndRequired, + fpc, epsc0, fpcu, epscu, EndRequired, + rat, ft, Ets, End }; return FedeasConcrParse(clientData, interp, argc, argv); diff --git a/SRC/runtime/commands/modeling/nodes.cpp b/SRC/runtime/commands/modeling/nodes.cpp index 20cd636168..ede1a660e9 100644 --- a/SRC/runtime/commands/modeling/nodes.cpp +++ b/SRC/runtime/commands/modeling/nodes.cpp @@ -1,11 +1,19 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // +// // Description: This file implements commands that configure Node objects // for an analysis. // diff --git a/SRC/runtime/commands/modeling/section/frame.cpp b/SRC/runtime/commands/modeling/section/frame.cpp index d6f49441f6..14f42ee47d 100644 --- a/SRC/runtime/commands/modeling/section/frame.cpp +++ b/SRC/runtime/commands/modeling/section/frame.cpp @@ -147,6 +147,12 @@ TclCommand_newElasticSectionTemplate(ClientData clientData, Tcl_Interp *interp, opserr << OpenSees::PromptParseError << "invalid area.\n"; return TCL_ERROR; } + + if (tracker.contains(Position::ky)) + consts.Ay = consts.A; // Default to A if Ay is not specified + if (tracker.contains(Position::kz)) + consts.Az = consts.A; // Default to A if Az is not specified + tracker.consume(Position::A); } @@ -158,6 +164,7 @@ TclCommand_newElasticSectionTemplate(ClientData clientData, Tcl_Interp *interp, return TCL_ERROR; } construct_full = true; + tracker.consume(Position::ky); } else if ((strcmp(argv[i], "-shear-z") == 0) || @@ -167,6 +174,7 @@ TclCommand_newElasticSectionTemplate(ClientData clientData, Tcl_Interp *interp, return TCL_ERROR; } construct_full = true; + tracker.consume(Position::kz); } else if ((strcmp(argv[i], "-inertia") == 0) || @@ -230,50 +238,50 @@ TclCommand_newElasticSectionTemplate(ClientData clientData, Tcl_Interp *interp, } construct_full = true; } - else if (strcmp(argv[i], "-Sa")==0) { - if (argc == ++i || Tcl_GetDouble (interp, argv[i], &consts.Sa) != TCL_OK) { - opserr << OpenSees::PromptParseError << "invalid Sa.\n"; - return TCL_ERROR; - } - construct_full = true; - } + // else if (strcmp(argv[i], "-Sa")==0) { + // if (argc == ++i || Tcl_GetDouble (interp, argv[i], &consts.Sa) != TCL_OK) { + // opserr << OpenSees::PromptParseError << "invalid Sa.\n"; + // return TCL_ERROR; + // } + // construct_full = true; + // } else if (strcmp(argv[i], "-Sy")==0) { - if (argc == ++i || Tcl_GetDouble (interp, argv[i], &consts.Sy) != TCL_OK) { + if (argc == ++i || Tcl_GetDouble(interp, argv[i], &consts.Sy) != TCL_OK) { opserr << OpenSees::PromptParseError << "invalid Sy.\n"; return TCL_ERROR; } construct_full = true; } else if (strcmp(argv[i], "-Sz")==0) { - if (argc == ++i || Tcl_GetDouble (interp, argv[i], &consts.Sz) != TCL_OK) { + if (argc == ++i || Tcl_GetDouble(interp, argv[i], &consts.Sz) != TCL_OK) { opserr << OpenSees::PromptParseError << "invalid Sz.\n"; return TCL_ERROR; } construct_full = true; } else if (strcmp(argv[i], "-Rw")==0) { - if (argc == ++i || Tcl_GetDouble (interp, argv[i], &consts.Rw) != TCL_OK) { + if (argc == ++i || Tcl_GetDouble(interp, argv[i], &consts.Rw) != TCL_OK) { opserr << OpenSees::PromptParseError << "invalid Rw.\n"; return TCL_ERROR; } construct_full = true; } else if (strcmp(argv[i], "-Ry")==0) { - if (argc == ++i || Tcl_GetDouble (interp, argv[i], &consts.Ry) != TCL_OK) { + if (argc == ++i || Tcl_GetDouble(interp, argv[i], &consts.Ry) != TCL_OK) { opserr << OpenSees::PromptParseError << "invalid Ry.\n"; return TCL_ERROR; } construct_full = true; } else if (strcmp(argv[i], "-Rz")==0) { - if (argc == ++i || Tcl_GetDouble (interp, argv[i], &consts.Rz) != TCL_OK) { + if (argc == ++i || Tcl_GetDouble(interp, argv[i], &consts.Rz) != TCL_OK) { opserr << OpenSees::PromptParseError << "invalid Rz.\n"; return TCL_ERROR; } construct_full = true; } else if (strcmp(argv[i], "-Cw")==0) { - if (argc == ++i || Tcl_GetDouble (interp, argv[i], &consts.Cw) != TCL_OK) { + if (argc == ++i || Tcl_GetDouble(interp, argv[i], &consts.Cw) != TCL_OK) { opserr << OpenSees::PromptParseError << "invalid Cw.\n"; return TCL_ERROR; } @@ -315,6 +323,10 @@ TclCommand_newElasticSectionTemplate(ClientData clientData, Tcl_Interp *interp, opserr << OpenSees::PromptParseError << "invalid A.\n"; return TCL_ERROR; } else { + if (tracker.contains(Position::ky)) + consts.Ay = consts.A; // Default to A if Ay is not specified + if (tracker.contains(Position::kz)) + consts.Az = consts.A; // Default to A if Az is not specified tracker.increment(); break; } diff --git a/SRC/runtime/commands/modeling/uniaxial.hpp b/SRC/runtime/commands/modeling/uniaxial.hpp index 96567ed98d..2db6a0c4ff 100644 --- a/SRC/runtime/commands/modeling/uniaxial.hpp +++ b/SRC/runtime/commands/modeling/uniaxial.hpp @@ -1,6 +1,15 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // //===----------------------------------------------------------------------===// // @@ -40,7 +49,6 @@ extern OPS_Routine OPS_CableMaterial; extern OPS_Routine OPS_Cast; extern OPS_Routine OPS_CreepMaterial; // Concrete -extern OPS_Routine OPS_Concrete01; extern OPS_Routine OPS_Concrete02; extern OPS_Routine OPS_Concrete02IS; extern OPS_Routine OPS_Concrete02Thermal; @@ -277,7 +285,7 @@ std::unordered_map uniaxial_dispatch { // Concretes {"Concrete01", dispatch }, - {"Concrete02", dispatch }, + {"Concrete02", dispatch }, {"Concrete04", dispatch }, {"Concrete06", dispatch }, {"Concrete07", dispatch }, diff --git a/SRC/runtime/commands/modeling/utilities/blockND.cpp b/SRC/runtime/commands/modeling/utilities/blockND.cpp index 279a329215..e4bb9a46d9 100644 --- a/SRC/runtime/commands/modeling/utilities/blockND.cpp +++ b/SRC/runtime/commands/modeling/utilities/blockND.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include "Block2D.h" #include "Block3D.h" diff --git a/SRC/runtime/parsing/ArgumentTracker.h b/SRC/runtime/parsing/ArgumentTracker.h index e84ab557c9..fe6675022f 100644 --- a/SRC/runtime/parsing/ArgumentTracker.h +++ b/SRC/runtime/parsing/ArgumentTracker.h @@ -1,7 +1,15 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation -// This file is not yet licensed. +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // //===----------------------------------------------------------------------===// // diff --git a/SRC/runtime/parsing/InterpreterAPI.cpp b/SRC/runtime/parsing/InterpreterAPI.cpp index 23be2d02d5..17d3e531db 100644 --- a/SRC/runtime/parsing/InterpreterAPI.cpp +++ b/SRC/runtime/parsing/InterpreterAPI.cpp @@ -15,9 +15,7 @@ #include #include #include -#include -#include -#include +#include #include #include @@ -29,6 +27,8 @@ #include +#include +#include static Tcl_Interp *theInterp = nullptr; static TCL_Char **currentArgv = nullptr; diff --git a/SRC/runtime/parsing/Parsing.h b/SRC/runtime/parsing/Parsing.h index e1d5851240..52ca07b354 100644 --- a/SRC/runtime/parsing/Parsing.h +++ b/SRC/runtime/parsing/Parsing.h @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// #pragma once #include @@ -11,7 +18,6 @@ typedef const char TCL_Char; #endif #ifndef G3_Char -// #define G3_Char const char typedef const char G3_Char; #endif diff --git a/SRC/runtime/runtime/BasicAnalysisBuilder.cpp b/SRC/runtime/runtime/BasicAnalysisBuilder.cpp index c03871607a..34063dafc7 100644 --- a/SRC/runtime/runtime/BasicAnalysisBuilder.cpp +++ b/SRC/runtime/runtime/BasicAnalysisBuilder.cpp @@ -14,7 +14,7 @@ #include "BasicModelBuilder.h" #include "BasicAnalysisBuilder.h" #include -#include +#include // Abstract classes #include #include diff --git a/SRC/runtime/runtime/BasicAnalysisBuilder.h b/SRC/runtime/runtime/BasicAnalysisBuilder.h index 27da80093f..278557a103 100644 --- a/SRC/runtime/runtime/BasicAnalysisBuilder.h +++ b/SRC/runtime/runtime/BasicAnalysisBuilder.h @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// // BasicAnalysisBuilder is an aggregate class which manages the analysis // objects: // diff --git a/SRC/runtime/runtime/BasicModelBuilder.cpp b/SRC/runtime/runtime/BasicModelBuilder.cpp index d36ec62a3f..dd60d69aa5 100644 --- a/SRC/runtime/runtime/BasicModelBuilder.cpp +++ b/SRC/runtime/runtime/BasicModelBuilder.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, Claudio M. Perez +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // A BasicModelBuilder stores intermediate "reference" objects like @@ -34,7 +41,8 @@ #include // For TCL_OK/ERROR -BasicModelBuilder::BasicModelBuilder(Domain &domain, Tcl_Interp *interp, +BasicModelBuilder::BasicModelBuilder(Domain &domain, + Tcl_Interp *interp, int NDM, int NDF) : ndm(NDM), ndf(NDF), theInterp(interp), section_builder_is_set(false), @@ -180,27 +188,26 @@ BasicModelBuilder::getDomain() const int BasicModelBuilder::printRegistry(const char *partition, OPS_Stream& stream, int flag) const { - int count = 0; - auto iter = m_registry.find(partition); - if (iter == m_registry.end()) { - return count; - } + int count = 0; + auto iter = m_registry.find(partition); + if (iter == m_registry.end()) { + return count; + } - for (auto const& [key, val] : iter->second) { - if (count != 0) - stream << ",\n"; + for (auto const& [key, val] : iter->second) { + if (count != 0) + stream << ",\n"; - val->Print(stream, flag); - count++; - } + val->Print(stream, flag); + count++; + } - return count; + return count; } void* BasicModelBuilder::getRegistryObject(const char* type, const char* specialize, int tag, int flags) const { - std::string partition = std::string{type}; if (specialize) partition += std::string{specialize}; @@ -222,7 +229,6 @@ BasicModelBuilder::getRegistryObject(const char* type, const char* specialize, i } return (void*)iter_objs->second; - } int diff --git a/SRC/runtime/runtime/TclPackageClassBroker.cpp b/SRC/runtime/runtime/TclPackageClassBroker.cpp index a15e0f3884..c39d74cdf5 100644 --- a/SRC/runtime/runtime/TclPackageClassBroker.cpp +++ b/SRC/runtime/runtime/TclPackageClassBroker.cpp @@ -1993,10 +1993,6 @@ TclPackageClassBroker::getNewEigenSOE(int classTagSOE) switch (classTagSOE) { - case EigenSOE_TAGS_ArpackSOE: - theSOE = new ArpackSOE(); - return theSOE; - default: opserr << "TclPackageClassBroker::getNewEigenSOE - "; opserr << " - no EigenSOE type exists for class tag "; @@ -2006,7 +2002,7 @@ TclPackageClassBroker::getNewEigenSOE(int classTagSOE) } DomainSolver * -TclPackageClassBroker::getNewDomainSolver(void) +TclPackageClassBroker::getNewDomainSolver() { return lastDomainSolver; } From 179e0fb850ba23e0e2efa7a6c54cbe6148e7a6b0 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 28 Aug 2025 21:37:28 -0700 Subject: [PATCH 222/261] clean unused files --- .../domain/database/TclBerkeleyDB.cpp | 46 ---- .../domain/database/TclDatabaseCommands.cpp | 225 ------------------ .../commands/domain/database/TclMySQL.cpp | 104 -------- .../commands/domain/database/database.cpp | 12 - 4 files changed, 387 deletions(-) delete mode 100644 SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp delete mode 100644 SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp delete mode 100644 SRC/runtime/commands/domain/database/TclMySQL.cpp delete mode 100644 SRC/runtime/commands/domain/database/database.cpp diff --git a/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp b/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp deleted file mode 100644 index 0c20272813..0000000000 --- a/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp +++ /dev/null @@ -1,46 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// -//===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// -// -// Description: This file contains the function invoked when the user invokes -// the MySQL command in the interpreter. -// -// Written: fmk -// -#include -#include -#include -#include - -#include - -#ifdef _USRDLL -#define DllExport _declspec(dllexport) -#else -#define DllExport -#endif - -extern "C" DllExport int -TclCommand_BerkeleyDB(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv, Domain *theDomain, - FEM_ObjectBroker *theBroker, FE_Datastore **theDatabase) -{ - - // delete the old database - if (*theDatabase != 0) - delete (*theDatabase); - - (*theDatabase) = new BerkeleyDbDatastore(argv[2], *theDomain, *theBroker); - - if (*theDatabase == 0) { - opserr << "WARNING database MySql dabaseName? - out of memory\n"; - return TCL_ERROR; - } - - return TCL_OK; -} - diff --git a/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp b/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp deleted file mode 100644 index 0ac2048bed..0000000000 --- a/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -// -// Written: fmk -// Created: 03/00 -// Revision: A -// -// Description: This file contains the function that is invoked -// by the interpreter when the comand 'database' is invoked by the -// user. -// -// What: "@(#) commands.C, revA" - -#include - -#include -#include -#include -#include - -#include -#include - -// known databases -#include - -// linked list of struct for other types of -// databases that can be added dynamically - -#include - -typedef struct databasePackageCommand { - char *funcName; - int (*funcPtr)(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv, Domain *, FEM_ObjectBroker *, - FE_Datastore **); - struct databasePackageCommand *next; -} DatabasePackageCommand; - -// static variables -static DatabasePackageCommand *theDatabasePackageCommands = NULL; -static bool createdDatabaseCommands = false; - -int save(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv); - -int restore(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv); - -extern FE_Datastore *theDatabase; - -int -TclAddDatabase(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, - Domain &theDomain, FEM_ObjectBroker &theBroker) -{ - if (createdDatabaseCommands == false) { - - // create the commands to commit and reset - Tcl_CreateCommand(interp, "save", save, (ClientData)NULL, - (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "restore", restore, (ClientData)NULL, - (Tcl_CmdDeleteProc *)NULL); - - createdDatabaseCommands = true; - } - - // make sure at least one other argument to contain integrator - if (argc < 2) { - opserr << "WARNING need to specify a Database type; valid type File, " - "MySQL, BerkeleyDB \n"; - return TCL_ERROR; - } - - // - // check argv[1] for type of Database, parse in rest of arguments - // needed for the type of Database, create the object and add to Domain - // - - // a File Database - if (strcmp(argv[1], "File") == 0) { - if (argc < 3) { - opserr << "WARNING database File fileName? "; - return TCL_ERROR; - } - - // delete the old database - if (theDatabase != 0) - delete theDatabase; - - theDatabase = new FileDatastore(argv[2], theDomain, theBroker); - // check we instantiated a database .. if not ran out of memory - if (theDatabase == nullptr) { - opserr << "WARNING ran out of memory - database File " << argv[2] - << endln; - return TCL_ERROR; - } - - return TCL_OK; - } else { - - // - // maybe a database package - // - - // try existing loaded packages - - DatabasePackageCommand *dataCommands = theDatabasePackageCommands; - bool found = false; - while (dataCommands != NULL && found == false) { - if (strcmp(argv[1], dataCommands->funcName) == 0) { - int result = (*(dataCommands->funcPtr))( - clientData, interp, argc, argv, &theDomain, &theBroker, &theDatabase); - return result; - } else - dataCommands = dataCommands->next; - } - - // load new package - - void *libHandle; - int (*funcPtr)(ClientData, Tcl_Interp *, int , - TCL_Char ** const argv, Domain *, FEM_ObjectBroker *, - FE_Datastore **); - int databaseNameLength = strlen(argv[1]); - char *tclFuncName = new char[databaseNameLength + 12]; - strcpy(tclFuncName, "TclCommand_"); - strcpy(&tclFuncName[11], argv[1]); - - int res = - getLibraryFunction(argv[1], tclFuncName, &libHandle, (void **)&funcPtr); - - if (res == 0) { - char *databaseName = new char[databaseNameLength + 1]; - strcpy(databaseName, argv[1]); - DatabasePackageCommand *theDataCommand = new DatabasePackageCommand; - theDataCommand->funcPtr = funcPtr; - theDataCommand->funcName = databaseName; - theDataCommand->next = theDatabasePackageCommands; - theDatabasePackageCommands = theDataCommand; - - int result = (*funcPtr)(clientData, interp, argc, argv, &theDomain, - &theBroker, &theDatabase); - return result; - } - } - opserr << "WARNING No database type exists "; - opserr << "for database of type:" << argv[1] << "valid database type File\n"; - - return TCL_ERROR; -} - -int -save(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - - if (theDatabase == nullptr) { - opserr << "WARNING: save - no database has been constructed\n"; - return TCL_OK; - } - - // make sure at least one other argument to contain type of system - if (argc < 2) { - opserr << "WARNING save no commit tag - want save commitTag?"; - return TCL_OK; - } - - // check argv[1] for commitTag - int commitTag; - if (Tcl_GetInt(interp, argv[1], &commitTag) != TCL_OK) { - opserr << "WARNING - save could not read commitTag " << argv[1] << endln; - return TCL_OK; - } - - if (theDatabase->commitState(commitTag) < 0) { - opserr << "WARNING - database failed to commitState \n"; - return TCL_ERROR; - } - - return TCL_OK; -} - -int -restore(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - - if (theDatabase == 0) { - opserr << "WARNING: restore - no database has been constructed\n"; - return TCL_OK; - } - - // make sure at least one other argument to contain type of system - if (argc < 2) { - opserr << "WARNING restore no commit tag - want restore commitTag?"; - return TCL_OK; - } - - // check argv[1] for commitTag - int commitTag; - if (Tcl_GetInt(interp, argv[1], &commitTag) != TCL_OK) { - opserr << "WARNING - restore could not read commitTag " << argv[1] << endln; - return TCL_OK; - } - - if (theDatabase->restoreState(commitTag) < 0) { - opserr << "WARNING - database failed to restoreState \n"; - return TCL_ERROR; - } - - return TCL_OK; -} diff --git a/SRC/runtime/commands/domain/database/TclMySQL.cpp b/SRC/runtime/commands/domain/database/TclMySQL.cpp deleted file mode 100644 index 1dc5c91003..0000000000 --- a/SRC/runtime/commands/domain/database/TclMySQL.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -// -// Written: fmk -// -// Description: This file contains the function invoked when the user invokes -// the MySQL command in the interpreter. -// -// What: "@(#) TclCommand_MySQL.C, revA" - -#include -#include -#include -#include - -#include - -#ifdef _USRDLL -#define DllExport _declspec(dllexport) -#else -#define DllExport -#endif - -extern "C" DllExport int -TclCommand_MySQL(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv, Domain *theDomain, - FEM_ObjectBroker *theBroker, FE_Datastore **theDatabase) -{ - - if (argc < 3) { - opserr << "WARNING database MySql dabaseName? "; - return TCL_ERROR; - } - - // delete the old database - if (*theDatabase != 0) - delete (*theDatabase); - - if (argc == 3) - (*theDatabase) = new MySqlDatastore(argv[2], *theDomain, *theBroker); - else { - const char *database = argv[2]; - const char *host = NULL; - const char *user = NULL; - const char *passwd = NULL; - const char *socket = NULL; - int port = 0; - int clientFlag = 0; - - int counter = 3; - while (counter < argc) { - if (strcmp(argv[counter], "-host") == 0) { - host = argv[counter + 1]; - counter += 2; - } else if (strcmp(argv[counter], "-user") == 0) { - user = argv[counter + 1]; - counter += 2; - } else if (strcmp(argv[counter], "-passwd") == 0) { - passwd = argv[counter + 1]; - counter += 2; - } else if (strcmp(argv[counter], "-socket") == 0) { - socket = argv[counter + 1]; - counter += 2; - } else if (strcmp(argv[counter], "-port") == 0) { - if (Tcl_GetInt(interp, argv[counter + 1], &port) != TCL_OK) - return TCL_ERROR; - counter += 2; - } else if (strcmp(argv[counter], "-clientFlag") == 0) { - if (Tcl_GetInt(interp, argv[counter + 1], &clientFlag) != TCL_OK) - return TCL_ERROR; - counter += 2; - } else { - counter++; - } - } - (*theDatabase) = - new MySqlDatastore(database, host, user, passwd, port, socket, - clientFlag, *theDomain, *theBroker); - } - - if (*theDatabase == 0) { - opserr << "WARNING database MySql dabaseName? - out of memory\n"; - return TCL_ERROR; - } - - return TCL_OK; -} diff --git a/SRC/runtime/commands/domain/database/database.cpp b/SRC/runtime/commands/domain/database/database.cpp deleted file mode 100644 index f09305980f..0000000000 --- a/SRC/runtime/commands/domain/database/database.cpp +++ /dev/null @@ -1,12 +0,0 @@ - -extern int TclAddDatabase(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv, Domain &theDomain, - FEM_ObjectBroker &theBroker); - -int -addDatabase(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - return TclAddDatabase(clientData, interp, argc, argv, theDomain, theBroker); -} - From 44780ca94f9d84414660c69d56e607f3707ff0d9 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 28 Aug 2025 21:52:26 -0700 Subject: [PATCH 223/261] clean up --- SRC/runtime/commands/analysis/solver.cpp | 63 ------------------------ 1 file changed, 63 deletions(-) diff --git a/SRC/runtime/commands/analysis/solver.cpp b/SRC/runtime/commands/analysis/solver.cpp index 9c8ce4c40c..f522416d19 100644 --- a/SRC/runtime/commands/analysis/solver.cpp +++ b/SRC/runtime/commands/analysis/solver.cpp @@ -218,9 +218,6 @@ LinearSOE* specifySparseGen(G3_Runtime* rt, int argc, G3_Char ** const argv) { // SPARSE GENERAL SOE * SOLVER -//if ((strcmp(argv[1], "SparseGeneral") == 0) || -// (strcmp(argv[1], "SuperLU") == 0) || -// (strcmp(argv[1], "SparseGEN") == 0)) Tcl_Interp *interp = G3_getInterpreter(rt); SparseGenColLinSolver *theSolver = nullptr; @@ -267,16 +264,6 @@ specifySparseGen(G3_Runtime* rt, int argc, G3_Char ** const argv) theSolver = new ThreadedSuperLU(np, permSpec, panelSize, relax, thresh); else return nullptr; -// #endif -// -// #ifdef _PARALLEL_PROCESSING -// if (theSolver != 0) -// delete theSolver; -// theSolver = 0; -// -// if (npRow != 0 && npCol != 0) { -// theSolver = new DistributedSuperLU(npRow, npCol); -// } #else char symmetric = 'N'; double drop_tol = 0.0; @@ -300,53 +287,3 @@ specifySparseGen(G3_Runtime* rt, int argc, G3_Char ** const argv) #endif } - -#if 0 // Some misc solvers - -else if (strcmp(argv[2],"Block") == 0) { - int blockSize = 4; - if (argc == 4) { - if (Tcl_GetInt(interp, argv[3], &blockSize) != TCL_OK) - return TCL_ERROR; - } - theSolver = theSolver = new ProfileSPDLinDirectBlockSolver(1.0e-12,blockSize); -} - - - int blockSize = 4; - int numThreads = 1; - if (argc == 5) { - if (Tcl_GetInt(interp, argv[3], &blockSize) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &numThreads) != TCL_OK) - return TCL_ERROR; - } - theSolver = new ProfileSPDLinDirectThreadSolver(numThreads,blockSize,1.0e-12); - - } else if (strcmp(argv[2],"Thread") == 0) { - int blockSize = 4; - int numThreads = 1; - if (argc == 5) { - if (Tcl_GetInt(interp, argv[3], &blockSize) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &numThreads) != TCL_OK) - return TCL_ERROR; - } - theSolver = new ProfileSPDLinDirectThreadSolver(numThreads,blockSize,1.0e-12); -} - -else if (strcmp(argv[2],"Skypack") == 0) { - if (argc == 5) { - int mCols, mRows; - if (Tcl_GetInt(interp, argv[3], &mCols) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &mRows) != TCL_OK) - return TCL_ERROR; - theSolver = new ProfileSPDLinDirectSkypackSolver(mCols, mRows); - } else - theSolver = new ProfileSPDLinDirectSkypackSolver(); -} -else - theSolver = new ProfileSPDLinDirectSolver(); - -#endif // misc solvers From 9db679e88ded3bc94a98bfadde405132c031263c Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Thu, 28 Aug 2025 21:53:26 -0700 Subject: [PATCH 224/261] clean up --- SRC/runtime/commands/analysis/solver.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SRC/runtime/commands/analysis/solver.cpp b/SRC/runtime/commands/analysis/solver.cpp index f522416d19..5d726946be 100644 --- a/SRC/runtime/commands/analysis/solver.cpp +++ b/SRC/runtime/commands/analysis/solver.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. @@ -218,6 +218,9 @@ LinearSOE* specifySparseGen(G3_Runtime* rt, int argc, G3_Char ** const argv) { // SPARSE GENERAL SOE * SOLVER +//if ((strcmp(argv[1], "SparseGeneral") == 0) || +// (strcmp(argv[1], "SuperLU") == 0) || +// (strcmp(argv[1], "SparseGEN") == 0)) Tcl_Interp *interp = G3_getInterpreter(rt); SparseGenColLinSolver *theSolver = nullptr; @@ -280,10 +283,7 @@ specifySparseGen(G3_Runtime* rt, int argc, G3_Char ** const argv) theSolver = new SuperLU(permSpec, drop_tol, panelSize, relax, symmetric); #endif -#ifdef _PARALLEL_PROCESSING - return new DistributedSparseGenColLinSOE(*theSolver); -#else - return new SparseGenColLinSOE(*theSolver); -#endif + return new SparseGenColLinSOE(*theSolver); } + From 7f44327e70bfed14e504fd87d0559e2308b86927 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Sat, 30 Aug 2025 02:57:27 -0700 Subject: [PATCH 225/261] Adding tests/ directory for pytest --- tests/README.md | 29 +++++++++++++++++++++ tests/test_force-beam-column.py | 46 +++++++++++++++++++++++++++++++++ tests/test_particle-dynamics.py | 42 ++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 tests/README.md create mode 100644 tests/test_force-beam-column.py create mode 100644 tests/test_particle-dynamics.py diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000000..9b5cfb2870 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,29 @@ +## Test Scripts + +A directory of verification tests using OpenSeesPy. + +### How to Run + +Run locally with `pytest` + +```console +pytest -v +``` + +### Import Statements + +So that the tests will work with the latest source code on GitHub +Actions, first try a local import, then use the standard pip install if +the local library is not found. + +```python +try: + import opensees as ops +except ModuleNotFoundError: + import openseespy.opensees as ops + +``` + +### Contributing + +Add test scripts to this folder via a PR. diff --git a/tests/test_force-beam-column.py b/tests/test_force-beam-column.py new file mode 100644 index 0000000000..e05a750357 --- /dev/null +++ b/tests/test_force-beam-column.py @@ -0,0 +1,46 @@ +import openseespy.opensees as ops +from math import isclose + +L = 48 +E = 29000 +A = 20 +I = 800 +P = 10 + +def end_loaded_cantilever(): + ops.wipe() + ops.model('basic','-ndm',2,'-ndf',3) + + ops.node(1,0,0); ops.fix(1,1,1,1) + ops.node(2,L,0) + + ops.section('Elastic',1,E,A,I) + ops.beamIntegration('Lobatto',1,1,3) + + ops.geomTransf('Linear',1) + + ops.element('forceBeamColumn',1,1,2,1,1) + + ops.timeSeries('Constant',1) + ops.pattern('Plain',1,1) + ops.load(2,0,P,0) + + ops.analysis('Static','-noWarnings') + ops.analyze(1) + ops.reactions() + +def test_deflection(): + end_loaded_cantilever() + assert isclose(ops.nodeDisp(2,2),P*L**3/(3*E*I)) + +def test_rotation(): + end_loaded_cantilever() + assert isclose(ops.nodeDisp(2,3),P*L**2/(2*E*I)) + +def test_force(): + end_loaded_cantilever() + assert isclose(ops.nodeReaction(1,2),-P) + +def test_moment(): + end_loaded_cantilever() + assert isclose(ops.nodeReaction(1,3),-P*L) diff --git a/tests/test_particle-dynamics.py b/tests/test_particle-dynamics.py new file mode 100644 index 0000000000..2a157522c1 --- /dev/null +++ b/tests/test_particle-dynamics.py @@ -0,0 +1,42 @@ +import openseespy.opensees as ops +from math import isclose + +m = 1.0 +F = 1.0 +t = 1.0 + +a = F/m + +def define_model(): + ops.wipe() + ops.model('basic','-ndm',1,'-ndf',1) + + ops.node(1,0); ops.mass(1,m) + + ops.timeSeries('Linear',1) + ops.pattern('Plain',1,1) + ops.load(1,F) + + ops.integrator('Newmark',0.5,1.0/6) + ops.analysis('Transient','-noWarnings') + Nsteps = 10 + dt = t/Nsteps + ops.analyze(Nsteps,dt) + +def test_acceleration(): + define_model() + + assert isclose(ops.nodeAccel(1,1),a) + +def test_velocity(): + define_model() + + assert isclose(ops.nodeVel(1,1),0.5*a*t) + +def test_displacement(): + define_model() + + assert isclose(ops.nodeDisp(1,1),a*t*t/6) + +if __name__ == '__main__': + test_displacement() From 7a2effff0434932baaae29c54c4ab7d04a215a64 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Sat, 30 Aug 2025 02:59:16 -0700 Subject: [PATCH 226/261] Updating import statement --- tests/test_force-beam-column.py | 5 ++++- tests/test_particle-dynamics.py | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/test_force-beam-column.py b/tests/test_force-beam-column.py index e05a750357..3358507a91 100644 --- a/tests/test_force-beam-column.py +++ b/tests/test_force-beam-column.py @@ -1,4 +1,7 @@ -import openseespy.opensees as ops +try: + import opensees as ops +except ModuleNotFoundError: + import openseespy.opensees as ops from math import isclose L = 48 diff --git a/tests/test_particle-dynamics.py b/tests/test_particle-dynamics.py index 2a157522c1..c742805068 100644 --- a/tests/test_particle-dynamics.py +++ b/tests/test_particle-dynamics.py @@ -1,4 +1,7 @@ -import openseespy.opensees as ops +try: + import opensees as ops +except ModuleNotFoundError: + import openseespy.opensees as ops from math import isclose m = 1.0 From c757e8082d4eb0775344438e74f9129859b7f199 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:21:48 -0700 Subject: [PATCH 227/261] update from xara --- SRC/runtime/OpenSeesRT.cpp | 2 +- SRC/runtime/commands/analysis/algorithm.cpp | 2 +- SRC/runtime/commands/analysis/solver.hpp | 2 +- SRC/runtime/commands/domain/commands.cpp | 8 +- .../domain/database/TclBerkeleyDB.cpp | 46 + .../domain/database/TclDatabaseCommands.cpp | 225 +++ .../commands/domain/database/TclMySQL.cpp | 104 + .../commands/domain/database/database.cpp | 12 + SRC/runtime/commands/domain/element.cpp | 12 +- .../commands/domain/loading/element_load.cpp | 2 +- SRC/runtime/commands/domain/nodes.cpp | 297 +-- SRC/runtime/commands/domain/region.cpp | 12 +- SRC/runtime/commands/interpreter.cpp | 10 +- SRC/runtime/commands/interpreter.h | 14 + SRC/runtime/commands/modeling/Block2D.cpp | 241 --- SRC/runtime/commands/modeling/Block2D.h | 65 - SRC/runtime/commands/modeling/Block3D.cpp | 346 ---- SRC/runtime/commands/modeling/Block3D.h | 69 - SRC/runtime/commands/modeling/blockND.cpp | 438 ----- SRC/runtime/commands/modeling/commands.h | 2 +- SRC/runtime/commands/modeling/constraint.cpp | 2 +- SRC/runtime/commands/modeling/element.cpp | 2 +- .../commands/modeling/element/frames.cpp | 2 +- .../commands/modeling/element/shells.cpp | 2 +- .../commands/modeling/element/truss.cpp | 2 +- SRC/runtime/commands/modeling/geomTransf.cpp | 2 +- SRC/runtime/commands/modeling/material.hpp | 188 -- .../commands/modeling/material/boucwen.cpp | 2 +- .../commands/modeling/material/concrete.cpp | 2 +- .../commands/modeling/material/elastic.cpp | 2 +- .../commands/modeling/material/fedeas.cpp | 2 +- .../commands/modeling/material/isotropy.cpp | 2 +- .../commands/modeling/material/isotropy.h | 2 +- .../commands/modeling/material/material.hpp | 2 +- .../commands/modeling/material/plastic.cpp | 2 +- .../commands/modeling/material/shell.cpp | 2 +- SRC/runtime/commands/modeling/nDMaterial.cpp | 1700 ----------------- SRC/runtime/commands/modeling/nodes.cpp | 3 +- .../commands/modeling/section/PlaneSection.h | 2 +- .../commands/modeling/section/frame.cpp | 2 +- .../commands/modeling/section/plane.cpp | 2 +- .../commands/modeling/section/truss.cpp | 2 +- .../transform/FrameTransformBuilder.hpp | 2 +- SRC/runtime/commands/modeling/uniaxial.hpp | 2 +- SRC/runtime/commands/parallel/mpiMain.cpp | 371 ---- .../commands/parallel/parallel_commands.cpp | 355 ---- SRC/runtime/commands/pragma.cpp | 9 +- SRC/runtime/parsing/ArgumentTracker.h | 2 +- SRC/runtime/parsing/Parsing.h | 2 +- SRC/runtime/runtime/BasicAnalysisBuilder.h | 2 +- SRC/runtime/runtime/BasicModelBuilder.cpp | 2 +- SRC/runtime/runtime/G3_Runtime.cpp | 143 -- SRC/runtime/runtime/MeshModelBuilder.h | 5 - .../runtime/SectionBuilder/CMakeLists.txt | 15 - .../SectionBuilder/FiberSectionBuilder.h | 110 -- .../SectionBuilder/cell/CMakeLists.txt | 19 - .../runtime/SectionBuilder/cell/Cell.h | 59 - .../SectionBuilder/cell/CircSectionCell.cpp | 84 - .../SectionBuilder/cell/CircSectionCell.h | 69 - .../runtime/SectionBuilder/cell/QuadCell.cpp | 170 -- .../runtime/SectionBuilder/cell/QuadCell.h | 75 - .../SectionBuilder/patch/CMakeLists.txt | 19 - .../SectionBuilder/patch/CircPatch.cpp | 180 -- .../runtime/SectionBuilder/patch/CircPatch.h | 65 - .../runtime/SectionBuilder/patch/Patch.h | 58 - .../SectionBuilder/patch/QuadPatch.cpp | 243 --- .../runtime/SectionBuilder/patch/QuadPatch.h | 75 - .../SectionBuilder/reinfBar/ReinfBar.cpp | 97 - .../SectionBuilder/reinfBar/ReinfBar.h | 70 - .../SectionBuilder/reinfLayer/CMakeLists.txt | 19 - .../reinfLayer/CircReinfLayer.cpp | 241 --- .../reinfLayer/CircReinfLayer.h | 103 - .../SectionBuilder/reinfLayer/ReinfLayer.cpp | 38 - .../SectionBuilder/reinfLayer/ReinfLayer.h | 70 - .../reinfLayer/StraightReinfLayer.cpp | 185 -- .../reinfLayer/StraightReinfLayer.h | 82 - .../Renderer}/CMakeLists.txt | 17 +- .../Patch.cpp => legacy/Renderer/ColorMap.h} | 44 +- .../runtime/legacy/Renderer/PlainMap.cpp | 208 ++ .../Cell.cpp => legacy/Renderer/PlainMap.h} | 47 +- .../runtime/legacy/Renderer/Renderer.cpp | 205 ++ .../runtime/legacy/Renderer/Renderer.h | 97 + 82 files changed, 1060 insertions(+), 6437 deletions(-) create mode 100644 SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp create mode 100644 SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp create mode 100644 SRC/runtime/commands/domain/database/TclMySQL.cpp create mode 100644 SRC/runtime/commands/domain/database/database.cpp delete mode 100644 SRC/runtime/commands/modeling/Block2D.cpp delete mode 100644 SRC/runtime/commands/modeling/Block2D.h delete mode 100644 SRC/runtime/commands/modeling/Block3D.cpp delete mode 100644 SRC/runtime/commands/modeling/Block3D.h delete mode 100644 SRC/runtime/commands/modeling/blockND.cpp delete mode 100644 SRC/runtime/commands/modeling/material.hpp delete mode 100644 SRC/runtime/commands/modeling/nDMaterial.cpp delete mode 100644 SRC/runtime/commands/parallel/mpiMain.cpp delete mode 100644 SRC/runtime/commands/parallel/parallel_commands.cpp delete mode 100644 SRC/runtime/runtime/G3_Runtime.cpp delete mode 100644 SRC/runtime/runtime/MeshModelBuilder.h delete mode 100644 SRC/runtime/runtime/SectionBuilder/CMakeLists.txt delete mode 100644 SRC/runtime/runtime/SectionBuilder/FiberSectionBuilder.h delete mode 100644 SRC/runtime/runtime/SectionBuilder/cell/CMakeLists.txt delete mode 100644 SRC/runtime/runtime/SectionBuilder/cell/Cell.h delete mode 100644 SRC/runtime/runtime/SectionBuilder/cell/CircSectionCell.cpp delete mode 100644 SRC/runtime/runtime/SectionBuilder/cell/CircSectionCell.h delete mode 100644 SRC/runtime/runtime/SectionBuilder/cell/QuadCell.cpp delete mode 100644 SRC/runtime/runtime/SectionBuilder/cell/QuadCell.h delete mode 100644 SRC/runtime/runtime/SectionBuilder/patch/CMakeLists.txt delete mode 100644 SRC/runtime/runtime/SectionBuilder/patch/CircPatch.cpp delete mode 100644 SRC/runtime/runtime/SectionBuilder/patch/CircPatch.h delete mode 100644 SRC/runtime/runtime/SectionBuilder/patch/Patch.h delete mode 100644 SRC/runtime/runtime/SectionBuilder/patch/QuadPatch.cpp delete mode 100644 SRC/runtime/runtime/SectionBuilder/patch/QuadPatch.h delete mode 100644 SRC/runtime/runtime/SectionBuilder/reinfBar/ReinfBar.cpp delete mode 100644 SRC/runtime/runtime/SectionBuilder/reinfBar/ReinfBar.h delete mode 100644 SRC/runtime/runtime/SectionBuilder/reinfLayer/CMakeLists.txt delete mode 100644 SRC/runtime/runtime/SectionBuilder/reinfLayer/CircReinfLayer.cpp delete mode 100644 SRC/runtime/runtime/SectionBuilder/reinfLayer/CircReinfLayer.h delete mode 100644 SRC/runtime/runtime/SectionBuilder/reinfLayer/ReinfLayer.cpp delete mode 100644 SRC/runtime/runtime/SectionBuilder/reinfLayer/ReinfLayer.h delete mode 100644 SRC/runtime/runtime/SectionBuilder/reinfLayer/StraightReinfLayer.cpp delete mode 100644 SRC/runtime/runtime/SectionBuilder/reinfLayer/StraightReinfLayer.h rename SRC/runtime/runtime/{SectionBuilder/reinfBar => legacy/Renderer}/CMakeLists.txt (55%) rename SRC/runtime/runtime/{SectionBuilder/patch/Patch.cpp => legacy/Renderer/ColorMap.h} (66%) create mode 100644 SRC/runtime/runtime/legacy/Renderer/PlainMap.cpp rename SRC/runtime/runtime/{SectionBuilder/cell/Cell.cpp => legacy/Renderer/PlainMap.h} (65%) create mode 100644 SRC/runtime/runtime/legacy/Renderer/Renderer.cpp create mode 100644 SRC/runtime/runtime/legacy/Renderer/Renderer.h diff --git a/SRC/runtime/OpenSeesRT.cpp b/SRC/runtime/OpenSeesRT.cpp index 970418d6c3..e020300596 100644 --- a/SRC/runtime/OpenSeesRT.cpp +++ b/SRC/runtime/OpenSeesRT.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/analysis/algorithm.cpp b/SRC/runtime/commands/analysis/algorithm.cpp index acd5a7ccc7..dfc135f8a9 100644 --- a/SRC/runtime/commands/analysis/algorithm.cpp +++ b/SRC/runtime/commands/analysis/algorithm.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/analysis/solver.hpp b/SRC/runtime/commands/analysis/solver.hpp index 352fc3e283..e7e04bfecf 100644 --- a/SRC/runtime/commands/analysis/solver.hpp +++ b/SRC/runtime/commands/analysis/solver.hpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/domain/commands.cpp b/SRC/runtime/commands/domain/commands.cpp index f3a76f2af8..33f993c8d6 100644 --- a/SRC/runtime/commands/domain/commands.cpp +++ b/SRC/runtime/commands/domain/commands.cpp @@ -367,8 +367,8 @@ getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, Tcl_AppendResult(interp, buffer, NULL); } } - - } else if (argc == 2) { + } + else if (argc == 2) { int patternTag; if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { @@ -418,8 +418,6 @@ getEleLoadTags(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, LoadPattern *thePattern; LoadPatternIter &thePatterns = the_domain->getLoadPatterns(); - // char buffer[20]; - Tcl_Obj *result = Tcl_NewListObj(0, nullptr); while ((thePattern = thePatterns()) != nullptr) { @@ -428,8 +426,6 @@ getEleLoadTags(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, while ((theLoad = theEleLoads()) != nullptr) { Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(theLoad->getElementTag())); - // sprintf(buffer, "%d ", theLoad->getElementTag()); - // Tcl_AppendResult(interp, buffer, NULL); } } diff --git a/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp b/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp new file mode 100644 index 0000000000..0c20272813 --- /dev/null +++ b/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// xara +// +//===----------------------------------------------------------------------===// +// https://xara.so +//===----------------------------------------------------------------------===// +// +// Description: This file contains the function invoked when the user invokes +// the MySQL command in the interpreter. +// +// Written: fmk +// +#include +#include +#include +#include + +#include + +#ifdef _USRDLL +#define DllExport _declspec(dllexport) +#else +#define DllExport +#endif + +extern "C" DllExport int +TclCommand_BerkeleyDB(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv, Domain *theDomain, + FEM_ObjectBroker *theBroker, FE_Datastore **theDatabase) +{ + + // delete the old database + if (*theDatabase != 0) + delete (*theDatabase); + + (*theDatabase) = new BerkeleyDbDatastore(argv[2], *theDomain, *theBroker); + + if (*theDatabase == 0) { + opserr << "WARNING database MySql dabaseName? - out of memory\n"; + return TCL_ERROR; + } + + return TCL_OK; +} + diff --git a/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp b/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp new file mode 100644 index 0000000000..0ac2048bed --- /dev/null +++ b/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp @@ -0,0 +1,225 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// Written: fmk +// Created: 03/00 +// Revision: A +// +// Description: This file contains the function that is invoked +// by the interpreter when the comand 'database' is invoked by the +// user. +// +// What: "@(#) commands.C, revA" + +#include + +#include +#include +#include +#include + +#include +#include + +// known databases +#include + +// linked list of struct for other types of +// databases that can be added dynamically + +#include + +typedef struct databasePackageCommand { + char *funcName; + int (*funcPtr)(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv, Domain *, FEM_ObjectBroker *, + FE_Datastore **); + struct databasePackageCommand *next; +} DatabasePackageCommand; + +// static variables +static DatabasePackageCommand *theDatabasePackageCommands = NULL; +static bool createdDatabaseCommands = false; + +int save(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv); + +int restore(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv); + +extern FE_Datastore *theDatabase; + +int +TclAddDatabase(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, + Domain &theDomain, FEM_ObjectBroker &theBroker) +{ + if (createdDatabaseCommands == false) { + + // create the commands to commit and reset + Tcl_CreateCommand(interp, "save", save, (ClientData)NULL, + (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "restore", restore, (ClientData)NULL, + (Tcl_CmdDeleteProc *)NULL); + + createdDatabaseCommands = true; + } + + // make sure at least one other argument to contain integrator + if (argc < 2) { + opserr << "WARNING need to specify a Database type; valid type File, " + "MySQL, BerkeleyDB \n"; + return TCL_ERROR; + } + + // + // check argv[1] for type of Database, parse in rest of arguments + // needed for the type of Database, create the object and add to Domain + // + + // a File Database + if (strcmp(argv[1], "File") == 0) { + if (argc < 3) { + opserr << "WARNING database File fileName? "; + return TCL_ERROR; + } + + // delete the old database + if (theDatabase != 0) + delete theDatabase; + + theDatabase = new FileDatastore(argv[2], theDomain, theBroker); + // check we instantiated a database .. if not ran out of memory + if (theDatabase == nullptr) { + opserr << "WARNING ran out of memory - database File " << argv[2] + << endln; + return TCL_ERROR; + } + + return TCL_OK; + } else { + + // + // maybe a database package + // + + // try existing loaded packages + + DatabasePackageCommand *dataCommands = theDatabasePackageCommands; + bool found = false; + while (dataCommands != NULL && found == false) { + if (strcmp(argv[1], dataCommands->funcName) == 0) { + int result = (*(dataCommands->funcPtr))( + clientData, interp, argc, argv, &theDomain, &theBroker, &theDatabase); + return result; + } else + dataCommands = dataCommands->next; + } + + // load new package + + void *libHandle; + int (*funcPtr)(ClientData, Tcl_Interp *, int , + TCL_Char ** const argv, Domain *, FEM_ObjectBroker *, + FE_Datastore **); + int databaseNameLength = strlen(argv[1]); + char *tclFuncName = new char[databaseNameLength + 12]; + strcpy(tclFuncName, "TclCommand_"); + strcpy(&tclFuncName[11], argv[1]); + + int res = + getLibraryFunction(argv[1], tclFuncName, &libHandle, (void **)&funcPtr); + + if (res == 0) { + char *databaseName = new char[databaseNameLength + 1]; + strcpy(databaseName, argv[1]); + DatabasePackageCommand *theDataCommand = new DatabasePackageCommand; + theDataCommand->funcPtr = funcPtr; + theDataCommand->funcName = databaseName; + theDataCommand->next = theDatabasePackageCommands; + theDatabasePackageCommands = theDataCommand; + + int result = (*funcPtr)(clientData, interp, argc, argv, &theDomain, + &theBroker, &theDatabase); + return result; + } + } + opserr << "WARNING No database type exists "; + opserr << "for database of type:" << argv[1] << "valid database type File\n"; + + return TCL_ERROR; +} + +int +save(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +{ + + if (theDatabase == nullptr) { + opserr << "WARNING: save - no database has been constructed\n"; + return TCL_OK; + } + + // make sure at least one other argument to contain type of system + if (argc < 2) { + opserr << "WARNING save no commit tag - want save commitTag?"; + return TCL_OK; + } + + // check argv[1] for commitTag + int commitTag; + if (Tcl_GetInt(interp, argv[1], &commitTag) != TCL_OK) { + opserr << "WARNING - save could not read commitTag " << argv[1] << endln; + return TCL_OK; + } + + if (theDatabase->commitState(commitTag) < 0) { + opserr << "WARNING - database failed to commitState \n"; + return TCL_ERROR; + } + + return TCL_OK; +} + +int +restore(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) +{ + + if (theDatabase == 0) { + opserr << "WARNING: restore - no database has been constructed\n"; + return TCL_OK; + } + + // make sure at least one other argument to contain type of system + if (argc < 2) { + opserr << "WARNING restore no commit tag - want restore commitTag?"; + return TCL_OK; + } + + // check argv[1] for commitTag + int commitTag; + if (Tcl_GetInt(interp, argv[1], &commitTag) != TCL_OK) { + opserr << "WARNING - restore could not read commitTag " << argv[1] << endln; + return TCL_OK; + } + + if (theDatabase->restoreState(commitTag) < 0) { + opserr << "WARNING - database failed to restoreState \n"; + return TCL_ERROR; + } + + return TCL_OK; +} diff --git a/SRC/runtime/commands/domain/database/TclMySQL.cpp b/SRC/runtime/commands/domain/database/TclMySQL.cpp new file mode 100644 index 0000000000..1dc5c91003 --- /dev/null +++ b/SRC/runtime/commands/domain/database/TclMySQL.cpp @@ -0,0 +1,104 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// Written: fmk +// +// Description: This file contains the function invoked when the user invokes +// the MySQL command in the interpreter. +// +// What: "@(#) TclCommand_MySQL.C, revA" + +#include +#include +#include +#include + +#include + +#ifdef _USRDLL +#define DllExport _declspec(dllexport) +#else +#define DllExport +#endif + +extern "C" DllExport int +TclCommand_MySQL(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv, Domain *theDomain, + FEM_ObjectBroker *theBroker, FE_Datastore **theDatabase) +{ + + if (argc < 3) { + opserr << "WARNING database MySql dabaseName? "; + return TCL_ERROR; + } + + // delete the old database + if (*theDatabase != 0) + delete (*theDatabase); + + if (argc == 3) + (*theDatabase) = new MySqlDatastore(argv[2], *theDomain, *theBroker); + else { + const char *database = argv[2]; + const char *host = NULL; + const char *user = NULL; + const char *passwd = NULL; + const char *socket = NULL; + int port = 0; + int clientFlag = 0; + + int counter = 3; + while (counter < argc) { + if (strcmp(argv[counter], "-host") == 0) { + host = argv[counter + 1]; + counter += 2; + } else if (strcmp(argv[counter], "-user") == 0) { + user = argv[counter + 1]; + counter += 2; + } else if (strcmp(argv[counter], "-passwd") == 0) { + passwd = argv[counter + 1]; + counter += 2; + } else if (strcmp(argv[counter], "-socket") == 0) { + socket = argv[counter + 1]; + counter += 2; + } else if (strcmp(argv[counter], "-port") == 0) { + if (Tcl_GetInt(interp, argv[counter + 1], &port) != TCL_OK) + return TCL_ERROR; + counter += 2; + } else if (strcmp(argv[counter], "-clientFlag") == 0) { + if (Tcl_GetInt(interp, argv[counter + 1], &clientFlag) != TCL_OK) + return TCL_ERROR; + counter += 2; + } else { + counter++; + } + } + (*theDatabase) = + new MySqlDatastore(database, host, user, passwd, port, socket, + clientFlag, *theDomain, *theBroker); + } + + if (*theDatabase == 0) { + opserr << "WARNING database MySql dabaseName? - out of memory\n"; + return TCL_ERROR; + } + + return TCL_OK; +} diff --git a/SRC/runtime/commands/domain/database/database.cpp b/SRC/runtime/commands/domain/database/database.cpp new file mode 100644 index 0000000000..f09305980f --- /dev/null +++ b/SRC/runtime/commands/domain/database/database.cpp @@ -0,0 +1,12 @@ + +extern int TclAddDatabase(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv, Domain &theDomain, + FEM_ObjectBroker &theBroker); + +int +addDatabase(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char ** const argv) +{ + return TclAddDatabase(clientData, interp, argc, argv, theDomain, theBroker); +} + diff --git a/SRC/runtime/commands/domain/element.cpp b/SRC/runtime/commands/domain/element.cpp index c4f9fccc0e..74769ca6c5 100644 --- a/SRC/runtime/commands/domain/element.cpp +++ b/SRC/runtime/commands/domain/element.cpp @@ -79,25 +79,25 @@ addElementRayleigh(ClientData clientData, Tcl_Interp *interp, double alphaM, betaK, betaKinit, betaKcomm; if (Tcl_GetDouble(interp, argv[2], &alphaM) != TCL_OK) { - opserr << "WARNING : setElementRayleighFactors invalid "; + opserr << "WARNING : invalid "; opserr << "alphaM: " << argv[2] << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3], &betaK) != TCL_OK) { - opserr << "WARNING : setElementRayleighFactors invalid "; + opserr << "WARNING : invalid "; opserr << "betaK: " << argv[3] << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &betaKinit) != TCL_OK) { - opserr << "WARNING : setElementRayleighFactors invalid "; + opserr << "WARNING : invalid "; opserr << "betaKinit: " << argv[4] << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &betaKcomm) != TCL_OK) { - opserr << "WARNING : setElementRayleighFactors invalid "; + opserr << "WARNING : invalid "; opserr << "betaKcomm: " << argv[5] << "\n"; return TCL_ERROR; } @@ -105,11 +105,11 @@ addElementRayleigh(ClientData clientData, Tcl_Interp *interp, Element *elePtr = theTclDomain->getElement(eleTag); if (elePtr == nullptr) - opserr << "WARNING : setElementRayleighFactors invalid eleTag: " << eleTag + opserr << "WARNING : invalid eleTag: " << eleTag << " the element does not exist in the domain \n"; if (elePtr->setRayleighDampingFactors(alphaM, betaK, betaKinit, betaKcomm) != 0) { - opserr << "ERROR : setElementRayleighFactors: FAILED to add damping " + opserr << "ERROR :: Failed to add damping " "factors for element " << eleTag << "\n"; } diff --git a/SRC/runtime/commands/domain/loading/element_load.cpp b/SRC/runtime/commands/domain/loading/element_load.cpp index 28d5d82fc8..8382febd92 100644 --- a/SRC/runtime/commands/domain/loading/element_load.cpp +++ b/SRC/runtime/commands/domain/loading/element_load.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/domain/nodes.cpp b/SRC/runtime/commands/domain/nodes.cpp index 9fe4b4a53a..72ae2d9dad 100644 --- a/SRC/runtime/commands/domain/nodes.cpp +++ b/SRC/runtime/commands/domain/nodes.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Description: This file implements commands for interacting with nodes @@ -160,9 +167,6 @@ setNodeCoord(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, } - -#if 1 - template int nodeResponseTemplate(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) @@ -259,291 +263,6 @@ nodeReaction(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char return nodeResponseTemplate(clientData, interp, argc, argv); } -#else -int -nodeDisp(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *domain = (Domain*)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeDisp nodeTag? \n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING could not read nodeTag? \n"; - return TCL_ERROR; - } - - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeDisp nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::Disp); - - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - - if (dof >= size) { - opserr << "WARNING nodeDisp nodeTag? dof? - dofTag? too large\n"; - return TCL_ERROR; - } - - Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); - - } else { - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} - -int -nodeVel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *the_domain = (Domain*)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeVel nodeTag? \n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING nodeVel nodeTag? dof? - could not read nodeTag? \n"; - return TCL_ERROR; - } - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeVel nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = the_domain->getNodeResponse(tag, NodeData::Vel); - - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - if (size < dof) - // TODO: add error message - return TCL_ERROR; - - double value = (*nodalResponse)(dof); - - // now we copy the value to the tcl string that is returned - char buffer[40]; - sprintf(buffer, "%35.20f", value); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); - - } else { - - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} - -int -nodeAccel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - - Domain *the_domain = (Domain *)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeAccel nodeTag? dof?\n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING nodeAccel nodeTag? dof? - could not read nodeTag? \n"; - return TCL_ERROR; - } - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeAccel nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = the_domain->getNodeResponse(tag, NodeData::Accel); - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - if (size < dof) - return TCL_ERROR; - - Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); - - } else { - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} - - -int -nodeUnbalance(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *domain = (Domain*)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeUnbalance nodeTag? \n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr - << "WARNING nodeUnbalance nodeTag? dof? - could not read nodeTag? \n"; - return TCL_ERROR; - } - - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeUnbalance nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::UnbalancedLoad); - - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - - if (dof >= size) { - opserr << "WARNING nodeUnbalance nodeTag? dof? - dofTag? too large\n"; - return TCL_ERROR; - } - - Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); - - } else { - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} - - -int -nodeReaction(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *domain = (Domain*)clientData; - - if (argc < 2) { - opserr << "WARNING want - nodeReaction nodeTag? \n"; - return TCL_ERROR; - } - - int tag; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING nodeReaction nodeTag? dof? - could not read nodeTag? \n"; - return TCL_ERROR; - } - - if (argc > 2) { - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING nodeReaction nodeTag? dof? - could not read dof? \n"; - return TCL_ERROR; - } - } - - dof--; - - const Vector *nodalResponse = domain->getNodeResponse(tag, NodeData::Reaction); - - if (nodalResponse == nullptr) - // TODO: add error message - return TCL_ERROR; - - int size = nodalResponse->Size(); - - if (dof >= 0) { - - if (dof >= size) { - opserr << "WARNING nodeReaction nodeTag? dof? - dofTag? too large\n"; - return TCL_ERROR; - } - - Tcl_SetObjResult(interp, Tcl_NewDoubleObj((*nodalResponse)(dof))); - - } else { - char buffer[40]; - for (int i = 0; i < size; ++i) { - sprintf(buffer, "%35.20f", (*nodalResponse)(i)); - Tcl_AppendResult(interp, buffer, NULL); - } - } - - return TCL_OK; -} -#endif int nodeMass(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) diff --git a/SRC/runtime/commands/domain/region.cpp b/SRC/runtime/commands/domain/region.cpp index 5f595c95a5..098bb096ee 100644 --- a/SRC/runtime/commands/domain/region.cpp +++ b/SRC/runtime/commands/domain/region.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // Description: This file contains the function that is invoked // by the interpreter when the command 'region' is invoked by the // user. @@ -13,8 +21,6 @@ // #include #include -// #include -// #include #include #include #include diff --git a/SRC/runtime/commands/interpreter.cpp b/SRC/runtime/commands/interpreter.cpp index d6d195b681..1f68be72cf 100644 --- a/SRC/runtime/commands/interpreter.cpp +++ b/SRC/runtime/commands/interpreter.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// + // Description: This file contains basic commands that enhance the // experience of the interpreter. This file should not reference // any analysis or modeling classes. diff --git a/SRC/runtime/commands/interpreter.h b/SRC/runtime/commands/interpreter.h index b903ab6858..e3ddd2c8ef 100644 --- a/SRC/runtime/commands/interpreter.h +++ b/SRC/runtime/commands/interpreter.h @@ -1,3 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// #include Tcl_CmdProc TclCommand_wipeModel; diff --git a/SRC/runtime/commands/modeling/Block2D.cpp b/SRC/runtime/commands/modeling/Block2D.cpp deleted file mode 100644 index f64784c45e..0000000000 --- a/SRC/runtime/commands/modeling/Block2D.cpp +++ /dev/null @@ -1,241 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// -// -// Description: This file contains the class definition for Block2D. -// -// Written: Ed Love -// Created: 07/99 -// -#include -#include -#include -#include - - -Block2D::Block2D(int numx, int numy, - const ID& nodeID, - const Matrix& coorArray, - int numNode) -: - element(numNode), - numNodesElement(numNode), - nx(numx), ny(numy), - errorFlag(0) -{ - - if (numNodesElement == 9) { - if (((numx % 2) != 0) || ((numy % 2) != 0)) { - opserr << "ERROR: Block2D::Block2D - numX & numY for nine noded elements must be even\n"; - errorFlag = 1; - } - } - - if (numNodesElement != 9 && numNodesElement != 4) { - opserr << "ERROR: Block2D::Block2D - numNode must be either 4 or 9\n"; - errorFlag = 1; - } - - if (this->setUpXl( nodeID, coorArray ) != 0) - errorFlag = 1; - -} - - -//destructor -Block2D::~Block2D( ) -{ - -} - - -//set up xl array -int -Block2D::setUpXl( const ID &nodeID, const Matrix &coorArray ) -{ - - - for (int i=0; i<4; i++ ){ - if ( nodeID(i) == -1 ) { - opserr << "Warning : in Block2D, block node " - << i << " is not defined.\n"; - return -1; - } - } - - // local storage xl = transpose(coorArray) - for (int i=0; i<3; i++ ) { - for (int j=0; j<9; j++ ) - xl[i][j] = coorArray(j,i); - } - - - if ( nodeID(4) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][4] = 0.5*( xl[i][0] + xl[i][1] ); - } - - if ( nodeID(5) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][5] = 0.5*( xl[i][1] + xl[i][2] ); - } - - if ( nodeID(6) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][6] = 0.5*( xl[i][2] + xl[i][3] ); - } - - if ( nodeID(7) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][7] = 0.5*( xl[i][3] + xl[i][0] ); - } - - if ( nodeID(8) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][8] = 0.25*( xl[i][0] + xl[i][1] + xl[i][2] + xl[i][3] ) ; - } - - - return 0; -} - - -//generate node -Vector3D -Block2D::getNodalCoords( int i, int j ) -{ - - double hx = 2.0 / nx; - double hy = 2.0 / ny; - double x = -1.0 + (i*hx); - double y = -1.0 + (j*hy); - - Vector3D coor; - coor[0] = x; - coor[1] = y; - coor[2] = 0.0; - - this->transformNodalCoordinates(coor); - - return coor; -} - - -//generate element -const ID& -Block2D::getElementNodes( int i, int j ) -{ - - if (errorFlag == 1) - return element; - - else if (numNodesElement == 4) { - int nenx = nx + 1; - // int neny = ny + 1; - - - int node1 = i + j*nenx; - int node2 = node1 + 1; - - int node3 = node2 + nenx; - int node4 = node1 + nenx; - - element(0) = node1; - element(1) = node2; - element(2) = node3; - element(3) = node4; - - } else { - - int nenx = nx + 1; - // int neny = ny + 1; - - int node1, node2, node3, node4, node5, node6, node7, node8, node9; - - node1 = i*2 + j*2*nenx; - node5 = node1 + 1; - node2 = node1 + 2; - - node4 = node1 + 2*nenx; - node7 = node4 + 1; - node3 = node7 + 1; - - node8 = node1 + nenx; - node9 = node8 + 1; - node6 = node9 + 1; - - element(0) = node1; - element(1) = node2; - element(2) = node3; - element(3) = node4; - element(4) = node5; - element(5) = node6; - element(6) = node7; - element(7) = node8; - element(8) = node9; - - } - - return element; -} - - - -//transform to real coordiantes -void -Block2D::transformNodalCoordinates(Vector3D& coor ) -{ - - static double shape[9]; - static double natCoor[2]; - - natCoor[0] = coor[0]; - natCoor[1] = coor[1]; - - coor.zero( ); - - this->shape2d( natCoor[0], natCoor[1], shape ); - - for ( int j=0; j<9; j++ ) { - - for ( int dim=0; dim<3; dim++ ) - coor[dim] += shape[j]*xl[dim][j]; - - } - - return; - -} - - -// shape functions -void Block2D::shape2d( double x, double y, - double shape[9] ) -{ - static double Nx[3]; - static double Ny[3]; - - Nx[0] = 0.5 * x * ( x - 1.0 ); - Nx[1] = 1.0 - (x*x); - Nx[2] = 0.5 * x * ( x + 1.0 ); - - Ny[0] = 0.5 * y * ( y - 1.0 ); - Ny[1] = 1.0 - (y*y); - Ny[2] = 0.5 * y * ( y + 1.0 ); - - shape[0] = Nx[0]*Ny[0]; - shape[1] = Nx[2]*Ny[0]; - shape[2] = Nx[2]*Ny[2]; - shape[3] = Nx[0]*Ny[2]; - - shape[4] = Nx[1]*Ny[0]; - shape[5] = Nx[2]*Ny[1]; - shape[6] = Nx[1]*Ny[2]; - shape[7] = Nx[0]*Ny[1]; - - shape[8] = Nx[1]*Ny[1]; - - return; -} diff --git a/SRC/runtime/commands/modeling/Block2D.h b/SRC/runtime/commands/modeling/Block2D.h deleted file mode 100644 index ff2c7c3fb5..0000000000 --- a/SRC/runtime/commands/modeling/Block2D.h +++ /dev/null @@ -1,65 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// -// -// Description: This file contains the implementation of Block2D. -// -// Written: Ed Love -// Created: 07/01 -// -#ifndef Block2D_h -#define Block2D_h - -#include -#include -#include -class Matrix; -class Vector; - -class Block2D { - - public: - - //constructor - Block2D(int numx, int numy, - const ID& nodeID, - const Matrix& coorArray, - int numNodeElement); - - // destructor - ~Block2D(); - - // generate node - Vector3D getNodalCoords(int i, int j); - - // generate element - const ID &getElementNodes(int i, int j); - - - private: - // set up xl array - int setUpXl(const ID &nodeID, const Matrix &coorArray); - - // transform to real coordiantes - void transformNodalCoordinates(Vector3D&); - - // shape functions - void shape2d(double x1, - double x2, - double shape[9]); - - int nx; //number of elements x-direction - int ny; //number of elements y-direction - - double xl[3][9]; //block coordinates - - ID element; //ID-array of an element - - - int numNodesElement; // 4 or 9 - int errorFlag; // flag indicating if odd nx and ny ok for 9-noded elements -}; - -#endif diff --git a/SRC/runtime/commands/modeling/Block3D.cpp b/SRC/runtime/commands/modeling/Block3D.cpp deleted file mode 100644 index 445a98adfa..0000000000 --- a/SRC/runtime/commands/modeling/Block3D.cpp +++ /dev/null @@ -1,346 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// -// -// Description: This file contains the implementation of Block3D. -// -// Written: Ed Love -// Created: 07/01 -// -#include - - -//constructor -Block3D::Block3D(int numx, int numy, int numz, - const ID& nodeID, - const Matrix& coorArray ) -: nx(numx), ny(numy), nz(numz), - coor(3), - element(8) -{ - this->setUpXl( nodeID, coorArray ); -} - - -// destructor -Block3D::~Block3D( ) -{ -} - - -//set up xl array -void Block3D::setUpXl( const ID &nodeID, const Matrix &coorArray ) -{ - - for (int i=0; i<8; i++ ){ - if ( nodeID(i) == -1 ) { - opserr << "Warning : in Block3D, block node " - << i - << " is not defined. No Generation will take place." - << endln; - break; - } - } - - - // xl = tranpose coorArray(27,3) - for (int i=0; i<3; i++ ) { - for (int j=0; j<27; j++ ) - xl[i][j] = coorArray(j,i); - } - - - if ( nodeID(8) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][8] = 0.5*( xl[i][0] + xl[i][4] ); - } - - if ( nodeID(9) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][9] = 0.5*( xl[i][1] + xl[i][5] ); - } - - if ( nodeID(10) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][10] = 0.5*( xl[i][2] + xl[i][6] ); - } - - if ( nodeID(11) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][11] = 0.5*( xl[i][3] + xl[i][7] ); - } - - - if ( nodeID(12) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][12] = 0.5*( xl[i][0] + xl[i][1] ); - } - - if ( nodeID(13) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][13] = 0.5*( xl[i][1] + xl[i][2] ); - } - - if ( nodeID(14) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][14] = 0.5*( xl[i][2] + xl[i][3] ); - } - - if ( nodeID(15) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][15] = 0.5*( xl[i][0] + xl[i][3] ); - } - - - if ( nodeID(16) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][16] = 0.25*( xl[i][0] + xl[i][1] + xl[i][2] + xl[i][3] ); - } - - - if ( nodeID(17) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][17] = 0.5*( xl[i][4] + xl[i][5] ); - } - - if ( nodeID(18) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][18] = 0.5*( xl[i][5] + xl[i][6] ); - } - - if ( nodeID(19) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][19] = 0.5*( xl[i][6] + xl[i][7] ); - } - - if ( nodeID(20) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][20] = 0.5*( xl[i][4] + xl[i][7] ); - } - - - if ( nodeID(21) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][21] = 0.25*( xl[i][4] + xl[i][5] + xl[i][6] + xl[i][7] ); - } - - - if ( nodeID(22) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][22] = 0.25*( xl[i][0] + xl[i][1] + xl[i][5] + xl[i][4] ); - } - - if ( nodeID(23) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][23] = 0.25*( xl[i][1] + xl[i][2] + xl[i][6] + xl[i][5] ); - } - - - if ( nodeID(24) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][24] = 0.25*( xl[i][3] + xl[i][2] + xl[i][6] + xl[i][7] ); - } - - if ( nodeID(25) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][25] = 0.25*( xl[i][0] + xl[i][3] + xl[i][7] + xl[i][4] ); - } - - - - if ( nodeID(26) == -1 ) { - for (int i=0; i<3; i++ ) - xl[i][26] = 0.125*( xl[i][0] + xl[i][1] + xl[i][2] + xl[i][3] + - xl[i][4] + xl[i][5] + xl[i][6] + xl[i][7] ); - } - - return; -} - - -//generate node -const Vector& -Block3D::getNodalCoords( int i, int j, int k ) -{ - - /* loop as follows (in pseudocode) - for ( k = 0, nz ) { - for ( j = 0, ny ) { - for ( i = 0, nx ) - call getNodalCoords(i,j,k); - } - } - */ - - double hx = 2.0 / nx; - - double hy = 2.0 / ny; - - double hhz = 2.0 / nz; - - double x = -1.0 + (i*hx); - - double y = -1.0 + (j*hy); - - double z = -1.0 + (k*hhz); - - coor(0) = x; - coor(1) = y; - coor(2) = z; - - this->transformNodalCoordinates( ); - - return coor; -} - - -//generate element -const ID& -Block3D::getElementNodes( int i, int j, int k ) -{ - - int nenx = nx + 1; - - int neny = ny + 1; - - int nInXYplane = nenx * neny; - - - int node1, node2, node3, node4; - int node5, node6, node7, node8; - - - node1 = i + (j*nenx) + (k*nInXYplane); - node2 = node1 + 1; - node3 = node2 + nenx; - node4 = node1 + nenx; - - node5 = node1 + nInXYplane; - node6 = node2 + nInXYplane; - node7 = node3 + nInXYplane; - node8 = node4 + nInXYplane; - - element(0) = node1; - element(1) = node2; - element(2) = node3; - element(3) = node4; - - element(4) = node5; - element(5) = node6; - element(6) = node7; - element(7) = node8; - - return element; -} - - - -//transform to real coordinates -void Block3D::transformNodalCoordinates( ) -{ - - double shape[27]; - static double natCoor[3]; - - natCoor[0] = coor(0); - natCoor[1] = coor(1); - natCoor[2] = coor(2); - - coor.Zero( ); - - this->shape3d( natCoor[0], natCoor[1], natCoor[2], shape ); - - for (int j=0; j<27; j++ ) { - - for (int dim=0; dim<3; dim++ ) - coor(dim) += shape[j]*xl[dim][j]; - - } - - return; - -} - - - -//shape functions -void Block3D::shape3d( double r, double s, double t, - double shape[27] ) -/* - * Adapted from: - subroutine shp04(shp,glu,glo,gu,eu,to,xjac,detj,r,s,t,xl,ul) -c----------------------------------------------------------------------- -c.....compute shape functions and their derivatives for linear,quadratic -c.....lagrangian and serendipity isoparametric 3-d elements -c.....global coordinate system x,y,z -c.....local coordinate system xsi,eta,zeta -c----------------------------------------------------------------------- -*/ -{ - - static constexpr int ri[] = {-1, 1, 1,-1, -1, 1, 1,-1, -1, 1, 1,-1, 0, 1, 0,-1, 0, 0, 1, 0,-1, 0, 0, 1, 0,-1, 0}; - - static constexpr int si[] = {-1,-1, 1, 1, -1,-1, 1, 1, -1,-1, 1, 1, -1, 0, 1, 0, 0, -1, 0, 1, 0, 0, -1, 0, 1, 0, 0}; - - static constexpr int ti[] = {-1,-1,-1,-1, 1, 1, 1, 1, 0, 0, 0, 0, -1,-1,-1,-1,-1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}; - - - static const double d1 = 1.0; - static const double d2 = 0.5; // = 1.0/2.0; - static const double d4 = 0.25; // = 1.0/4.0; - static const double d8 = 0.125; // = 1.0/8.0; - - - double rr = r*r; - double ss = s*s; - double tt = t*t; - - int kk; - - //shape functions for 27-node element - for (int k=1; k<=27; k++ ) { - - kk = k-1; //C-style numbering - - double r0 = r*ri[kk]; - double s0 = s*si[kk]; - double t0 = t*ti[kk]; - - //corner nodes top/bottom - if ( k>=1 && k<=8 ) - shape[kk] = d8*(rr+r0) *(ss+s0) *(tt+t0); - - //corner nodes midside - if ( k>=9 && k<=12 ) - shape[kk] = d4*(rr+r0) *(ss+s0) *(d1-tt); - - //midside nodes top/bottom r-dir - if ( k==13 || k==15 || k==18 || k==20 ) - shape[kk] = d4*(d1-rr)*(ss+s0) *(tt+t0); - - //midside nodes top/bottom s-dir - if ( k==14 || k==16 || k==19 || k==21 ) - shape[kk] = d4*(rr+r0) *(d1-ss)*(tt+t0); - - //midside nodes mid plane r-dir - if ( k==23 || k==25 ) - shape[kk] = d2*(d1-rr)*(ss+s0) *(d1-tt); - - //midside nodes mid plane s-dir - if ( k==24 || k==26 ) - shape[kk] = d2*(rr+r0) *(d1-ss)*(d1-tt); - - //central nodes top/bottom - if ( k==17 || k==22 ) - shape[kk] = d2*(d1-rr)*(d1-ss)*(tt+t0); - - if ( k==27 ) - shape[kk] = (d1-rr)*(d1-ss)*(d1-tt); - - } - - return; -} - diff --git a/SRC/runtime/commands/modeling/Block3D.h b/SRC/runtime/commands/modeling/Block3D.h deleted file mode 100644 index 981546ca46..0000000000 --- a/SRC/runtime/commands/modeling/Block3D.h +++ /dev/null @@ -1,69 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// -// -// Written: Ed Love -// Created: 07/01 -// -// Description: This file contains the implementation of Block3D. -// -#ifndef Block3D_h -#define Block3D_h -// - -#include -#include -#include -#include - -class Block3D { - - public: - - //constructor - Block3D(int numx, int numy, int numz, - const ID& nodeID, - const Matrix& coorArray); - - //destructor - virtual ~Block3D(); - - //generate node - const Vector &getNodalCoords(int i, int j, int k); - - //generate element - const ID &getElementNodes(int i, int j, int k); - - protected: - - private: - - int nx; //number of elements x-direction - - int ny; //number of elements y-direction - - int nz; //number of elements z-direction - - double xl[3][27]; //block coordinates - - Vector coor; //coordinates of a node - - ID element; //ID-array of an element - - //set up xl array - void setUpXl(const ID &nodeID, const Matrix &coorArray); - - //transform to real coordiantes - void transformNodalCoordinates(); - - //shape functions - void shape3d(double x1, - double x2, - double x3, - double shape[27]); - -}; - -#endif diff --git a/SRC/runtime/commands/modeling/blockND.cpp b/SRC/runtime/commands/modeling/blockND.cpp deleted file mode 100644 index 6b49fe43b7..0000000000 --- a/SRC/runtime/commands/modeling/blockND.cpp +++ /dev/null @@ -1,438 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// -// -// NOTE: This doesnt really need access to the model builder, it would -// work with just the domain -// -#ifdef _TCL85 -# define TCL_Char const char -#elif _TCL84 -# define TCL_Char const char -#else -# define TCL_Char char -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Block2D.h" -#include "Block3D.h" - - -int -TclCommand_doBlock2D(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder* builder = static_cast(clientData); - Domain *theTclDomain = builder->getDomain(); - int ndm = builder->getNDM(); - int ndf = builder->getNDF(); - - if (ndm < 2) { - opserr << G3_ERROR_PROMPT - << "model dimension (ndm) must be at leat 2 " << "\n"; - return TCL_ERROR; - } - - if (argc < 8) { - opserr << G3_ERROR_PROMPT << "incorrect number of args, expected:" - "\n\tblock2D numX? numY? startNode? startEle? eleType? eleArgs?"; - return TCL_ERROR; - } - int numX, numY, startNodeNum, startEleNum; - if (Tcl_GetInt(interp, argv[1], &numX) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "invalid numX (" << argv[1] << "), expected:\n\t" - << "block2D numX? numY? startNode? startEle? eleType? eleArgs?"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[2], &numY) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "block2D numX? numY? startNode? startEle? eleType? eleArgs?"; - opserr << " : invalid numY: " << argv[2] << "\n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[3], &startNodeNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "block2D numX? numY? startNode? startEle? eleType? eleArgs?"; - opserr << " : invalid startNode: " << argv[3] << "\n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[4], &startEleNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "block2D numX? numY? startNode? startEle? eleType? eleArgs?"; - opserr << " : invalid startEle: " << argv[4] << "\n"; - return TCL_ERROR; - } - - - static Matrix Coordinates(9,3); - Coordinates.Zero(); - - static ID haveNode(9); - for (int k=0; k<9; k++) - haveNode(k) = -1; - - int numNodes = 4; - if (argc == 10) { - if (strcmp(argv[7],"-numEleNodes") == 0) - if (Tcl_GetInt(interp, argv[8], &numNodes) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "block2D numX? numY? startNode? startEle? eleType eleArgs?"; - opserr << " -numEleNodes numNodes?: invalid numNodes: " << argv[8] << "\n"; - return TCL_ERROR; - } - if (numNodes != 4 && numNodes != 9) { - opserr << G3_ERROR_PROMPT << "block2D numX? numY? startNode? startEle? eleType? eleArgs? "; - opserr << "-numEleNodes numNodes?: invalid numNodes: " << argv[8] << " 4 or 9 only\n"; - return TCL_ERROR; - } - - if (numNodes == 9) { - if (((numX % 2) != 0) || ((numY % 2) != 0)) { - opserr << G3_ERROR_PROMPT << "block2D numX? numY? startNode? startEle? eleType? eleArgs? "; - opserr << "numX and numY must both be even when using -numEleNodes 9\n"; - return TCL_ERROR; - } - } - } - - int nodalInfo = 9; - if (numNodes == 4) - nodalInfo = 7; - - TCL_Char ** argvNodes; - int argcNodes; - - Tcl_SplitList(interp, argv[nodalInfo], &argcNodes, &argvNodes); - - - int count = 0; - while (count < argcNodes) { - int nodeTag; - double value; - if ((count + ndm + 1) > argcNodes) { - opserr << G3_ERROR_PROMPT << "block2D numX? numY? startNode? startEle? eleType? eleArgs?"; - opserr << " : invalid number of node args: " << argv[7] << "\n"; - Tcl_Free((char *)argvNodes); - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argvNodes[count], &nodeTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "block2D numX? numY? startNode? startEle? eleType? eleArgs?"; - opserr << " : invalid node tag: " << argvNodes[count] << "\n"; - Tcl_Free((char *)argvNodes); - return TCL_ERROR; - } - if (nodeTag < 1 || nodeTag > 9) { - opserr << G3_ERROR_PROMPT - << " : invalid node tag out of bounds [1,9]: " << argvNodes[count] << "\n"; - Tcl_Free((char *)argvNodes); - return TCL_ERROR; - } - for (int i=0; i(nodeID, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - break; - case 6: - theNode = new NodeND<3, 6>(nodeID, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - break; - default: - theNode = new Node(nodeID, ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - break; - } - } else - theNode = new Node(nodeID, ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - // theNode = new Node(nodeID,ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - } - - if (theTclDomain->addNode(theNode) == false) { - opserr << G3_ERROR_PROMPT << "failed to add node to the domain\n"; - opserr << "node: " << nodeID << "\n"; - delete theNode; - return TCL_ERROR; - } - nodeID++; - } - } - - // create the elements: numX*numY elements to be created if 4 node elements - // numX/2 * numY /2 nodes to be v=created if 9 node elements - TCL_Char *eleType = argv[5]; - TCL_Char *additionalEleArgs = argv[6]; - // const ID &nodeTags = theBlock.getElementNodes(0,0); - // int numNodes = nodeTags.Size(); - - // assumes 15 is largest string for individual nodeTags - count = int(10 + strlen(eleType) + strlen(additionalEleArgs) + 15 *(numNodes+1)); - char *eleCommand = new char[count]; - int initialCount = int(8 + strlen(eleType)); - - int eleID = startEleNum; - if (numNodes == 9) { - numX /= 2; - numY /= 2; - } - - for (int jj=0; jj(clientData); - Domain *theTclDomain = builder->getDomain(); - int ndm = builder->getNDM(); - int ndf = builder->getNDF(); - - if (ndm < 3) { - opserr << G3_ERROR_PROMPT << "block3D numX? numY? startNode? startEle? eleType? eleArgs?"; - opserr << " : model dimension (ndm) must be at leat 2 " << "\n"; - return TCL_ERROR; - } - - int numX, numY, numZ, startNodeNum, startEleNum; - if (Tcl_GetInt(interp, argv[1], &numX) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "block3D numX? numY? numZ? startNode? startEle? eleType? eleArgs?"; - opserr << " : invalid numX: " << argv[1] << "\n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[2], &numY) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "block3D numX? numY? numZ? startNode? startEle? eleType? eleArgs?"; - opserr << " : invalid numY: " << argv[2] << "\n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[3], &numZ) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "block3D numX? numY? numZ? startNode? startEle? eleType? eleArgs?"; - opserr << " : invalid numZ: " << argv[3] << "\n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[4], &startNodeNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "block3D numX? numY? numZ? startNode? startEle? eleType? eleArgs?"; - opserr << " : invalid startNode: " << argv[4] << "\n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[5], &startEleNum) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "block3D numX? numY? numZ? startNode? startEle? eleType? eleArgs?"; - opserr << " : invalid startEle: " << argv[5] << "\n"; - return TCL_ERROR; - } - - static Matrix Coordinates(27,3); - static ID haveNode(27); - Coordinates.Zero(); - for (int k=0; k<27; k++) haveNode(k) = -1; - - TCL_Char *nodalInfo = argv[8]; - TCL_Char ** argvNodes; - int argcNodes; - - Tcl_SplitList(interp, nodalInfo, &argcNodes, &argvNodes); - - - int count = 0; - while (count < argcNodes) { - if ((count + ndm + 1) > argcNodes) { - opserr << G3_ERROR_PROMPT << "block3D numX? numY? numZ? startNode? startEle? eleType eleArgs?"; - opserr << " : invalid number of node args: " << argv[8] << "\n"; - Tcl_Free((char *)argvNodes); - return TCL_ERROR; - } - int nodeTag; - double value; - if (Tcl_GetInt(interp, argvNodes[count], &nodeTag) != TCL_OK) { - opserr << G3_ERROR_PROMPT << "block3D numX? numY? numZ? startNode? startEle? eleType? eleArgs?"; - opserr << " : invalid node id in node args: " << argvNodes[count] << "\n"; - Tcl_Free((char *)argvNodes); - return TCL_ERROR; - } - if (nodeTag < 1 || nodeTag > 27) { - opserr << G3_ERROR_PROMPT << "block3D numX? numY? numZ? startNode? startEle? eleType? eleArgs?"; - opserr << " : node tag out of bounds [1, 27]: " << argvNodes[count] << "\n"; - Tcl_Free((char *)argvNodes); - return TCL_ERROR; - } - for (int i=0; i(nodeID, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - break; - case 6: - theNode = new NodeND<3, 6>(nodeID, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - break; - default: - theNode = new Node(nodeID, ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - break; - } - } else - theNode = new Node(nodeID, ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - - // theNode = new Node(nodeID,ndf,nodeCoords(0),nodeCoords(1),nodeCoords(2)); - - if (theTclDomain->addNode(theNode) == false) { - opserr << G3_ERROR_PROMPT << "failed to add node to the domain\n"; - opserr << "node: " << nodeID << "\n"; - delete theNode; - return TCL_ERROR; - } - - nodeID++; - } - } - } - - // create the elements: numX*numY elements to be created - TCL_Char *eleType = argv[6]; - TCL_Char *additionalEleArgs = argv[7]; - const ID &nodeTags = theBlock.getElementNodes(0,0,0); - int numNodes = nodeTags.Size(); - - // TODO: assumes 15 is largest string for individual nodeTags - count = int(10 + strlen(eleType) + strlen(additionalEleArgs) + 15 * (numNodes+1)); - char *eleCommand = new char[count]; - int initialCount = int(8 + strlen(eleType)); - - int eleID = startEleNum; - for (kk=0; kk(clientData); - int ndm = builder->getNDM(); - - if (argc < 1) { - opserr << G3_ERROR_PROMPT << "block {args}\n"; - return TCL_ERROR; - } - - if (ndm == 2) - return TclCommand_doBlock2D(clientData, interp, argc, argv); - - else if (strcmp(argv[1], "2d") == 0) - return TclCommand_doBlock2D(clientData, interp, argc-1, argv+1); - - else - return TclCommand_doBlock3D(clientData, interp, argc, argv); - - return TCL_OK; -} diff --git a/SRC/runtime/commands/modeling/commands.h b/SRC/runtime/commands/modeling/commands.h index 0a02b98623..4107b04e63 100644 --- a/SRC/runtime/commands/modeling/commands.h +++ b/SRC/runtime/commands/modeling/commands.h @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/constraint.cpp b/SRC/runtime/commands/modeling/constraint.cpp index 436e50564a..3675eda8f0 100644 --- a/SRC/runtime/commands/modeling/constraint.cpp +++ b/SRC/runtime/commands/modeling/constraint.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/element.cpp b/SRC/runtime/commands/modeling/element.cpp index 2283f6d61f..971d423726 100644 --- a/SRC/runtime/commands/modeling/element.cpp +++ b/SRC/runtime/commands/modeling/element.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index 8e382ef3d4..6d9b34f086 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/element/shells.cpp b/SRC/runtime/commands/modeling/element/shells.cpp index dc78dd7122..b58a92506c 100644 --- a/SRC/runtime/commands/modeling/element/shells.cpp +++ b/SRC/runtime/commands/modeling/element/shells.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/element/truss.cpp b/SRC/runtime/commands/modeling/element/truss.cpp index 73d2cd03c8..9cb40de445 100644 --- a/SRC/runtime/commands/modeling/element/truss.cpp +++ b/SRC/runtime/commands/modeling/element/truss.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/geomTransf.cpp b/SRC/runtime/commands/modeling/geomTransf.cpp index c437af44b8..3b88444885 100644 --- a/SRC/runtime/commands/modeling/geomTransf.cpp +++ b/SRC/runtime/commands/modeling/geomTransf.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/material.hpp b/SRC/runtime/commands/modeling/material.hpp deleted file mode 100644 index e55b72fbe3..0000000000 --- a/SRC/runtime/commands/modeling/material.hpp +++ /dev/null @@ -1,188 +0,0 @@ -#include -#include -#include - -extern OPS_Routine OPS_ASDConcrete3DMaterial; -extern OPS_Routine OPS_ReinforcedConcretePlaneStressMaterial; -extern OPS_Routine OPS_FAReinforcedConcretePlaneStressMaterial; -extern OPS_Routine OPS_FAFourSteelRCPlaneStressMaterial; -extern OPS_Routine OPS_RAFourSteelRCPlaneStressMaterial; -extern OPS_Routine OPS_PrestressedConcretePlaneStressMaterial; -extern OPS_Routine OPS_FAPrestressedConcretePlaneStressMaterial; -extern OPS_Routine OPS_FAFourSteelPCPlaneStressMaterial; -extern OPS_Routine OPS_RAFourSteelPCPlaneStressMaterial; -// extern OPS_Routine OPS_MaterialCMM; -// extern OPS_Routine OPS_NewMaterialCMM; -extern OPS_Routine OPS_NewPlasticDamageConcrete3d; -extern OPS_Routine OPS_NewPlasticDamageConcretePlaneStress; -extern OPS_Routine OPS_ElasticIsotropicMaterial; -extern OPS_Routine OPS_ElasticIsotropic3D; -extern OPS_Routine OPS_IncrementalElasticIsotropicThreeDimensional; -extern OPS_Routine OPS_ElasticOrthotropicMaterial; -extern OPS_Routine OPS_DruckerPragerMaterial; -extern OPS_Routine OPS_BoundingCamClayMaterial; -extern OPS_Routine OPS_ContactMaterial2DMaterial; -extern OPS_Routine OPS_ContactMaterial3DMaterial; -extern OPS_Routine OPS_InitialStateAnalysisWrapperMaterial; -extern OPS_Routine OPS_ManzariDafaliasMaterial; -extern OPS_Routine OPS_ManzariDafaliasMaterialRO; -extern OPS_Routine OPS_PM4SandMaterial; -extern OPS_Routine OPS_PM4SiltMaterial; -extern OPS_Routine OPS_J2CyclicBoundingSurfaceMaterial; -extern OPS_Routine OPS_CycLiqCPMaterial; -extern OPS_Routine OPS_CycLiqCPSPMaterial; -extern OPS_Routine OPS_InitStressNDMaterial; -extern OPS_Routine OPS_InitStrainNDMaterial; -extern OPS_Routine OPS_StressDensityMaterial; -extern OPS_Routine OPS_J2PlateFibreMaterial; -extern OPS_Routine OPS_PlaneStressLayeredMaterial; -extern OPS_Routine OPS_PlaneStressRebarMaterial; -extern OPS_Routine OPS_PlateFiberMaterial; -extern OPS_Routine OPS_BeamFiberMaterial; -extern OPS_Routine OPS_BeamFiberMaterial2d; -extern OPS_Routine OPS_BeamFiberMaterial2dPS; -extern OPS_Routine OPS_LinearCap; -extern OPS_Routine OPS_AcousticMedium; -extern OPS_Routine OPS_UVCmultiaxial; -extern OPS_Routine OPS_UVCplanestress; -extern OPS_Routine OPS_SAniSandMSMaterial; -extern OPS_Routine OPS_OrthotropicRotatingAngleConcreteT2DMaterial01; // M. J. Nunez - UChile -extern OPS_Routine OPS_SmearedSteelDoubleLayerT2DMaterial01; // M. J. Nunez - UChile - -extern OPS_Routine OPS_ElasticIsotropicMaterialThermal; // L.Jiang [SIF] -extern OPS_Routine OPS_DruckerPragerMaterialThermal; // L.Jiang [SIF] -extern OPS_Routine OPS_PlasticDamageConcretePlaneStressThermal; // L.Jiang [SIF] - -extern OPS_Routine OPS_ElasticOrthotropicPlaneStress; -extern OPS_Routine OPS_OrthotropicMaterial; -extern OPS_Routine OPS_Series3DMaterial; -extern OPS_Routine OPS_Parallel3DMaterial; - -extern OPS_Routine OPS_AllASDPlasticMaterials; - -#ifdef _HAVE_Faria1998 -extern OPS_Routine OPS_NewFaria1998Material; -extern OPS_Routine OPS_NewConcreteMaterial; -#endif - -extern OPS_Routine OPS_FSAMMaterial; // K Kolozvari - -#ifdef _HAVE_Damage2p -extern OPS_Routine OPS_Damage2p; -#endif - -static std::unordered_map material_dispatch = { - {"InitStressMaterial", OPS_InitStressNDMaterial}, - {"InitStrainMaterial", OPS_InitStrainNDMaterial}, - {"InitStrain", OPS_InitStrainNDMaterial}, - - {"ReinforcedConcretePlaneStress", OPS_ReinforcedConcretePlaneStressMaterial}, - {"PlaneStressLayeredMaterial", OPS_PlaneStressLayeredMaterial}, - {"PlaneStressRebarMaterial", OPS_PlaneStressRebarMaterial}, - -#ifdef OPS_USE_ASDPlasticMaterials - {"ASDPlasticMaterial", OPS_AllASDPlasticMaterials}, -#endif - - {"ASDConcrete3D", OPS_ASDConcrete3DMaterial}, - - {"PlasticDamageConcrete", OPS_NewPlasticDamageConcrete3d}, - - {"PlasticDamageConcretePlaneStress", OPS_NewPlasticDamageConcretePlaneStress}, - - - {"J2PlateFibre", OPS_J2PlateFibreMaterial}, - {"PlateFiber", OPS_PlateFiberMaterial}, - - // Beam fiber - {"BeamFiber", OPS_BeamFiberMaterial}, - {"BeamFiber2d", OPS_BeamFiberMaterial2d}, - {"BeamFiber2dPS", OPS_BeamFiberMaterial2dPS}, - - - {"DruckerPragerThermal", OPS_DruckerPragerMaterialThermal}, -#if 0 - {"CDPPlaneStressThermal", OPS_PlasticDamageConcretePlaneStressThermal}, -#endif - - -#ifdef _HAVE_Faria1998 - {"Faria1998", OPS_NewFaria1998Material}, - {"Concrete", OPS_NewConcreteMaterial}, -#endif - - {"FAReinforcedConcretePlaneStress", OPS_FAReinforcedConcretePlaneStressMaterial}, - {"RAFourSteelRCPlaneStress", OPS_RAFourSteelRCPlaneStressMaterial}, - {"FAFourSteelRCPlaneStress", OPS_FAFourSteelRCPlaneStressMaterial}, - -#ifdef _HAVE_Damage2p - {"Damage2p", OPS_Damage2p}, -#endif - - {"PrestressedConcretePlaneStress", OPS_PrestressedConcretePlaneStressMaterial}, - {"FAPrestressedConcretePlaneStress", OPS_FAPrestressedConcretePlaneStressMaterial}, - {"RAFourSteetPCPlaneStress", OPS_RAFourSteelPCPlaneStressMaterial}, - - {"FAFourSteelPCPlaneStress", OPS_FAFourSteelPCPlaneStressMaterial}, - - {"DruckerPrager", OPS_DruckerPragerMaterial}, - - {"TruncatedDP", OPS_LinearCap}, - - // K Kolozvari - {"FSAM", OPS_FSAMMaterial}, - - {"AcousticMedium", OPS_AcousticMedium}, - - {"UVCplanestress", OPS_UVCplanestress}, - - {"UVCmultiaxial", OPS_UVCmultiaxial}, - -//{"MaterialCMM", OPS_MaterialCMM}, - - {"CycLiqCP", OPS_CycLiqCPMaterial}, - - {"CycLiqCPSP", OPS_CycLiqCPSPMaterial}, - - {"BoundingCamClay", OPS_BoundingCamClayMaterial}, - - {"ManzariDafalias", OPS_ManzariDafaliasMaterial}, - - {"ManzariDafaliasRO", OPS_ManzariDafaliasMaterialRO}, - - {"PM4Sand", OPS_PM4SandMaterial}, - - {"J2CyclicBoundingSurface", OPS_J2CyclicBoundingSurfaceMaterial}, - - {"PM4Silt", OPS_PM4SiltMaterial}, - - {"ContactMaterial2D", OPS_ContactMaterial2DMaterial}, - - {"ContactMaterial3D", OPS_ContactMaterial3DMaterial}, - - {"InitialStateAnalysisWrapper", OPS_InitialStateAnalysisWrapperMaterial}, - - {"stressDensity", OPS_StressDensityMaterial}, - - {"ElasticIsotropic3D", OPS_ElasticIsotropic3D}, - - {"ElasticIsotropic", OPS_ElasticIsotropicMaterial}, - - {"ElasticOrthotropic", OPS_ElasticOrthotropicMaterial}, - - {"ElasticIsotropic3DThermal", OPS_ElasticIsotropicMaterialThermal}, - - {"IncrementalElasticIsotropic3D", OPS_IncrementalElasticIsotropicThreeDimensional}, - - {"OrthotropicRAConcrete", OPS_OrthotropicRotatingAngleConcreteT2DMaterial01}, - {"SmearedSteelDoubleLayer", OPS_SmearedSteelDoubleLayerT2DMaterial01}, - - {"SAniSandMS", OPS_SAniSandMSMaterial}, - - {"OrthotropicMaterial", OPS_OrthotropicMaterial}, - {"ElasticOrthotropicPlaneStress", OPS_ElasticOrthotropicPlaneStress}, - {"Series3DMaterial", OPS_Series3DMaterial}, - {"Parallel3DMaterial", OPS_Parallel3DMaterial}, - {"Parallel3D", OPS_Parallel3DMaterial}, -}; - diff --git a/SRC/runtime/commands/modeling/material/boucwen.cpp b/SRC/runtime/commands/modeling/material/boucwen.cpp index 16f2181106..3a7c87c2f6 100644 --- a/SRC/runtime/commands/modeling/material/boucwen.cpp +++ b/SRC/runtime/commands/modeling/material/boucwen.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/material/concrete.cpp b/SRC/runtime/commands/modeling/material/concrete.cpp index 4a347f6642..20e403ecf3 100644 --- a/SRC/runtime/commands/modeling/material/concrete.cpp +++ b/SRC/runtime/commands/modeling/material/concrete.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/material/elastic.cpp b/SRC/runtime/commands/modeling/material/elastic.cpp index 66e164eb9b..7d90b96c67 100644 --- a/SRC/runtime/commands/modeling/material/elastic.cpp +++ b/SRC/runtime/commands/modeling/material/elastic.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/material/fedeas.cpp b/SRC/runtime/commands/modeling/material/fedeas.cpp index 885cc2b010..53a84fc96a 100644 --- a/SRC/runtime/commands/modeling/material/fedeas.cpp +++ b/SRC/runtime/commands/modeling/material/fedeas.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/material/isotropy.cpp b/SRC/runtime/commands/modeling/material/isotropy.cpp index 83d1999471..00eae94af3 100644 --- a/SRC/runtime/commands/modeling/material/isotropy.cpp +++ b/SRC/runtime/commands/modeling/material/isotropy.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/material/isotropy.h b/SRC/runtime/commands/modeling/material/isotropy.h index 7f3857b7ee..88508ee3bb 100644 --- a/SRC/runtime/commands/modeling/material/isotropy.h +++ b/SRC/runtime/commands/modeling/material/isotropy.h @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/material/material.hpp b/SRC/runtime/commands/modeling/material/material.hpp index 91b93ebbcf..d6f549cacb 100644 --- a/SRC/runtime/commands/modeling/material/material.hpp +++ b/SRC/runtime/commands/modeling/material/material.hpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/material/plastic.cpp b/SRC/runtime/commands/modeling/material/plastic.cpp index a2b73363f9..04804129d1 100644 --- a/SRC/runtime/commands/modeling/material/plastic.cpp +++ b/SRC/runtime/commands/modeling/material/plastic.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/material/shell.cpp b/SRC/runtime/commands/modeling/material/shell.cpp index 8b2ad71555..154bd22994 100644 --- a/SRC/runtime/commands/modeling/material/shell.cpp +++ b/SRC/runtime/commands/modeling/material/shell.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/nDMaterial.cpp b/SRC/runtime/commands/modeling/nDMaterial.cpp deleted file mode 100644 index 3045e8db86..0000000000 --- a/SRC/runtime/commands/modeling/nDMaterial.cpp +++ /dev/null @@ -1,1700 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// -// -// Description: This file contains the function invoked when the user -// invokes the nDMaterial command in the interpreter. -// -// Developed by: -// Frank McKenna (fmckenna@ce.berkeley.edu) -// Gregory L. Fenves (fenves@ce.berkeley.edu) -// Filip C. Filippou (filippou@ce.berkeley.edu) -// -// With extensive contributions from -// Boris Jeremic (jeremic@ucdavis.edu) -// Zaohui Yang (zhyang@ucdavis.edu) -// Zhao Cheng (zcheng@ucdavis.edu) -// -#include "material.hpp" -#include -#include -#include -#include -#include - -#include -#include -#include // Gang Wang - -#include -#include // Antonios Vytiniotis: -#include - -// start Yuli Huang & Xinzheng Lu -#include -#include -#include -#include -// end Yuli Huang & Xinzheng Lu - -#include // Quan Gu & ZhiJian Qiu 2013 -#include // Quan Gu & ZhiJian Qiu 2013-6-26 -#include // Quan Gu & ZhiJian Qiu 2013-6-26 - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include // added by L.Jiang [SIF] -#include // L.Jiang [SIF] -#include // Liming Jiang [SIF] -#include // Liming Jiang [SIF] - -#include - -#if 0 -extern NDMaterial *Tcl_addWrapperNDMaterial(matObj *, ClientData, Tcl_Interp *, - int, TCL_Char **); -#endif -extern OPS_Routine OPS_J2Plasticity; -extern OPS_Routine OPS_J2BeamFiber2dMaterial; -extern OPS_Routine OPS_J2BeamFiber3dMaterial; - -#if defined(OPSDEF_Material_FEAP) -NDMaterial *TclBasicBuilder_addFeapMaterial(ClientData clientData, - Tcl_Interp *interp, int argc, - TCL_Char ** const argv); -#endif // _OPS_Material_FEAP - - -extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp *interp, int cArg, - int mArg, TCL_Char ** const argv, Domain *domain); - -typedef struct ndMaterialPackageCommand { - char *funcName; - void *(*funcPtr)(); - struct ndMaterialPackageCommand *next; -} NDMaterialPackageCommand; - -static NDMaterialPackageCommand *theNDMaterialPackageCommands = nullptr; - -int -TclCommand_addNDMaterial(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) -{ - G3_Runtime *rt = G3_getRuntime(interp); - BasicModelBuilder *builder = static_cast(clientData); - - // Make sure there is a minimum number of arguments - if (argc < 3) { - opserr << "WARNING insufficient number of ND material arguments\n"; - opserr << "Want: nDMaterial type? tag? " << "\n"; - return TCL_ERROR; - } - - OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, 0); - - // Pointer to an ND material that will be added to the model builder - NDMaterial *theMaterial = nullptr; - - auto tcl_cmd = material_dispatch.find(std::string(argv[1])); - if (tcl_cmd != material_dispatch.end()) { - void* theMat = (*tcl_cmd->second)(rt, argc, &argv[0]); - if (theMat != 0) - theMaterial = (NDMaterial *)theMat; - else - return TCL_ERROR; - } - - // Check argv[1] for ND material type - else if (strcmp(argv[1], "J2BeamFiber") == 0) { - void *theMat = 0; - if (builder->getNDM() == 2) - theMat = OPS_J2BeamFiber2dMaterial(rt, argc, argv); - else - theMat = OPS_J2BeamFiber3dMaterial(rt, argc, argv); - - if (theMat != 0) - theMaterial = (NDMaterial *)theMat; - else - return TCL_ERROR; - } - - else if (strcmp(argv[1], "PressureDependentElastic3D") == 0) { - if (argc < 6) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PressureDependentElastic3D tag? E? v? rho?" - << "\n"; - return TCL_ERROR; - } - - int tag = 0; - double E = 0.0; - double v = 0.0; - double rho = 0.0; - double expp = 0.0; - double prp = 0.0; - double pop = 0.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid PressureDependentElastic3D tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { - opserr << "WARNING invalid E\n"; - opserr << "nDMaterial PressureDependentElastic3D: E" << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &v) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: v" << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &rho) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: rho" << tag << "\n"; - return TCL_ERROR; - } - - ////////////////////////////////////////////////////////////////////////////////// - if (argc == 6) { - theMaterial = new PressureDependentElastic3D(tag, E, v, rho); - // opserr << "nDMaterial PressureDependentElastic3D: expp =" << expp << - // "\n"; - } - ////////////////////////////////////////////////////////////////////////////////// - else if (argc == 7) { - // get the exponent of the pressure sensitive elastic material) - if (Tcl_GetDouble(interp, argv[6], &expp) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: " << tag << "\n"; - return TCL_ERROR; - } - theMaterial = new PressureDependentElastic3D(tag, E, v, rho, expp); - // opserr << "nDMaterial PressureDependentElastic3D: expp =" << expp << - // "\n"; - } - ////////////////////////////////////////////////////////////////////////////////// - else if (argc == 8) { - // get the exponent pressure of the pressure sensitive elastic material) - if (Tcl_GetDouble(interp, argv[6], &expp) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: expp" << tag << "\n"; - return TCL_ERROR; - } - // get the reference pressure of the pressure sensitive elastic material) - if (Tcl_GetDouble(interp, argv[7], &prp) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: prp " << tag << "\n"; - return TCL_ERROR; - } - // opserr << "nDMaterial ElasticIsotropic3D: prp =" << prp << "\n"; - theMaterial = new PressureDependentElastic3D(tag, E, v, rho, expp, prp); - } - ////////////////////////////////////////////////////////////////////////////////// - else if (argc >= 9) { - // get the exponent of the pressure sensitive elastic material) - if (Tcl_GetDouble(interp, argv[6], &expp) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: expp" << tag << "\n"; - return TCL_ERROR; - } - // get the reference pressure of the pressure sensitive elastic material) - if (Tcl_GetDouble(interp, argv[7], &prp) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: prp" << tag << "\n"; - return TCL_ERROR; - } - // get the cutoff pressure po of the pressure sensitive elastic material) - if (Tcl_GetDouble(interp, argv[8], &pop) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: pop" << tag << "\n"; - return TCL_ERROR; - } - // opserr << "nDMaterial PressureDependentElastic3D: pop =" << pop << - // "\n"; - theMaterial = - new PressureDependentElastic3D(tag, E, v, rho, expp, prp, pop); - } - - } - - // Check argv[1] for J2PlaneStrain material type - else if ((strcmp(argv[1], "J2Plasticity") == 0) || - (strcmp(argv[1], "J2") == 0)) { - - void *theMat = OPS_J2Plasticity(rt, argc, argv); - if (theMat != 0) - theMaterial = (NDMaterial *)theMat; - else - return TCL_ERROR; - - } - - ///////////////////////////////////////////////////////////////// - /* - nDmaterial PlaneStressJ2 $matTag $G $K $sig0 $H_kin $H_iso - - - PlaneStress (int tag, - int nd, - NDMaterial &the3DMaterial); - - */ - - else if ((strcmp(argv[1], "PlaneStressSimplifiedJ2") == 0)) { - if (argc < 8) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDmaterial Simplified3DJ2 $matTag $G $K $sig0 " - "$H_kin $H_iso" - << "\n"; - return TCL_ERROR; - } - - int tag; - double K, G, sig0, H_kin, H_iso; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid SimplifiedJ2 tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &G) != TCL_OK) { - opserr << "WARNING invalid G\n"; - opserr << "nDMaterial SimplifiedJ2: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &K) != TCL_OK) { - opserr << "WARNING invalid K\n"; - opserr << "nDMaterial SimplifiedJ2: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &sig0) != TCL_OK) { - opserr << "WARNING invalid sig0\n"; - opserr << "nDMaterial SimplifiedJ2: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &H_kin) != TCL_OK) { - opserr << "WARNING invalid H_kin\n"; - opserr << "nDMaterial SimplifiedJ2: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[7], &H_iso) != TCL_OK) { - opserr << "WARNING invalid H_iso\n"; - opserr << "nDMaterial SimplifiedJ2: " << tag << "\n"; - return TCL_ERROR; - } - - NDMaterial *theMaterial2 = - new SimplifiedJ2(tag, 3, G, K, sig0, H_kin, H_iso); - - theMaterial = new PlaneStressSimplifiedJ2(tag, 2, *theMaterial2); - - // delete theMaterial2; - - } - ///////////////////////////////////////////////////////////////// - - // - // MultiAxialCyclicPlasticity Model by Gang Wang - // - // nDMaterial MultiaxialCyclicPlasticity $tag, $rho, $K, $G, - // $Su , $Ho , $h, $m, $beta, $KCoeff - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - else if ((strcmp(argv[1], "MultiaxialCyclicPlasticity") == 0) || - (strcmp(argv[1], "MCP") == 0)) { - if (argc < 12) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial MultiaxialCyclicPlasticity tag? rho? K? G? " - "Su? Ho? h? m? beta? KCoeff? " - << "\n"; - return TCL_ERROR; - } - - int tag; - double K, G, rho, Su, Ho, h, m, beta, Kcoeff; - double eta = 0.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid MultiaxialCyclicPlasticity tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &rho) != TCL_OK) { - opserr << "WARNING invalid rho\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &K) != TCL_OK) { - opserr << "WARNING invalid K\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &G) != TCL_OK) { - opserr << "WARNING invalid G\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &Su) != TCL_OK) { - opserr << "WARNING invalid alpha1\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[7], &Ho) != TCL_OK) { - opserr << "WARNING invalid Ho\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[8], &h) != TCL_OK) { - opserr << "WARNING invalid h\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[9], &m) != TCL_OK) { - opserr << "WARNING invalid m\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[10], &beta) != TCL_OK) { - opserr << "WARNING invalid beta\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[11], &Kcoeff) != TCL_OK) { - opserr << "WARNING invalid Kcoeff\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (argc > 12 && Tcl_GetDouble(interp, argv[12], &eta) != TCL_OK) { - opserr << "WARNING invalid eta\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - theMaterial = new MultiaxialCyclicPlasticity(tag, 0, rho, K, G, Su, Ho, h, - m, beta, Kcoeff, eta); - } - - // Pressure Independent Multi-yield, by ZHY - else if (strcmp(argv[1], "PressureIndependMultiYield") == 0) { - const int numParam = 6; - const int totParam = 10; - int tag; - double param[totParam]; - param[6] = 0.0; - param[7] = 100.; - param[8] = 0.0; - param[9] = 20; - - const char *arg[] = {"nd", - "rho", - "refShearModul", - "refBulkModul", - "cohesi", - "peakShearStra", - "frictionAng (=0)", - "refPress (=100)", - "pressDependCoe (=0.0)", - "numberOfYieldSurf (=20)"}; - if (argc < (3 + numParam)) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PressureIndependMultiYield tag? " << arg[0]; - opserr << "? " - << "\n"; - opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " - << "\n"; - opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " - << "\n"; - opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid PressureIndependMultiYield tag" << "\n"; - return TCL_ERROR; - } - - for (int i = 3; (i < argc && i < 13); ++i) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - - static double *gredu = 0; - // user defined yield surfaces - if (param[9] < 0 && param[9] > -40) { - param[9] = -int(param[9]); - gredu = new double[int(2 * param[9])]; - for (int i = 0; i < 2 * param[9]; ++i) - if (Tcl_GetDouble(interp, argv[i + 13], &gredu[i]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - } - - PressureIndependMultiYield *temp = new PressureIndependMultiYield( - tag, param[0], param[1], param[2], param[3], param[4], param[5], - param[6], param[7], param[8], param[9], gredu); - theMaterial = temp; - - if (gredu != 0) { - delete[] gredu; - gredu = 0; - } - } - - // Pressure Independent Multi-yield, by Quan Gu - else if (strcmp(argv[1], "MultiYieldSurfaceClay") == 0) { - const int numParam = 6; - const int totParam = 10; - int tag; - double param[totParam]; - param[6] = 0.0; - param[7] = 100.; - param[8] = 0.0; - param[9] = 20; - - const char *arg[] = {"nd", - "rho", - "refShearModul", - "refBulkModul", - "cohesi", - "peakShearStra", - "frictionAng (=0)", - "refPress (=100)", - "pressDependCoe (=0.0)", - "numberOfYieldSurf (=20)"}; - if (argc < (3 + numParam)) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial MultiYieldSurfaceClay tag? " << arg[0]; - opserr << "? " - << "\n"; - opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " - << "\n"; - opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " - << "\n"; - opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid MultiYieldSurfaceClay tag" << "\n"; - return TCL_ERROR; - } - - for (int i = 3; (i < argc && i < 13); ++i) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial MultiYieldSurfaceClay: " << tag << "\n"; - return TCL_ERROR; - } - - static double *gredu = 0; - // user defined yield surfaces - if (param[9] < 0 && param[9] > -40) { - param[9] = -int(param[9]); - gredu = new double[int(2 * param[9])]; - for (int i = 0; i < 2 * param[9]; ++i) - if (Tcl_GetDouble(interp, argv[i + 13], &gredu[i]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial MultiYieldSurfaceClay: " << tag << "\n"; - return TCL_ERROR; - } - } - - MultiYieldSurfaceClay *temp = new MultiYieldSurfaceClay( - tag, param[0], param[1], param[2], param[3], param[4], param[5], - param[6], param[7], param[8], param[9], gredu); - theMaterial = temp; - - if (gredu != 0) { - delete[] gredu; - gredu = 0; - } - } - // ============ - - // Pressure Dependent Multi-yield, by ZHY - else if (strcmp(argv[1], "PressureDependMultiYield") == 0) { - const int numParam = 15; - const int totParam = 24; - int tag; - double param[totParam]; - param[15] = 20; - param[16] = 0.6; - param[17] = 0.9; - param[18] = 0.02; - param[19] = 0.7; - param[20] = 101.; - param[21] = .3; - param[22] = 0.; - param[23] = 1.; - - const char *arg[] = {"nd", - "rho", - "refShearModul", - "refBulkModul", - "frictionAng", - "peakShearStra", - "refPress", - "pressDependCoe", - "phaseTransformAngle", - "contractionParam1", - "dilationParam1", - "dilationParam2", - "liquefactionParam1", - "liquefactionParam2", - "liquefactionParam4", - "numberOfYieldSurf (=20)", - "e (=0.6)", - "volLimit1 (=0.9)", - "volLimit2 (=0.02)", - "volLimit3 (=0.7)", - "Atmospheric pressure (=101)", - "cohesi (=.5)", - "Hv (=0)", - "Pv (=1.)"}; - if (argc < (3 + numParam)) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PressureDependMultiYield tag? " << arg[0]; - opserr << "? " - << "\n"; - opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " - << "\n"; - opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " - << "\n"; - opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " - << "\n"; - opserr << arg[10] << "? " << arg[11] << "? " << arg[12] << "? " - << "\n"; - opserr << arg[13] << "? " << arg[14] << "? " << arg[15] << "? " - << "\n"; - opserr << arg[16] << "? " << arg[17] << "? " << arg[18] << "? " - << "\n"; - opserr << arg[19] << "? " << arg[20] << "? " << arg[21] << "? " << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid PressureDependMultiYield tag" << "\n"; - return TCL_ERROR; - } - - for (int i = 3; (i < argc && i < 19); ++i) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureDependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - - static double *gredu = 0; - // user defined yield surfaces - if (param[15] < 0 && param[15] > -40) { - param[15] = -int(param[15]); - gredu = new double[int(2 * param[15])]; - - for (int i = 0; i < 2 * param[15]; ++i) - if (Tcl_GetDouble(interp, argv[i + 19], &gredu[i]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - } - - if (gredu != 0) { - for (int i = 19 + int(2 * param[15]); i < argc; ++i) - if (Tcl_GetDouble(interp, argv[i], - ¶m[i - 3 - int(2 * param[15])]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[15])] - << "\n"; - opserr << "nDMaterial PressureDependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - } else { - for (int i = 19; i < argc; ++i) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[15])] - << "\n"; - opserr << "nDMaterial PressureDependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - } - - PressureDependMultiYield *temp = new PressureDependMultiYield( - tag, param[0], param[1], param[2], param[3], param[4], param[5], - param[6], param[7], param[8], param[9], param[10], param[11], param[12], - param[13], param[14], param[15], gredu, param[16], param[17], param[18], - param[19], param[20], param[21], param[22], param[23]); - - theMaterial = temp; - if (gredu != 0) { - delete[] gredu; - gredu = 0; - } - } - - // Pressure Dependent Multi-yield, by ZHY - else if (strcmp(argv[1], "PressureDependMultiYield02") == 0) { - const int numParam = 13; - const int totParam = 26; - int tag; - double param[totParam]; - param[numParam] = 20; - param[numParam + 1] = 5.0; - param[numParam + 2] = 3.; - param[numParam + 3] = 1.; - param[numParam + 4] = 0.; - param[numParam + 5] = 0.6; - param[numParam + 6] = 0.9; - param[numParam + 7] = 0.02; - param[numParam + 8] = 0.7; - param[numParam + 9] = 101.; - param[numParam +10] = 0.1; - param[numParam +11] = 0.; - param[numParam +12] = 1.; - - const char *arg[] = {"nd", - "rho", - "refShearModul", - "refBulkModul", - "frictionAng", - "peakShearStra", - "refPress", - "pressDependCoe", - "phaseTransformAngle", - "contractionParam1", - "contractionParam3", - "dilationParam1", - "dilationParam3", - "numberOfYieldSurf (=20)", - "contractionParam2=5.0", - "dilationParam2=3.0", - "liquefactionParam1=1.0", - "liquefactionParam2=0.0", - "e (=0.6)", - "volLimit1 (=0.9)", - "volLimit2 (=0.02)", - "volLimit3 (=0.7)", - "Atmospheric pressure (=101)", - "cohesi (=.1)", - "Hv (=0)", - "Pv (=1.)"}; - if (argc < (3 + numParam)) { - opserr << "WARNING insufficient arguments\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid PressureDependMultiYield02 tag" << "\n"; - return TCL_ERROR; - } - - int in = 17; - for (int i = 3; (i < argc && i < in); ++i) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureDependMultiYield02: " << tag << "\n"; - return TCL_ERROR; - } - - static double *gredu = 0; - - // user defined yield surfaces - if (param[numParam] < 0 && param[numParam] > -100) { - param[numParam] = -int(param[numParam]); - gredu = new double[int(2 * param[numParam])]; - - for (int i = 0; i < 2 * param[numParam]; ++i) - if (Tcl_GetDouble(interp, argv[i + in], &gredu[i]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - } - - if (gredu != 0) { - for (int i = in + int(2 * param[numParam]); i < argc; ++i) - if (Tcl_GetDouble(interp, argv[i], - ¶m[i - 3 - int(2 * param[numParam])]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[numParam])] - << "\n"; - opserr << "nDMaterial PressureDependMultiYield02: " << tag << "\n"; - return TCL_ERROR; - } - } else { - for (int i = in; i < argc; ++i) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[numParam])] - << "\n"; - opserr << "nDMaterial PressureDependMultiYield02: " << tag << "\n"; - return TCL_ERROR; - } - } - - PressureDependMultiYield02 *temp = new PressureDependMultiYield02( - tag, param[0], param[1], param[2], param[3], param[4], param[5], - param[6], param[7], param[8], param[9], param[10], param[11], param[12], - param[13], gredu, param[14], param[15], param[16], param[17], param[18], - param[19], param[20], param[21], param[22], param[23], param[24], - param[25]); - - theMaterial = temp; - if (gredu != 0) { - delete[] gredu; - gredu = 0; - } - } - - // nDMaterial PressureDependMultiYield03 $tag $nd $rho $refShearModul - // $refBulkModul $frictionAng $peakShearStra $refPress $pressDependCoe - // $PTAng $mType $ca $cb $cc $cd $ce $da $db $dc <$noYieldSurf=20 - // <$r1 $Gs1 …> $liquefac1=1. $liquefac2=0. $pa=101 <$c=1.73>> - // PressureDependMultiYield03 (based on PressureDependMultiYield02). - else if (strcmp(argv[1], "PressureDependMultiYield03") == 0) { - const int numParam = 18; - const int totParam = 23; - int tag; - double param[totParam]; - param[numParam] = 20; - param[numParam + 1] = 1.; - param[numParam + 2] = 0.; - param[numParam + 3] = 101.; - param[numParam + 4] = 1.73; - - const char *arg[] = {"nd", - "rho", - "refShearModul", - "refBulkModul", - "frictionAng", - "peakShearStra", - "refPress", - "pressDependCoe", - "phaseTransformAngle", - "mType", - "ca", - "cb", - "cc", - "cd", - "ce", - "da", - "db", - "dc", - "numberOfYieldSurf (=20)", - "liquefactionParam1=1.0", - "liquefactionParam2=0.0", - "Atmospheric pressure (=101)", - "cohesi (=1.73)"}; - - if (argc < (3 + numParam)) { // 3 refers to "nDMaterial - // PressureDependMultiYield03 $tag" - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PressureDependMultiYield03 tag? " << arg[0]; - opserr << "? " - << "\n"; - opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " - << "\n"; - opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " - << "\n"; - opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " - << "\n"; - opserr << arg[10] << "? " << arg[11] << "? " << arg[12] << "? " - << "\n"; - opserr << arg[13] << "? " << arg[14] << "? " << arg[15] << "? " - << "\n"; - opserr << arg[16] << "? " << arg[17] << "? " << arg[18] << "? " - << "\n"; - opserr << arg[19] << "? " << arg[20] << "? " << arg[21] << "? " << arg[22] - << "? " << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid PressureDependMultiYield03 tag" << "\n"; - return TCL_ERROR; - } - - int in = 22; - for (int i = 3; (i < argc && i < in); ++i) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureDependMultiYield03: " << tag << "\n"; - return TCL_ERROR; - } - - static double *gredu = 0; - - // user defined yield surfaces - if (param[numParam] < 0 && param[numParam] > -100) { - param[numParam] = -int(param[numParam]); - gredu = new double[int(2 * param[numParam])]; - - for (int i = 0; i < 2 * param[numParam]; ++i) - if (Tcl_GetDouble(interp, argv[i + in], &gredu[i]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureDependMultiYield03: " << tag << "\n"; - return TCL_ERROR; - } - } - - if (gredu != 0) { - for (int i = in + int(2 * param[numParam]); i < argc; ++i) - if (Tcl_GetDouble(interp, argv[i], - ¶m[i - 3 - int(2 * param[numParam])]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[numParam])] - << "\n"; - opserr << "nDMaterial PressureDependMultiYield03: " << tag << "\n"; - return TCL_ERROR; - } - } else { - for (int i = in; i < argc; ++i) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[numParam])] - << "\n"; - opserr << "nDMaterial PressureDependMultiYield03: " << tag << "\n"; - return TCL_ERROR; - } - } - - PressureDependMultiYield03 *temp = new PressureDependMultiYield03( - tag, param[0], param[1], param[2], param[3], param[4], param[5], - param[6], param[7], param[8], param[9], param[10], param[11], param[12], - param[13], param[14], param[15], param[16], param[17], param[18], gredu, - param[19], param[20], param[21], param[22]); - - theMaterial = temp; - if (gredu != 0) { - delete[] gredu; - gredu = 0; - } - } - - // Fluid Solid Porous, by ZHY - else if (strcmp(argv[1], "FluidSolidPorous") == 0) { - - int tag; - double param[4]; - const char *arg[] = {"nd", "soilMatTag", "combinedBulkModul", - "Atmospheric pressure"}; - if (argc < 6) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial FluidSolidPorous tag? " << arg[0]; - opserr << "? " - << "\n"; - opserr << arg[1] << "? " << arg[2] << "? " << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid FluidSolidPorous tag" << "\n"; - return TCL_ERROR; - } - - for (int i = 3; i < 6; ++i) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial FluidSolidPorous: " << tag << "\n"; - return TCL_ERROR; - } - - NDMaterial *soil = builder->getTypedObject(param[1]); - if (soil == nullptr) - return TCL_ERROR; - - - param[3] = 101.; - if (argc == 7) { - if (Tcl_GetDouble(interp, argv[6], ¶m[3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[3] << "\n"; - opserr << "nDMaterial FluidSolidPorous: " << tag << "\n"; - return TCL_ERROR; - } - } - - theMaterial = - new FluidSolidPorousMaterial(tag, param[0], *soil, param[2], param[3]); - } - - else if (strcmp(argv[1], "PlaneStressMaterial") == 0 || - strcmp(argv[1], "PlaneStress") == 0) { - if (argc < 4) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PlaneStress tag? matTag?" << "\n"; - return TCL_ERROR; - } - - int tag, matTag; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid nDMaterial PlaneStress tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << "WARNING invalid matTag" << "\n"; - opserr << "PlaneStress: " << matTag << "\n"; - return TCL_ERROR; - } - - NDMaterial *threeDMaterial = builder->getTypedObject(matTag); - if (threeDMaterial == nullptr) - return TCL_ERROR; - - theMaterial = new PlaneStressMaterial(tag, *threeDMaterial); - } - - // PlaneStrainMaterial - else if (strcmp(argv[1], "PlaneStrainMaterial") == 0 || - strcmp(argv[1], "PlaneStrain") == 0) { - if (argc < 4) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PlaneStrain tag? matTag?" << "\n"; - return TCL_ERROR; - } - - int tag, matTag; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid nDMaterial PlaneStrain tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << "WARNING invalid matTag" << "\n"; - opserr << "PlaneStrain: " << matTag << "\n"; - return TCL_ERROR; - } - - NDMaterial *threeDMaterial = builder->getTypedObject(matTag); - if (threeDMaterial == nullptr) - return TCL_ERROR; - - theMaterial = new PlaneStrainMaterial(tag, *threeDMaterial); - } - - // ----- Cap plasticity model ------ // Quan Gu & ZhiJian Qiu 2013 - - // format nDmaterial CapPlasticity $tag $ndm $rho $G $K $X $D $W $R $lambda - // $theta $beta $alpha $T $tol - else if (strcmp(argv[1], "CapPlasticity") == 0) { - - int tag; - int ndm = 3; - double rho = 0.0; - double G = 1.0e10; - double K = 1.1e10; - double X = 1.1032e8; - double D = 4.6412e-10; - double W = 0.42; - double R = 4.43; - double lambda = 7.9979e6; - double theta = 0.11; - double beta = 6.3816e-8; - double alpha = 2.6614e7; - double T = -2.0684e6; - double tol = 1.0e-10; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &ndm) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity nd" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &rho) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity rho" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &G) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity G" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &K) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity K" << "\n"; - return TCL_ERROR; - } - - if (argc > 7) { - - if (Tcl_GetDouble(interp, argv[7], &X) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity X" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[8], &D) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity D" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[9], &W) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity W" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[10], &R) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity R" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[11], &lambda) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity lambda" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[12], &theta) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity theta" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[13], &beta) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity beta" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[14], &alpha) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity alpha" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[15], &T) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity T" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[16], &tol) != TCL_OK) { - opserr << "WARNING invalid CapPlasticity tol" << "\n"; - return TCL_ERROR; - } - - } // end if - - theMaterial = new CapPlasticity(tag, G, K, rho, X, D, W, R, lambda, theta, - beta, alpha, T, ndm, tol); - - } - - ///////////////////////////////////////////////////////////////// - /* - nDmaterial Simplified3DJ2 $matTag $G $K $sig0 $H_kin $H_iso - - - SimplifiedJ2 (int tag, - int nd, - double G, - double K, - double sigmaY0, - double H_kin, - double H_iso); - - */ - - // Check argv[1] for J2PlaneStrain material type - else if ((strcmp(argv[1], "Simplified3DJ2") == 0) || - (strcmp(argv[1], "3DJ2") == 0)) { - if (argc < 8) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDmaterial Simplified3DJ2 $matTag $G $K $sig0 " - "$H_kin $H_iso" - << "\n"; - return TCL_ERROR; - } - - int tag; - double K, G, sig0, H_kin, H_iso; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid SimplifiedJ2 tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &G) != TCL_OK) { - opserr << "WARNING invalid G\n"; - opserr << "nDMaterial SimplifiedJ2: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &K) != TCL_OK) { - opserr << "WARNING invalid K\n"; - opserr << "nDMaterial SimplifiedJ2: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &sig0) != TCL_OK) { - opserr << "WARNING invalid sig0\n"; - opserr << "nDMaterial SimplifiedJ2: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &H_kin) != TCL_OK) { - opserr << "WARNING invalid H_kin\n"; - opserr << "nDMaterial SimplifiedJ2: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[7], &H_iso) != TCL_OK) { - opserr << "WARNING invalid H_iso\n"; - opserr << "nDMaterial SimplifiedJ2: " << tag << "\n"; - return TCL_ERROR; - } - - theMaterial = new SimplifiedJ2(tag, 3, G, K, sig0, H_kin, H_iso); - } - - else if (strcmp(argv[1], "PlateRebarMaterial") == 0 || - strcmp(argv[1], "PlateRebar") == 0) { - if (argc < 5) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PlateRebar tag? matTag? angle?" << "\n"; - return TCL_ERROR; - } - - int tag, matTag; - double angle; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid nDMaterial PlateRebar tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << "WARNING invalid matTag" << "\n"; - opserr << "PlateRebar: " << tag << "\n"; - return TCL_ERROR; - } - - UniaxialMaterial *theMat = builder->getTypedObject(matTag); - if (theMat == nullptr) - return TCL_ERROR; - - if (Tcl_GetDouble(interp, argv[4], &angle) != TCL_OK) { - opserr << "WARNING invalid angle" << "\n"; - opserr << "PlateRebar: " << tag << "\n"; - return TCL_ERROR; - } - - theMaterial = new PlateRebarMaterial(tag, *theMat, angle); - } - - // start Yuli Huang & Xinzheng Lu PlateFromPlaneStressMaterial - else if (strcmp(argv[1], "PlateFromPlaneStressMaterial") == 0 || - strcmp(argv[1], "PlateFromPlaneStress") == 0) { - if (argc < 5) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PlateFromPlaneStress tag? matTag? gmod?" - << "\n"; - return TCL_ERROR; - } - - int tag, matTag; - double gmod; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid nDMaterial PlateFromPlaneStress tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << "WARNING invalid matTag" << "\n"; - opserr << "PlateFromPlaneStress: " << tag << "\n"; - return TCL_ERROR; - } - - NDMaterial *theMat = builder->getTypedObject(matTag); - if (theMat == nullptr) - return TCL_ERROR; - - if (Tcl_GetDouble(interp, argv[4], &gmod) != TCL_OK) { - opserr << "WARNING invalid gmod" << "\n"; - opserr << "PlateFromPlaneStress: " << tag << "\n"; - return TCL_ERROR; - } - - theMaterial = new PlateFromPlaneStressMaterial(tag, *theMat, gmod); - } - - // start Yuli Huang & Xinzheng Lu ConcreteS - else if (strcmp(argv[1], "ConcreteS") == 0) { - if (argc < 8) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial ConcreteS tag? E? nu? fc? ft? Es?" << "\n"; - return TCL_ERROR; - } - - int tag; - double E, nu, fc, ft, Es; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid nDMaterial ConcreteS tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { - opserr << "WARNING invalid E" << "\n"; - opserr << "ConcreteS: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &nu) != TCL_OK) { - opserr << "WARNING invalid nu" << "\n"; - opserr << "ConcreteS: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &fc) != TCL_OK) { - opserr << "WARNING invalid fc" << "\n"; - opserr << "ConcreteS: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &ft) != TCL_OK) { - opserr << "WARNING invalid ft" << "\n"; - opserr << "ConcreteS: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[7], &Es) != TCL_OK) { - opserr << "WARNING invalid Es" << "\n"; - opserr << "ConcreteS: " << tag << "\n"; - return TCL_ERROR; - } - - theMaterial = new ConcreteS(tag, E, nu, fc, ft, Es); - } - // end Yuli Huang & Xinzheng Lu ConcreteS - - // start Yuli Huang & Xinzheng Lu PlaneStressUserMaterial - else if (strcmp(argv[1], "PlaneStressUserMaterial") == 0) { - if (argc < 6) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PlaneStressUserMaterial tag? nstatevs? " - "nprops? prop1? ... propn?" - << "\n"; - return TCL_ERROR; - } - - int tag, nstatevs, nprops; - double *props, p; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid nDMaterial PlaneStressUserMaterial tag" - << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &nstatevs) != TCL_OK) { - opserr << "WARNING invalid nDMaterial PlaneStressUserMaterial nstatevs" - << "\n"; - return TCL_ERROR; - } - - if (nstatevs < 1) - nstatevs = 1; - - if (Tcl_GetInt(interp, argv[4], &nprops) != TCL_OK) { - opserr << "WARNING invalid nDMaterial PlaneStressUserMaterial nprops" - << "\n"; - return TCL_ERROR; - } - - if (nprops < 1) - nprops = 1; - - props = new double[nprops]; - for (int i = 0; i < nprops; ++i) { - if (Tcl_GetDouble(interp, argv[5 + i], &p) != TCL_OK) { - opserr << "WARNING invalid prop" << "\n"; - opserr << "PlaneStressUserMaterial: " << tag << "\n"; - return TCL_ERROR; - } - props[i] = p; - } - - theMaterial = new PlaneStressUserMaterial(tag, nstatevs, nprops, props); - - if (props != nullptr) - delete [] props; - } - // end Yuli Huang & Xinzheng Lu PlaneStressUserMaterial - - else if (strcmp(argv[1], "ConcreteMcftNonLinear7") == 0 || - strcmp(argv[1], "ConcreteMcftNonLinear5") == 0) { - if (argc < 11) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial ConcreteMcftNonlinear7 tag? fcu? ecu? Ec? " - "fcr? Esv? fyv? alphaV? RoV?" - << "\n"; - return TCL_ERROR; - } - - int tag = 0; - double fcu = 0.0; - double ecu = 0.0; - double Ec = 0.0; - double fcr = 0.0; - double Esv = 0.0; - double fyv = 0.0; - double alphaV = 0.0; - double RoV = 0.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid ConcreteMcftNonlinear7: tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &fcu) != TCL_OK) { - opserr << "WARNING invalid fcu\n"; - opserr << "nDMaterial ConcreteMcftNonLinearNonLinear5: fcu" << tag - << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &ecu) != TCL_OK) { - opserr << "WARNING invalid ecu\n"; - opserr << "nDMaterial ConcreteMcftNonLinearNonLinear5: ecu" << tag - << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &Ec) != TCL_OK) { - opserr << "WARNING invalid Ec\n"; - opserr << "nDMaterial ConcreteMcftNonlinear7: Ec" << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &fcr) != TCL_OK) { - opserr << "WARNING invalid fcr\n"; - opserr << "nDMaterial ConcreteMcftNonlinear7: fcr" << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[7], &Esv) != TCL_OK) { - opserr << "WARNING invalid Esv\n"; - opserr << "nDMaterial ConcreteMcftNonlinear7: Esv" << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[8], &fyv) != TCL_OK) { - opserr << "WARNING invalid fyv\n"; - opserr << "nDMaterial ConcreteMcftNonlinear7: fyv" << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[9], &alphaV) != TCL_OK) { - opserr << "WARNING invalid alphaV\n"; - opserr << "nDMaterial ConcreteMcftNonlinear7: alphaV" << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[10], &RoV) != TCL_OK) { - opserr << "WARNING invalid RoV\n"; - opserr << "nDMaterial ConcreteMcftNonlinear7: RoV" << tag << "\n"; - return TCL_ERROR; - } - - if (strcmp(argv[1], "ConcreteMcftNonLinear7") == 0) - theMaterial = new ConcreteMcftNonLinear7(tag, fcu, ecu, Ec, fcr, Esv, fyv, - alphaV, RoV); - else - theMaterial = new ConcreteMcftNonLinear5(tag, fcu, ecu, Ec, fcr, Esv, fyv, - alphaV, RoV); - } - - else if (strcmp(argv[1], "Bidirectional") == 0) { - opserr << "nDMaterial Bidirectional is now a section model, please " - << "change to \'section Bidirectional\'" << "\n"; - return TCL_ERROR; - } - - //------------------------------------------------------------- - else if (strcmp(argv[1], "PlateFromPlaneStressThermal") == 0) { - if (argc < 5) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PlateFromPlaneStress tag? matTag? gmod?" - << "\n"; - return TCL_ERROR; - } - - int tag, matTag; - double gmod; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid nDMaterial PlateFromPlaneStress tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << "WARNING invalid matTag" << "\n"; - opserr << "PlateFromPlaneStress: " << tag << "\n"; - return TCL_ERROR; - } - - NDMaterial *theMat = builder->getTypedObject(matTag); - if (theMat == nullptr) - return TCL_ERROR; - - if (Tcl_GetDouble(interp, argv[4], &gmod) != TCL_OK) { - opserr << "WARNING invalid gmod" << "\n"; - opserr << "PlateFromPlaneStress: " << tag << "\n"; - return TCL_ERROR; - } - - theMaterial = new PlateFromPlaneStressMaterialThermal(tag, *theMat, gmod); - } else if (strcmp(argv[1], "PlateRebarMaterialThermal") == 0 || - strcmp(argv[1], "PlateRebarThermal") == 0) { - if (argc < 5) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PlateRebar tag? matTag? angle?" << "\n"; - return TCL_ERROR; - } - - int tag, matTag; - double angle; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid nDMaterial PlateRebar tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << "WARNING invalid matTag" << "\n"; - opserr << "PlateRebar: " << tag << "\n"; - return TCL_ERROR; - } - - UniaxialMaterial *theMat = builder->getTypedObject(matTag); - if (theMat == nullptr) - return TCL_ERROR; - - - if (Tcl_GetDouble(interp, argv[4], &angle) != TCL_OK) { - opserr << "WARNING invalid angle" << "\n"; - opserr << "PlateRebar: " << tag << "\n"; - return TCL_ERROR; - } - - theMaterial = new PlateRebarMaterialThermal(tag, *theMat, angle); -// - } else if ((strcmp(argv[1], "J2PlasticityThermal") == 0) || - (strcmp(argv[1], "J2Thermal") == 0)) { - if (argc < 9) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial J2PlasticityThermal tag? K? G? sig0? sigInf? " - "delta? H? " - << "\n"; - return TCL_ERROR; - } - - int tag; - double K, G, sig0, sigInf, delta, H; - double eta = 0.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid J2PlasticityThermal tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &K) != TCL_OK) { - opserr << "WARNING invalid K\n"; - opserr << "nDMaterial J2PlasticityThermal: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &G) != TCL_OK) { - opserr << "WARNING invalid G\n"; - opserr << "nDMaterial J2PlasticityThermal: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &sig0) != TCL_OK) { - opserr << "WARNING invalid sig0\n"; - opserr << "nDMaterial J2PlasticityThermal: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &sigInf) != TCL_OK) { - opserr << "WARNING invalid sigInf\n"; - opserr << "nDMaterial J2PlasticityThermal: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[7], &delta) != TCL_OK) { - opserr << "WARNING invalid delta\n"; - opserr << "nDMaterial J2PlasticityThermal: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[8], &H) != TCL_OK) { - opserr << "WARNING invalid H\n"; - opserr << "nDMaterial J2PlasticityThermal: " << tag << "\n"; - return TCL_ERROR; - } - if (argc > 9 && Tcl_GetDouble(interp, argv[9], &eta) != TCL_OK) { - opserr << "WARNING invalid eta\n"; - opserr << "nDMaterial J2PlasticityThermal: " << tag << "\n"; - return TCL_ERROR; - } - - theMaterial = - new J2PlasticityThermal(tag, 0, K, G, sig0, sigInf, delta, H, eta); - - } else if (strcmp(argv[1], "PlateFiberMaterialThermal") == 0 || - strcmp(argv[1], "PlateFiberThermal") == 0) { - if (argc < 4) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PlateFiberThermal tag? matTag?" << "\n"; - return TCL_ERROR; - } - - int tag, matTag; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid nDMaterial PlateFiberThermal tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << "WARNING invalid matTag" << "\n"; - opserr << "PlateFiberThermal: " << matTag << "\n"; - return TCL_ERROR; - } - - NDMaterial *threeDMaterial = builder->getTypedObject(matTag); - if (threeDMaterial == nullptr) - return TCL_ERROR; - - theMaterial = new PlateFiberMaterialThermal(tag, *threeDMaterial); - } - //--------End of adding PlateFiberMaterialThermal - - // end of adding thermo-mechanical nd materials-L.Jiang[SIF] - -#if defined(OPSDEF_Material_FEAP) - else { - theMaterial = TclBasicBuilder_addFeapMaterial(clientData, interp, argc, argv); - } -#endif // _OPS_Material_FEAP - - if (theMaterial == 0) { - // - // maybe element in a class package already loaded - // loop through linked list of loaded functions comparing names & if find - // call it - // - - NDMaterialPackageCommand *matCommands = theNDMaterialPackageCommands; - bool found = false; - while (matCommands != NULL && found == false) { - if (strcmp(argv[1], matCommands->funcName) == 0) { - theMaterial = (NDMaterial *)(*(matCommands->funcPtr))(); - found = true; - ; - } else - matCommands = matCommands->next; - } - } - - // - // check to see if element is a procedure - // the proc may already have been loaded from a package or may exist in a - // package yet to be loaded - // - if (theMaterial == nullptr) { -#if 0 - // maybe material in a routine - // - - char *matType = new char[strlen(argv[1]) + 1]; - strcpy(matType, argv[1]); - matObj *matObject = OPS_GetMaterialType(matType, strlen(matType)); - - delete[] matType; - - if (matObject != 0) { - - theMaterial = Tcl_addWrapperNDMaterial(matObject, clientData, interp, - argc, argv); - - if (theMaterial == 0) - delete matObject; - } -#endif - } - - // - // maybe material class exists in a package yet to be loaded - // - - if (theMaterial == 0) { - - void *libHandle; - void *(*funcPtr)(); - - int matNameLength = strlen(argv[1]); - char *tclFuncName = new char[matNameLength + 12]; - strcpy(tclFuncName, "OPS_"); - strcpy(&tclFuncName[4], argv[1]); - int res = - getLibraryFunction(argv[1], tclFuncName, &libHandle, (void **)&funcPtr); - - delete[] tclFuncName; - - if (res == 0) { - // - // add loaded function to list of functions - // - char *matName = new char[matNameLength + 1]; - strcpy(matName, argv[1]); - NDMaterialPackageCommand *theMatCommand = new NDMaterialPackageCommand; - theMatCommand->funcPtr = funcPtr; - theMatCommand->funcName = matName; - theMatCommand->next = theNDMaterialPackageCommands; - theNDMaterialPackageCommands = theMatCommand; - - theMaterial = (NDMaterial *)(*funcPtr)(); - } - } - - if (theMaterial == nullptr) { - opserr << "WARNING could not create nDMaterial: " << argv[1]; - return TCL_ERROR; - } - - // Now add the material to the modelBuilder - if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { - - opserr << "WARNING could not add material to the domain\n"; - opserr << *theMaterial << "\n"; - delete theMaterial; - return TCL_ERROR; - } - - return TCL_OK; -} diff --git a/SRC/runtime/commands/modeling/nodes.cpp b/SRC/runtime/commands/modeling/nodes.cpp index ede1a660e9..7cbf7ca512 100644 --- a/SRC/runtime/commands/modeling/nodes.cpp +++ b/SRC/runtime/commands/modeling/nodes.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. @@ -34,7 +34,6 @@ #define HeapNode Node -// #define G3_MAX_NUM_DOFS 1000000000000 #define G3_NUM_DOF_BUFFER 20 int diff --git a/SRC/runtime/commands/modeling/section/PlaneSection.h b/SRC/runtime/commands/modeling/section/PlaneSection.h index 69433b1a5a..5011a4b8e1 100644 --- a/SRC/runtime/commands/modeling/section/PlaneSection.h +++ b/SRC/runtime/commands/modeling/section/PlaneSection.h @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/section/frame.cpp b/SRC/runtime/commands/modeling/section/frame.cpp index 14f42ee47d..9f9b9e73eb 100644 --- a/SRC/runtime/commands/modeling/section/frame.cpp +++ b/SRC/runtime/commands/modeling/section/frame.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/section/plane.cpp b/SRC/runtime/commands/modeling/section/plane.cpp index c31610cd3e..6ddd47405f 100644 --- a/SRC/runtime/commands/modeling/section/plane.cpp +++ b/SRC/runtime/commands/modeling/section/plane.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/section/truss.cpp b/SRC/runtime/commands/modeling/section/truss.cpp index 12b3a739ac..a446da2a96 100644 --- a/SRC/runtime/commands/modeling/section/truss.cpp +++ b/SRC/runtime/commands/modeling/section/truss.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp index c41852bbbf..8b8961e59d 100644 --- a/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp +++ b/SRC/runtime/commands/modeling/transform/FrameTransformBuilder.hpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/modeling/uniaxial.hpp b/SRC/runtime/commands/modeling/uniaxial.hpp index 2db6a0c4ff..9c085fffee 100644 --- a/SRC/runtime/commands/modeling/uniaxial.hpp +++ b/SRC/runtime/commands/modeling/uniaxial.hpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/commands/parallel/mpiMain.cpp b/SRC/runtime/commands/parallel/mpiMain.cpp deleted file mode 100644 index 57db9fc825..0000000000 --- a/SRC/runtime/commands/parallel/mpiMain.cpp +++ /dev/null @@ -1,371 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -/* - * tclAppInit.c -- - * - * Provides a default version of the main program and Tcl_AppInit - * procedure for Tcl applications (without Tk). - * - * Copyright (c) 1993 The Regents of the University of California. - * Copyright (c) 1994-1997 Sun Microsystems, Inc. - * Copyright (c) 1998-1999 by Scriptics Corporation. - * - * See Tcl/Tk License Terms for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: mpiMain.cpp,v 1.13 2010-04-23 23:01:14 fmk Exp $ - -Tcl/Tk License Terms: -This software is copyrighted by the Regents of the University of -California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState -Corporation and other parties. The following terms apply to all files -associated with the software unless explicitly disclaimed in -individual files. - -The authors hereby grant permission to use, copy, modify, distribute, -and license this software and its documentation for any purpose, provided -that existing copyright notices are retained in all copies and that this -notice is included verbatim in any distributions. No written agreement, -license, or royalty fee is required for any of the authorized uses. -Modifications to this software may be copyrighted by their authors -and need not follow the licensing terms described here, provided that -the new terms are clearly indicated on the first page of each file where -they apply. - -IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY -FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY -DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE -IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE -NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR -MODIFICATIONS. - -GOVERNMENT USE: If you are acquiring this software on behalf of the -U.S. government, the Government shall have only "Restricted Rights" -in the software and related documentation as defined in the Federal -Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you -are acquiring the software on behalf of the Department of Defense, the -software shall be classified as "Commercial Computer Software" and the -Government shall have only "Restricted Rights" as defined in Clause -252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the -authors grant the U.S. Government and others acting in its behalf -permission to use and distribute the software in accordance with the -terms specified in this license. - - */ - -extern "C" { -#include -} - - -// #include -#include "commands.h" - -/* - * The following variable is a special hack that is needed in order for - * Sun shared libraries to be used for Tcl. - */ - -#ifdef _KAI -//extern "C" int matherr(); -#endif - -#ifdef _UNIX -//#include - -//int *tclDummyMathPtr = (int *)matherr; -#endif - - -#ifdef TCL_TEST - -extern "C" { -#include "tclInt.h" -} - - - -extern int Procbodytest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -extern int Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp *interp)); -extern int TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -extern int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -#ifdef TCL_THREADS -extern int TclThread_Init _ANSI_ARGS_((Tcl_Interp *interp)); -#endif - -#endif /* TCL_TEST */ - -#ifdef TCL_XT_TEST -extern void XtToolkitInitialize _ANSI_ARGS_((void)); -extern int Tclxttest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -#endif - -/* - *---------------------------------------------------------------------- - * - * main -- - * - * This is the main program for the application. - * - * Results: - * None: Tcl_Main never returns here, so this procedure never - * returns either. - * - * Side effects: - * Whatever the application does. - * - *---------------------------------------------------------------------- - */ - -extern void g3TclMain(int argc, char **argv, Tcl_AppInitProc *appInitProc, int rank, int np); -#include -#include - -#include -#include -#include -#include -#include - -#include - -extern PartitionedDomain theDomain; -extern int OPS_PARALLEL_PROCESSING; -extern int OPS_NUM_SUBDOMAINS; -extern bool OPS_PARTITIONED; -extern FEM_ObjectBroker *OPS_OBJECT_BROKER; -extern MachineBroker *OPS_MACHINE; -extern bool OPS_USING_MAIN_DOMAIN; -extern int OPS_MAIN_DOMAIN_PARTITION_ID; - -extern DomainPartitioner *OPS_DOMAIN_PARTITIONER; -extern GraphPartitioner *OPS_GRAPH_PARTITIONER; -extern LoadBalancer *OPS_BALANCER; -extern FEM_ObjectBroker *OPS_OBJECT_BROKER; -extern MachineBroker *OPS_MACHINE; -extern Channel **OPS_theChannels; - -extern MachineBroker *theMachineBroker; -extern Channel **theChannels; -extern int numChannels; -extern int OPS_rank; -extern int OPS_np; - -#include - -int -main(int argc, char **argv) -{ - theMachineBroker = new MPI_MachineBroker(0, argc, argv); - FEM_ObjectBrokerAllClasses theBroker; - theMachineBroker->setObjectBroker(&theBroker); - - OPS_rank = theMachineBroker->getPID(); - OPS_np = theMachineBroker->getNP(); - - // - // depending on rank we do something - // - if (OPS_rank != 0) { - - // - // on secondary processes we spin waiting to create & run actors - // - fprintf(stderr, "Secondary Process Running %d\n", OPS_rank); - theMachineBroker->runActors(); - - } else { - - // - // on process 0 we create some ShadowSubdomains & then start the OpenSees interpreter - // - fprintf(stderr, "Primary Process Running OpenSees Interpreter %d\n", OPS_rank); - - // - // set some global parameters - // - OPS_OBJECT_BROKER = &theBroker; - // OPS_MACHINE = &theMachine; - OPS_MACHINE = theMachineBroker; - OPS_PARALLEL_PROCESSING = OPS_np; - - /* only use p0 if even number of partitions - if (OPS_np%2 == 0) { - OPS_NUM_SUBDOMAINS = OPS_np; - OPS_USING_MAIN_DOMAIN = true; - OPS_MAIN_DOMAIN_PARTITION_ID = 1; - } else - OPS_NUM_SUBDOMAINS = OPS_np - 1; - */ - // always use p0 even if ODD number of partitions - OPS_NUM_SUBDOMAINS = OPS_np; - OPS_USING_MAIN_DOMAIN = true; - OPS_MAIN_DOMAIN_PARTITION_ID = 1; - - OPS_PARTITIONED = false; - - // - // the rest straightr out of regular tclMain to start our interpreter - // - - /* - * The following #if block allows you to change the AppInit - * function by using a #define of TCL_LOCAL_APPINIT instead - * of rewriting this entire file. The #if checks for that - * #define and uses Tcl_AppInit if it doesn't exist. - */ - -#ifndef TCL_LOCAL_APPINIT -#define TCL_LOCAL_APPINIT Tcl_AppInit -#endif - - /* fmk - comment out the following block to get to compile - extern "C" int TCL_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp)); - fmk - end commented block */ - - /* - * The following #if block allows you to change how Tcl finds the startup - * script, prime the library or encoding paths, fiddle with the argv, - * etc., without needing to rewrite Tcl_Main() - */ - -#ifdef TCL_LOCAL_MAIN_HOOK - extern int TCL_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv)); -#endif - -#ifdef TCL_XT_TEST - XtToolkitInitialize(); -#endif - -#ifdef TCL_LOCAL_MAIN_HOOK - TCL_LOCAL_MAIN_HOOK(&argc, &argv); -#endif - - g3TclMain(argc, argv, TCL_LOCAL_APPINIT, 1, 0); - - // some clean up to shut the remotes down if still running - theDomain.clearAll(); - - // shutdown the remote machines - theMachineBroker->shutdown(); - } - - // - // mpi clean up - // - - fprintf(stderr, "Process Terminating %d\n", OPS_rank); - - if (theMachineBroker != 0) - delete theMachineBroker; - - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_AppInit -- - * - * This procedure performs application-specific initialization. - * Most applications, especially those that incorporate additional - * packages, will have their own version of this procedure. - * - * Results: - * Returns a standard Tcl completion code, and leaves an error - * message in the interp's result if an error occurs. - * - * Side effects: - * Depends on the startup script. - * - *---------------------------------------------------------------------- - */ - - -int Tcl_AppInit(Tcl_Interp *interp) -{ - if (Tcl_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - -#ifdef TCL_TEST -#ifdef TCL_XT_TEST - if (Tclxttest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } -#endif - if (Tcltest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, - (Tcl_PackageInitProc *) NULL); - if (TclObjTest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } -#ifdef TCL_THREADS - if (TclThread_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } -#endif - if (Procbodytest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init, - Procbodytest_SafeInit); -#endif /* TCL_TEST */ - - /* - * Call the init procedures for included packages. Each call should - * look like this: - * - * if (Mod_Init(interp) == TCL_ERROR) { - * return TCL_ERROR; - * } - * - * where "Mod" is the name of the module. - */ - - /* - * Call Tcl_CreateCommand for application-specific commands, if - * they weren't already created by the init procedures called above. - */ - - if (OpenSeesAppInit(interp) < 0) - return TCL_ERROR; - - /* - * Specify a user-specific startup file to invoke if the application - * is run interactively. Typically the startup file is "~/.apprc" - * where "app" is the name of the application. If this line is deleted - * then no user-specific startup file will be run under any conditions. - */ - - Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY); - return TCL_OK; -} - - diff --git a/SRC/runtime/commands/parallel/parallel_commands.cpp b/SRC/runtime/commands/parallel/parallel_commands.cpp deleted file mode 100644 index 2804def62a..0000000000 --- a/SRC/runtime/commands/parallel/parallel_commands.cpp +++ /dev/null @@ -1,355 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// -// -// -#include -#include -#include -#include -#include - -#define _PARALLEL_MP - -#ifdef _PARALLEL_SP -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# define MPIPP_H -# include -# include - -// MachineBroker *theMachineBroker = 0; - int OPS_PARALLEL_SP = 0; - int OPS_NUM_SUBDOMAINS = 0; - bool OPS_PARTITIONED = false; - bool OPS_USING_MAIN_DOMAIN = false; - bool setMPIDSOEFlag = false; - int OPS_MAIN_DOMAIN_PARTITION_ID = 0; - PartitionedDomain theDomain; - DomainPartitioner *OPS_DOMAIN_PARTITIONER = nullptr; - GraphPartitioner *OPS_GRAPH_PARTITIONER = nullptr; - LoadBalancer *OPS_BALANCER = nullptr; - TclPackageClassBroker *OPS_OBJECT_BROKER = nullptr; - MachineBroker *OPS_MACHINE = nullptr; - Channel **OPS_theChannels = nullptr; - -# elif defined(_PARALLEL_MP) - - bool setMPIDSOEFlag = false; - - // parallel analysis - #include - -// Domain theDomain; -#endif - -int getPID(ClientData, Tcl_Interp *, int, TCL_Char ** const argv); -int getNP( ClientData, Tcl_Interp *, int, TCL_Char ** const argv); -int opsBarrier(ClientData, Tcl_Interp *, int, TCL_Char ** const argv); -int opsSend(ClientData, Tcl_Interp *, int, TCL_Char ** const argv); -int opsRecv(ClientData, Tcl_Interp *, int,TCL_Char ** const argv); -int opsPartition(ClientData, Tcl_Interp *, int, TCL_Char ** const argv); -int wipePP(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -void Init_Parallel(Tcl_Interp* interp) -{ - MachineBroker* theMachineBroker = new MPI_MachineBroker(nullptr, 0, nullptr); - Tcl_CreateCommand(interp, "getNP", &getNP, (ClientData)theMachineBroker, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "getPID", &getPID, (ClientData)theMachineBroker, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "send", &opsSend, (ClientData)theMachineBroker, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "recv", &opsRecv, (ClientData)theMachineBroker, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "barrier", &opsBarrier, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "partition", &opsPartition, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); -} - - -int -getPID(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - int pid = 0; - - MachineBroker* theMachineBroker = (MachineBroker*)clientData; - - if (theMachineBroker != nullptr) - pid = theMachineBroker->getPID(); - - // now we copy the value to the tcl string that is returned - char buffer[30]; - sprintf(buffer, "%d", pid); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); - - return TCL_OK; -} - -int -getNP(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - int np = 1; - MachineBroker* theMachineBroker = (MachineBroker*)clientData; - - if (theMachineBroker != nullptr) - np = theMachineBroker->getNP(); - - // now we copy the value to the tcl string that is returned - char buffer[30]; - sprintf(buffer, "%d", np); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); - - return TCL_OK; -} - - -#ifdef _PARALLEL_SP -static int -partitionModel(int eleTag) -{ - if (OPS_PARTITIONED == true) - return 0; - - int result = 0; - - if (OPS_theChannels != 0) - delete[] OPS_theChannels; - - OPS_theChannels = new Channel *[OPS_NUM_SUBDOMAINS]; - - // create some subdomains - for (int i = 1; i <= OPS_NUM_SUBDOMAINS; i++) { - if (i != OPS_MAIN_DOMAIN_PARTITION_ID) { - ShadowSubdomain *theSubdomain = - new ShadowSubdomain(i, *OPS_MACHINE, *OPS_OBJECT_BROKER); - theDomain.addSubdomain(theSubdomain); - OPS_theChannels[i - 1] = theSubdomain->getChannelPtr(); - } - } - - // create a partitioner & partition the domain - if (OPS_DOMAIN_PARTITIONER == nullptr) { - // OPS_BALANCER = new ShedHeaviest(); - OPS_GRAPH_PARTITIONER = new Metis; - // OPS_DOMAIN_PARTITIONER = new DomainPartitioner(*OPS_GRAPH_PARTITIONER, - // *OPS_BALANCER); - OPS_DOMAIN_PARTITIONER = new DomainPartitioner(*OPS_GRAPH_PARTITIONER); - theDomain.setPartitioner(OPS_DOMAIN_PARTITIONER); - } - - result = theDomain.partition(OPS_NUM_SUBDOMAINS, OPS_USING_MAIN_DOMAIN, - OPS_MAIN_DOMAIN_PARTITION_ID, eleTag); - - if (result < 0) - return result; - - OPS_PARTITIONED = true; - - DomainDecompositionAnalysis *theSubAnalysis; - SubdomainIter &theSubdomains = theDomain.getSubdomains(); - Subdomain *theSub = 0; - - // create the appropriate domain decomposition analysis - while ((theSub = theSubdomains()) != 0) { - if (the_static_analysis != 0) { - theSubAnalysis = new StaticDomainDecompositionAnalysis( - *theSub, *theHandler, *theNumberer, *the_analysis_model, *theAlgorithm, - *theSOE, *theStaticIntegrator, theTest, false); - - } else { - theSubAnalysis = new TransientDomainDecompositionAnalysis( - *theSub, *theHandler, *theNumberer, *the_analysis_model, *theAlgorithm, - *theSOE, *theTransientIntegrator, theTest, false); - } - theSub->setDomainDecompAnalysis(*theSubAnalysis); - } - - return result; -} -#endif - - -int -opsBarrier(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ -#ifdef _PARALLEL_MP - return MPI_Barrier(MPI_COMM_WORLD); -#endif - return TCL_OK; -} - -int -opsSend(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - if (argc < 2) - return TCL_OK; - - int otherPID = -1; - MachineBroker* theMachineBroker = (MachineBroker*)clientData; - int myPID = theMachineBroker->getPID(); - int np = theMachineBroker->getNP(); - const char *dataToSend = argv[argc - 1]; - int msgLength = strlen(dataToSend) + 1; - - const char *gMsg = dataToSend; - // strcpy(gMsg, dataToSend); - - if (strcmp(argv[1], "-pid") == 0 && argc > 3) { - - if (Tcl_GetInt(interp, argv[2], &otherPID) != TCL_OK) { - opserr << "send -pid pid? data? - pid: " << argv[2] << " invalid\n"; - return TCL_ERROR; - } - - if (otherPID > -1 && otherPID != myPID && otherPID < np) { - - MPI_Send((void *)(&msgLength), 1, MPI_INT, otherPID, 0, MPI_COMM_WORLD); - MPI_Send((void *)gMsg, msgLength, MPI_CHAR, otherPID, 1, MPI_COMM_WORLD); - - } else { - opserr << "send -pid pid? data? - pid: " << otherPID << " invalid\n"; - return TCL_ERROR; - } - - } else { - if (myPID == 0) { - MPI_Bcast((void *)(&msgLength), 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast((void *)gMsg, msgLength, MPI_CHAR, 0, MPI_COMM_WORLD); - } else { - opserr << "send data - only process 0 can do a broadcast - you may need " - "to kill the application"; - return TCL_ERROR; - } - } - return TCL_OK; -} - -int -opsRecv(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ -#ifdef _PARALLEL_MP - MachineBroker* theMachineBroker = (MachineBroker*)clientData; - if (argc < 2) - return TCL_OK; - - int otherPID = 0; - int myPID = theMachineBroker->getPID(); - int np = theMachineBroker->getNP(); - TCL_Char *varToSet = argv[argc - 1]; - - int msgLength = 0; - char *gMsg = 0; - - if (strcmp(argv[1], "-pid") == 0 && argc > 3) { - - bool fromAny = false; - - if ((strcmp(argv[2], "ANY") == 0) || (strcmp(argv[2], "ANY_SOURCE") == 0) || - (strcmp(argv[2], "MPI_ANY_SOURCE") == 0)) { - fromAny = true; - } else { - if (Tcl_GetInt(interp, argv[2], &otherPID) != TCL_OK) { - opserr << "recv -pid pid? data? - pid: " << argv[2] << " invalid\n"; - return TCL_ERROR; - } - } - - if (otherPID > -1 && otherPID < np) { - MPI_Status status; - - if (fromAny == false) - if (myPID != otherPID) - MPI_Recv((void *)(&msgLength), 1, MPI_INT, otherPID, 0, - MPI_COMM_WORLD, &status); - else { - opserr << "recv -pid pid? data? - " << otherPID - << " cant receive from self!\n"; - return TCL_ERROR; - } - else { - MPI_Recv((void *)(&msgLength), 1, MPI_INT, MPI_ANY_SOURCE, 0, - MPI_COMM_WORLD, &status); - otherPID = status.MPI_SOURCE; - } - - if (msgLength > 0) { - gMsg = new char[msgLength]; - - MPI_Recv((void *)gMsg, msgLength, MPI_CHAR, otherPID, 1, MPI_COMM_WORLD, - &status); - - Tcl_SetVar(interp, varToSet, gMsg, TCL_LEAVE_ERR_MSG); - } - - } else { - opserr << "recv -pid pid? data? - " << otherPID << " invalid\n"; - return TCL_ERROR; - } - } else { - if (myPID != 0) { - MPI_Bcast((void *)(&msgLength), 1, MPI_INT, 0, MPI_COMM_WORLD); - - if (msgLength > 0) { - gMsg = new char[msgLength]; - - MPI_Bcast((void *)gMsg, msgLength, MPI_CHAR, 0, MPI_COMM_WORLD); - - Tcl_SetVar(interp, varToSet, gMsg, TCL_LEAVE_ERR_MSG); - } - - } else { - opserr << "recv data - only process 0 can do a broadcast - you may need " - "to kill the application"; - return TCL_ERROR; - } - } -#endif - - return TCL_OK; -} - - -int -opsPartition(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ -#ifdef _PARALLEL_SP - int eleTag; - if (argc == 2) { - if (Tcl_GetInt(interp, argv[1], &eleTag) != TCL_OK) { - ; - } - } - partitionModel(eleTag); -#endif - return TCL_OK; -} - -int -wipePP(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - -#ifdef _PARALLEL_SP - if (OPS_PARTITIONED == true && OPS_NUM_SUBDOMAINS > 1) { - SubdomainIter &theSubdomains = theDomain.getSubdomains(); - Subdomain *theSub =0; - - // create the appropriate domain decomposition analysis - while ((theSub = theSubdomains()) != 0) - theSub->wipeAnalysis(); - } -#endif - return TCL_OK; -} - diff --git a/SRC/runtime/commands/pragma.cpp b/SRC/runtime/commands/pragma.cpp index 1ca9a3a28b..5514f13444 100644 --- a/SRC/runtime/commands/pragma.cpp +++ b/SRC/runtime/commands/pragma.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // #include diff --git a/SRC/runtime/parsing/ArgumentTracker.h b/SRC/runtime/parsing/ArgumentTracker.h index fe6675022f..1d8b3e3b88 100644 --- a/SRC/runtime/parsing/ArgumentTracker.h +++ b/SRC/runtime/parsing/ArgumentTracker.h @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/parsing/Parsing.h b/SRC/runtime/parsing/Parsing.h index 52ca07b354..88f59106e1 100644 --- a/SRC/runtime/parsing/Parsing.h +++ b/SRC/runtime/parsing/Parsing.h @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/runtime/BasicAnalysisBuilder.h b/SRC/runtime/runtime/BasicAnalysisBuilder.h index 278557a103..9609ab6d11 100644 --- a/SRC/runtime/runtime/BasicAnalysisBuilder.h +++ b/SRC/runtime/runtime/BasicAnalysisBuilder.h @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/runtime/BasicModelBuilder.cpp b/SRC/runtime/runtime/BasicModelBuilder.cpp index dd60d69aa5..35ecb469af 100644 --- a/SRC/runtime/runtime/BasicModelBuilder.cpp +++ b/SRC/runtime/runtime/BasicModelBuilder.cpp @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// // -// Copyright (c) 2025, Claudio M. Perez +// Copyright (c) 2025, OpenSees/Xara Developers // All rights reserved. No warranty, explicit or implicit, is provided. // // This source code is licensed under the BSD 2-Clause License. diff --git a/SRC/runtime/runtime/G3_Runtime.cpp b/SRC/runtime/runtime/G3_Runtime.cpp deleted file mode 100644 index 6e045a079a..0000000000 --- a/SRC/runtime/runtime/G3_Runtime.cpp +++ /dev/null @@ -1,143 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// -// -// written: cmp -// -#include -#include -#include "G3_Runtime.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// DEFAULTS -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class StaticIntegrator; - -#define G3Config_keyExists(conf, key) ((conf).find((key)) != (conf).end()) - -template -using G3_Parse = T* (*)(G3_Runtime*, int, const char **const); - - -// Wrap a function with signature -// T* G3Parse_newT(G3_Runtime*, int argc, G3_Char** argv) -// so that it works with a std::vector -template -T* G3Object_newParsed(G3_Runtime *rt, G3_Char* command, std::vector args) { - std::vector cstrs; - cstrs.reserve(args.size()+1); - cstrs.push_back(command); - for (auto &s : args) - cstrs.push_back(const_cast(s.c_str())); - return (*fn)(rt, cstrs.size(), cstrs.data()); -} - - - -void * -G3_Runtime::newStaticAnalysis(G3_Config conf) -{ - StaticIntegrator* sintegrator = new LoadControl(1, 1, 1, 1); - - // CONVERGENCE TEST - ConvergenceTest* test = new CTestNormUnbalance(1.0e-6,25,0); - - // ALGORITHM - EquiSolnAlgo* the_algorithm = new NewtonRaphson(*test); - - // NUMBERER - DOF_Numberer* the_numberer = new DOF_Numberer(*(new RCM(false))); - - // CONSTRAINT HANDLER - ConstraintHandler *the_handler = new TransformationConstraintHandler(); - - // LINEAR SYSTEM - LinearSOE* the_soe = new ProfileSPDLinSOE(*new ProfileSPDLinDirectSolver()); - - - if (m_analysis_model == nullptr) - m_analysis_model = new AnalysisModel(); - - return new StaticAnalysis(*m_domain, - *the_handler, - *the_numberer, - *m_analysis_model, - *the_algorithm, - *the_soe, - *sintegrator, - test); -} -#if 1 -void * -G3_Runtime::newTransientAnalysis(G3_Config conf) -{ - // NUMBERER - DOF_Numberer* the_numberer = new DOF_Numberer(*(new RCM(false))); - - // CONSTRAINT HANDLER - ConstraintHandler *the_handler = new TransformationConstraintHandler(); - - // CONVERGENCE TEST - ConvergenceTest *test = new CTestNormUnbalance(1.0e-6,25,0); - - // ALGORITHM - EquiSolnAlgo* the_algorithm = new NewtonRaphson(*test); - - // LINEAR SYSTEM - LinearSOE* the_soe = new ProfileSPDLinSOE(*new ProfileSPDLinDirectSolver()); - - - // ANALYSIS MODEL - if (m_analysis_model == nullptr) - m_analysis_model = new AnalysisModel(); - - TransientIntegrator* tintegrator = new Newmark(0.5, 0.25); - - - if (G3Config_keyExists(conf, "analysis")) { - if (!conf["analysis"].empty() && (conf["analysis"][0] == "Variable")) - return new VariableTimeStepDirectIntegrationAnalysis( - *m_domain, - *the_handler, - *the_numberer, - *m_analysis_model, - *the_algorithm, - *the_soe, - *tintegrator, - test); - } - return new DirectIntegrationAnalysis( - *m_domain, - *the_handler, - *the_numberer, - *m_analysis_model, - *the_algorithm, - *the_soe, - *tintegrator, - test); -} - -#endif diff --git a/SRC/runtime/runtime/MeshModelBuilder.h b/SRC/runtime/runtime/MeshModelBuilder.h deleted file mode 100644 index 339c8a255d..0000000000 --- a/SRC/runtime/runtime/MeshModelBuilder.h +++ /dev/null @@ -1,5 +0,0 @@ -// -// -// added commands: -// material -// diff --git a/SRC/runtime/runtime/SectionBuilder/CMakeLists.txt b/SRC/runtime/runtime/SectionBuilder/CMakeLists.txt deleted file mode 100644 index d1715ccf64..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -#============================================================================== -# -# OpenSees -- Open System For Earthquake Engineering Simulation -# Pacific Earthquake Engineering Research Center -# -#============================================================================== -add_library(OPS_Section_Repres OBJECT) - -target_include_directories(OPS_Section_Repres PUBLIC ${CMAKE_CURRENT_LIST_DIR}) - -add_subdirectory(./cell/) -add_subdirectory(./patch/) -add_subdirectory(./reinfBar/) -add_subdirectory(./reinfLayer/) - diff --git a/SRC/runtime/runtime/SectionBuilder/FiberSectionBuilder.h b/SRC/runtime/runtime/SectionBuilder/FiberSectionBuilder.h deleted file mode 100644 index 8661a5f481..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/FiberSectionBuilder.h +++ /dev/null @@ -1,110 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// -// -// Written: cmp -// -#ifndef FiberSectionBuilder_h -#define FiberSectionBuilder_h - -#include -#include -#include -#include -#include - -#include - -// Inherit tagged object so that the model builder can delete -class SectionBuilder: public TaggedObject { -public: - SectionBuilder(int tag) : TaggedObject(tag) {} - - virtual int addFiber(int tag, int mat, double area, const Vector& cPos) =0; - virtual int addHFiber(int tag, int mat, double area, const Vector& cPos)=0; - - int addPatch(const Patch& patch) { - Cell** cells = patch.getCells(); - const int nc = patch.getNumCells(); - const int mat = patch.getMaterialID(); - for(int j=0; jgetArea(); - const Vector& cPos = cells[j]->getCentroidPosition(); - - if (this->addFiber(j, mat, area, cPos) != 0) - return -1; - } - return 0; - } - - int addLayer(const ReinfLayer& layer) { - - int numReinfBars = layer.getNumReinfBars(); - ReinfBar* reinfBar = layer.getReinfBars(); - int mat = layer.getMaterialID(); - - for(int j=0; jaddFiber(j, mat, area, cPos) != 0) - return -1; - } - return 0; - } - -}; - -template -class FiberSectionBuilder : public SectionBuilder { -public: - FiberSectionBuilder(BasicModelBuilder& builder_, SecT& section_) - : SectionBuilder(section_.getTag()), builder(builder_), section(section_) {} - - virtual int addHFiber(int tag, int mat, double area, const Vector& cPos); - int addFiber(int tag, int mat, double area, const Vector& cPos) { - - MatT * theMaterial = builder.getTypedObject(mat); - if (theMaterial == nullptr) { - opserr << "no material with tag " << mat << " for fiber " << tag << "\n"; - return -1; - } - - if constexpr (ndm==2) { - section.addFiber(*theMaterial, area, cPos(0)); - - } else { - section.addFiber(*theMaterial, area, cPos(0), cPos(1)); - } - return 0; - } - -private: - BasicModelBuilder& builder; - SecT& section; -}; - -template <> int -FiberSectionBuilder<2, UniaxialMaterial, FiberSection2dInt>::addHFiber(int tag, int mat, double area, const Vector& cPos) { - - UniaxialMaterial * theMaterial = builder.getTypedObject(mat); - if (theMaterial == nullptr) { - opserr << G3_ERROR_PROMPT << "no material with tag " << mat << " for fiber " << tag << "\n"; - return -1; - } - - section.addHFiber(*theMaterial, area, cPos(0)); - return 0; -} - -template int -FiberSectionBuilder::addHFiber(int tag, int mat, double area, const Vector& cPos) { - opserr << G3_ERROR_PROMPT << "section does not support H fibers\n"; - return -1; -} - -#endif - diff --git a/SRC/runtime/runtime/SectionBuilder/cell/CMakeLists.txt b/SRC/runtime/runtime/SectionBuilder/cell/CMakeLists.txt deleted file mode 100644 index dd766ddbf3..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/cell/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -#============================================================================== -# -# OpenSees -- Open System For Earthquake Engineering Simulation -# Pacific Earthquake Engineering Research Center -# -#============================================================================== - -target_sources(OPS_Section_Repres - PRIVATE - Cell.cpp - CircSectionCell.cpp - QuadCell.cpp - PUBLIC - Cell.h - CircSectionCell.h - QuadCell.h -) -target_include_directories(OPS_Section_Repres PUBLIC ${CMAKE_CURRENT_LIST_DIR}) - diff --git a/SRC/runtime/runtime/SectionBuilder/cell/Cell.h b/SRC/runtime/runtime/SectionBuilder/cell/Cell.h deleted file mode 100644 index 76302ed124..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/cell/Cell.h +++ /dev/null @@ -1,59 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -// -// File: Cell.h -// -// Written by Remo M. de Souza -// December 1998 - - -#ifndef Cell_h -#define Cell_h - -#include - -class Vector; - -class Cell -{ - public: - - Cell(); - virtual ~Cell(); - - // edition functions - - // reinforcing bar inquiring functions - - virtual double getArea (void) const = 0; - virtual double getdValue (void) const = 0; - virtual const Vector &getCentroidPosition (void) = 0; - - virtual void Print(OPS_Stream &s, int flag =0) const = 0; - friend OPS_Stream &operator<<(OPS_Stream &s, const Cell &Cell); - - protected: - - private: -}; - - -#endif - diff --git a/SRC/runtime/runtime/SectionBuilder/cell/CircSectionCell.cpp b/SRC/runtime/runtime/SectionBuilder/cell/CircSectionCell.cpp deleted file mode 100644 index fdc970ae98..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/cell/CircSectionCell.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -// Written: fmk -// March 2014 - -#include -#include -#include - -#include - -CircSectionCell::CircSectionCell(double R1, double R2, double Alpha, double Theta, double offX, double offY) - :r1(R1), r2(R2), alpha(Alpha), theta(Theta), A(0.0), Centroid(2), offsetX(offX), offsetY(offY) -{ - - double a = alpha/2.0; - - double At = a*r2*r2; - double ct = 2.0*r2*sin(a)/(3.0*a); - double A1 = a*r1*r1; - double c1 = 2.0*r1*sin(a)/(3.0*a); - - A = At - A1; - double c = (At*ct - A1*c1)/A; - - Centroid(0) = cos(Theta)*c + offX; - Centroid(1) = sin(Theta)*c + offY; -} - - -CircSectionCell::~CircSectionCell() -{ - -} - -double CircSectionCell::getArea (void) const -{ - return A; -} - -double CircSectionCell::getdValue (void) const -{ - return 1.0; // TODO: Should be something meaningful -- MHS -} - -const Vector & -CircSectionCell::getCentroidPosition(void) -{ - return Centroid; -} - - - -void CircSectionCell::Print(OPS_Stream &s, int flag) const -{ - s << "\nCell Type: CircSectionCell"; - s << "\n\tr1: " << r1 << " r2: " << r2 << " alpha: " << alpha << " theta: " << theta << endln; -} - - -OPS_Stream &operator<<(OPS_Stream &s, const CircSectionCell &cell) -{ - cell.Print(s); - return s; -} - diff --git a/SRC/runtime/runtime/SectionBuilder/cell/CircSectionCell.h b/SRC/runtime/runtime/SectionBuilder/cell/CircSectionCell.h deleted file mode 100644 index 07c66c8d15..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/cell/CircSectionCell.h +++ /dev/null @@ -1,69 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -#ifndef CircSectionCell_h -#define CircSectionCell_h - -#include -#include - -class Matrix; -class Vector; - - -class CircSectionCell: public Cell -{ - public: - - CircSectionCell(); - CircSectionCell(double r2, double r1, double alpha, double theta, double centerX, double centerY); - - ~CircSectionCell(); - - // edition functions - - void setVertCoords (const Matrix &vertexCoords); - - // reinforcing bar inquiring functions - - double getArea (void) const; - double getdValue (void) const; - const Matrix &getVertCoords (void) const; - const Vector &getCentroidPosition (void); - - void Print(OPS_Stream &s, int flag =0) const; - friend OPS_Stream &operator<<(OPS_Stream &s, const CircSectionCell &quadCell); - - protected: - - private: - double r1, r2; // r1 inner and r2 outer radii - double alpha; // inner angle of section - double theta; // angle of centerline about z axis - - double A; - Vector Centroid; - double offsetX, offsetY; -// double area; -}; - - -#endif - diff --git a/SRC/runtime/runtime/SectionBuilder/cell/QuadCell.cpp b/SRC/runtime/runtime/SectionBuilder/cell/QuadCell.cpp deleted file mode 100644 index 6c9324bb50..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/cell/QuadCell.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -// $Revision: 1.3 $ -// $Date: 2003/05/02 18:34:56 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/section/repres/cell/QuadCell.cpp,v $ - - -// File: QuadCell.C -// Written by Remo M. de Souza -// December 1998 - -#include -#include - -#include - - -QuadCell::QuadCell(void): - vertCoord(4,2), Centroid(2) -{ - -} - - -QuadCell::QuadCell(const Matrix &vertexCoords): - vertCoord(vertexCoords), Centroid(2) -{ - -} - - -QuadCell::~QuadCell() -{ - -} - -const Matrix & -QuadCell::getVertCoords (void) const -{ - return vertCoord; -} - -double QuadCell::getdValue (void) const -{ - double dVa = vertCoord(0,0); - return dVa; -} - -void QuadCell::setVertCoords (const Matrix &vertexCoords) -{ - vertCoord = vertexCoords; -} - - -double QuadCell::getArea (void) const -{ - double area; - double x0, y0, x1, y1, x2, y2, x3, y3; - -// opserr << "cell vertCoord: " << vertCoord; - - x0 = vertCoord(0,0); - y0 = vertCoord(0,1); - x1 = vertCoord(1,0); - y1 = vertCoord(1,1); - x2 = vertCoord(2,0); - y2 = vertCoord(2,1); - x3 = vertCoord(3,0); - y3 = vertCoord(3,1); - - area = ((x2-x1)*(y0-y1) - (x0-x1)*(y2-y1) + - (x0-x3)*(y2-y3) - (x2-x3)*(y0-y3)) / 2.0; - -// opserr << "area1=" << area; - - int i, i1; - double yi, zi, yi1, zi1; - area = 0; - - for (i = 0; i < 4; i++) - { - i1 = (i+1)%4; - yi = vertCoord(i,0); - zi = vertCoord(i,1); - yi1 = vertCoord(i1,0); - zi1 = vertCoord(i1,1); - - area += (zi1 - zi) * (yi1 + yi); - } - area /= 2.0; - -// opserr << "area2= " << area << endln; - - return area; - -} - - -const Vector & -QuadCell::getCentroidPosition(void) -{ - int i, i1; - double yi, zi, yi1, zi1, dyi, dzi; - double area, integ; - double CGy = 0.0, CGz = 0.0; - - area = this->getArea(); - - for (i = 0; i < 4; i++) - { - i1 = (i+1)%4; - - yi = vertCoord(i,0); - zi = vertCoord(i,1); - yi1 = vertCoord(i1,0); - zi1 = vertCoord(i1,1); - - dyi = yi1 - yi; - dzi = zi1 - zi; - - integ = yi*zi + (yi*dzi + zi*dyi)/2.0 + dyi*dzi/3.0; - - CGy -= dyi * integ; - CGz += dzi * integ; - } - - CGy /= area; - CGz /= area; - - Centroid(0) = CGy; - Centroid(1) = CGz; - -// opserr << "\narea : " << area << " centroid: " << Centroid; - - return Centroid; -} - - - -void QuadCell::Print(OPS_Stream &s, int flag) const -{ - s << "\nCell Type: QuadCell"; - s << "\nVertex Coordinates: " << vertCoord; -} - - -OPS_Stream &operator<<(OPS_Stream &s, const QuadCell &quadCell) -{ - quadCell.Print(s); - return s; -} - diff --git a/SRC/runtime/runtime/SectionBuilder/cell/QuadCell.h b/SRC/runtime/runtime/SectionBuilder/cell/QuadCell.h deleted file mode 100644 index 314005d35c..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/cell/QuadCell.h +++ /dev/null @@ -1,75 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -// $Revision: 1.2 $ -// $Date: 2003/02/14 23:01:36 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/section/repres/cell/QuadCell.h,v $ - - -// File: QuadCell.h -// -// Written by Remo M. de Souza -// December 1998 - - -#ifndef QuadCell_h -#define QuadCell_h - -#include -#include - -class Matrix; -class Vector; - - -class QuadCell: public Cell -{ - public: - - QuadCell(); - QuadCell(const Matrix &vertexCoords); - - ~QuadCell(); - - // edition functions - - void setVertCoords (const Matrix &vertexCoords); - - // reinforcing bar inquiring functions - - double getArea (void) const; - double getdValue (void) const; - const Matrix &getVertCoords (void) const; - const Vector &getCentroidPosition (void); - - void Print(OPS_Stream &s, int flag =0) const; - friend OPS_Stream &operator<<(OPS_Stream &s, const QuadCell &quadCell); - - protected: - - private: - Matrix vertCoord; - Vector Centroid; -// double area; -}; - - -#endif - diff --git a/SRC/runtime/runtime/SectionBuilder/patch/CMakeLists.txt b/SRC/runtime/runtime/SectionBuilder/patch/CMakeLists.txt deleted file mode 100644 index 253d0d8b5e..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/patch/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -#============================================================================== -# -# OpenSees -- Open System For Earthquake Engineering Simulation -# Pacific Earthquake Engineering Research Center -# -#============================================================================== - -target_sources(OPS_Section_Repres - PRIVATE - CircPatch.cpp - Patch.cpp - QuadPatch.cpp - PUBLIC - CircPatch.h - Patch.h - QuadPatch.h -) -target_include_directories(OPS_Section_Repres PUBLIC ${CMAKE_CURRENT_LIST_DIR}) - diff --git a/SRC/runtime/runtime/SectionBuilder/patch/CircPatch.cpp b/SRC/runtime/runtime/SectionBuilder/patch/CircPatch.cpp deleted file mode 100644 index e8f3b70aa8..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/patch/CircPatch.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ****************************************************************** */ -// -// File: CircPatch.C -// Written by Remo M. de Souza -// December 1998 -// -#include -#include -#include -#include -#include -#include - - - -CircPatch::CircPatch(int materialID, int numSubdivCircunf, int numSubdivRadial, - const VectorND<2> ¢erPosition, double internRadius, - double externRadius, double initialAngle, double finalAngle): - matID(materialID), - nDivCirc(numSubdivCircunf), nDivRad(numSubdivRadial), - centerPosit(centerPosition), - intRad(internRadius), extRad(externRadius), - initAng(initialAngle), finalAng(finalAngle) -{ - -} - - -CircPatch::~CircPatch() -{ - -} - -void CircPatch::setMaterialID(int materialID) -{ - matID = materialID; -} - - -void CircPatch::setDiscretization(int numSubdivCircunf, int numSubdivRadial) -{ - nDivRad = numSubdivRadial; - nDivCirc = numSubdivCircunf; -} - - -void CircPatch::setRadii(double internRadius, double externRadius) -{ - intRad = internRadius; - extRad = externRadius; -} - -void CircPatch::setAngles(double initialAngle, double finalAngle) -{ - initAng = initialAngle; - finalAng = finalAngle; -} - - -int CircPatch::getMaterialID(void) const -{ - return matID; -} - -void CircPatch::getDiscretization(int &numSubdivCircunf, int &numSubdivRadial) const -{ - numSubdivCircunf = nDivCirc; - numSubdivRadial = nDivRad; -} - -void CircPatch::getRadii(double &internRadius, double &externRadius) const -{ - internRadius = intRad; - externRadius = extRad; -} - -void CircPatch::getAngles(double &initialAngle, double &finalAngle) const -{ - initialAngle = initAng; - finalAngle = finalAng; -} - -VectorND<2> -CircPatch::getCenterPosition() const -{ - return centerPosit; -} - -int CircPatch::getNumCells() const -{ - return nDivCirc * nDivRad; -} - -Cell ** -CircPatch::getCells() const -{ - double pi = acos(-1.0); - double deltaRad, deltaTheta; - double initAngRadians, finalAngRadians; - double rad_j, rad_j1, theta_i, theta_i1; - Matrix cellVertCoord(4,2); - - int numCells; - Cell **cells; - - if (nDivRad > 0 && nDivCirc > 0) - { - numCells = this->getNumCells(); - - cells = new Cell* [numCells]; - - initAngRadians = pi * initAng / 180.0; - finalAngRadians = pi * finalAng / 180.0; - - deltaRad = (extRad - intRad) / nDivRad; - deltaTheta = (finalAngRadians - initAngRadians) / nDivCirc; - - int k = 0; - for (int j = 0; j < nDivRad; j++) - { - rad_j = intRad + deltaRad*j; - rad_j1 = rad_j + deltaRad; - - for (int i = 0; i < nDivCirc; i++) - { - // compute coordinates - - theta_i = initAngRadians + deltaTheta*i; - - /* - theta_i1 = theta_i + deltaTheta; - cellVertCoord(0,0) = centerPosit(0) + rad_j * cos(theta_i1); - cellVertCoord(0,1) = centerPosit(1) + rad_j * sin(theta_i1); - cellVertCoord(1,0) = centerPosit(0) + rad_j * cos(theta_i); - cellVertCoord(1,1) = centerPosit(1) + rad_j * sin(theta_i); - cellVertCoord(2,0) = centerPosit(0) + rad_j1 * cos(theta_i); - cellVertCoord(2,1) = centerPosit(1) + rad_j1 * sin(theta_i); - cellVertCoord(3,0) = centerPosit(0) + rad_j1 * cos(theta_i1); - cellVertCoord(3,1) = centerPosit(1) + rad_j1 * sin(theta_i1); - - cells[k] = new QuadCell(cellVertCoord); - */ - - theta_i1 = theta_i + deltaTheta/2.0; - cells[k] = new CircSectionCell(rad_j, rad_j1, deltaTheta, theta_i1, centerPosit(0), centerPosit(1)); - - k++; - } - } - } - else - return 0; - - return cells; -} - - -Patch * -CircPatch::getCopy() const -{ - CircPatch *theCopy = new CircPatch (matID, nDivCirc, nDivRad, - centerPosit, intRad, extRad, - initAng, finalAng); - return theCopy; -} - -void CircPatch::Print(OPS_Stream &s, int flag) const -{ - s << "\nPatch Type: CircPatch"; - s << "\nMaterial Id: " << matID; - s << "\nNumber of subdivisions in the radial direction: " << nDivRad; - s << "\nNumber of subdivisions in the circunferential direction: " << nDivCirc; -// s << "\nCenter Position: " << Vector(centerPosit); - s << "\nInternal Radius: " << intRad << "\tExternal Radius: " << extRad; - s << "\nInitial Angle: " << initAng << "\tFinal Angle: " << finalAng; -} - diff --git a/SRC/runtime/runtime/SectionBuilder/patch/CircPatch.h b/SRC/runtime/runtime/SectionBuilder/patch/CircPatch.h deleted file mode 100644 index c19abe08c3..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/patch/CircPatch.h +++ /dev/null @@ -1,65 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ****************************************************************** */ -// -// File: CircPatch.h -// Written by Remo M. de Souza -// December 1998 -// -#ifndef CircPatch_h -#define CircPatch_h - -#include -#include -#include -using OpenSees::VectorND; - -class Cell; -class Matrix; - -class CircPatch: public Patch -{ - public: - - CircPatch(int materialID, int numSubdivCircunf, int numSubdivRadial, - const VectorND<2> ¢erPosition, double internRadius, - double externRadius, double initialAngle, double finalAngle); - - ~CircPatch(); - - // edition functions - - void setMaterialID (int materialID); - void setDiscretization (int numSubdivCircunf, int numSubdivRadial); - void setRadii (double internRadius, double externRadius); - void setAngles (double initialAngle, double finalAngle); - - // reinforcing bar inquiring functions - - int getMaterialID () const; - int getNumCells () const; - Cell **getCells () const; - Patch *getCopy () const; - - void getDiscretization (int &numSubdivCircunf, int &numSubdivRadial) const; - void getRadii (double &internRadius, double &externRadius) const; - void getAngles (double &initialAngle, double &finalAngle) const; - VectorND<2> getCenterPosition () const; - - void Print(OPS_Stream &s, int flag =0) const; - - protected: - - private: - int matID; - int nDivCirc, nDivRad; - const VectorND<2> centerPosit; - double intRad, extRad; - double initAng, finalAng; -}; - - -#endif - - diff --git a/SRC/runtime/runtime/SectionBuilder/patch/Patch.h b/SRC/runtime/runtime/SectionBuilder/patch/Patch.h deleted file mode 100644 index 2b247cbba5..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/patch/Patch.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -// -// File: Patch.h -// Written by Remo M. de Souza -// December 1998 -// -#ifndef Patch_h -#define Patch_h - -class Cell; -class OPS_Stream; - -class Patch -{ - public: - - Patch(); - virtual ~Patch(); - - // edition functions - - virtual void setMaterialID (int materialID) = 0; - - // inquiring functions - - virtual int getMaterialID (void) const = 0; - virtual int getNumCells (void) const = 0; - virtual Cell **getCells (void) const = 0; - virtual Patch *getCopy (void) const = 0; - - virtual void Print(OPS_Stream &s, int flag =0) const =0; - friend OPS_Stream &operator<<(OPS_Stream &s, const Patch &patch); - - protected: - - private: -}; - - -#endif diff --git a/SRC/runtime/runtime/SectionBuilder/patch/QuadPatch.cpp b/SRC/runtime/runtime/SectionBuilder/patch/QuadPatch.cpp deleted file mode 100644 index 64a10788bc..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/patch/QuadPatch.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -// -// File: QuadPatch.C -// Written by Remo M. de Souza -// December 1998 -// -#include -#include -#include -#include -#include - -void * OPS_ADD_RUNTIME_VPV(OPS_QuadPatch) -{ - if(OPS_GetNumRemainingInputArgs() < 11) { - opserr<<"insufficient arguments for QuadPatch\n"; - return 0; - } - - // get idata - int numData = 3; - int idata[3]; - if(OPS_GetIntInput(&numData,&idata[0]) < 0) return 0; - - // get data - static Matrix vertexCoords(4,2); - double data[8]; - numData = 8; - if(OPS_GetDoubleInput(&numData,&data[0]) < 0) return 0; - for(int i=0; i<4; i++) { - for(int j=0; j<2; j++) { - vertexCoords(i,j) = data[i*2+j]; - } - } - - return new QuadPatch(idata[0],idata[1],idata[2],vertexCoords); -} - -void * OPS_ADD_RUNTIME_VPV(OPS_RectPatch) -{ - if(OPS_GetNumRemainingInputArgs() < 7) { - opserr<<"insufficient arguments for RectPatch\n"; - return 0; - } - - // get idata - int numData = 3; - int idata[3]; - if(OPS_GetIntInput(&numData,&idata[0]) < 0) return 0; - - // get data - static Matrix vertexCoords(4,2); - double data[4]; - numData = 4; - if(OPS_GetDoubleInput(&numData,&data[0]) < 0) return 0; - vertexCoords(0,0) = data[0]; - vertexCoords(0,1) = data[1]; - vertexCoords(1,0) = data[2]; - vertexCoords(1,1) = data[1]; - vertexCoords(2,0) = data[2]; - vertexCoords(2,1) = data[3]; - vertexCoords(3,0) = data[0]; - vertexCoords(3,1) = data[3]; - - return new QuadPatch(idata[0],idata[1],idata[2],vertexCoords); -} - - -QuadPatch::QuadPatch(): - matID(0), nDivIJ(1), nDivJK(1), vertCoord(4,2) -{ - -} - - -QuadPatch::QuadPatch(int materialID, int numSubdivIJ, int numSubdivJK, - const Matrix &vertexCoords): - matID(materialID), - nDivIJ(numSubdivIJ), nDivJK(numSubdivJK), - vertCoord(vertexCoords) - -{ - -} - - -QuadPatch::~QuadPatch() -{ - -} - -void QuadPatch::setMaterialID(int materialID) -{ - matID = materialID; -} - - -void QuadPatch::setDiscretization(int numSubdivIJ, int numSubdivJK) -{ - nDivIJ = numSubdivIJ; - nDivJK = numSubdivJK; -} - -void QuadPatch::setVertCoords(const Matrix &vertexCoords) -{ - vertCoord = vertexCoords; -} - -int QuadPatch::getMaterialID(void) const -{ - return matID; -} - -void QuadPatch::getDiscretization(int &numSubdivIJ, int &numSubdivJK) const -{ - numSubdivIJ = nDivIJ; - numSubdivJK = nDivJK; -} - -const Matrix & QuadPatch::getVertCoords (void) const -{ - return vertCoord; -} - -int QuadPatch::getNumCells (void) const -{ - return nDivIJ * nDivJK; -} - -Cell ** -QuadPatch::getCells (void) const -{ - double deltaXi; - double deltaEta; - Matrix cellVertCoord(4,2); - Vector N(4); - double xi, eta; - int i, j, k, r, s; - int numCells; - Cell **cells; - - if (nDivIJ > 0 && nDivJK > 0) - { - numCells = this->getNumCells(); - - cells = new Cell* [numCells]; - - if (!cells) - return 0; - - deltaXi = 2.0 / nDivIJ; - deltaEta = 2.0 / nDivJK; - - k = 0; - for (j = 0; j < nDivJK; j++) - for (i = 0; i < nDivIJ; i++) - { - // compute natural coordinates - - cellVertCoord(0,0) = -1.0 + deltaXi * i; - cellVertCoord(0,1) = -1.0 + deltaEta * j; - cellVertCoord(1,0) = -1.0 + deltaXi * (i+1); - cellVertCoord(1,1) = cellVertCoord(0,1); - cellVertCoord(2,0) = cellVertCoord(1,0); - cellVertCoord(2,1) = -1.0 + deltaEta * (j+1); - cellVertCoord(3,0) = cellVertCoord(0,0); - cellVertCoord(3,1) = cellVertCoord(2,1); - - // map to cartesian coordinates using bilinear - // shape functions - - for (r = 0; r < 4; r++) - { - xi = cellVertCoord(r,0); - eta = cellVertCoord(r,1); - - N(0) = (1.0 - xi)*(1.0 - eta)/4.0; - N(1) = (1.0 + xi)*(1.0 - eta)/4.0; - N(2) = (1.0 + xi)*(1.0 + eta)/4.0; - N(3) = (1.0 - xi)*(1.0 + eta)/4.0; - - cellVertCoord(r,0) = 0.0; - cellVertCoord(r,1) = 0.0; - - for (s = 0; s < 4; s++) - { - cellVertCoord(r,0) += N(s) * vertCoord(s,0); - cellVertCoord(r,1) += N(s) * vertCoord(s,1); - } - } - - cells[k] = new QuadCell(cellVertCoord); - //opserr << "\ncreating cells Cell " << k << " :" << cells[k]; - k++; - } - } - else - return 0; - - return cells; -} - - -Patch * -QuadPatch::getCopy (void) const -{ - QuadPatch *theCopy = new QuadPatch (matID, nDivIJ, nDivJK, vertCoord); - return theCopy; -} - -void QuadPatch::Print(OPS_Stream &s, int flag) const -{ - s << "\nPatch Type: QuadPatch"; - s << "\nMaterial Id: " << matID; - s << "\nNumber of subdivisions in the IJ direction: " << nDivIJ; - s << "\nNumber of subdivisions in the JK direction: " << nDivJK; - s << "\nVertex Coordinates: " << vertCoord; -} - - -OPS_Stream &operator<<(OPS_Stream &s, QuadPatch &quadPatch) -{ - quadPatch.Print(s); - return s; -} diff --git a/SRC/runtime/runtime/SectionBuilder/patch/QuadPatch.h b/SRC/runtime/runtime/SectionBuilder/patch/QuadPatch.h deleted file mode 100644 index 83fb453d95..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/patch/QuadPatch.h +++ /dev/null @@ -1,75 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -// -// File: QuadPatch.h -// Written by Remo M. de Souza -// December 1998 -// -#ifndef QuadPatch_h -#define QuadPatch_h - -#include -#include -#include - -class Cell; -class Matrix; - -class QuadPatch: public Patch -{ - public: - - QuadPatch(); - QuadPatch(int materialID, int numSubdivIJ, int numSubdivJK, - const Matrix &vertexCoords); - - ~QuadPatch(); - - // edition functions - - void setMaterialID (int materialID); - void setDiscretization (int numSubdivIJ, int numSubdivJK); - void setVertCoords (const Matrix &vertexCoords); - - // reinforcing bar inquiring functions - - int getMaterialID (void) const; - int getNumCells (void) const; - Cell **getCells (void) const; - Patch *getCopy (void) const; - - void getDiscretization (int &numSubdivIJ, int &numSubdivJK) const; - const Matrix &getVertCoords (void) const; - - void Print(OPS_Stream &s, int flag =0) const; - friend OPS_Stream &operator<<(OPS_Stream &s, QuadPatch &quadPatch); - - protected: - - private: - int matID; - int nDivIJ, nDivJK; - Matrix vertCoord; -}; - - -#endif - - diff --git a/SRC/runtime/runtime/SectionBuilder/reinfBar/ReinfBar.cpp b/SRC/runtime/runtime/SectionBuilder/reinfBar/ReinfBar.cpp deleted file mode 100644 index 296f0aea98..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/reinfBar/ReinfBar.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -// -// File: ReinfBar.C -// Written by Remo M. de Souza -// December 1998 - -#include -#include -#include -#include -#include - - -ReinfBar::ReinfBar (void): - diameter(0.0), area(0.0), matID(0), posit(2) -{ - -} - - -ReinfBar::ReinfBar(double barArea, int materialID, const Vector &position): - diameter(0.0), area(barArea), - matID(materialID), posit(position) -{ -} - -ReinfBar::~ReinfBar() -{ - -} - -void ReinfBar::setDiameter (double barDiameter) -{ - double pi = acos(-1.0); - diameter = barDiameter; - area = pi * diameter*diameter/4.0; -} - -void ReinfBar::setArea (double barArea) -{ - area = barArea; -} - -void ReinfBar::setMaterial (int materialID) -{ - matID = materialID; -} - -void ReinfBar::setPosition (const Vector &position) -{ - posit = position; -} - -double ReinfBar::getDiameter(void) const -{ - return diameter; -} - -double ReinfBar::getArea (void) const -{ - return area; -} - - -const Vector & ReinfBar::getPosition(void) const -{ - return posit; -} - - -void ReinfBar::Print(OPS_Stream &s, int flag) const -{ - s << "\nReinforcing Bar area: " << area; - s << "\nMaterial ID: " << matID; - s << "\nDiameter: " << diameter; - s << "\nArea: " << area; - s << "\nPosition: " << posit; -} - diff --git a/SRC/runtime/runtime/SectionBuilder/reinfBar/ReinfBar.h b/SRC/runtime/runtime/SectionBuilder/reinfBar/ReinfBar.h deleted file mode 100644 index 845f70a88c..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/reinfBar/ReinfBar.h +++ /dev/null @@ -1,70 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -// -// File: ReinfBar.h -// -// Written by Remo M. de Souza -// November 1998 - - -#ifndef ReinfBar_h -#define ReinfBar_h - -#include - -class ReinfBar -{ - public: - - ReinfBar(); - ReinfBar(double barArea, int materialID, const Vector &position); - - virtual ~ReinfBar(); - - // edition functions - - void setDiameter (double barDiameter); - void setArea (double barArea); - void setMaterial (int materialID); - void setPosition (const Vector &position); - - // reinforcing bar inquiring functions - - double getDiameter (void) const; - double getArea (void) const; - int getMaterial (void) const; - - const Vector & getPosition (void) const; - - virtual void Print(OPS_Stream &s, int flag =0) const; - friend OPS_Stream &operator<<(OPS_Stream &s, const ReinfBar &reinfBar); - - protected: - - private: - int matID; - double diameter; - double area; - Vector posit; -}; - - -#endif - diff --git a/SRC/runtime/runtime/SectionBuilder/reinfLayer/CMakeLists.txt b/SRC/runtime/runtime/SectionBuilder/reinfLayer/CMakeLists.txt deleted file mode 100644 index 6651d6dcdd..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/reinfLayer/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -#============================================================================== -# -# OpenSees -- Open System For Earthquake Engineering Simulation -# Pacific Earthquake Engineering Research Center -# -#============================================================================== - -target_sources(OPS_Section_Repres - PRIVATE - CircReinfLayer.cpp - ReinfLayer.cpp - StraightReinfLayer.cpp - PUBLIC - CircReinfLayer.h - ReinfLayer.h - StraightReinfLayer.h -) -target_include_directories(OPS_Section_Repres PUBLIC ${CMAKE_CURRENT_LIST_DIR}) - diff --git a/SRC/runtime/runtime/SectionBuilder/reinfLayer/CircReinfLayer.cpp b/SRC/runtime/runtime/SectionBuilder/reinfLayer/CircReinfLayer.cpp deleted file mode 100644 index 05d112e73a..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/reinfLayer/CircReinfLayer.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -// $Revision: 1.3 $ -// $Date: 2003-02-14 23:01:37 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/section/repres/reinfLayer/CircReinfLayer.cpp,v $ - - -// File: CircReinfLayer.C -// Written by Remo M. de Souza -// December 1998 - -#include -#include -#include - -#include -#include -#include - -void * OPS_ADD_RUNTIME_VPV(OPS_CircReinfLayer) -{ - if(OPS_GetNumRemainingInputArgs() < 6) { - opserr<<"insufficient arguments for CircReinfLayer\n"; - return 0; - } - - // get idata - int numData = 2; - int idata[2]; - if(OPS_GetIntInput(&numData,&idata[0]) < 0) return 0; - - // get data - double data[6] = {0,0,0,0,0,0}; - numData = OPS_GetNumRemainingInputArgs(); - if(numData > 6) numData = 6; - if(OPS_GetDoubleInput(&numData,&data[0]) < 0) return 0; - static Vector cpos(2); - cpos(0) = data[1]; - cpos(1) = data[2]; - - if(numData < 6) { - return new CircReinfLayer(idata[0],idata[1],data[0], - cpos,data[3]); - } else { - return new CircReinfLayer(idata[0],idata[1],data[0], - cpos,data[3],data[4],data[5]); - } -} - - -CircReinfLayer::CircReinfLayer(void): - nReinfBars(0), matID(0), barDiam(0.0), - area(0.0), centerPosit(2), arcRad(0.0), - initAng(0.0), finalAng(0.0) -{ -} - - -CircReinfLayer::CircReinfLayer(int materialID, int numReinfBars, - double reinfBarArea, - const Vector ¢erPosition, - double arcRadius, double initialAngle, - double finalAngle): - nReinfBars(numReinfBars), - matID(materialID), area(reinfBarArea), - barDiam(0.0),centerPosit(centerPosition), - arcRad(arcRadius),initAng(initialAngle), - finalAng(finalAngle) -{ -} - -CircReinfLayer::CircReinfLayer(int materialID, int numReinfBars, double reinfBarArea, - const Vector ¢erPosition, double radius): -nReinfBars(numReinfBars), matID(materialID), area(reinfBarArea), -barDiam(0.0), centerPosit(centerPosition), arcRad(radius), -initAng(0.0), finalAng(0.0) -{ - // Figure out final angle so that complete circle does not put - // two bars at the same location - if (nReinfBars > 0) - finalAng = 360.0 - 360.0/nReinfBars; -} - -CircReinfLayer::~CircReinfLayer() -{ - -} - - -void CircReinfLayer::setNumReinfBars(int numReinfBars) -{ - nReinfBars = numReinfBars; -} - -void CircReinfLayer::setMaterialID (int materialID) -{ - matID = materialID; -} - -void CircReinfLayer::setReinfBarDiameter (double reinfBarDiameter) -{ - barDiam = reinfBarDiameter; - double pi = acos(-1.0); - area = pi * barDiam*barDiam/4.0; -} - -void CircReinfLayer::setReinfBarArea(double reinfBarArea) -{ - area = reinfBarArea; -} - - -int CircReinfLayer::getNumReinfBars (void) const -{ - return nReinfBars; -} - -int CircReinfLayer::getMaterialID (void) const -{ - return matID; -} - -double CircReinfLayer::getReinfBarDiameter (void) const -{ - return barDiam; -} - -double CircReinfLayer::getReinfBarArea (void) const -{ - return area; -} - -ReinfBar * -CircReinfLayer::getReinfBars (void) const -{ - double theta, dtheta; - static Vector barPosit(2); - int i; - ReinfBar *reinfBars; - double pi = acos(-1.0); - double initAngRad, finalAngRad; - - if (nReinfBars > 0) - { - initAngRad = pi * initAng / 180.0; - finalAngRad = pi * finalAng / 180.0; - - if (nReinfBars > 1) - dtheta = (finalAngRad - initAngRad) /(nReinfBars - 1); - else - dtheta = 0.0; // Doesn't really matter what this is - - reinfBars = new ReinfBar [nReinfBars]; - - for (i = 0; i < nReinfBars; i++) - { - theta = initAngRad + dtheta * i; - barPosit(0) = centerPosit(0) + arcRad*cos(theta); - barPosit(1) = centerPosit(1) + arcRad*sin(theta); - - reinfBars[i].setPosition(barPosit); - reinfBars[i].setArea(this->area); - } - } - else - return 0; - - return reinfBars; -} - - -const Vector & -CircReinfLayer::getCenterPosition(void) const -{ - return centerPosit; -} - -double CircReinfLayer::getArcRadius(void) const -{ - return arcRad; -} - -double CircReinfLayer::getInitAngle(void) const -{ - return initAng; -} - -double CircReinfLayer::getFinalAngle(void) const -{ - return finalAng; -} - - -ReinfLayer * -CircReinfLayer::getCopy (void) const -{ - CircReinfLayer *theCopy = new CircReinfLayer (matID, nReinfBars, area, - centerPosit, arcRad, - initAng, finalAng); - return theCopy; -} - - - -void CircReinfLayer::Print(OPS_Stream &s, int flag) const -{ - s << "\nReinforcing Layer type: Circ"; - s << "\nMaterial ID: " << matID; - s << "\nReinf. bar diameter: " << barDiam; - s << "\nReinf. bar area: " << area; - s << "\nCenter Position: " << centerPosit; - s << "\nArc Radius: " << arcRad; - s << "\nInitial angle: " << initAng; - s << "\nFinal angle: " << finalAng; -} - - -OPS_Stream &operator<<(OPS_Stream &s, const CircReinfLayer &CircReinfLayer) -{ - CircReinfLayer.Print(s); - return s; -} - diff --git a/SRC/runtime/runtime/SectionBuilder/reinfLayer/CircReinfLayer.h b/SRC/runtime/runtime/SectionBuilder/reinfLayer/CircReinfLayer.h deleted file mode 100644 index c905859e29..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/reinfLayer/CircReinfLayer.h +++ /dev/null @@ -1,103 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -// $Revision: 1.3 $ -// $Date: 2003-02-14 23:01:37 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/section/repres/reinfLayer/CircReinfLayer.h,v $ - - -// File: CircReinfLayer.h -// Written by Remo M. de Souza -// December 1998 - - -#ifndef CircReinfLayer_h -#define CircReinfLayer_h - -#include -#include - -class ReinfBar; - -class CircReinfLayer : public ReinfLayer -{ - public: - - CircReinfLayer(); - // Constructor for an arc - CircReinfLayer(int materialID, int numReinfBars, double reinfBarArea, - const Vector ¢erPosition, double arcRadius, double - initialAngle, double finalAngle); - // Constructor for full circle - CircReinfLayer(int materialID, int numReinfBars, double reinfBarArea, - const Vector ¢erPosition, double radius); - - ~CircReinfLayer(); - - // edition functions - - void setNumReinfBars (int numReinfBars); - void setMaterialID (int materialID); - void setReinfBarDiameter (double reinfBarDiameter); - void setReinfBarArea (double reinfBarArea); - - void setCenterPosition (const Vector ¢erPosition); - void setArcRadius (double arcRadius); - void setInitAngle (double initialAngle); - void setFinalAngle (double finalAngle); - - // inquiring functions - - int getNumReinfBars (void) const; - int getMaterialID (void) const; - double getReinfBarDiameter (void) const; - double getReinfBarArea (void) const; - ReinfBar *getReinfBars (void) const; - - - ReinfLayer *getCopy (void) const; - const Vector &getCenterPosition (void) const; - double getArcRadius (void) const; - double getInitAngle (void) const; - double getFinalAngle (void) const; - - - void Print(OPS_Stream &s, int flag =0) const; - friend OPS_Stream &operator<<(OPS_Stream &s, const CircReinfLayer &CircReinfLayer); - - protected: - - private: - int nReinfBars; - int matID; - double barDiam; - double area; - Vector centerPosit; - double arcRad; - double initAng; - double finalAng; -}; - - -#endif - - - - diff --git a/SRC/runtime/runtime/SectionBuilder/reinfLayer/ReinfLayer.cpp b/SRC/runtime/runtime/SectionBuilder/reinfLayer/ReinfLayer.cpp deleted file mode 100644 index 94a2da2a2b..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/reinfLayer/ReinfLayer.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -// File: ReinfLayer.C -// Written by Remo M. de Souza -// December 1998 - -#include - - -ReinfLayer::ReinfLayer(void) -{ - -} - - -ReinfLayer::~ReinfLayer(void) -{ - -} - diff --git a/SRC/runtime/runtime/SectionBuilder/reinfLayer/ReinfLayer.h b/SRC/runtime/runtime/SectionBuilder/reinfLayer/ReinfLayer.h deleted file mode 100644 index ebfb366941..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/reinfLayer/ReinfLayer.h +++ /dev/null @@ -1,70 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -// $Revision: 1.3 $ -// $Date: 2003-02-14 23:01:37 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/section/repres/reinfLayer/ReinfLayer.h,v $ - - -// File: ReinfLayer.h -// Written by Remo M. de Souza -// December 1998 - -#ifndef ReinfLayer_h -#define ReinfLayer_h - -// #include - -class ReinfBar; -class OPS_Stream; - -class ReinfLayer -{ - public: - - ReinfLayer(); - virtual ~ReinfLayer(); - - // edition functions - - virtual void setNumReinfBars (int numReinfBars) = 0; - virtual void setMaterialID (int materialID) = 0; - virtual void setReinfBarDiameter (double reinfBarDiemater) = 0; - virtual void setReinfBarArea (double reinfBarArea) = 0; - - // reinforcing layer inquiring functions - - virtual int getNumReinfBars (void) const = 0; - virtual int getMaterialID (void) const = 0; - virtual double getReinfBarDiameter (void) const = 0; - virtual double getReinfBarArea (void) const = 0; - virtual ReinfLayer *getCopy (void) const = 0; - virtual ReinfBar *getReinfBars (void) const = 0; - - virtual void Print(OPS_Stream &s, int flag =0) const = 0; - friend OPS_Stream &operator<<(OPS_Stream &s, const ReinfLayer &ReinfLayer); - - protected: - - private: -}; - - -#endif diff --git a/SRC/runtime/runtime/SectionBuilder/reinfLayer/StraightReinfLayer.cpp b/SRC/runtime/runtime/SectionBuilder/reinfLayer/StraightReinfLayer.cpp deleted file mode 100644 index fe68a231ec..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/reinfLayer/StraightReinfLayer.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -// -// File: StraightReinfLayer.C -// Written by Remo M. de Souza -// December 1998 -// -#include -#include -#include - -#include -#include -#include - - -StraightReinfLayer::StraightReinfLayer(int materialID, int numReinfBars, - double reinfBarArea, - const Vector &InitialPosition, - const Vector &FinalPosition): - nReinfBars(numReinfBars), - matID(materialID), - area(reinfBarArea), - barDiam(0.0), - initPosit(InitialPosition), - finalPosit(FinalPosition) -{ -} - - -StraightReinfLayer::~StraightReinfLayer() -{ - -} - - -void StraightReinfLayer::setNumReinfBars(int numReinfBars) -{ - nReinfBars = numReinfBars; -} - -void StraightReinfLayer::setMaterialID (int materialID) -{ - matID = materialID; -} - -void StraightReinfLayer::setReinfBarDiameter (double reinfBarDiameter) -{ - barDiam = reinfBarDiameter; - double pi = acos(-1.0); - area = pi * barDiam*barDiam/4.0; -} - -void StraightReinfLayer::setReinfBarArea(double reinfBarArea) -{ - area = reinfBarArea; -} - -void StraightReinfLayer::setInitialPosition (const Vector &initialPosition) -{ - initPosit = initialPosition; -} - -void StraightReinfLayer::setFinalPosition (const Vector &finalPosition) -{ - finalPosit = finalPosition; -} - - -int StraightReinfLayer::getNumReinfBars (void) const -{ - return nReinfBars; -} - -int StraightReinfLayer::getMaterialID (void) const -{ - return matID; -} - -double StraightReinfLayer::getReinfBarDiameter (void) const -{ - return barDiam; -} - -double StraightReinfLayer::getReinfBarArea (void) const -{ - return area; -} - -ReinfBar * -StraightReinfLayer::getReinfBars (void) const -{ - Vector barPosit(2); - ReinfBar *reinfBars; - - if (nReinfBars == 1) { - barPosit(0) = (initPosit(0) + finalPosit(0)) / 2; - barPosit(1) = (initPosit(1) + finalPosit(1)) / 2; - - reinfBars = new ReinfBar [1]; - - reinfBars[0].setPosition(barPosit); - reinfBars[0].setArea(this->area); - } - - else if (nReinfBars > 1) - { - double dy = (finalPosit(0) - initPosit(0))/(nReinfBars - 1); - double dz = (finalPosit(1) - initPosit(1))/(nReinfBars - 1); - - reinfBars = new ReinfBar [nReinfBars]; - - for (int i = 0; i < nReinfBars; i++) - { - barPosit(0) = initPosit(0) + dy * i; - barPosit(1) = initPosit(1) + dz * i; - - reinfBars[i].setPosition(barPosit); - reinfBars[i].setArea(this->area); - } - } - else - return 0; - - return reinfBars; -} - -const Vector & -StraightReinfLayer::getInitialPosition (void) const -{ - return initPosit; -} - -const Vector & -StraightReinfLayer::getFinalPosition (void) const -{ - return finalPosit; -} - - -ReinfLayer * -StraightReinfLayer::getCopy (void) const -{ - StraightReinfLayer *theCopy = new StraightReinfLayer (matID, - nReinfBars, area, - initPosit, finalPosit); - return theCopy; -} - - - -void StraightReinfLayer::Print(OPS_Stream &s, int flag) const -{ - s << "\nReinforcing Layer type: Straight"; - s << "\nMaterial ID: " << matID; - s << "\nReinf. bar diameter: " << barDiam; - s << "\nReinf. bar area: " << area; - s << "\nInitial Position: " << initPosit; - s << "\nFinal Position: " << finalPosit; -} - - -OPS_Stream &operator<<(OPS_Stream &s, const StraightReinfLayer &straightReinfLayer) -{ - straightReinfLayer.Print(s); - return s; -} - diff --git a/SRC/runtime/runtime/SectionBuilder/reinfLayer/StraightReinfLayer.h b/SRC/runtime/runtime/SectionBuilder/reinfLayer/StraightReinfLayer.h deleted file mode 100644 index 4205a45662..0000000000 --- a/SRC/runtime/runtime/SectionBuilder/reinfLayer/StraightReinfLayer.h +++ /dev/null @@ -1,82 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -// -// File: StraightReinfLayer.h -// Written by Remo M. de Souza -// December 1998 -// -#ifndef StraightReinfLayer_h -#define StraightReinfLayer_h - -#include -#include - -class ReinfBar; - -class StraightReinfLayer : public ReinfLayer -{ - public: - - StraightReinfLayer(int materialID, int numReinfBars, double reinfBarArea, - const Vector &initialPosition, - const Vector &finalPosition); - - ~StraightReinfLayer(); - - // edition functions - - void setNumReinfBars (int numReinfBars); - void setMaterialID (int materialID); - void setReinfBarDiameter (double reinfBarDiameter); - void setReinfBarArea (double reinfBarArea); - - void setInitialPosition (const Vector &initialPosition); - void setFinalPosition (const Vector &finalPosition); - - // inquiring functions - - int getNumReinfBars (void) const; - int getMaterialID (void) const; - double getReinfBarDiameter (void) const; - double getReinfBarArea (void) const; - ReinfBar *getReinfBars (void) const; - - - ReinfLayer *getCopy (void) const; - const Vector &getInitialPosition (void) const; - const Vector &getFinalPosition (void) const; - - void Print(OPS_Stream &s, int flag =0) const; - friend OPS_Stream &operator<<(OPS_Stream &s, const StraightReinfLayer &straightReinfLayer); - - protected: - - private: - int nReinfBars; - int matID; - double barDiam; - double area; - Vector initPosit; - Vector finalPosit; -}; - - -#endif - diff --git a/SRC/runtime/runtime/SectionBuilder/reinfBar/CMakeLists.txt b/SRC/runtime/runtime/legacy/Renderer/CMakeLists.txt similarity index 55% rename from SRC/runtime/runtime/SectionBuilder/reinfBar/CMakeLists.txt rename to SRC/runtime/runtime/legacy/Renderer/CMakeLists.txt index 36a8f2fd20..8e4f4a30df 100644 --- a/SRC/runtime/runtime/SectionBuilder/reinfBar/CMakeLists.txt +++ b/SRC/runtime/runtime/legacy/Renderer/CMakeLists.txt @@ -5,11 +5,16 @@ # #============================================================================== -target_sources(OPS_Section_Repres - PRIVATE - ReinfBar.cpp - PUBLIC - ReinfBar.h + +add_library(OPS_Renderer OBJECT EXCLUDE_FROM_ALL) + +target_sources(OPS_Renderer + PRIVATE + PlainMap.cpp + Renderer.cpp + PUBLIC + PlainMap.h + Renderer.h ) -target_include_directories(OPS_Section_Repres PUBLIC ${CMAKE_CURRENT_LIST_DIR}) +target_include_directories(OPS_Renderer PUBLIC ${CMAKE_CURRENT_LIST_DIR}) diff --git a/SRC/runtime/runtime/SectionBuilder/patch/Patch.cpp b/SRC/runtime/runtime/legacy/Renderer/ColorMap.h similarity index 66% rename from SRC/runtime/runtime/SectionBuilder/patch/Patch.cpp rename to SRC/runtime/runtime/legacy/Renderer/ColorMap.h index 4e340ddca7..9c86cbdbe1 100644 --- a/SRC/runtime/runtime/SectionBuilder/patch/Patch.cpp +++ b/SRC/runtime/runtime/legacy/Renderer/ColorMap.h @@ -18,25 +18,41 @@ ** ** ** ****************************************************************** */ -// $Revision: 1.1.1.1 $ -// $Date: 2000-09-15 08:23:22 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/section/repres/patch/Patch.cpp,v $ +// $Revision: 1.2 $ +// $Date: 2001-07-26 00:56:05 $ +// $Source: /usr/local/cvs/OpenSees/SRC/renderer/ColorMap.h,v $ -// File: Patch.C -// Written by Remo M. de Souza -// December 1998 +// File: ~/graphics/ColorMap.h +// +// Written: fmk +// Created: 10/98 +// Revision: A +// +// Description: This file contains the class definition for ColorMap. +// ColorMap is an abstract base class. An ColorMap object is used +// to determine the r,g,b values given an input value. +// +// What: "@(#) ColorMap.h, revA" +#ifndef ColorMap_h +#define ColorMap_h -#include - -Patch::Patch(void) +class ColorMap { + public: + ColorMap() {}; + virtual ~ColorMap() {}; + virtual float getRed(float value) =0; + virtual float getGreen(float value) =0; + virtual float getBlue(float value) =0; + virtual int getRGB(float value, float &red, float &green, float &blue) =0; + virtual int startImage() =0; + protected: + + private: +}; -} - -Patch::~Patch(void) -{ -} +#endif diff --git a/SRC/runtime/runtime/legacy/Renderer/PlainMap.cpp b/SRC/runtime/runtime/legacy/Renderer/PlainMap.cpp new file mode 100644 index 0000000000..b945edf975 --- /dev/null +++ b/SRC/runtime/runtime/legacy/Renderer/PlainMap.cpp @@ -0,0 +1,208 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.3 $ +// $Date: 2003-02-14 23:01:58 $ +// $Source: /usr/local/cvs/OpenSees/SRC/renderer/PlainMap.cpp,v $ + +// Written: fmk +// Created: 10/98 +// +// Description: This file contains the class definition for PlainMap. +// PlainMap is an abstract base class. An PlainMap object is used +// to determine the r,g,b values given an input value. +// +// What: "@(#) PlainMap.h, revA" + +#include "PlainMap.h" +#include +#include +#include + +static float jet[64*3] = { + 0, 0, 0.5625, + 0, 0, 0.6250, + 0, 0, 0.6875, + 0, 0, 0.7500, + 0, 0, 0.8125, + 0, 0, 0.8750, + 0, 0, 0.9375, + 0, 0, 1.0000, + 0, 0.0625, 1.0000, + 0, 0.1250, 1.0000, + 0, 0.1875, 1.0000, + 0, 0.2500, 1.0000, + 0, 0.3125, 1.0000, + 0, 0.3750, 1.0000, + 0, 0.4375, 1.0000, + 0, 0.5000, 1.0000, + 0, 0.5625, 1.0000, + 0, 0.6250, 1.0000, + 0, 0.6875, 1.0000, + 0, 0.7500, 1.0000, + 0, 0.8125, 1.0000, + 0, 0.8750, 1.0000, + 0, 0.9375, 1.0000, + 0, 1.0000, 1.0000, + 0.0625, 1.0000, 1.0000, + 0.1250, 1.0000, 0.9375, + 0.1875, 1.0000, 0.8750, + 0.2500, 1.0000, 0.8125, + 0.3125, 1.0000, 0.7500, + 0.3750, 1.0000, 0.6875, + 0.4375, 1.0000, 0.6250, + 0.5000, 1.0000, 0.5625, + 0.5625, 1.0000, 0.5000, + 0.6250, 1.0000, 0.4375, + 0.6875, 1.0000, 0.3750, + 0.7500, 1.0000, 0.3125, + 0.8125, 1.0000, 0.2500, + 0.8750, 1.0000, 0.1875, + 0.9375, 1.0000, 0.1250, + 1.0000, 1.0000, 0.0625, + 1.0000, 1.0000, 0, + 1.0000, 0.9375, 0, + 1.0000, 0.8750, 0, + 1.0000, 0.8125, 0, + 1.0000, 0.7500, 0, + 1.0000, 0.6875, 0, + 1.0000, 0.6250, 0, + 1.0000, 0.5625, 0, + 1.0000, 0.5000, 0, + 1.0000, 0.4375, 0, + 1.0000, 0.3750, 0, + 1.0000, 0.3125, 0, + 1.0000, 0.2500, 0, + 1.0000, 0.1875, 0, + 1.0000, 0.1250, 0, + 1.0000, 0.0625, 0, + 1.0000, 0, 0, + 0.9375, 0, 0, + 0.8750, 0, 0, + 0.8125, 0, 0, + 0.7500, 0, 0, + 0.6875, 0, 0, + 0.6250, 0, 0, + 0.5625, 0, 0}; + + + +PlainMap::PlainMap() + :max(0.0), min(0.0), maxLast(0.0), minLast(0.0) +{ + data = jet; + sizeData = 64; +} + + +float +PlainMap::getRed(float value){ + if (value > max) + max = value; + else if (value < min) + min = value; + + if (maxLast == minLast) { + int index = sizeData/2; + return data[index*3-3]; + + } else if (value > maxLast) + return data[sizeData*3-3]; + else if (value < minLast) + return data[0]; + else { + int index = (floor)((value-minLast)*sizeData/((maxLast-minLast))); + return data[index*3-3]; + } + + return 0.0; +} + + +float +PlainMap::getGreen(float value) { + if (value > max) + max = value; + else if (value < min) + min = value; + + if (maxLast == minLast) { + int index = sizeData/2; + return data[index*3-2]; + + } else if (value > maxLast) + return data[sizeData*3-2]; + else if (value < minLast) + return data[1]; + else { + int index = (floor)((value-minLast)*sizeData/((maxLast-minLast))); + return data[index*3-2]; + } + + return 0.0; +} + +float +PlainMap::getBlue(float value) { + if (value > max) + max = value; + else if (value < min) + min = value; + + if (maxLast == minLast) { + int index = sizeData/2; + return data[index*3-1]; + + } else if (value > maxLast) + return data[sizeData*3-1]; + else if (value < minLast) + return data[2]; + else { + int index = (floor)((value-minLast)*sizeData/((maxLast-minLast))); + return data[index*3-1]; + } + + return 0.0; +} + +int +PlainMap::getRGB(float value, float &red, float &blue, float &green) { + red = this->getRed(value); + green = this->getGreen(value); + blue = this->getBlue(value); + return 0; +} + + + +int +PlainMap::startImage() +{ + maxLast = max; + minLast = min; + max = 0; + min = 0; + + if (maxLast > -minLast) + maxLast = -minLast; + if (minLast < -maxLast) + minLast = -maxLast; + return 0; +} diff --git a/SRC/runtime/runtime/SectionBuilder/cell/Cell.cpp b/SRC/runtime/runtime/legacy/Renderer/PlainMap.h similarity index 65% rename from SRC/runtime/runtime/SectionBuilder/cell/Cell.cpp rename to SRC/runtime/runtime/legacy/Renderer/PlainMap.h index 8e0e460b54..5436ff1c8c 100644 --- a/SRC/runtime/runtime/SectionBuilder/cell/Cell.cpp +++ b/SRC/runtime/runtime/legacy/Renderer/PlainMap.h @@ -18,24 +18,47 @@ ** ** ** ****************************************************************** */ -// $Revision: 1.1.1.1 $ -// $Date: 2000-09-15 08:23:22 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/section/repres/cell/Cell.cpp,v $ +// $Revision: 1.2 $ +// $Date: 2001-07-26 00:56:05 $ +// $Source: /usr/local/cvs/OpenSees/SRC/renderer/PlainMap.h,v $ -// File: Cell.C -// Written by Remo M. de Souza -// December 1998 +// File: ~/graphics/PlainMap.h +// +// Written: fmk +// Created: 10/98 +// Revision: A +// +// Description: This file contains the class definition for PlainMap. +// PlainMap is an abstract base class. An PlainMap object is used +// to determine the r,g,b values given an input value. +// +// What: "@(#) PlainMap.h, revA" -#include +#ifndef PlainMap_h +#define PlainMap_h -Cell::Cell(void) +#include "ColorMap.h" + +class PlainMap: public ColorMap { + public: + PlainMap(); + float getRed(float value); + float getGreen(float value); + float getBlue(float value); + int getRGB(float value, float &red, float &green, float &blue); + int startImage(); -} + protected: + + private: + float max, min; + float maxLast, minLast; + float *data; + int sizeData; +}; -Cell::~Cell(void) -{ -} +#endif diff --git a/SRC/runtime/runtime/legacy/Renderer/Renderer.cpp b/SRC/runtime/runtime/legacy/Renderer/Renderer.cpp new file mode 100644 index 0000000000..9c362cd047 --- /dev/null +++ b/SRC/runtime/runtime/legacy/Renderer/Renderer.cpp @@ -0,0 +1,205 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ****************************************************************** */ +// +// Written: fmk +// Created: 10/98 +// Revision: A +// +// Description: This file contains the class interface for Renderer. +// Renderer is an abstract base class. An Renderer object is used +// to create an image of the domain. +// +#include "Renderer.h" +#include "ColorMap.h" +#include +#include + +#include +#include + +#include + +int Renderer::numRenderers(0); +char **Renderer::theTitles =0; +Renderer **Renderer::theRenderers =0; + +Renderer::Renderer(ColorMap &_theMap) + :theMap(&_theMap) +{ + +} + + +Renderer::Renderer(const char *title, ColorMap &_theMap) + :theMap(&_theMap) +{ + int loc = -1; + + // look for an empty slot + for (int i=0; isaveImage(fileName); + + return 0; +} + +int +Renderer::drawVector(const Vector &position, const Vector &value, double factor, int tag) +{ + return 0; +} + + +void +Renderer::setColorMap(ColorMap &map) +{ + theMap = ↦ +} + +int +Renderer::drawCube(const Matrix &points, const Vector &values, int tag, int mode) +{ + + static Matrix polyData(4,3); + static Vector polyValues(4); + // draw the 6 faces + + int a,b,c,d; + + a=2; b=3; c=7; d=6; + for (int i=0; i<3; i++) { + polyData(0,i) = points(a,i); + polyData(1,i) = points(b,i); + polyData(2,i) = points(c,i); + polyData(3,i) = points(d,i); + } + polyValues(0) = values(a); + polyValues(1) = values(b); + polyValues(2) = values(c); + polyValues(3) = values(d); + this->drawPolygon(polyData, polyValues, tag, mode); + + a=5; b=4; c=0; d=1; + for (int i=0; i<3; i++) { + polyData(0,i) = points(a,i); + polyData(1,i) = points(b,i); + polyData(2,i) = points(c,i); + polyData(3,i) = points(d,i); + } + polyValues(0) = values(a); + polyValues(1) = values(b); + polyValues(2) = values(c); + polyValues(3) = values(d); + this->drawPolygon(polyData, polyValues, tag, mode); + + a=6; b=7; c=4; d=5; + for (int i=0; i<3; i++) { + polyData(0,i) = points(a,i); + polyData(1,i) = points(b,i); + polyData(2,i) = points(c,i); + polyData(3,i) = points(d,i); + } + polyValues(0) = values(a); + polyValues(1) = values(b); + polyValues(2) = values(c); + polyValues(3) = values(d); + this->drawPolygon(polyData, polyValues, tag, mode); + + a=1; b=0; c=3; d=2; + for (int i=0; i<3; i++) { + polyData(0,i) = points(a,i); + polyData(1,i) = points(b,i); + polyData(2,i) = points(c,i); + polyData(3,i) = points(d,i); + } + polyValues(0) = values(a); + polyValues(1) = values(b); + polyValues(2) = values(c); + polyValues(3) = values(d); + this->drawPolygon(polyData, polyValues, tag, mode); + + a=7; b=3; c=0; d=4; + for (int i=0; i<3; i++) { + polyData(0,i) = points(a,i); + polyData(1,i) = points(b,i); + polyData(2,i) = points(c,i); + polyData(3,i) = points(d,i); + } + polyValues(0) = values(a); + polyValues(1) = values(b); + polyValues(2) = values(c); + polyValues(3) = values(d); + this->drawPolygon(polyData, polyValues, tag, mode); + + a=2; b=6; c=5; d=1; + for (int i=0; i<3; i++) { + polyData(0,i) = points(a,i); + polyData(1,i) = points(b,i); + polyData(2,i) = points(c,i); + polyData(3,i) = points(d,i); + } + polyValues(0) = values(a); + polyValues(1) = values(b); + polyValues(2) = values(c); + polyValues(3) = values(d); + return this->drawPolygon(polyData, polyValues, tag, mode); +} + diff --git a/SRC/runtime/runtime/legacy/Renderer/Renderer.h b/SRC/runtime/runtime/legacy/Renderer/Renderer.h new file mode 100644 index 0000000000..ea7e9b9014 --- /dev/null +++ b/SRC/runtime/runtime/legacy/Renderer/Renderer.h @@ -0,0 +1,97 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ****************************************************************** */ +// +// Description: This file contains the class definition for Renderer. +// Renderer is an abstract base class. An Renderer object is used +// to process 3d graphics. +// +// Written: fmk +// Created: 10/98 +// Revision: A +// +#ifndef Renderer_h +#define Renderer_h + +class Vector; +class Matrix; +class ColorMap; + +class Renderer +{ + public: + Renderer(ColorMap &theMap); + Renderer(const char *title, ColorMap &theMap); + ~Renderer(); + + // method to set the color map + void setColorMap(ColorMap &theMap); + + // method to clear the current image + int clearImage() {return -1;} + int saveImage(const char *imageName); + int saveImage(const char *title, const char *imageName); + + // methods to be invoked when image processing is to start or is finished + int startImage() {return -1;} + int doneImage() {return -1;} + + // methods invoked by the objects to display themselves + int drawPoint(const Vector &, float , int tag = 0, int mode = 0, int width = 1) {return -1;} + int drawPoint(const Vector &, const Vector &, int tag = 0, int mode = 0, int width = 1) {return -1;} + + int drawLine(const Vector &, const Vector &, + float V1, float V2, int tag = 0, int mode = 0) {return -1;} + int drawLine(const Vector &, const Vector &, + const Vector &, const Vector &, int tag = 0, int mode = 0) {return -1;} + + int drawCube(const Matrix &, const Vector &, int tag = 0, int mode = 0); + + int drawPolygon(const Matrix &, const Vector &, int tag = 0, int mode = 0) {return -1;} + int drawPolygon(const Matrix &, const Matrix &, int tag = 0, int mode = 0) {return -1;} + + int drawVector(const Vector &position, const Vector &value, double fcator = 1.0, int tag = 0); + + + int drawText(const Vector &, char *, int , + char horizontalJustify = 'l', + char verticalJustify = 'b') {return -1;} + + // + // the following are for setting up the viewing system + // + + // the following are in world coordinates & define view coord system + int setVRP(float , float , float ) {return -1;} // point on view plane + int setVPN(float , float , float ) {return -1;} // view plane normal + int setVUP(float , float , float ) {return -1;} // view-up vector + + // the following are in view coordinates + int setViewWindow(float, float, float, float) {return -1;} // view bounds + // umin, umax, vmin, vmax + + // location of near and far clipping planes from view plane + int setPlaneDist(float, float) {return -1;} + + int setProjectionMode(const char *) {return -1;} //parallel or perspective + int setFillMode(const char *) {return -1;} // wire or fill + int setLineWidth(int) {return -1;} // line width + + // eye location if perspective, dirn to +ViewPlane if parallel + int setPRP(float , float , float ) {return -1;} + + // the following are in normalized coordinates + int setPortWindow(float, float, float, float) {return -1;} // view port + // left, right, bottom, top [-1,1,-1,1] + protected: + ColorMap *theMap; + + private: + static int numRenderers; + static char **theTitles; + static Renderer **theRenderers; +}; + +#endif + From 0dbea85912afa66074249a8f085d35379dd086d4 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:29:06 -0700 Subject: [PATCH 228/261] clean if 0s --- SRC/runtime/commands/analysis/algorithm.cpp | 4 +- SRC/runtime/commands/analysis/analysis.h | 9 +- SRC/runtime/commands/analysis/integrator.cpp | 8 + SRC/runtime/commands/analysis/itpack.cpp | 14 + SRC/runtime/commands/analysis/modal/modal.cpp | 2 +- SRC/runtime/commands/analysis/solver.cpp | 36 +- SRC/runtime/commands/analysis/solver.hpp | 7 +- SRC/runtime/commands/analysis/transient.cpp | 72 +- .../domain/TclUpdateMaterialCommand.cpp | 12 +- .../domain/TclUpdateMaterialStageCommand.cpp | 36 +- SRC/runtime/commands/domain/commands.cpp | 12 +- .../domain/database/TclDatabaseCommands.cpp | 6 +- SRC/runtime/commands/domain/domain.cpp | 47 +- SRC/runtime/commands/domain/element.cpp | 59 +- .../domain/loading/drm/TclPatternCommand.cpp | 2 +- .../commands/domain/loading/groundMotion.cpp | 40 +- .../commands/domain/loading/pattern.cpp | 12 +- .../commands/domain/loading/series.cpp | 128 --- SRC/runtime/commands/domain/nodes.cpp | 10 +- SRC/runtime/commands/domain/recorder.cpp | 98 --- SRC/runtime/commands/domain/region.cpp | 27 +- SRC/runtime/commands/domain/rigid_links.cpp | 302 +++---- SRC/runtime/commands/modeling/commands.h | 18 - SRC/runtime/commands/modeling/constraint.cpp | 92 --- SRC/runtime/commands/modeling/element.cpp | 173 ++-- SRC/runtime/commands/modeling/element.hpp | 3 - .../commands/modeling/element/brick.cpp | 78 +- .../commands/modeling/element/frames.cpp | 15 - .../commands/modeling/element/plane.cpp | 336 -------- .../commands/modeling/element/shells.cpp | 261 ------ .../commands/modeling/material/elastic.cpp | 118 --- .../commands/modeling/material/fedeas.cpp | 568 ------------- .../commands/modeling/material/material.cpp | 770 ------------------ .../commands/modeling/material/material.hpp | 3 - .../commands/modeling/material/nDMaterial.cpp | 27 +- .../commands/modeling/material/plastic.cpp | 140 +--- .../commands/modeling/material/shell.cpp | 20 +- .../commands/modeling/material/wrapper.cpp | 16 +- SRC/runtime/commands/modeling/model.cpp | 61 -- SRC/runtime/commands/modeling/nodes.cpp | 15 - SRC/runtime/commands/modeling/printing.cpp | 112 +-- SRC/runtime/commands/modeling/section.cpp | 360 +------- .../commands/modeling/section/truss.cpp | 117 --- SRC/runtime/commands/modeling/uniaxial.cpp | 71 -- SRC/runtime/commands/modeling/uniaxial.hpp | 21 - .../commands/modeling/uniaxialMaterial.cpp | 393 +++++---- .../commands/modeling/utilities/blockND.cpp | 30 - SRC/runtime/commands/parallel/partition.cpp | 16 - SRC/runtime/commands/parallel/sequential.cpp | 49 -- SRC/runtime/commands/strings.cpp | 21 - SRC/runtime/python/OpenSeesPyRT.cpp | 26 - SRC/runtime/runtime/TclPackageClassBroker.cpp | 82 +- 52 files changed, 725 insertions(+), 4230 deletions(-) diff --git a/SRC/runtime/commands/analysis/algorithm.cpp b/SRC/runtime/commands/analysis/algorithm.cpp index dfc135f8a9..fb3986d745 100644 --- a/SRC/runtime/commands/analysis/algorithm.cpp +++ b/SRC/runtime/commands/analysis/algorithm.cpp @@ -781,7 +781,7 @@ printAlgorithm(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, int flag; if (Tcl_GetInt(interp, argv[eleArg], &flag) != TCL_OK) { opserr << "WARNING print algorithm failed to get integer flag: \n"; - opserr << argv[eleArg] << endln; + opserr << argv[eleArg] << "\n"; return TCL_ERROR; } theAlgorithm->Print(output, flag); @@ -843,7 +843,7 @@ TclCommand_algorithmRecorder(ClientData clientData, Tcl_Interp *interp, Tcl_Size if (theAlgo != nullptr) { if ((theAlgo->addRecorder(*theRecorder)) < 0) { opserr << "WARNING could not add to domain - recorder " << argv[1] - << endln; + << "\n"; delete theRecorder; return TCL_ERROR; } diff --git a/SRC/runtime/commands/analysis/analysis.h b/SRC/runtime/commands/analysis/analysis.h index 2f6cce7d24..fff885de18 100644 --- a/SRC/runtime/commands/analysis/analysis.h +++ b/SRC/runtime/commands/analysis/analysis.h @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // #include diff --git a/SRC/runtime/commands/analysis/integrator.cpp b/SRC/runtime/commands/analysis/integrator.cpp index 239b5c15c8..673cfb9861 100644 --- a/SRC/runtime/commands/analysis/integrator.cpp +++ b/SRC/runtime/commands/analysis/integrator.cpp @@ -5,6 +5,14 @@ // //===----------------------------------------------------------------------===// // +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// // Description: This file implements selection of an integrator. // #include diff --git a/SRC/runtime/commands/analysis/itpack.cpp b/SRC/runtime/commands/analysis/itpack.cpp index 5181c5a21a..24d1c3cfcc 100644 --- a/SRC/runtime/commands/analysis/itpack.cpp +++ b/SRC/runtime/commands/analysis/itpack.cpp @@ -1,3 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// #include #include #include diff --git a/SRC/runtime/commands/analysis/modal/modal.cpp b/SRC/runtime/commands/analysis/modal/modal.cpp index 9331d191c6..85bb9f80ff 100644 --- a/SRC/runtime/commands/analysis/modal/modal.cpp +++ b/SRC/runtime/commands/analysis/modal/modal.cpp @@ -100,7 +100,7 @@ responseSpectrumAnalysis(ClientData clientData, } if (clientData == nullptr) { - opserr << "ResponseSpectrumAnalysis - eigen and modalProperties have not been called" << endln; + opserr << "ResponseSpectrumAnalysis - eigen and modalProperties have not been called" << "\n"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/analysis/solver.cpp b/SRC/runtime/commands/analysis/solver.cpp index 5d726946be..e33e20ae8a 100644 --- a/SRC/runtime/commands/analysis/solver.cpp +++ b/SRC/runtime/commands/analysis/solver.cpp @@ -123,32 +123,17 @@ G3Parse_newLinearSOE(ClientData clientData, Tcl_Interp* interp, Tcl_Size argc, return ctor->second.ss(rt, argc, argv); } -#if 1 || defined(XARA_USE_MUMPS) +#if defined(XARA_USE_MUMPS) else if (strcasecmp(argv[1], "mumps") == 0) { return TclDispatch_newMumpsLinearSOE(clientData, interp, argc, argv); } #endif + else if (strcasecmp(argv[1], "Umfpack")==0) { // TODO: if "umfpack" is in solver.hpp, this wont be reached return TclDispatch_newUmfpackLinearSOE(clientData, interp, argc, argv); } -#if 0 - else if (strcmp(argv[2],"Thread") == 0) { - int blockSize = 4; - int numThreads = 1; - if (argc == 5) { - if (Tcl_GetInt(interp, argv[3], &blockSize) != TCL_OK) - return nullptr; //TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &numThreads) != TCL_OK) - return nullptr; //TCL_ERROR; - } - return new ProfileSPDLinSOE( - *new ProfileSPDLinDirectThreadSolver(numThreads,blockSize,1.0e-12) - ); - } -#endif - #if defined(OPS_PETSC) else if (strcmp(argv[1], "petsc")==0 || strcmp(argv[1], "Petsc")==0) { @@ -267,6 +252,16 @@ specifySparseGen(G3_Runtime* rt, int argc, G3_Char ** const argv) theSolver = new ThreadedSuperLU(np, permSpec, panelSize, relax, thresh); else return nullptr; +// #endif +// +// #ifdef _PARALLEL_PROCESSING +// if (theSolver != 0) +// delete theSolver; +// theSolver = 0; +// +// if (npRow != 0 && npCol != 0) { +// theSolver = new DistributedSuperLU(npRow, npCol); +// } #else char symmetric = 'N'; double drop_tol = 0.0; @@ -283,7 +278,10 @@ specifySparseGen(G3_Runtime* rt, int argc, G3_Char ** const argv) theSolver = new SuperLU(permSpec, drop_tol, panelSize, relax, symmetric); #endif - return new SparseGenColLinSOE(*theSolver); +#ifdef _PARALLEL_PROCESSING + return new DistributedSparseGenColLinSOE(*theSolver); +#else + return new SparseGenColLinSOE(*theSolver); +#endif } - diff --git a/SRC/runtime/commands/analysis/solver.hpp b/SRC/runtime/commands/analysis/solver.hpp index e7e04bfecf..64f9bfc966 100644 --- a/SRC/runtime/commands/analysis/solver.hpp +++ b/SRC/runtime/commands/analysis/solver.hpp @@ -52,15 +52,10 @@ #include #include -#if 1 || defined(_PETSC) +#if defined(_PETSC) LinearSOE *TclCommand_newPetscSOE(int, TCL_Char**); #endif -#ifdef _CUDA -# include -# include -#endif - #if defined(_PARALLEL_PROCESSING) // parallel soe & solvers # include diff --git a/SRC/runtime/commands/analysis/transient.cpp b/SRC/runtime/commands/analysis/transient.cpp index 7de54416db..c5cac7396c 100644 --- a/SRC/runtime/commands/analysis/transient.cpp +++ b/SRC/runtime/commands/analysis/transient.cpp @@ -162,48 +162,48 @@ TclCommand_newNewmarkIntegrator(ClientData clientData, Tcl_Interp* interp, TransientIntegrator* G3Parse_newNewmark1Integrator(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { - double gamma; - double beta; - double alphaM, betaK, betaKi, betaKc; - if (argc != 4 && argc != 8) { - opserr << "WARNING integrator Newmark1 gamma beta " - " \n"; + double gamma; + double beta; + double alphaM, betaK, betaKi, betaKc; + if (argc != 4 && argc != 8) { + opserr << "WARNING integrator Newmark1 gamma beta " + " \n"; + return nullptr; + } + if (Tcl_GetDouble(interp, argv[2], &gamma) != TCL_OK) { + opserr << "WARNING integrator Newmark1 gamma beta - undefined gamma\n"; + return nullptr; + } + if (Tcl_GetDouble(interp, argv[3], &beta) != TCL_OK) { + opserr << "WARNING integrator Newmark1 gamma beta - undefined beta\n"; + return nullptr; + } + + if (argc == 8 || argc == 7) { + if (Tcl_GetDouble(interp, argv[4], &alphaM) != TCL_OK) { + opserr << "WARNING integrator Newmark1 gamma beta alphaM betaK betaKi " + "betaKc - alphaM\n"; return nullptr; } - if (Tcl_GetDouble(interp, argv[2], &gamma) != TCL_OK) { - opserr << "WARNING integrator Newmark1 gamma beta - undefined gamma\n"; + if (Tcl_GetDouble(interp, argv[5], &betaK) != TCL_OK) { + opserr << "WARNING integrator Newmark1 gamma beta alphaM betaK betaKi " + "betaKc - betaK\n"; return nullptr; } - if (Tcl_GetDouble(interp, argv[3], &beta) != TCL_OK) { - opserr << "WARNING integrator Newmark1 gamma beta - undefined beta\n"; + if (Tcl_GetDouble(interp, argv[6], &betaKi) != TCL_OK) { + opserr << "WARNING integrator Newmark1 gamma beta alphaM betaK betaKi " + "betaKc - betaKi\n"; return nullptr; } - - if (argc == 8 || argc == 7) { - if (Tcl_GetDouble(interp, argv[4], &alphaM) != TCL_OK) { - opserr << "WARNING integrator Newmark1 gamma beta alphaM betaK betaKi " - "betaKc - alphaM\n"; - return nullptr; - } - if (Tcl_GetDouble(interp, argv[5], &betaK) != TCL_OK) { - opserr << "WARNING integrator Newmark1 gamma beta alphaM betaK betaKi " - "betaKc - betaK\n"; - return nullptr; - } - if (Tcl_GetDouble(interp, argv[6], &betaKi) != TCL_OK) { - opserr << "WARNING integrator Newmark1 gamma beta alphaM betaK betaKi " - "betaKc - betaKi\n"; - return nullptr; - } - if (Tcl_GetDouble(interp, argv[7], &betaKc) != TCL_OK) { - opserr << "WARNING integrator Newmark1 gamma beta alphaM betaK betaKi " - "betaKc - betaKc\n"; - return nullptr; - } + if (Tcl_GetDouble(interp, argv[7], &betaKc) != TCL_OK) { + opserr << "WARNING integrator Newmark1 gamma beta alphaM betaK betaKi " + "betaKc - betaKc\n"; + return nullptr; } - if (argc == 4) - return new Newmark1(gamma, beta); - else - return new Newmark1(gamma, beta, alphaM, betaK, betaKi, betaKc); + } + if (argc == 4) + return new Newmark1(gamma, beta); + else + return new Newmark1(gamma, beta, alphaM, betaK, betaKi, betaKc); } diff --git a/SRC/runtime/commands/domain/TclUpdateMaterialCommand.cpp b/SRC/runtime/commands/domain/TclUpdateMaterialCommand.cpp index fe0b115f9f..869ae1abd4 100644 --- a/SRC/runtime/commands/domain/TclUpdateMaterialCommand.cpp +++ b/SRC/runtime/commands/domain/TclUpdateMaterialCommand.cpp @@ -30,14 +30,14 @@ TclCommand_UpdateMaterialsCommand(ClientData clientData, Tcl_Interp *interp, if (argc < 5) { opserr << "WARNING insufficient number of UpdateMaterialStage arguments\n"; opserr << "Want: UpdateMaterialStage material matTag? stage value?" - << endln; + << "\n"; return TCL_ERROR; } if (strcmp(argv[1], "-material") != 0) { opserr << "WARNING UpdateMaterialStage: Only accept parameter '-material' " "for now" - << endln; + << "\n"; return TCL_ERROR; } @@ -45,7 +45,7 @@ TclCommand_UpdateMaterialsCommand(ClientData clientData, Tcl_Interp *interp, double valueD; if (Tcl_GetInt(interp, argv[2], &materialTag) != TCL_OK) { - opserr << "WARNING MYSstage: invalid material tag" << endln; + opserr << "WARNING MYSstage: invalid material tag" << "\n"; return TCL_ERROR; } @@ -55,7 +55,7 @@ TclCommand_UpdateMaterialsCommand(ClientData clientData, Tcl_Interp *interp, if (argc > 5) { if (strcmp(argv[5], "-parameter") == 0) { if (Tcl_GetInt(interp, argv[6], &parTag) != TCL_OK) { - opserr << "WARNING UpdateMaterialStage: invalid parameter tag" << endln; + opserr << "WARNING UpdateMaterialStage: invalid parameter tag" << "\n"; return TCL_ERROR; } } @@ -66,7 +66,7 @@ TclCommand_UpdateMaterialsCommand(ClientData clientData, Tcl_Interp *interp, if (theDomain->addParameter(theParameter) == false) { opserr << "WARNING could not add updateMaterialStage - " "MaterialStageParameter to domain" - << endln; + << "\n"; return TCL_ERROR; } @@ -74,7 +74,7 @@ TclCommand_UpdateMaterialsCommand(ClientData clientData, Tcl_Interp *interp, if (Tcl_GetInt(interp, argv[4], &value) != TCL_OK) { if (Tcl_GetDouble(interp, argv[4], &valueD) != TCL_OK) { - opserr << "WARNING UpdateMaterialStage: could not read value" << endln; + opserr << "WARNING UpdateMaterialStage: could not read value" << "\n"; return TCL_ERROR; } else { diff --git a/SRC/runtime/commands/domain/TclUpdateMaterialStageCommand.cpp b/SRC/runtime/commands/domain/TclUpdateMaterialStageCommand.cpp index 70ea09aaed..e77b1ee810 100644 --- a/SRC/runtime/commands/domain/TclUpdateMaterialStageCommand.cpp +++ b/SRC/runtime/commands/domain/TclUpdateMaterialStageCommand.cpp @@ -29,6 +29,8 @@ // $Revision: 1.16 $ // $Date: 2007-10-16 00:15:07 $ // +#include +#include #include #include #include @@ -72,7 +74,7 @@ TclCommand_updateMaterialStage(ClientData clientData, if (Tcl_GetInt(interp, argv[2], &materialTag) != TCL_OK) { opserr << "WARNING MYSstage: invalid material tag" - << endln; + << "\n"; return TCL_ERROR; } @@ -84,7 +86,7 @@ TclCommand_updateMaterialStage(ClientData clientData, if (strcmp(argv[5], "-parameter") == 0) { if (Tcl_GetInt(interp, argv[6], &parTag) != TCL_OK) { opserr << "WARNING UpdateMaterialStage: invalid parameter tag used" - << endln; + << "\n"; return TCL_ERROR; } } @@ -95,19 +97,19 @@ TclCommand_updateMaterialStage(ClientData clientData, if (domain->addParameter(theParameter) == false) { opserr << "WARNING could not add updateMaterialStage - " "MaterialStageParameter to domain" - << endln; + << "\n"; return TCL_ERROR; } if (strcmp(argv[3], "-stage") != 0) { opserr << "WARNING UpdateMaterialStage: Only accept parameter '-stage' for now" - << endln; + << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[4], &value) != TCL_OK) { - opserr << "WARNING UpdateMaterialStage: invalid parameter value" << endln; + opserr << "WARNING UpdateMaterialStage: invalid parameter value" << "\n"; return TCL_ERROR; } @@ -131,14 +133,14 @@ TclBasicBuilderUpdateParameterCommand(ClientData clientData, Tcl_Interp *interp, if (argc < 5) { opserr << "WARNING insufficient number of updateParameter arguments\n"; opserr << "Want: updateParameter -material matNum? -param? newValue?" - << endln; + << "\n"; return TCL_ERROR; } if (strcmp(argv[1], "-material") != 0) { opserr << "WARNING UpdateParameter: Only accept parameter '-material' for now" - << endln; + << "\n"; return TCL_ERROR; } @@ -146,7 +148,7 @@ TclBasicBuilderUpdateParameterCommand(ClientData clientData, Tcl_Interp *interp, double value; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING UpdateParameter: invalid material tag" << endln; + opserr << "WARNING UpdateParameter: invalid material tag" << "\n"; return TCL_ERROR; } @@ -156,17 +158,17 @@ TclBasicBuilderUpdateParameterCommand(ClientData clientData, Tcl_Interp *interp, if (a == 0) { // opserr << "WARNING UpdateParameter: couldn't get NDmaterial tagged: " << - // tag << endln; return TCL_ERROR; + // tag << "\n"; return TCL_ERROR; UniaxialMaterial *a = builder->getTypedObject(tag); if (a == 0) { opserr << "WARNING UpdateParameter: couldn't get Uniaxialmaterial tagged: " - << tag << endln; + << tag << "\n"; return TCL_ERROR; } if (strcmp(argv[3], "-E") == 0) { if (Tcl_GetDouble(interp, argv[4], &value) != TCL_OK) { - opserr << "WARNING UpdateParameter: invalid parameter value" << endln; + opserr << "WARNING UpdateParameter: invalid parameter value" << "\n"; return TCL_ERROR; } Information info; @@ -174,7 +176,7 @@ TclBasicBuilderUpdateParameterCommand(ClientData clientData, Tcl_Interp *interp, a->updateParameter(0, info); } else if (strcmp(argv[3], "-fy") == 0) { if (Tcl_GetDouble(interp, argv[4], &value) != TCL_OK) { - opserr << "WARNING UpdateParameter: invalid parameter value" << endln; + opserr << "WARNING UpdateParameter: invalid parameter value" << "\n"; return TCL_ERROR; } Information info; @@ -183,7 +185,7 @@ TclBasicBuilderUpdateParameterCommand(ClientData clientData, Tcl_Interp *interp, } else { opserr << "WARNING UpdateParameter: Only accept parameter '-E' or '-fy' " "for now" - << endln; + << "\n"; return TCL_ERROR; } return TCL_OK; @@ -196,12 +198,12 @@ TclBasicBuilderUpdateParameterCommand(ClientData clientData, Tcl_Interp *interp, else { opserr << "WARNING UpdateParameter: Only accept parameter '-refG' or " "'-refB' for now" - << endln; + << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &value) != TCL_OK) { - opserr << "WARNING UpdateParameter: invalid parameter value" << endln; + opserr << "WARNING UpdateParameter: invalid parameter value" << "\n"; return TCL_ERROR; } @@ -212,10 +214,10 @@ TclBasicBuilderUpdateParameterCommand(ClientData clientData, Tcl_Interp *interp, info.setDouble(value); a->updateParameter(id, info); } else { - opserr << "WARNING UpdateParameter: The tagged is not a " << endln; + opserr << "WARNING UpdateParameter: The tagged is not a " << "\n"; opserr << "PressureDependMultiYield/PressureIndependMultiYield/" "FluidSolidPorous material. " - << endln; + << "\n"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/domain/commands.cpp b/SRC/runtime/commands/domain/commands.cpp index 33f993c8d6..ac3c02fff7 100644 --- a/SRC/runtime/commands/domain/commands.cpp +++ b/SRC/runtime/commands/domain/commands.cpp @@ -256,12 +256,12 @@ InitialStateAnalysis(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, if (argc < 2) { opserr << "WARNING: Incorrect number of arguments for InitialStateAnalysis " "command" - << endln; + << "\n"; return TCL_ERROR; } if (strcmp(argv[1], "on") == 0) { - opserr << "InitialStateAnalysis ON" << endln; + opserr << "InitialStateAnalysis ON" << "\n"; // set global variable to true // FMK changes for parallel: @@ -274,7 +274,7 @@ InitialStateAnalysis(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, return TCL_OK; } else if (strcmp(argv[1], "off") == 0) { - opserr << "InitialStateAnalysis OFF" << endln; + opserr << "InitialStateAnalysis OFF" << "\n"; // call revert to start to zero the displacements the_domain->revertToStart(); @@ -291,7 +291,7 @@ InitialStateAnalysis(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, } else { opserr << "WARNING: Incorrect arguments - want InitialStateAnalysis on, or " "InitialStateAnalysis off" - << endln; + << "\n"; return TCL_ERROR; } @@ -457,7 +457,7 @@ getEleLoadTags(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, } } else { - opserr << OpenSees::PromptValueError << "unexpectd arguments\n" << endln; + opserr << OpenSees::PromptValueError << "unexpectd arguments\n" << "\n"; return TCL_ERROR; } @@ -528,7 +528,7 @@ getEleLoadData(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, } else { opserr << OpenSees::PromptValueError - << "want - getEleLoadTags " << endln; + << "want - getEleLoadTags " << "\n"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp b/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp index 0ac2048bed..869af3b376 100644 --- a/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp +++ b/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp @@ -106,7 +106,7 @@ TclAddDatabase(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** // check we instantiated a database .. if not ran out of memory if (theDatabase == nullptr) { opserr << "WARNING ran out of memory - database File " << argv[2] - << endln; + << "\n"; return TCL_ERROR; } @@ -182,7 +182,7 @@ save(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv // check argv[1] for commitTag int commitTag; if (Tcl_GetInt(interp, argv[1], &commitTag) != TCL_OK) { - opserr << "WARNING - save could not read commitTag " << argv[1] << endln; + opserr << "WARNING - save could not read commitTag " << argv[1] << "\n"; return TCL_OK; } @@ -212,7 +212,7 @@ restore(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const a // check argv[1] for commitTag int commitTag; if (Tcl_GetInt(interp, argv[1], &commitTag) != TCL_OK) { - opserr << "WARNING - restore could not read commitTag " << argv[1] << endln; + opserr << "WARNING - restore could not read commitTag " << argv[1] << "\n"; return TCL_OK; } diff --git a/SRC/runtime/commands/domain/domain.cpp b/SRC/runtime/commands/domain/domain.cpp index 30410f21ec..01dead67d4 100644 --- a/SRC/runtime/commands/domain/domain.cpp +++ b/SRC/runtime/commands/domain/domain.cpp @@ -78,32 +78,7 @@ removeObject(ClientData clientData, Tcl_Interp *interp, int argc, } Element *theEle = the_domain->removeElement(tag); if (theEle != nullptr) { -#if 0 - // we also have to remove any elemental loads from the domain - LoadPatternIter &theLoadPatterns = the_domain->getLoadPatterns(); - LoadPattern *thePattern; - - // go through all load patterns - while ((thePattern = theLoadPatterns()) != 0) { - ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); - ElementalLoad *theLoad; - - // go through all elemental loads in the pattern - while ((theLoad = theEleLoads()) != 0) { - - // remove & destroy elemental from elemental load if there - // note - if last element in load, remove the load and delete it - - /* ***************** - int numLoadsLeft = theLoad->removeElement(tag); - if (numLoadsLeft == 0) { - thePattern->removeElementalLoad(theLoad->getTag()); - delete theLoad; - } - *********************/ - } - } -#endif + // finally invoke the destructor on the element delete theEle; } @@ -126,25 +101,7 @@ removeObject(ClientData clientData, Tcl_Interp *interp, int argc, delete thePattern; } } -#if 0 - else if ((strcmp(remove_type, "TimeSeries") == 0) || - (strcmp(remove_type, "timeSeries") == 0)) { - if (argc < 3) { - opserr << "WARNING want - remove loadPattern patternTag?\n"; - return TCL_ERROR; - } - if (Tcl_GetIntFromObj(interp, objv[2], &tag) != TCL_OK) { - opserr << "WARNING remove loadPattern tag? failed to read tag: " - << Tcl_GetString(objv[2]) << "\n"; - return TCL_ERROR; - } - bool ok = OPS_removeTimeSeries(tag); - if (ok == true) - return TCL_OK; - else - return TCL_ERROR; - } -#endif + else if (strcmp(remove_type, "parameter") == 0) { if (argc < 3) { opserr << "WARNING want - remove parameter paramTag?\n"; diff --git a/SRC/runtime/commands/domain/element.cpp b/SRC/runtime/commands/domain/element.cpp index 74769ca6c5..522f38c325 100644 --- a/SRC/runtime/commands/domain/element.cpp +++ b/SRC/runtime/commands/domain/element.cpp @@ -117,55 +117,6 @@ addElementRayleigh(ClientData clientData, Tcl_Interp *interp, return TCL_OK; } -#if 0 -int -setElementRayleighDampingFactors(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain *the_domain = (Domain*)clientData; - - if (argc < 6) { - opserr << OpenSees::PromptValueError << "setElementRayleighDampingFactors eleTag? alphaM? betaK? " - "betaK0? betaKc? - not enough arguments to command\n"; - return TCL_ERROR; - } - - int eleTag; - double alphaM, betaK, betaK0, betaKc; - - if (Tcl_GetInt(interp, argv[1], &eleTag) != TCL_OK) { - opserr << OpenSees::PromptValueError << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " - "read eleTag? \n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[2], &alphaM) != TCL_OK) { - opserr << OpenSees::PromptValueError << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " - "read alphaM? \n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[3], &betaK) != TCL_OK) { - opserr << OpenSees::PromptValueError << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " - "read betaK? \n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[4], &betaK0) != TCL_OK) { - opserr << OpenSees::PromptValueError << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " - "read betaK0? \n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[5], &betaKc) != TCL_OK) { - opserr << OpenSees::PromptValueError << "rayleigh alphaM? betaK? betaK0? betaKc? - could not " - "read betaKc? \n"; - return TCL_ERROR; - } - - Element *theEle = the_domain->getElement(eleTag); - theEle->setRayleighDampingFactors(alphaM, betaK, betaK0, betaKc); - return TCL_OK; -} -#endif int eleForce(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char** const argv) @@ -195,14 +146,6 @@ eleForce(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char** const a dof--; -#if 0 - Element *theEle = the_domain->getElement(tag); - if (theEle == 0) - return TCL_ERROR; - - const Vector &force = theEle->getResistingForce(); -#endif - const char *myArgv[1]; char myArgv0[8]; strcpy(myArgv0, "forces"); @@ -482,7 +425,7 @@ getEleClassTags(ClientData clientData, Tcl_Interp *interp, int argc, } else { opserr << OpenSees::PromptValueError - << "want - getEleClassTags \n" << endln; + << "want - getEleClassTags \n" << "\n"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/domain/loading/drm/TclPatternCommand.cpp b/SRC/runtime/commands/domain/loading/drm/TclPatternCommand.cpp index 4c8ca54434..7b42790979 100644 --- a/SRC/runtime/commands/domain/loading/drm/TclPatternCommand.cpp +++ b/SRC/runtime/commands/domain/loading/drm/TclPatternCommand.cpp @@ -165,7 +165,7 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, int argc, currentArg++; velSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); - if (velSeries == 0) { + if (velSeries == nullptr) { opserr << "WARNING invalid vel series: " << argv[currentArg]; opserr << " pattern UniformExcitation -vel {series}\n"; return TCL_ERROR; diff --git a/SRC/runtime/commands/domain/loading/groundMotion.cpp b/SRC/runtime/commands/domain/loading/groundMotion.cpp index 07320373bc..2f8a101f98 100644 --- a/SRC/runtime/commands/domain/loading/groundMotion.cpp +++ b/SRC/runtime/commands/domain/loading/groundMotion.cpp @@ -59,14 +59,14 @@ TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, // make sure at least one other argument to contain integrator if (argc < 4) { - opserr << "WARNING invalid command - want: groundMotion tag type \n"; + opserr << OpenSees::PromptValueError << "invalid command - want: groundMotion tag type \n"; opserr << " valid types: AccelRecord and Interpolated \n"; return TCL_ERROR; } int gMotionTag; if (Tcl_GetInt(interp, argv[1], &gMotionTag) != TCL_OK) { - opserr << "WARNING invalid tag: groundMotion tag type \n"; + opserr << OpenSees::PromptValueError << "invalid tag: groundMotion tag type \n"; return TCL_ERROR; } @@ -92,8 +92,8 @@ TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, currentArg++; accelSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); - if (accelSeries == 0) { - opserr << "WARNING invalid accel series: " << argv[currentArg]; + if (accelSeries == nullptr) { + opserr << OpenSees::PromptValueError << "invalid accel series: " << argv[currentArg]; opserr << " groundMotion tag Series -accel {series}\n"; return TCL_ERROR; } @@ -105,8 +105,8 @@ TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, currentArg++; velSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); - if (velSeries == 0) { - opserr << "WARNING invalid vel series: " << argv[currentArg]; + if (velSeries == nullptr) { + opserr << OpenSees::PromptValueError << "invalid vel series: " << argv[currentArg]; opserr << " groundMotion tag Series -vel {series}\n"; return TCL_ERROR; } @@ -118,8 +118,8 @@ TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, currentArg++; dispSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); - if (dispSeries == 0) { - opserr << "WARNING invalid disp series: " << argv[currentArg]; + if (dispSeries == nullptr) { + opserr << OpenSees::PromptValueError << "invalid disp series: " << argv[currentArg]; opserr << " groundMotion tag Series -disp {series}\n"; return TCL_ERROR; } @@ -131,8 +131,8 @@ TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, currentArg++; seriesIntegrator = TclDispatch_newSeriesIntegrator((ClientData)0, interp, argv[currentArg]); - if (seriesIntegrator == 0) { - opserr << "WARNING invalid series integrator: " << argv[currentArg]; + if (seriesIntegrator == nullptr) { + opserr << OpenSees::PromptValueError << "invalid series integrator: " << argv[currentArg]; opserr << " - groundMotion tag Series -int {Series Integrator}\n"; return TCL_ERROR; } @@ -145,7 +145,7 @@ TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, currentArg++; if (Tcl_GetDouble(interp, argv[currentArg], &dtInt) != TCL_OK) { - opserr << "WARNING invalid dtInt: " << argv[currentArg]; + opserr << OpenSees::PromptValueError << "invalid dtInt: " << argv[currentArg]; opserr << " - groundMotion tag Series -dtInt dt\n"; return TCL_ERROR; } @@ -158,7 +158,7 @@ TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, currentArg++; if (Tcl_GetDouble(interp, argv[currentArg], &fact) != TCL_OK) { - opserr << "WARNING invalid factor: " << argv[currentArg]; + opserr << OpenSees::PromptValueError << "invalid factor: " << argv[currentArg]; opserr << " - groundMotion tag Series -fact factor\n"; return TCL_ERROR; } @@ -169,14 +169,6 @@ TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, theMotion = new GroundMotion(dispSeries, velSeries, accelSeries, seriesIntegrator, dtInt, fact); - - if (theMotion == 0) { - opserr << "WARNING ran out of memory creating ground motion - pattern " - "UniformExcitation "; - opserr << gMotionTag << endln; - - return TCL_ERROR; - } } else if (strcmp(argv[startArg], "Interpolated") == 0) { @@ -202,7 +194,7 @@ TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, GroundMotion *theMotion1 = thePattern->getMotion(motionID); if (theMotion1 == nullptr) { - opserr << "WARNING no groundMotion with tag " << motionID << " :"; + opserr << OpenSees::PromptValueError << "no groundMotion with tag " << motionID << " :"; opserr << " pattern MultiSupport gMotion1? gMotion? .. "; opserr << "-fact fact1? fact2? .. \n"; return TCL_ERROR; @@ -211,7 +203,7 @@ TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, theMotions[i - 3] = theMotion1; } } else { - opserr << "WARNING no gMotionTags want :"; + opserr << OpenSees::PromptValueError << "no gMotionTags want :"; opserr << " pattern MultiSupport gMotion1? gMotion? .. "; opserr << "-fact fact1? fact2? .. \n"; return TCL_ERROR; @@ -229,7 +221,7 @@ TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, } else { - opserr << "WARNING unknown pattern type " << argv[1]; + opserr << OpenSees::PromptValueError << "unknown pattern type " << argv[1]; opserr << " - want: pattern patternType " << gMotionTag; opserr << " \t valid types: Plain, UniformExcitation \n"; return TCL_ERROR; @@ -238,7 +230,7 @@ TclCommand_newGroundMotion(ClientData clientData, Tcl_Interp* interp, int argc, // now add the load pattern to the modelBuilder if (theMotion != nullptr) { if (thePattern->addMotion(*theMotion, gMotionTag) < 0) { - opserr << "WARNING could not add ground motion with tag " << gMotionTag; + opserr << OpenSees::PromptValueError << "could not add ground motion with tag " << gMotionTag; opserr << " to pattern\n "; delete theMotion; // free the memory, pattern destroys the time series return TCL_ERROR; diff --git a/SRC/runtime/commands/domain/loading/pattern.cpp b/SRC/runtime/commands/domain/loading/pattern.cpp index 3e0e022ba3..4d5c015f53 100644 --- a/SRC/runtime/commands/domain/loading/pattern.cpp +++ b/SRC/runtime/commands/domain/loading/pattern.cpp @@ -134,7 +134,7 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, if (theSeries == nullptr) { opserr << OpenSees::PromptValueError << "problem creating TimeSeries for LoadPattern " - << patternID << endln; + << patternID << "\n"; // clean up the memory and return an error if (thePattern != nullptr) @@ -285,7 +285,7 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, if (Tcl_GetDouble(interp, argv[i + 2], &dt) != TCL_OK) { opserr << OpenSees::PromptValueError << "problem reading ground motion " << "time interval - pattern UniformExcitation: " << patternID - << endln; + << "\n"; return TCL_ERROR; } numInputs -= 3; @@ -321,7 +321,7 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, break; default: opserr << OpenSees::PromptValueError << "cannot read direction for excitation \n"; - opserr << "UniformExcitation " << patternID << " dir factor" << endln; + opserr << "UniformExcitation " << patternID << " dir factor" << "\n"; return TCL_ERROR; break; } @@ -340,7 +340,7 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, // Read in the ground motion if (accelFileName == 0) { opserr << OpenSees::PromptValueError << "No ground motion data provided\n"; - opserr << "UniformExcitation tag: " << patternID << endln; + opserr << "UniformExcitation tag: " << patternID << "\n"; return TCL_ERROR; } @@ -716,13 +716,13 @@ TclCommand_addPattern(ClientData clientData, Tcl_Interp *interp, int argc, opserr << "Creating H5DRM tag = " << tag << " filename = " << filename.c_str() << " factor = " << factor - << endln; + << "\n"; thePattern = new H5DRM(tag, filename, factor); opserr << "Done! Creating H5DRM tag = " << tag << " filename = " << filename.c_str() << " factor = " << factor - << endln; + << "\n"; domain->addLoadPattern(thePattern); return TCL_OK; diff --git a/SRC/runtime/commands/domain/loading/series.cpp b/SRC/runtime/commands/domain/loading/series.cpp index 7704421e0b..51df870189 100644 --- a/SRC/runtime/commands/domain/loading/series.cpp +++ b/SRC/runtime/commands/domain/loading/series.cpp @@ -194,19 +194,6 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T } -#if 0 - else if ((strcmp(argv[0], "Trig") == 0) || - (strcmp(argv[0], "TrigSeries") == 0) || - (strcmp(argv[0], "Sine") == 0) || - (strcmp(argv[0], "SineSeries") == 0)) { - - void *theResult = OPS_TrigSeries(rt, argc, argv); - if (theResult != nullptr) - theSeries = (TimeSeries *)theResult; - - } -#endif - else if ((strcmp(argv[0], "Linear") == 0) || (strcmp(argv[0], "LinearSeries") == 0)) { @@ -405,32 +392,6 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T theSeries = new RectangularSeries(tStart, tFinish, cFactor); } -#if 0 - else if (strcmp(argv[0], "Rectangular") == 0) { - - void *theResult = OPS_RectangularSeries(rt, argc, argv); - if (theResult != 0) - theSeries = (TimeSeries *)theResult; - - } - else if ((strcmp(argv[0], "Pulse") == 0) || - (strcmp(argv[0], "PulseSeries") == 0)) { - - void *theResult = OPS_PulseSeries(rt, argc, argv); - if (theResult != 0) - theSeries = (TimeSeries *)theResult; - - } - else if ((strcmp(argv[0], "Triangle") == 0) || - (strcmp(argv[0], "TriangleSeries") == 0)) { - - void *theResult = OPS_TriangleSeries(rt, argc, argv); - if (theResult != 0) - theSeries = (TimeSeries *)theResult; - - } -#endif - else if ((strcmp(argv[0], "Series") == 0) || (strcmp(argv[0], "Path") == 0)) { double cFactor = 1.0; @@ -669,95 +630,6 @@ TclDispatch_newTimeSeries(ClientData clientData, Tcl_Interp *interp, int argc, T } -#if 0 - else if ((strcmp(argv[0], "PeerDatabase") == 0) || - (strcmp(argv[0], "PeerMotion") == 0)) { - - void *theResult = OPS_PeerMotion(rt, argc, argv); - if (theResult != 0) - theSeries = (TimeSeries *)theResult; - - PeerMotion *thePeerMotion = (PeerMotion *)theSeries; - - if (argc > 4 && theSeries != 0) { - int argCount = 4; - - while (argCount + 1 < argc) { - if ((strcmp(argv[argCount], "-dT") == 0) || - (strcmp(argv[argCount], "-dt") == 0) || - (strcmp(argv[argCount], "-DT") == 0)) { - const char *variableName = argv[argCount + 1]; - double dT = thePeerMotion->getDt(); - char string[30]; - sprintf(string, "set %s %.18e", variableName, dT); - if (Tcl_Eval(interp, string) != TCL_OK) { - opserr << G3_WARN_PROMPT << Tcl_GetStringResult(interp); - Tcl_Exit(TCL_ERROR); - } - argCount += 2; - } else if ((strcmp(argv[argCount], "-nPts") == 0) || - (strcmp(argv[argCount], "-NPTS") == 0)) { - const char *variableName = argv[argCount + 1]; - int nPts = thePeerMotion->getNPts(); - char string[30]; - sprintf(string, "set %s %d", variableName, nPts); - if (Tcl_Eval(interp, string) != TCL_OK) { - opserr << G3_WARN_PROMPT << Tcl_GetStringResult(interp); - Tcl_Exit(TCL_ERROR); - } - argCount += 2; - } else - argCount++; - } - } - } -#endif - - -#if 0 - else if ((strcmp(argv[0], "PeerNGADatabase") == 0) || - (strcmp(argv[0], "PeerNGAMotion") == 0)) { - - void *theResult = OPS_PeerNGAMotion(rt, argc, argv); - if (theResult != 0) - theSeries = (TimeSeries *)theResult; - - PeerNGAMotion *thePeerMotion = (PeerNGAMotion *)(theSeries); - - if (argc > 3 && theSeries != 0) { - int argCount = 3; - - while (argCount + 1 < argc) { - if ((strcmp(argv[argCount], "-dT") == 0) || - (strcmp(argv[argCount], "-dt") == 0) || - (strcmp(argv[argCount], "-DT") == 0)) { - const char *variableName = argv[argCount + 1]; - double dT = thePeerMotion->getDt(); - char string[30]; - sprintf(string, "set %s %.18e", variableName, dT); - if (Tcl_Eval(interp, string) != TCL_OK) { - opserr << G3_WARN_PROMPT << Tcl_GetStringResult(interp); - Tcl_Exit(TCL_ERROR); - } - argCount += 2; - - } else if ((strcmp(argv[argCount], "-nPts") == 0) || - (strcmp(argv[argCount], "-NPTS") == 0)) { - const char *variableName = argv[argCount + 1]; - int nPts = thePeerMotion->getNPts(); - char string[30]; - sprintf(string, "set %s %d", variableName, nPts); - if (Tcl_Eval(interp, string) != TCL_OK) { - opserr << G3_WARN_PROMPT << Tcl_GetStringResult(interp); - Tcl_Exit(TCL_ERROR); - } - argCount += 2; - } else - argCount++; - } - } - } -#endif else { // type unknown opserr << "WARNING unknown Series type " << argv[0] << " - "; diff --git a/SRC/runtime/commands/domain/nodes.cpp b/SRC/runtime/commands/domain/nodes.cpp index 72ae2d9dad..8ecacf2263 100644 --- a/SRC/runtime/commands/domain/nodes.cpp +++ b/SRC/runtime/commands/domain/nodes.cpp @@ -290,12 +290,12 @@ nodeMass(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** c Node *theNode = the_domain->getNode(tag); if (theNode == nullptr) { - opserr << "WARNING nodeMass node " << tag << " not found" << endln; + opserr << "WARNING nodeMass node " << tag << " not found" << "\n"; return TCL_ERROR; } int numDOF = theNode->getNumberDOF(); if (dof < 1 || dof > numDOF) { - opserr << "WARNING nodeMass dof " << dof << " not in range" << endln; + opserr << "WARNING nodeMass dof " << dof << " not in range" << "\n"; return TCL_ERROR; } else { const Matrix &mass = theNode->getMass(); @@ -387,7 +387,7 @@ setNodeVel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** Node *theNode = the_domain->getNode(tag); if (theNode == nullptr) { opserr << "WARNING setNodeVel -- node with tag " << tag << " not found" - << endln; + << "\n"; return TCL_ERROR; } @@ -445,7 +445,7 @@ setNodeDisp(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, Node *theNode = the_domain->getNode(tag); if (theNode == nullptr) { opserr << "WARNING setNodeDisp -- node with tag " << tag << " not found" - << endln; + << "\n"; return TCL_ERROR; } @@ -506,7 +506,7 @@ setNodeAccel(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, Node *theNode = the_domain->getNode(tag); if (theNode == nullptr) { opserr << "WARNING setNodeAccel -- node with tag " << tag << " not found" - << endln; + << "\n"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/domain/recorder.cpp b/SRC/runtime/commands/domain/recorder.cpp index 169061c68f..095329c4bd 100644 --- a/SRC/runtime/commands/domain/recorder.cpp +++ b/SRC/runtime/commands/domain/recorder.cpp @@ -1310,104 +1310,6 @@ TclCreateRecorder(ClientData clientData, Tcl_Interp *interp, int argc, (*theRecorder) = (Recorder *)OPS_GmshRecorder(rt, argc, argv); } - // else if (strcmp(argv[1],"gmshparallel") == 0 || - // strcmp(argv[1],"GMSHPARALLEL") == 0) { - // OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, &theDomain); - // (*theRecorder) = (Recorder*) OPS_GmshRecorderParallel(); - // } - -#if 0 - else if (strcmp(argv[1], "mpco") == 0) { - OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, &theDomain); - (*theRecorder) = (Recorder*)OPS_MPCORecorder(rt, argc, argv); - if (theRecorder == 0) { - return TCL_ERROR; - } - } -#endif - -#if 0 - else if (strcmp(argv[1],"GSA") == 0) { - if (argc < 3) { - opserr << argc; - opserr << "WARNING recorder GSA -file filename? -dT deltaT? - not enough arguments\n"; - return TCL_ERROR; - } - TCL_Char *filename = 0; - TCL_Char *title1 =0; - TCL_Char *title2 =0; - TCL_Char *title3 =0; - TCL_Char *jobno =0; - TCL_Char *initials =0; - TCL_Char *spec =0; - TCL_Char *currency =0; - TCL_Char *length =0; - TCL_Char *force =0; - TCL_Char *temp =0; - double dT = 0.0; - int loc = 2; - - while (loc < argc) { - if ((strcmp(argv[loc],"-file") == 0) || - (strcmp(argv[loc],"-file") == 0)) { - filename = argv[loc+1]; - loc += 2; - } else if ((strcmp(argv[loc],"-title1") == 0) || - (strcmp(argv[loc],"-Title1e") == 0)) { - title1 = argv[loc+1]; - loc += 2; - } else if ((strcmp(argv[loc],"-title2") == 0) || - (strcmp(argv[loc],"-Title2e") == 0)) { - title2 = argv[loc+1]; - loc += 2; - } else if ((strcmp(argv[loc],"-title3") == 0) || - (strcmp(argv[loc],"-Title3e") == 0)) { - title3 = argv[loc+1]; - loc += 2; - } else if ((strcmp(argv[loc],"-jobno") == 0) || - (strcmp(argv[loc],"-JobNo") == 0)) { - jobno = argv[loc+1]; - loc += 2; - } else if ((strcmp(argv[loc],"-initials") == 0) || - (strcmp(argv[loc],"-Initials") == 0)) { - initials = argv[loc+1]; - loc += 2; - } else if ((strcmp(argv[loc],"-spec") == 0) || - (strcmp(argv[loc],"-Spec") == 0)) { - spec = argv[loc+1]; - loc += 2; - } else if ((strcmp(argv[loc],"-currency") == 0) || - (strcmp(argv[loc],"-Currency") == 0)) { - currency = argv[loc+1]; - loc += 2; - } else if ((strcmp(argv[loc],"-length") == 0) || - (strcmp(argv[loc],"-Length") == 0)) { - length = argv[loc+1]; - loc += 2; - } else if ((strcmp(argv[loc],"-force") == 0) || - (strcmp(argv[loc],"-Force") == 0)) { - force = argv[loc+1]; - loc += 2; - } else if ((strcmp(argv[loc],"-temp") == 0) || - (strcmp(argv[loc],"-Temp") == 0)) { - temp = argv[loc+1]; - loc += 2; - } - else if (strcmp(argv[loc],"-dT") == 0) { - if (Tcl_GetDouble(interp, argv[loc+1], &dT) != TCL_OK) - return TCL_ERROR; - loc += 2; - } - else - loc++; - } - - GSA_Recorder *theR = new GSA_Recorder(theDomain, filename, title1, title2, - title3, jobno, initials, spec, currency, length, force, temp, dT); - (*theRecorder) = theR; - } -#endif - else { // try existing loaded packages diff --git a/SRC/runtime/commands/domain/region.cpp b/SRC/runtime/commands/domain/region.cpp index 098bb096ee..67f99d638e 100644 --- a/SRC/runtime/commands/domain/region.cpp +++ b/SRC/runtime/commands/domain/region.cpp @@ -55,7 +55,7 @@ TclCommand_addMeshRegion(ClientData clientData, Tcl_Interp *interp, Tcl_Size arg } if (Tcl_GetInt(interp, argv[loc], &tag) != TCL_OK) { - opserr << "WARNING region tag? .. - invalid tag " << argv[loc] << endln; + opserr << "WARNING region tag? .. - invalid tag " << argv[loc] << "\n"; return TCL_ERROR; } @@ -92,8 +92,9 @@ TclCommand_addMeshRegion(ClientData clientData, Tcl_Interp *interp, Tcl_Size arg if (loc < argc) loc--; - } else if (strcmp(argv[loc], "-eleRange") == 0 || - strcmp(argv[loc], "-eleOnlyRange") == 0) { + } + else if (strcmp(argv[loc], "-eleRange") == 0 || + strcmp(argv[loc], "-eleOnlyRange") == 0) { if (strcmp(argv[loc], "-eleOnlyRange") == 0) eleOnly = true; @@ -112,12 +113,12 @@ TclCommand_addMeshRegion(ClientData clientData, Tcl_Interp *interp, Tcl_Size arg int start, end; if (Tcl_GetInt(interp, argv[loc + 1], &start) != TCL_OK) { opserr << "WARNING region tag? -eleRange start? end? - invalid start " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[loc + 2], &end) != TCL_OK) { opserr << "WARNING region tag? -eleRange start? end? - invalid end " - << argv[loc + 2] << endln; + << argv[loc + 2] << "\n"; return TCL_ERROR; } if (start > end) { @@ -152,7 +153,7 @@ TclCommand_addMeshRegion(ClientData clientData, Tcl_Interp *interp, Tcl_Size arg // read in list of nodes - if (theNodes == 0) + if (theNodes == nullptr) theNodes = new ID(0, 64); int nodTag; while (loc < argc && Tcl_GetInt(interp, argv[loc++], &nodTag) == TCL_OK) { @@ -179,12 +180,12 @@ TclCommand_addMeshRegion(ClientData clientData, Tcl_Interp *interp, Tcl_Size arg int start, end; if (Tcl_GetInt(interp, argv[loc + 1], &start) != TCL_OK) { opserr << "WARNING region tag? -eleRange start? end? - invalid start " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[loc + 2], &end) != TCL_OK) { opserr << "WARNING region tag? -eleRange start? end? - invalid end " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } if (start > end) { @@ -213,22 +214,22 @@ TclCommand_addMeshRegion(ClientData clientData, Tcl_Interp *interp, Tcl_Size arg // read in rayleigh damping factors if (Tcl_GetDouble(interp, argv[loc + 1], &alphaM) != TCL_OK) { opserr << "WARNING region tag? .. -rayleigh aM bK bK0 - invalid aM " - << argv[loc + 1] << endln; + << argv[loc + 1] << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[loc + 2], &betaK) != TCL_OK) { opserr << "WARNING region tag? .. -rayleigh aM bK bK0 - invalid bK " - << argv[loc + 2] << endln; + << argv[loc + 2] << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[loc + 3], &betaK0) != TCL_OK) { opserr << "WARNING region tag? .. -rayleigh aM bK bK0 - invalid bK0 " - << argv[loc + 3] << endln; + << argv[loc + 3] << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[loc + 4], &betaKc) != TCL_OK) { opserr << "WARNING region tag? .. -rayleigh aM bK bK0 - invalid bKc " - << argv[loc + 4] << endln; + << argv[loc + 4] << "\n"; return TCL_ERROR; } loc += 5; @@ -293,7 +294,7 @@ TclCommand_addMeshRegion(ClientData clientData, Tcl_Interp *interp, Tcl_Size arg MeshRegion *theRegion = new MeshRegion(tag); if (theDomain.addRegion(*theRegion) < 0) { - opserr << "WARNING could not add to domain - region " << tag << endln; + opserr << "WARNING could not add to domain - region " << tag << "\n"; delete theRegion; return TCL_ERROR; } diff --git a/SRC/runtime/commands/domain/rigid_links.cpp b/SRC/runtime/commands/domain/rigid_links.cpp index 9d0df0ccc9..de6426da40 100644 --- a/SRC/runtime/commands/domain/rigid_links.cpp +++ b/SRC/runtime/commands/domain/rigid_links.cpp @@ -35,110 +35,110 @@ static int createLinearRigidDiaphragm(Domain &theDomain, int ret_tag, ID &nC, in static int createLinearRigidBeam(Domain &theDomain, int ret_tag, int con_tag) { - - // get a pointer to the retained and constrained nodes - make sure they exist - Node *nodeR = theDomain.getNode(ret_tag); - if (nodeR == nullptr) { - opserr << OpenSees::PromptValueError - << "retained node " << ret_tag << " not in domain\n"; - return CONSTRAINT_ERROR; - } + // get a pointer to the retained and constrained nodes - make sure they exist + Node *nodeR = theDomain.getNode(ret_tag); - Node *nodeC = theDomain.getNode(con_tag); - if (nodeR == nullptr) { - opserr << OpenSees::PromptValueError - << "constrained node " << con_tag << " not in domain\n"; - return CONSTRAINT_ERROR; - } + if (nodeR == nullptr) { + opserr << OpenSees::PromptValueError + << "retained node " << ret_tag << " not in domain\n"; + return CONSTRAINT_ERROR; + } - // get the coordinates of the two nodes - check dimensions are the same - const Vector &crdR = nodeR->getCrds(); - const Vector &crdC = nodeC->getCrds(); - int dimR = crdR.Size(); - int dimC = crdC.Size(); - if (dimR != dimC) { - opserr << OpenSees::PromptValueError - << "mismatch in dimension between constrained node " - << con_tag << " and retained node " << ret_tag << "\n"; - return CONSTRAINT_ERROR; - } - - // check the number of dof at each node is the same - int numDOF = nodeR->getNumberDOF(); - if (numDOF != nodeC->getNumberDOF()){ - opserr << OpenSees::PromptValueError - << "mismatch in numDOF between constrained node " - << con_tag << " and retained node " << ret_tag << "\n"; - return CONSTRAINT_ERROR; - } + Node *nodeC = theDomain.getNode(con_tag); + if (nodeR == nullptr) { + opserr << OpenSees::PromptValueError + << "constrained node " << con_tag << " not in domain\n"; + return CONSTRAINT_ERROR; + } - // check the number of dof at the nodes >= dimension of problem - if(numDOF < dimR){ - opserr << OpenSees::PromptValueError - << "numDOF at nodes " << ret_tag << " and " - << con_tag << " must be >= dimension of problem\n"; - return CONSTRAINT_ERROR; - } + // get the coordinates of the two nodes - check dimensions are the same + const Vector &crdR = nodeR->getCrds(); + const Vector &crdC = nodeC->getCrds(); + int dimR = crdR.Size(); + int dimC = crdC.Size(); + if (dimR != dimC) { + opserr << OpenSees::PromptValueError + << "mismatch in dimension between constrained node " + << con_tag << " and retained node " << ret_tag << "\n"; + return CONSTRAINT_ERROR; + } + + // check the number of dof at each node is the same + int numDOF = nodeR->getNumberDOF(); + if (numDOF != nodeC->getNumberDOF()){ + opserr << OpenSees::PromptValueError + << "mismatch in numDOF between constrained node " + << con_tag << " and retained node " << ret_tag << "\n"; + return CONSTRAINT_ERROR; + } - // create the ID to identify the constrained dof - ID id(numDOF); + // check the number of dof at the nodes >= dimension of problem + if(numDOF < dimR){ + opserr << OpenSees::PromptValueError + << "numDOF at nodes " << ret_tag << " and " + << con_tag << " must be >= dimension of problem\n"; + return CONSTRAINT_ERROR; + } - // construct the transformation matrix Ccr, where Uc = Ccr Ur & set the diag, Ccr = I - Matrix mat(numDOF,numDOF); - mat.Zero(); + // create the ID to identify the constrained dof + ID id(numDOF); - // set the values - for (int i=0; igetCrds(); - const Vector &crdC = nodeC->getCrds(); - int dimR = crdR.Size(); - int dimC = crdC.Size(); - if (dimR != dimC) { - opserr << OpenSees::PromptValueError - << "mismatch in dimension between constrained node " - << con_tag << " and retained node " << ret_tag << "\n"; - return CONSTRAINT_ERROR; - } - - // check the number of dof at each node is the same - int numDOF = nodeR->getNumberDOF(); - if (numDOF != nodeC->getNumberDOF()){ - opserr << OpenSees::PromptValueError - << "mismatch in numDOF " << "between constrained node " - << con_tag << " and retained node " << ret_tag << "\n"; - return CONSTRAINT_ERROR; - } + // get the coordinates of the two nodes - check dimensions are the same + const Vector &crdR = nodeR->getCrds(); + const Vector &crdC = nodeC->getCrds(); + int dimR = crdR.Size(); + int dimC = crdC.Size(); + if (dimR != dimC) { + opserr << OpenSees::PromptValueError + << "mismatch in dimension between constrained node " + << con_tag << " and retained node " << ret_tag << "\n"; + return CONSTRAINT_ERROR; + } + + // check the number of dof at each node is the same + int numDOF = nodeR->getNumberDOF(); + if (numDOF != nodeC->getNumberDOF()){ + opserr << OpenSees::PromptValueError + << "mismatch in numDOF " << "between constrained node " + << con_tag << " and retained node " << ret_tag << "\n"; + return CONSTRAINT_ERROR; + } - // check the number of dof at the nodes >= dimension of problem - if(numDOF < dimR){ - opserr << OpenSees::PromptValueError - << "numDOF at nodes " << ret_tag << " and " << con_tag - << " must be >= dimension of problem\n"; - return CONSTRAINT_ERROR; - } - - // create the ID to identify the constrained dof - ID id(dimR); + // check the number of dof at the nodes >= dimension of problem + if(numDOF < dimR){ + opserr << OpenSees::PromptValueError + << "numDOF at nodes " << ret_tag << " and " << con_tag + << " must be >= dimension of problem\n"; + return CONSTRAINT_ERROR; + } - // construct the transformation matrix Ccr, where Uc = Ccr Ur & set the diag - Matrix mat(dimR,dimR); - mat.Zero(); + // create the ID to identify the constrained dof + ID id(dimR); - // set the values - for (int i=0; i(clientData); - - if (theTclBuilder == 0 || clientData == 0) { - opserr << OpenSees::PromptValueError << "builder has been destroyed - equalDOF \n"; - return TCL_ERROR; - } - - // Check number of arguments - if (argc < 4) { - opserr << OpenSees::PromptValueError << "bad command - want: equalDOFmixed RnodeID? CnodeID? numDOF? RDOF1? CDOF1? ... ..."; - return TCL_ERROR; - } - - // Read in the node IDs and the DOF - int RnodeID, CnodeID, dofIDR, dofIDC, numDOF; - - if (Tcl_GetInt(interp, argv[1], &RnodeID) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid RnodeID: " << argv[1] - << " equalDOF RnodeID? CnodeID? numDOF? RDOF1? CDOF1? ..."; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[2], &CnodeID) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid CnodeID: " << argv[2] - << " equalDOF RnodeID? CnodeID? numDOF? RDOF1? CDOF1? ..."; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &numDOF) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid numDOF: " << argv[2] - << " equalDOF RnodeID? CnodeID? numDOF? RDOF1? CDOF1? ..."; - return TCL_ERROR; - } - - // The number of DOF to be coupled - // int numDOF = argc - 3; - - // The constraint matrix ... U_c = C_cr * U_r - Matrix Ccr (numDOF, numDOF); - Ccr.Zero(); - - // The vector containing the retained and constrained DOFs - ID rDOF (numDOF); - ID cDOF (numDOF); - - int i, j, k; - // Read the degrees of freedom which are to be coupled - for (i = 4, j = 5, k = 0; k < numDOF; i+=2, j+=2, k++) { - if (Tcl_GetInt(interp, argv[i], &dofIDR) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid dofID: " << argv[3] - << " equalDOF RnodeID? CnodeID? DOF1? DOF2? ..."; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[j], &dofIDC) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid dofID: " << argv[3] - << " equalDOF RnodeID? CnodeID? DOF1? DOF2? ..."; - return TCL_ERROR; - } - - dofIDR -= 1; // Decrement for 0-based indexing - dofIDC -= 1; - if (dofIDC < 0 || dofIDR < 0) { - opserr << OpenSees::PromptValueError << "invalid dofID: " << argv[i] - << " must be >= 1"; - return TCL_ERROR; - } - rDOF(k) = dofIDR; - cDOF(k) = dofIDC; - Ccr(k,k) = 1.0; - } - - // Create the multi-point constraint - MP_Constraint *theMP = new MP_Constraint (RnodeID, CnodeID, Ccr, cDOF, rDOF); - - // Add the multi-point constraint to the domain - if (theTclDomain->addMP_Constraint (theMP) == false) { - opserr << OpenSees::PromptValueError << "could not add equalDOF MP_Constraint to domain "; - delete theMP; - return TCL_ERROR; - } - - Tcl_SetObjResult(interp, Tcl_NewIntObj(theMP->getTag())); - return TCL_OK; -} -#endif - - int TclCommand_addImposedMotionSP(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) diff --git a/SRC/runtime/commands/modeling/element.cpp b/SRC/runtime/commands/modeling/element.cpp index 971d423726..4be3402ba3 100644 --- a/SRC/runtime/commands/modeling/element.cpp +++ b/SRC/runtime/commands/modeling/element.cpp @@ -61,11 +61,6 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp *interp // // THE PROTOTYPES OF THE FUNCTIONS INVOKED BY THE INTERPRETER // - -#if 0 // cmp - commented out to eliminate use of TclBasicBuilder -extern int Tcl_addWrapperElement(eleObj *, ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, Domain *, TclBuilder *); -// Added by Quan Gu and Yongdou Liu, et al. on 2018/10/31 (Xiamen University) -#endif static Tcl_CmdProc TclBasicBuilder_addWheelRail; @@ -111,9 +106,6 @@ G3_TclElementCommand TclBasicBuilder_addMasonPan12; G3_TclElementCommand TclBasicBuilder_addMasonPan3D; G3_TclElementCommand TclBasicBuilder_addBeamGT; - - - // Shells Element* TclDispatch_newShellANDeS(ClientData, Tcl_Interp*, int, TCL_Char** const); @@ -166,22 +158,6 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C else theEle = OPS_PML3D(rt, argc, argv); } -#if 0 - else if (strcmp(argv[1], "gradientInelasticBeamColumn") == 0) { - - Element *theEle = 0; - if (ndm == 2) - theEle = OPS_GradientInelasticBeamColumn2d(rt, argc, argv); - else - theEle = OPS_GradientInelasticBeamColumn3d(rt, argc, argv); - - if (theEle != 0) - theElement = theEle; - else { - return TCL_ERROR; - } - } -#endif #if defined(_HAVE_LHNMYS) || defined(OPSDEF_ELEMENT_LHNMYS) else if (strcmp(argv[1], "beamColumn2DwLHNMYS") == 0) { @@ -288,7 +264,7 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C if (theElement != nullptr) { if (theTclDomain->addElement(theElement) == false) { - opserr << "WARNING could not add element of with tag: " + opserr << OpenSees::PromptValueError << "could not add element of with tag: " << theElement->getTag() << " and of type: " << theElement->getClassType() << " to the Domain\n"; @@ -298,7 +274,7 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C return TCL_OK; } -#if 0 && defined(OPSDEF_ELEMENT_FEAP) +#if defined(OPSDEF_ELEMENT_FEAP) if (strcmp(argv[1], "fTruss") == 0) { int eleArgStart = 1; int result = TclBasicBuilder_addFeapTruss( @@ -464,28 +440,6 @@ TclCommand_addElement(ClientData clientData, Tcl_Interp *interp, int argc, TCL_C eleCommands = eleCommands->next; } -#if 0 - // - // maybe element in a routine, check existing ones or try loading new ones - // - - char *eleType = new char[strlen(argv[1]) + 1]; - strcpy(eleType, argv[1]); - eleObj *eleObject = OPS_GetElementType(eleType, (int)strlen(eleType)); - - delete[] eleType; - - if (eleObject != 0) { - - int result = Tcl_addWrapperElement(eleObject, clientData, interp, argc, argv, - theTclDomain, theTclBuilder); - - if (result != 0) - delete eleObject; - else - return result; - } -#endif // // try loading new dynamic library containing a C++ class // @@ -547,7 +501,7 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp BasicModelBuilder *builder = static_cast(clientData); if (builder == 0 || clientData == 0) { - opserr << "WARNING builder has been destroyed - multipleShearSpring\n"; + opserr << OpenSees::PromptValueError << "builder has been destroyed - multipleShearSpring\n"; return TCL_ERROR; } @@ -557,7 +511,7 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp if (ndm != 3 || ndf != 6) { opserr << "ndm=" << ndm << ", ndf=" << ndf << OpenSees::SignalMessageEnd; - opserr << "WARNING multipleShearSpring command only works when ndm is 3 " + opserr << OpenSees::PromptValueError << "multipleShearSpring command only works when ndm is 3 " "and ndf is 6" << OpenSees::SignalMessageEnd; return TCL_ERROR; @@ -593,29 +547,29 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp if (argc < 8) { // element multipleShearSpring eleTag? iNode? jNode? nSpring? // -mat matTag? - opserr << "WARNING insufficient arguments\n"; + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; ifNoError = false; } else { // argv[2~5] if (Tcl_GetInt(interp, argv[2], &eleTag) != TCL_OK) { - opserr << "WARNING invalid multipleShearSpring eleTag\n"; + opserr << OpenSees::PromptValueError << "invalid multipleShearSpring eleTag\n"; ifNoError = false; } if (Tcl_GetInt(interp, argv[3], &iNode) != TCL_OK) { - opserr << "WARNING invalid iNode\n"; + opserr << OpenSees::PromptValueError << "invalid iNode\n"; ifNoError = false; } if (Tcl_GetInt(interp, argv[4], &jNode) != TCL_OK) { - opserr << "WARNING invalid jNode\n"; + opserr << OpenSees::PromptValueError << "invalid jNode\n"; ifNoError = false; } if (Tcl_GetInt(interp, argv[5], &nSpring) != TCL_OK || nSpring <= 0) { - opserr << "WARNING invalid nSpring\n"; + opserr << OpenSees::PromptValueError << "invalid nSpring\n"; ifNoError = false; } @@ -628,15 +582,12 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp (i + 1) <= (argc - 1)) { // -mat matTag? if (Tcl_GetInt(interp, argv[i + 1], &matTag) != TCL_OK) { - opserr << "WARNING invalid matTag\n"; + opserr << OpenSees::PromptValueError << "invalid matTag\n"; ifNoError = false; } material = builder->getTypedObject(matTag); - if (material == 0) { - opserr << "WARNING material model not found\n"; - opserr << "uniaxialMaterial: " << matTag << OpenSees::SignalMessageEnd; - opserr << "multipleShearSpring element: " << eleTag << OpenSees::SignalMessageEnd; + if (material == nullptr) { return TCL_ERROR; } @@ -649,13 +600,13 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp theMaterials = new UniaxialMaterial *[nSpring]; for (int j = 0; j < nSpring; j++) { if (Tcl_GetInt(interp, argv[j + i + 1], &matTag) != TCL_OK) { - opserr << "WARNING invalid matTag\n"; + opserr << OpenSees::PromptValueError << "invalid matTag\n"; ifNoError = false; } theMaterials[j] = builder->getTypedObject(matTag); if (theMaterials[j] == 0) { - opserr << "WARNING material model not found\n"; + opserr << OpenSees::PromptValueError << "material model not found\n"; opserr << "uniaxialMaterial: " << matTag << OpenSees::SignalMessageEnd; opserr << "multipleShearSpring element: " << eleTag << OpenSees::SignalMessageEnd; return TCL_ERROR; @@ -672,7 +623,7 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp for (int j = 1; j <= 3; j++) { if (Tcl_GetDouble(interp, argv[i + j], &value) != TCL_OK) { - opserr << "WARNING invalid -orient value\n"; + opserr << OpenSees::PromptValueError << "invalid -orient value\n"; ifNoError = false; } else { oriX(j - 1) = value; @@ -683,7 +634,7 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp for (int j = 1; j <= 3; j++) { if (Tcl_GetDouble(interp, argv[i + j], &value) != TCL_OK) { - opserr << "WARNING invalid -orient value\n"; + opserr << OpenSees::PromptValueError << "invalid -orient value\n"; ifNoError = false; } else { oriYp(j - 1) = value; @@ -697,7 +648,7 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp for (int j = 1; j <= 3; j++) { if (Tcl_GetDouble(interp, argv[i + j], &value) != TCL_OK) { - opserr << "WARNING invalid -orient value\n"; + opserr << OpenSees::PromptValueError << "invalid -orient value\n"; ifNoError = false; } else { oriYp(j - 1) = value; @@ -710,7 +661,7 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp // <-mass m?> if (Tcl_GetDouble(interp, argv[i + 1], &mass) != TCL_OK || mass <= 0) { - opserr << "WARNING invalid mass\n"; + opserr << OpenSees::PromptValueError << "invalid mass\n"; ifNoError = false; } @@ -720,7 +671,7 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp // <-lim limDisp?> if (Tcl_GetDouble(interp, argv[i + 1], &limDisp) != TCL_OK || limDisp < 0) { - opserr << "WARNING invalid limDisp\n"; + opserr << OpenSees::PromptValueError << "invalid limDisp\n"; ifNoError = false; } @@ -728,7 +679,7 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp } else { // invalid option - opserr << "WARNING invalid optional arguments \n"; + opserr << OpenSees::PromptValueError << "invalid optional arguments \n"; ifNoError = false; break; } @@ -738,7 +689,7 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp // confirm material if (recvMat != 1) { - opserr << "WARNING wrong number of -mat inputs\n"; + opserr << OpenSees::PromptValueError << "wrong number of -mat inputs\n"; opserr << "got " << recvMat << " inputs, but want 1 input\n"; ifNoError = false; } @@ -763,7 +714,7 @@ TclBasicBuilder_addMultipleShearSpring(ClientData clientData, Tcl_Interp *interp // then add the multipleShearSpring to the domain if (theTclDomain->addElement(theElement) == false) { - opserr << "WARNING could not add element to the domain\n"; + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; opserr << "multipleShearSpring element: " << eleTag << OpenSees::SignalMessageEnd; delete theElement; return TCL_ERROR; @@ -803,7 +754,7 @@ TclBasicBuilder_addMultipleNormalSpring(ClientData clientData, Tcl_Interp *inter int ndf = builder->getNDF(); if (ndm != 3 || ndf != 6) { - opserr << "WARNING multipleNormalSpring command only works when ndm is 3 " + opserr << OpenSees::PromptValueError << "multipleNormalSpring command only works when ndm is 3 " "and ndf is 6" << OpenSees::SignalMessageEnd; return TCL_ERROR; @@ -1054,7 +1005,7 @@ TclBasicBuilder_addMultipleNormalSpring(ClientData clientData, Tcl_Interp *inter // then add the multipleNormalSpring to the domain if (theTclDomain->addElement(theElement) == false) { - opserr << "WARNING could not add element to the domain\n"; + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; opserr << "multipleNormalSpring element: " << eleTag << OpenSees::SignalMessageEnd; delete theElement; return TCL_ERROR; @@ -1078,7 +1029,7 @@ TclBasicBuilder_addKikuchiBearing(ClientData clientData, Tcl_Interp *interp, if (ndm != 3 || ndf != 6) { opserr << "ndm=" << ndm << ", ndf=" << ndf << OpenSees::SignalMessageEnd; - opserr << "WARNING KikuchiBearing command only works when ndm is 3 and ndf " + opserr << OpenSees::PromptValueError << "KikuchiBearing command only works when ndm is 3 and ndf " "is 6" << OpenSees::SignalMessageEnd; return TCL_ERROR; @@ -1543,7 +1494,7 @@ TclBasicBuilder_addKikuchiBearing(ClientData clientData, Tcl_Interp *interp, // then add the KikuchiBearing to the domain if (builder->getDomain()->addElement(theElement) == false) { - opserr << "WARNING could not add element to the domain\n"; + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; opserr << "KikuchiBearing element: " << eleTag << OpenSees::SignalMessageEnd; delete theElement; return TCL_ERROR; @@ -1569,7 +1520,7 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, if (ndm != 3 || ndf != 6) { opserr << "ndm=" << ndm << ", ndf=" << ndf << OpenSees::SignalMessageEnd; - opserr << "WARNING YamamotoBiaxialHDR command only works when ndm is 3 and " + opserr << OpenSees::PromptValueError << "YamamotoBiaxialHDR command only works when ndm is 3 and " "ndf is 6" << OpenSees::SignalMessageEnd; return TCL_ERROR; } @@ -1601,25 +1552,25 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, if (argc < 9) { // element YamamotoBiaxialHDR eleTag? iNode? jNode? Tp? DDo? DDi? Hr? - opserr << "WARNING insufficient arguments\n"; + opserr << OpenSees::PromptValueError << "insufficient arguments\n"; ifNoError = false; } else { // argv[2~8] if (Tcl_GetInt(interp, argv[2], &eleTag) != TCL_OK) { - opserr << "WARNING invalid YamamotoBiaxialHDR eleTag\n"; + opserr << OpenSees::PromptValueError << "invalid YamamotoBiaxialHDR eleTag\n"; ifNoError = false; } // iNode if (Tcl_GetInt(interp, argv[3], &iNode) != TCL_OK) { - opserr << "WARNING invalid iNode\n"; + opserr << OpenSees::PromptValueError << "invalid iNode\n"; ifNoError = false; } // jNode if (Tcl_GetInt(interp, argv[4], &jNode) != TCL_OK) { - opserr << "WARNING invalid jNode\n"; + opserr << OpenSees::PromptValueError << "invalid jNode\n"; ifNoError = false; } @@ -1627,25 +1578,25 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, if (strcmp(argv[5], "1") == 0) { Tp = 1; // Bridgestone X0.6R (EESD version) } else { - opserr << "WARNING invalid YamamotoBiaxialHDR Tp" << OpenSees::SignalMessageEnd; + opserr << OpenSees::PromptValueError << "invalid YamamotoBiaxialHDR Tp" << OpenSees::SignalMessageEnd; ifNoError = false; } // DDo if (Tcl_GetDouble(interp, argv[6], &DDo) != TCL_OK || DDo <= 0.0) { - opserr << "WARNING invalid YamamotoBiaxialHDR DDo" << OpenSees::SignalMessageEnd; + opserr << OpenSees::PromptValueError << "invalid YamamotoBiaxialHDR DDo" << OpenSees::SignalMessageEnd; ifNoError = false; } // DDi if (Tcl_GetDouble(interp, argv[7], &DDi) != TCL_OK || DDi < 0.0) { - opserr << "WARNING invalid YamamotoBiaxialHDR DDi" << OpenSees::SignalMessageEnd; + opserr << OpenSees::PromptValueError << "invalid YamamotoBiaxialHDR DDi" << OpenSees::SignalMessageEnd; ifNoError = false; } // Hr if (Tcl_GetDouble(interp, argv[8], &Hr) != TCL_OK || Hr <= 0.0) { - opserr << "WARNING invalid YamamotoBiaxialHDR Hr" << OpenSees::SignalMessageEnd; + opserr << OpenSees::PromptValueError << "invalid YamamotoBiaxialHDR Hr" << OpenSees::SignalMessageEnd; ifNoError = false; } @@ -1662,7 +1613,7 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, // x1, x2, x3 for (int j = 1; j <= 3; j++) { if (Tcl_GetDouble(interp, argv[i + j], &value) != TCL_OK) { - opserr << "WARNING invalid -orient value\n"; + opserr << OpenSees::PromptValueError << "invalid -orient value\n"; ifNoError = false; } else { oriX(j - 1) = value; @@ -1674,7 +1625,7 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, // yp1, yp2, yp3 for (int j = 1; j <= 3; j++) { if (Tcl_GetDouble(interp, argv[i + j], &value) != TCL_OK) { - opserr << "WARNING invalid -orient value\n"; + opserr << OpenSees::PromptValueError << "invalid -orient value\n"; ifNoError = false; } else { oriYp(j - 1) = value; @@ -1688,7 +1639,7 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, for (int j = 1; j <= 3; j++) { if (Tcl_GetDouble(interp, argv[i + j], &value) != TCL_OK) { - opserr << "WARNING invalid -orient value\n"; + opserr << OpenSees::PromptValueError << "invalid -orient value\n"; ifNoError = false; } else { oriYp(j - 1) = value; @@ -1701,7 +1652,7 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, // <-mass m?> if (Tcl_GetDouble(interp, argv[i + 1], &mass) != TCL_OK || mass <= 0) { - opserr << "WARNING invalid mass\n"; + opserr << OpenSees::PromptValueError << "invalid mass\n"; ifNoError = false; } @@ -1711,11 +1662,11 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, // <-coRS cr? cs?> if (Tcl_GetDouble(interp, argv[i + 1], &Cr) != TCL_OK || Cr <= 0) { - opserr << "WARNING invalid cr\n"; + opserr << OpenSees::PromptValueError << "invalid cr\n"; ifNoError = false; } if (Tcl_GetDouble(interp, argv[i + 2], &Cs) != TCL_OK || Cs <= 0) { - opserr << "WARNING invalid cs\n"; + opserr << OpenSees::PromptValueError << "invalid cs\n"; ifNoError = false; } @@ -1723,7 +1674,7 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, } else { - opserr << "WARNING invalid optional arguments \n"; + opserr << OpenSees::PromptValueError << "invalid optional arguments \n"; ifNoError = false; break; } @@ -1745,7 +1696,7 @@ TclBasicBuilder_addYamamotoBiaxialHDR(ClientData clientData, Tcl_Interp *interp, // then add the YamamotoBiaxialHDR to the domain if (theTclDomain->addElement(theElement) == false) { - opserr << "WARNING could not add element to the domain\n"; + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; opserr << "YamamotoBiaxialHDR element: " << eleTag << OpenSees::SignalMessageEnd; delete theElement; return TCL_ERROR; @@ -1776,14 +1727,14 @@ TclBasicBuilder_addWheelRail(ClientData clientData, Tcl_Interp *interp, int argc // check plane frame problem has 3 dof per node if (ndf != 3) { - opserr << "WARNING invalid ndf: " << ndf; + opserr << OpenSees::PromptValueError << "invalid ndf: " << ndf; opserr << ", for plane problem need 3 - elasticBeamColumn \n"; return TCL_ERROR; } // check the number of arguments if ((argc - eleArgStart) < 8) { - opserr << "WARNING bad command - want: elasticBeamColumn beamId iNode " + opserr << OpenSees::PromptValueError << "bad command - want: elasticBeamColumn beamId iNode " "jNode A E I transTag <-mass m> <-cMass>\n"; return TCL_ERROR; } @@ -1794,68 +1745,68 @@ TclBasicBuilder_addWheelRail(ClientData clientData, Tcl_Interp *interp, int argc double pDeltT, pVel, pInitLocation, pRWheel, pI, pE, pA; if (Tcl_GetInt(interp, argv[1 + eleArgStart], &pTag) != TCL_OK) { - opserr << "WARNING invalid pTag: " << argv[1 + eleArgStart]; + opserr << OpenSees::PromptValueError << "invalid pTag: " << argv[1 + eleArgStart]; opserr << " - WheelRail pTag iNode jNode"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[2 + eleArgStart], &pDeltT) != TCL_OK) { - opserr << "WARNING invalid pDeltT - WheelRail " << pTag + opserr << OpenSees::PromptValueError << "invalid pDeltT - WheelRail " << pTag << " iNode jNode A E I\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3 + eleArgStart], &pVel) != TCL_OK) { - opserr << "WARNING invalid pVel - WheelRail " << pTag + opserr << OpenSees::PromptValueError << "invalid pVel - WheelRail " << pTag << " iNode jNode A E I\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4 + eleArgStart], &pInitLocation) != TCL_OK) { - opserr << "WARNING invalid pInitLocation - WheelRail " << pTag + opserr << OpenSees::PromptValueError << "invalid pInitLocation - WheelRail " << pTag << " iNode jNode A E I\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[5 + eleArgStart], &pNd1) != TCL_OK) { - opserr << "WARNING invalid pNd1 - WheelRail " << pTag + opserr << OpenSees::PromptValueError << "invalid pNd1 - WheelRail " << pTag << " iNode jNode A E I\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[6 + eleArgStart], &pRWheel) != TCL_OK) { - opserr << "WARNING invalid pRWheel - WheelRail " << pTag + opserr << OpenSees::PromptValueError << "invalid pRWheel - WheelRail " << pTag << " iNode jNode A E I\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[7 + eleArgStart], &pI) != TCL_OK) { - opserr << "WARNING invalid pI - WheelRail " << pTag + opserr << OpenSees::PromptValueError << "invalid pI - WheelRail " << pTag << " iNode jNode A E I\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[8 + eleArgStart], &pE) != TCL_OK) { - opserr << "WARNING invalid pE - WheelRail " << pTag + opserr << OpenSees::PromptValueError << "invalid pE - WheelRail " << pTag << " iNode jNode A E I\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[9 + eleArgStart], &pA) != TCL_OK) { - opserr << "WARNING invalid pA - WheelRail " << pTag + opserr << OpenSees::PromptValueError << "invalid pA - WheelRail " << pTag << " iNode jNode A E I\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[10 + eleArgStart], &transTag) != TCL_OK) { - opserr << "WARNING invalid transTag - WheelRail " << pTag + opserr << OpenSees::PromptValueError << "invalid transTag - WheelRail " << pTag << " iNode jNode A E I\n"; return TCL_ERROR; } CrdTransf *theTransRWheel = builder->getTypedObject(transTag); if (Tcl_GetInt(interp, argv[11 + eleArgStart], &pnLoad) != TCL_OK) { - opserr << "WARNING invalid I - WheelRail " << pTag + opserr << OpenSees::PromptValueError << "invalid I - WheelRail " << pTag << " iNode jNode A E I\n"; return TCL_ERROR; } @@ -1873,7 +1824,7 @@ TclBasicBuilder_addWheelRail(ClientData clientData, Tcl_Interp *interp, int argc if (Tcl_SplitList(interp, argv[13 + eleArgStart], &pathSize, &pathStrings) != TCL_OK) { - opserr << "WARNING problem splitting path list " + opserr << OpenSees::PromptValueError << "problem splitting path list " << argv[13 + eleArgStart] << " - "; opserr << " NodeList -values {path} ... \n"; return TCL_OK; @@ -1883,7 +1834,7 @@ TclBasicBuilder_addWheelRail(ClientData clientData, Tcl_Interp *interp, int argc double value; // int debug = Tcl_GetDouble(interp, pathStrings[i], &value); if (Tcl_GetDouble(interp, pathStrings[i], &value) != TCL_OK) { - opserr << "WARNING problem reading path data value " << pathStrings[i] + opserr << OpenSees::PromptValueError << "problem reading path data value " << pathStrings[i] << " - "; opserr << " -strain {path} ... \n"; return 0; @@ -1896,7 +1847,7 @@ TclBasicBuilder_addWheelRail(ClientData clientData, Tcl_Interp *interp, int argc TCL_Char **pathStrings; if (Tcl_SplitList(interp, argv[15 + eleArgStart], &pathSize, &pathStrings) != TCL_OK) { - opserr << "WARNING problem splitting path list " + opserr << OpenSees::PromptValueError << "problem splitting path list " << argv[15 + eleArgStart] << " - "; opserr << " NodeList -values {path} ... \n"; return TCL_OK; @@ -1905,7 +1856,7 @@ TclBasicBuilder_addWheelRail(ClientData clientData, Tcl_Interp *interp, int argc for (int i = 0; i < pathSize; ++i) { double value; if (Tcl_GetDouble(interp, pathStrings[i], &value) != TCL_OK) { - opserr << "WARNING problem reading path data value " << pathStrings[i] + opserr << OpenSees::PromptValueError << "problem reading path data value " << pathStrings[i] << " - "; opserr << " -strain {path} ... \n"; return 0; @@ -1918,7 +1869,7 @@ TclBasicBuilder_addWheelRail(ClientData clientData, Tcl_Interp *interp, int argc TCL_Char **pathStrings; if (Tcl_SplitList(interp, argv[17 + eleArgStart], &pathSize, &pathStrings) != TCL_OK) { - opserr << "WARNING problem splitting path list " + opserr << OpenSees::PromptValueError << "problem splitting path list " << argv[17 + eleArgStart] << " - "; opserr << " NodeList -values {path} ... \n"; return TCL_OK; @@ -1927,7 +1878,7 @@ TclBasicBuilder_addWheelRail(ClientData clientData, Tcl_Interp *interp, int argc for (int i = 0; i < pathSize; ++i) { double value; if (Tcl_GetDouble(interp, pathStrings[i], &value) != TCL_OK) { - opserr << "WARNING problem reading path data value " << pathStrings[i] + opserr << OpenSees::PromptValueError << "problem reading path data value " << pathStrings[i] << " - "; opserr << " -strain {path} ... \n"; return 0; @@ -1949,7 +1900,7 @@ TclBasicBuilder_addWheelRail(ClientData clientData, Tcl_Interp *interp, int argc // add the WheelRail element to the Domain if (builder->getDomain()->addElement(theElement) == false) { - opserr << "WARNING could not add element to the domain\n"; + opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; opserr << "YamamotoBiaxialHDR element: " << pTag << OpenSees::SignalMessageEnd; delete theElement; return TCL_ERROR; diff --git a/SRC/runtime/commands/modeling/element.hpp b/SRC/runtime/commands/modeling/element.hpp index 0f09aeda65..a61ccf54dc 100644 --- a/SRC/runtime/commands/modeling/element.hpp +++ b/SRC/runtime/commands/modeling/element.hpp @@ -268,9 +268,6 @@ element_dispatch = { {"componentElement2d", OPS_ComponentElement2d}, {"componentElement3d", OPS_ComponentElement3d}, -#if 0 - {"componentElementDamp2d", OPS_ComponentElementDamp2d}, -#endif {"ModElasticBeam2d", OPS_ModElasticBeam2d}, {"ModElasticBeam3d", OPS_ModElasticBeam3d}, diff --git a/SRC/runtime/commands/modeling/element/brick.cpp b/SRC/runtime/commands/modeling/element/brick.cpp index a32c9a256c..f21b69379d 100644 --- a/SRC/runtime/commands/modeling/element/brick.cpp +++ b/SRC/runtime/commands/modeling/element/brick.cpp @@ -45,7 +45,7 @@ TclBasicBuilder_addBrick(ClientData clientData, Tcl_Interp *interp, int argc, Node5, Node6, Node7, Node8; if (Tcl_GetInt(interp, argv[1 + eleArgStart], &BrickId) != TCL_OK) { - opserr << "WARNING invalid Brick eleTag" << endln; + opserr << "WARNING invalid Brick eleTag" << "\n"; return TCL_ERROR; } @@ -100,7 +100,7 @@ TclBasicBuilder_addBrick(ClientData clientData, Tcl_Interp *interp, int argc, if ((argc - eleArgStart) > 11) { if (Tcl_GetDouble(interp, argv[11 + eleArgStart], &b1) != TCL_OK) { opserr << "WARNING invalid b1\n"; - opserr << "Brick element: " << BrickId << endln; + opserr << "Brick element: " << BrickId << "\n"; return TCL_ERROR; } } @@ -108,7 +108,7 @@ TclBasicBuilder_addBrick(ClientData clientData, Tcl_Interp *interp, int argc, if ((argc - eleArgStart) > 12) { if (Tcl_GetDouble(interp, argv[12 + eleArgStart], &b2) != TCL_OK) { opserr << "WARNING invalid b2\n"; - opserr << "Brick element: " << BrickId << endln; + opserr << "Brick element: " << BrickId << "\n"; return TCL_ERROR; } } @@ -116,7 +116,7 @@ TclBasicBuilder_addBrick(ClientData clientData, Tcl_Interp *interp, int argc, if ((argc - eleArgStart) > 13) { if (Tcl_GetDouble(interp, argv[13 + eleArgStart], &b3) != TCL_OK) { opserr << "WARNING invalid b3\n"; - opserr << "Brick element: " << BrickId << endln; + opserr << "Brick element: " << BrickId << "\n"; return TCL_ERROR; } } @@ -212,7 +212,7 @@ TclBasicBuilder_addTwentyNodeBrick(ClientData clientData, Tcl_Interp *interp, double b2 = 0.0; double b3 = 0.0; if (Tcl_GetInt(interp, argv[argStart], &brickId) != TCL_OK) { - opserr << "WARNING invalid 20NodeBrick eleTag" << endln; + opserr << "WARNING invalid 20NodeBrick eleTag" << "\n"; return TCL_ERROR; } for (int i = 0; i < 20; i++) @@ -303,14 +303,14 @@ TclBasicBuilder_addBrickUP(ClientData clientData, Tcl_Interp *interp, int argc, double b3 = 0.0; if (Tcl_GetInt(interp, argv[argStart], &brickUPId) != TCL_OK) { - opserr << "WARNING invalid brickUP eleTag" << endln; + opserr << "WARNING invalid brickUP eleTag" << "\n"; return TCL_ERROR; } for (int i = 0; i < 8; i++) if (Tcl_GetInt(interp, argv[1 + argStart + i], &(Nod[i])) != TCL_OK) { opserr << "WARNING invalid Node number\n"; - opserr << "brickUP element: " << brickUPId << endln; + opserr << "brickUP element: " << brickUPId << "\n"; return TCL_ERROR; } @@ -347,21 +347,21 @@ TclBasicBuilder_addBrickUP(ClientData clientData, Tcl_Interp *interp, int argc, if ((argc - argStart) >= 16) { if (Tcl_GetDouble(interp, argv[15 + argStart], &b1) != TCL_OK) { opserr << "WARNING invalid b1\n"; - opserr << "brickUP element: " << brickUPId << endln; + opserr << "brickUP element: " << brickUPId << "\n"; return TCL_ERROR; } } if ((argc - argStart) >= 17) { if (Tcl_GetDouble(interp, argv[16 + argStart], &b2) != TCL_OK) { opserr << "WARNING invalid b2\n"; - opserr << "brickUP element: " << brickUPId << endln; + opserr << "brickUP element: " << brickUPId << "\n"; return TCL_ERROR; } } if ((argc - argStart) >= 18) { if (Tcl_GetDouble(interp, argv[17 + argStart], &b3) != TCL_OK) { opserr << "WARNING invalid b3\n"; - opserr << "brickUP element: " << brickUPId << endln; + opserr << "brickUP element: " << brickUPId << "\n"; return TCL_ERROR; } } @@ -371,7 +371,7 @@ TclBasicBuilder_addBrickUP(ClientData clientData, Tcl_Interp *interp, int argc, if (theMaterial == 0) { opserr << "WARNING material not found\n"; opserr << "Material: " << matID; - opserr << "\nbrickUP element: " << brickUPId << endln; + opserr << "\nbrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } @@ -429,71 +429,71 @@ TclBasicBuilder_addTwentyEightNodeBrickUP(ClientData clientData, Tcl_Interp *int double b3 = 0.0; if (Tcl_GetInt(interp, argv[argStart], &brickUPId) != TCL_OK) { - opserr << "WARNING invalid 20_8_BrickUP eleTag" << endln; + opserr << "WARNING invalid 20_8_BrickUP eleTag" << "\n"; return TCL_ERROR; } for (int i = 0; i < 20; i++) if (Tcl_GetInt(interp, argv[1 + argStart + i], &(Nod[i])) != TCL_OK) { opserr << "WARNING invalid Node number\n"; - opserr << "20_8_BrickUP element: " << brickUPId << endln; + opserr << "20_8_BrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[21 + argStart], &matID) != TCL_OK) { opserr << "WARNING invalid matID\n"; - opserr << "20_8_BrickUP element: " << brickUPId << endln; + opserr << "20_8_BrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[22 + argStart], &bk) != TCL_OK) { opserr << "WARNING invalid fluid bulk modulus\n"; - opserr << "20_8_BrickUP element: " << brickUPId << endln; + opserr << "20_8_BrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[23 + argStart], &r) != TCL_OK) { opserr << "WARNING invalid fluid mass density\n"; - opserr << "20_8_BrickUP element: " << brickUPId << endln; + opserr << "20_8_BrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[24 + argStart], &perm1) != TCL_OK) { opserr << "WARNING invalid permeability_x\n"; - opserr << "20_8_BrickUP element: " << brickUPId << endln; + opserr << "20_8_BrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[25 + argStart], &perm2) != TCL_OK) { opserr << "WARNING invalid permeability_y\n"; - opserr << "20_8_BrickUP element: " << brickUPId << endln; + opserr << "20_8_BrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[26 + argStart], &perm3) != TCL_OK) { opserr << "WARNING invalid permeability_z\n"; - opserr << "20_8_BrickUP element: " << brickUPId << endln; + opserr << "20_8_BrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } if ((argc - argStart) >= 28) { if (Tcl_GetDouble(interp, argv[27 + argStart], &b1) != TCL_OK) { opserr << "WARNING invalid b1\n"; - opserr << "20_8_BrickUP element: " << brickUPId << endln; + opserr << "20_8_BrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } } if ((argc - argStart) >= 29) { if (Tcl_GetDouble(interp, argv[28 + argStart], &b2) != TCL_OK) { opserr << "WARNING invalid b2\n"; - opserr << "20_8_BrickUP element: " << brickUPId << endln; + opserr << "20_8_BrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } } if ((argc - argStart) >= 30) { if (Tcl_GetDouble(interp, argv[29 + argStart], &b3) != TCL_OK) { opserr << "WARNING invalid b3\n"; - opserr << "20_8_BrickUP element: " << brickUPId << endln; + opserr << "20_8_BrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } } @@ -503,7 +503,7 @@ TclBasicBuilder_addTwentyEightNodeBrickUP(ClientData clientData, Tcl_Interp *int if (theMaterial == 0) { opserr << "WARNING material not found\n"; opserr << "Material: " << matID; - opserr << "\n20_8_BrickUP element: " << brickUPId << endln; + opserr << "\n20_8_BrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } @@ -516,13 +516,13 @@ TclBasicBuilder_addTwentyEightNodeBrickUP(ClientData clientData, Tcl_Interp *int perm1, perm2, perm3, b1, b2, b3); if (theTwentyEightNodeBrickUP == 0) { opserr << "WARNING ran out of memory creating element\n"; - opserr << "20_8_BrickUP element: " << brickUPId << endln; + opserr << "20_8_BrickUP element: " << brickUPId << "\n"; return TCL_ERROR; } if (theTclDomain->addElement(theTwentyEightNodeBrickUP) == false) { opserr << "WARNING could not add element to the domain\n"; - opserr << "20_8_BrickUP element: " << brickUPId << endln; + opserr << "20_8_BrickUP element: " << brickUPId << "\n"; delete theTwentyEightNodeBrickUP; return TCL_ERROR; } @@ -575,71 +575,71 @@ TclBasicBuilder_addBBarBrickUP(ClientData clientData, Tcl_Interp *interp, int ar double b3 = 0.0; if (Tcl_GetInt(interp, argv[argStart], &BBarBrickUPId) != TCL_OK) { - opserr << "WARNING invalid BBarBrickUP eleTag" << endln; + opserr << "WARNING invalid BBarBrickUP eleTag" << "\n"; return TCL_ERROR; } for (int i = 0; i < 8; i++) if (Tcl_GetInt(interp, argv[1 + argStart + i], &(Nod[i])) != TCL_OK) { opserr << "WARNING invalid Node number\n"; - opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "BBarBrickUP element: " << BBarBrickUPId << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[9 + argStart], &matID) != TCL_OK) { opserr << "WARNING invalid matID\n"; - opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "BBarBrickUP element: " << BBarBrickUPId << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[10 + argStart], &bk) != TCL_OK) { opserr << "WARNING invalid fluid bulk modulus\n"; - opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "BBarBrickUP element: " << BBarBrickUPId << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[11 + argStart], &r) != TCL_OK) { opserr << "WARNING invalid fluid mass density\n"; - opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "BBarBrickUP element: " << BBarBrickUPId << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[12 + argStart], &perm1) != TCL_OK) { opserr << "WARNING invalid permeability_x\n"; - opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "BBarBrickUP element: " << BBarBrickUPId << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[13 + argStart], &perm2) != TCL_OK) { opserr << "WARNING invalid permeability_y\n"; - opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "BBarBrickUP element: " << BBarBrickUPId << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[14 + argStart], &perm3) != TCL_OK) { opserr << "WARNING invalid permeability_z\n"; - opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "BBarBrickUP element: " << BBarBrickUPId << "\n"; return TCL_ERROR; } if ((argc - argStart) >= 16) { if (Tcl_GetDouble(interp, argv[15 + argStart], &b1) != TCL_OK) { opserr << "WARNING invalid b1\n"; - opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "BBarBrickUP element: " << BBarBrickUPId << "\n"; return TCL_ERROR; } } if ((argc - argStart) >= 17) { if (Tcl_GetDouble(interp, argv[16 + argStart], &b2) != TCL_OK) { opserr << "WARNING invalid b2\n"; - opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "BBarBrickUP element: " << BBarBrickUPId << "\n"; return TCL_ERROR; } } if ((argc - argStart) >= 18) { if (Tcl_GetDouble(interp, argv[17 + argStart], &b3) != TCL_OK) { opserr << "WARNING invalid b3\n"; - opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "BBarBrickUP element: " << BBarBrickUPId << "\n"; return TCL_ERROR; } } @@ -649,7 +649,7 @@ TclBasicBuilder_addBBarBrickUP(ClientData clientData, Tcl_Interp *interp, int ar if (theMaterial == 0) { opserr << "WARNING material not found\n"; opserr << "Material: " << matID; - opserr << "\nBBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "\nBBarBrickUP element: " << BBarBrickUPId << "\n"; return TCL_ERROR; } @@ -659,13 +659,13 @@ TclBasicBuilder_addBBarBrickUP(ClientData clientData, Tcl_Interp *interp, int ar Nod[7], *theMaterial, bk, r, perm1, perm2, perm3, b1, b2, b3); if (theBBarBrickUP == 0) { opserr << "WARNING ran out of memory creating element\n"; - opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "BBarBrickUP element: " << BBarBrickUPId << "\n"; return TCL_ERROR; } if (theTclDomain->addElement(theBBarBrickUP) == false) { opserr << "WARNING could not add element to the domain\n"; - opserr << "BBarBrickUP element: " << BBarBrickUPId << endln; + opserr << "BBarBrickUP element: " << BBarBrickUPId << "\n"; delete theBBarBrickUP; return TCL_ERROR; } diff --git a/SRC/runtime/commands/modeling/element/frames.cpp b/SRC/runtime/commands/modeling/element/frames.cpp index 6d9b34f086..55af8186ab 100644 --- a/SRC/runtime/commands/modeling/element/frames.cpp +++ b/SRC/runtime/commands/modeling/element/frames.cpp @@ -329,9 +329,6 @@ CreateFrame(BasicModelBuilder& builder, static_loop<0, 3>([&](auto nwm) constexpr { if (nwm.value + 6 == ndf) { // Create the transform -#if 0 || defined(NEW_TRANSFORM) - FrameTransform<2,6+nwm.value> *tran = tb->template create<2,6+nwm.value>(); -#endif if (!options.shear_flag) { static_loop<2,30>([&](auto nip) constexpr { if (nip.value == sections.size()) @@ -417,18 +414,6 @@ CreateFrame(BasicModelBuilder& builder, } -#if 0 -Element* -CreateInelasticFrame(std::string, std::vector& nodes, - std::vector&, - BeamIntegration&, - // FrameQuadrature&, - FrameTransform&, - Options&); -Element* -CreatePrismaticFrame(std::string); -#endif - // 0 1 2 3 4 // element beam 1 $i $j 0 1 2 // diff --git a/SRC/runtime/commands/modeling/element/plane.cpp b/SRC/runtime/commands/modeling/element/plane.cpp index 3e78eb1301..23db57e5b1 100644 --- a/SRC/runtime/commands/modeling/element/plane.cpp +++ b/SRC/runtime/commands/modeling/element/plane.cpp @@ -1165,342 +1165,6 @@ TclBasicBuilder_addBBarFourNodeQuadUP(ClientData clientData, Tcl_Interp *interp, return TCL_OK; } -#if 0 -int -TclDispatch_newTri31(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **const argv) -{ - BasicModelBuilder* builder = static_cast(clientData); - - if (argc < 9) { - opserr << "Invalid #args, want: " - // 0 1 2 3 4 5 6 7 8 9 10 11 12 - << "element Tri31 eleTag? iNode? jNode? kNode? thk? type? matTag? \n"; - return TCL_ERROR; - } - - int tag, matID; - std::array nodes; - char *type; - double thickness, - pressure=0, - density=0, - b1 = 0, - b2 = 0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid element tag\n"; - return TCL_ERROR; - } - for (int i=0; i<3; i++) { - if (Tcl_GetInt(interp, argv[i+3], &nodes[i]) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid node tag\n"; - return TCL_ERROR; - } - } - - if (Tcl_GetDouble(interp, argv[6], &thickness) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid element thickness\n"; - return TCL_ERROR; - } - - - type = strdup(argv[7]); - if ( strcmp(type,"PlaneStrain") != 0 - && strcmp(type,"PlaneStress") != 0 - && strcmp(type,"PlaneStrain2D") != 0 - && strcmp(type,"PlaneStress2D") != 0) { - opserr << OpenSees::PromptValueError - << "improper material type: " << type << "for Tri31" - << OpenSees::SignalMessageEnd; - return TCL_ERROR; - } - - - if (Tcl_GetInt(interp, argv[8], &matID) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid material tag\n"; - return TCL_ERROR; - } - NDMaterial *theMaterial = builder->getTypedObject(matID); - if (theMaterial == nullptr) { - return TCL_ERROR; - } - - if (argc > 9 && Tcl_GetDouble(interp, argv[ 9], &pressure) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid element pressure\n"; - return TCL_ERROR; - } - if (argc > 10 && Tcl_GetDouble(interp, argv[10], &density) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid element density\n"; - return TCL_ERROR; - } - if (argc > 11 && Tcl_GetDouble(interp, argv[11], &b1) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid element load b1\n"; - return TCL_ERROR; - } - if (argc > 12 && Tcl_GetDouble(interp, argv[12], &b2) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid element load b2\n"; - return TCL_ERROR; - } - - // parsing was successful, create the element - - Element *theElement = new Tri31(tag, - nodes, - *theMaterial, - type, - thickness, - pressure, - density, - b1, b2); - - if (builder->getDomain()->addElement(theElement) == false) { - opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; - delete theElement; - return TCL_ERROR; - } - - free(type); - - return TCL_OK; -} - - -// Regular nine node quad - -int -TclBasicBuilder_addNineNodeQuad(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - // TODO: assertions, clean up - BasicModelBuilder *builder = (BasicModelBuilder*)clientData; - - if (builder == 0 || clientData == 0) { - opserr << OpenSees::PromptValueError << "builder has been destroyed\n"; - return TCL_ERROR; - } - - if (builder->getNDM() != 2 || builder->getNDF() != 2) { - opserr << OpenSees::PromptValueError << "-- model dimensions and/or nodal DOF not compatible " - "with quad element\n"; - return TCL_ERROR; - } - - // check the number of arguments is correct - int argStart = 2; - - if ((argc - argStart) < 13) { - opserr << OpenSees::PromptValueError << "insufficient arguments\n"; - opserr << "Want: element NineNodeQuad eleTag? iNode? jNode? kNode? lNode? " - "nNode? mNode? pNode? qNode? cNode? thk? type? matTag? " - "\n"; - return TCL_ERROR; - } - - // get the id and end nodes - int NineNodeQuadId; - std::array nodes{}; - int matID; - double thickness = 1.0; - double p = 0.0; // uniform normal traction (pressure) - double rho = 0.0; // mass density - double b1 = 0.0; - double b2 = 0.0; - - if (Tcl_GetInt(interp, argv[argStart], &NineNodeQuadId) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid NineNodeQuad eleTag" << "\n"; - return TCL_ERROR; - } - - for (int i=0; i<9; i++) - if (Tcl_GetInt(interp, argv[1 + argStart+i], &nodes[i]) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid node\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[10 + argStart], &thickness) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid thickness\n"; - return TCL_ERROR; - } - - TCL_Char *type = argv[11 + argStart]; - - if (Tcl_GetInt(interp, argv[12 + argStart], &matID) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid matID\n"; - return TCL_ERROR; - } - - if ((argc - argStart) > 16) { - if (Tcl_GetDouble(interp, argv[13 + argStart], &p) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid pressure\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[14 + argStart], &rho) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid b1\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[15 + argStart], &b1) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid b1\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[16 + argStart], &b2) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid b2\n"; - return TCL_ERROR; - } - } - - NDMaterial *theMaterial = builder->getTypedObject(matID); - if (theMaterial == nullptr) - return TCL_ERROR; - - - // now create the NineNodeQuad and add it to the Domain - NineNodeQuad *theNineNodeQuad = new NineNodeQuad( - NineNodeQuadId, nodes, *theMaterial, type, thickness, p, rho, b1, b2); - - - if (builder->getDomain()->addElement(theNineNodeQuad) == false) { - opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; - delete theNineNodeQuad; - return TCL_ERROR; - } - - return TCL_OK; -} - - -// -// Regular eight node quad -// -int -TclBasicBuilder_addEightNodeQuad(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) -{ - BasicModelBuilder *builder = (BasicModelBuilder*)clientData; - - if (builder->getNDM() != 2 || builder->getNDF() != 2) { - opserr << OpenSees::PromptValueError << "-- model dimensions and/or nodal DOF not compatible " - "with quad element\n"; - return TCL_ERROR; - } - - // check the number of arguments is correct - int argStart = 2; - - if ((argc - argStart) < 12) { - opserr << OpenSees::PromptValueError << "insufficient arguments\n"; - opserr << "Want: element EightNodeQuad eleTag? iNode? jNode? kNode? lNode? " - "nNode? mNode? pNode? qNode? thk? type? matTag? \n"; - return TCL_ERROR; - } - - // get the id and end nodes - int EightNodeQuadId; - int iNode, jNode, kNode, lNode, nNode, mNode, pNode, qNode; - int matID; - double thickness = 1.0; - double p = 0.0; // uniform normal traction (pressure) - double rho = 0.0; // mass density - double b1 = 0.0; - double b2 = 0.0; - - if (Tcl_GetInt(interp, argv[argStart], &EightNodeQuadId) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid EightNodeQuad eleTag" << "\n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[1 + argStart], &iNode) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid iNode\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[2 + argStart], &jNode) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid jNode\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3 + argStart], &kNode) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid kNode\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[4 + argStart], &lNode) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid lNode\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[5 + argStart], &nNode) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid nNode\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[6 + argStart], &mNode) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid mNode\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[7 + argStart], &pNode) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid pNode\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[8 + argStart], &qNode) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid qNode\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[9 + argStart], &thickness) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid thickness\n"; - return TCL_ERROR; - } - - TCL_Char *type = argv[10 + argStart]; - - if (Tcl_GetInt(interp, argv[11 + argStart], &matID) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid matID\n"; - return TCL_ERROR; - } - - if ((argc - argStart) > 15) { - if (Tcl_GetDouble(interp, argv[12 + argStart], &p) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid pressure\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[13 + argStart], &rho) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid b1\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[14 + argStart], &b1) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid b1\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[15 + argStart], &b2) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid b2\n"; - return TCL_ERROR; - } - } - - NDMaterial *theMaterial = builder->getTypedObject(matID); - if (theMaterial == nullptr) - return TCL_ERROR; - - - // now create the EightNodeQuad and add it to the Domain - EightNodeQuad *theEightNodeQuad = new EightNodeQuad( - EightNodeQuadId, iNode, jNode, kNode, lNode, nNode, mNode, pNode, qNode, - *theMaterial, type, thickness, p, rho, b1, b2); - - if (builder->getDomain()->addElement(theEightNodeQuad) == false) { - opserr << OpenSees::PromptValueError << "could not add element to the domain\n"; - delete theEightNodeQuad; - return TCL_ERROR; - } - - return TCL_OK; -} - -#endif - - int TclBasicBuilder_addSixNodeTri(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) diff --git a/SRC/runtime/commands/modeling/element/shells.cpp b/SRC/runtime/commands/modeling/element/shells.cpp index b58a92506c..e6d1da5509 100644 --- a/SRC/runtime/commands/modeling/element/shells.cpp +++ b/SRC/runtime/commands/modeling/element/shells.cpp @@ -419,264 +419,3 @@ TclDispatch_newShellANDeS(ClientData clientData, Tcl_Interp* interp, int argc, T return theElement; } - -#if 0 -Element* -TclDispatch_newShellDKGQ(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder* builder = (BasicModelBuilder*)clientData; - - if (argc < 6) { - opserr << "Want: element ShellDKGQ $tag $iNode $jNoe $kNode $lNode $secTag"; - return nullptr; - } - - int iData[6]; - int numData = 6; - if (OPS_GetInt(&numData, iData) != 0) { - opserr << "WARNING invalid integer tag\n"; - return nullptr; - } - - SectionForceDeformation *theSection = builder->getTypedObject(iData[5]); - if (theSection == nullptr) - return nullptr; - - return new ShellDKGQ(iData[0], iData[1], iData[2], iData[3], iData[4], *theSection); -} - -int -TclDispatch_newShellMITC4(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder* builder = (BasicModelBuilder*)clientData; - - bool updateBasis = false; - Element *theElement = nullptr; - - if (argc < 6) { - opserr << "Want: element ShellMITC4 $tag $iNode $jNode $kNode $lNode $secTag <-updateBasis>"; - return TCL_ERROR; - } - - int iData[6]; - int numData = 6; - if (OPS_GetInt(&numData, iData) != 0) { - opserr << "WARNING invalid integer tag\n"; - return TCL_ERROR; - } - - if (argc == 7) { - const char *type = OPS_GetString(); - if (strcmp(type, "-updateBasis") == 0) - updateBasis = true; - } - - SectionForceDeformation *theSection = builder->getTypedObject(iData[5]); - if (theSection == nullptr) - return TCL_ERROR; - - theElement = new ShellMITC4(iData[0], iData[1], iData[2], iData[3], iData[4], - *theSection, updateBasis); - - if (builder->getDomain()->addElement(theElement) == false) - return TCL_ERROR; - return TCL_OK; -} - - - -Element* -TclDispatch_newShellMITC9(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder* builder = (BasicModelBuilder*)clientData; - - int numArgs = OPS_GetNumRemainingInputArgs(); - - if (numArgs < 11) { - opserr << "Want: element ShellMITC9 $tag $node1 $node2 .... $node9 $secTag"; - return nullptr; - } - - int iData[11]; - int numData = 11; - if (OPS_GetInt(&numData, iData) != 0) { - opserr << "WARNING invalid integer tag\n"; - return nullptr; - } - - SectionForceDeformation *theSection = builder->getTypedObject(iData[10]); - if (theSection == nullptr) - return nullptr; - - return - new ShellMITC9(iData[0], iData[1], iData[2], iData[3], iData[4], iData[5], - iData[6], iData[7], iData[8], iData[9], *theSection); -} - - -Element* -TclDispatch_newShellNLDKGQ(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder* builder = (BasicModelBuilder*)clientData; - - int numArgs = OPS_GetNumRemainingInputArgs(); - - if (numArgs < 6) { - opserr - << "Want: element ShellNLDKGQ $tag $iNode $jNoe $kNode $lNode $secTag"; - return nullptr; - } - - int iData[6]; - int numData = 6; - if (OPS_GetInt(&numData, iData) != 0) { - opserr << "WARNING invalid integer tag\n"; - return nullptr; - } - - SectionForceDeformation *theSection = builder->getTypedObject(iData[5]); - if (theSection == nullptr) - return nullptr; - - return new ShellNLDKGQ(iData[0], iData[1], iData[2], iData[3], iData[4], - *theSection); - -} - -Element* -TclDispatch_newShellDKGT(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder* builder = (BasicModelBuilder*)clientData; - - int numArgs = OPS_GetNumRemainingInputArgs(); - - if (numArgs < 5) { - opserr << "Want: element ShellDKGT $tag $iNode $jNoe $kNode $secTag"; - return nullptr; - } - - int iData[5]; - int numData = 5; - if (OPS_GetInt(&numData, iData) != 0) { - opserr << "WARNING invalid integer tag\n"; - return nullptr; - } - - SectionForceDeformation *theSection = builder->getTypedObject(iData[4]); - if (theSection == nullptr) - return nullptr; - - - double b_data[3] = {0, 0, 0}; - - int num_remaining_args = OPS_GetNumRemainingInputArgs(); - - if (num_remaining_args > 3) { - num_remaining_args = 3; - } - if (num_remaining_args > 0) { - if (OPS_GetDoubleInput(&num_remaining_args, b_data) < 0) { - opserr << "WARNING: invalid double b_data\n"; - return nullptr; - } - } - - return new ShellDKGT(iData[0], iData[1], iData[2], iData[3], - *theSection, b_data[0], b_data[1], b_data[2]); -} - -Element* -TclDispatch_newShellMITC4Thermal(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder* builder = (BasicModelBuilder*)clientData; - - int numArgs = OPS_GetNumRemainingInputArgs(); - - if (numArgs < 6) { - opserr << "Want: element ShellMITC4Thermal $tag $iNode $jNoe $kNode $lNode " - "$secTag"; - return nullptr; - } - - int iData[6]; - int numData = 6; - if (OPS_GetInt(&numData, iData) != 0) { - opserr << "WARNING invalid integer tag\n"; - return nullptr; - } - - SectionForceDeformation *theSection = builder->getTypedObject(iData[5]); - if (theSection == nullptr) - return nullptr; - - return new ShellMITC4Thermal(iData[0], iData[1], iData[2], iData[3], iData[4], *theSection); -} - - - -Element* -TclDispatch_newShellNLDKGQThermal(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder* builder = (BasicModelBuilder*)clientData; - - int numArgs = OPS_GetNumRemainingInputArgs(); - - if (numArgs < 6) { - opserr << "Want: element ShellNLDKGQThermal $tag $iNode $jNoe $kNode " - "$lNode $secTag"; - return nullptr; - } - - int iData[6]; - int numData = 6; - if (OPS_GetInt(&numData, iData) != 0) { - opserr << "WARNING invalid integer tag\n"; - return nullptr; - } - - SectionForceDeformation *theSection = builder->getTypedObject(iData[5]); - if (theSection == nullptr) - return nullptr; - - return new ShellNLDKGQThermal(iData[0], iData[1], iData[2], iData[3], - iData[4], *theSection); - -} - - -Element* -TclDispatch_newShellNLDKGT(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** const argv) -{ - assert(clientData != nullptr); - BasicModelBuilder* builder = (BasicModelBuilder*)clientData; - - int numArgs = OPS_GetNumRemainingInputArgs(); - - if (numArgs < 5) { - opserr << "Want: element ShellNLDKGT $tag $iNode $jNoe $kNode $secTag"; - return nullptr; - } - - int iData[5]; - int numData = 5; - if (OPS_GetInt(&numData, iData) != 0) { - opserr << "WARNING invalid integer tag\n"; - return nullptr; - } - - SectionForceDeformation *theSection = builder->getTypedObject(iData[4]); - if (theSection == nullptr) - return nullptr; - - return - new ShellNLDKGT(iData[0], iData[1], iData[2], iData[3], *theSection); - -} -#endif diff --git a/SRC/runtime/commands/modeling/material/elastic.cpp b/SRC/runtime/commands/modeling/material/elastic.cpp index 7d90b96c67..64ad1dfcc2 100644 --- a/SRC/runtime/commands/modeling/material/elastic.cpp +++ b/SRC/runtime/commands/modeling/material/elastic.cpp @@ -487,121 +487,3 @@ enum class MaterialSymmetry { Isotropic // 2 }; - -#if 0 -int -TclCommand_newElasticAnisotropic(ClientData clientData, Tcl_Interp* interp, int argc, const char**const argv) -{ - BasicModelBuilder* builder = static_cast(clientData); - -//MaterialSymmetry symm = MaterialSymmetry::Isotropic; -//PlaneType type = PlaneType::None; - - if ((strcmp(argv[1], "ElasticIsotropic") == 0) || - (strcmp(argv[1], "Elastic") == 0) || - (strcmp(argv[1], "ElasticBeamFiber") == 0) || - (strcmp(argv[1], "ElasticIsotropic3D") == 0)) - { - - int tag; - double E, v; - double rho = 0.0; - - int loc = 2; - if (Tcl_GetInt(interp, argv[loc], &tag) != TCL_OK) { - opserr << "WARNING invalid ElasticIsotropic tag" << "\n"; - return TCL_ERROR; - } - loc++; - - if (Tcl_GetDouble(interp, argv[loc], &E) != TCL_OK) { - opserr << "WARNING invalid E\n"; - return TCL_ERROR; - } - loc++; - - if (Tcl_GetDouble(interp, argv[loc], &v) != TCL_OK) { - opserr << "WARNING invalid v\n"; - return TCL_ERROR; - } - loc++; - - if (argc > loc && Tcl_GetDouble(interp, argv[loc], &rho) != TCL_OK) { - opserr << "WARNING invalid rho\n"; - return TCL_ERROR; - } - loc++; - - - builder->addTaggedObject(*new ElasticMaterial(tag, E, 0.0, E)); - builder->addTaggedObject(*new ElasticIsotropicMaterial(tag, E, v, rho)); - builder->addTaggedObject> (*new ElasticIsotropic<3>(tag, E, v, rho)); - - // builder->addTaggedObject(*new ElasticIsotropicBeamFiber(tag, E, v, rho)); - // builder->addTaggedObject(*new ElasticIsotropicPlaneStrain2D(tag, E, v, rho)); - // builder->addTaggedObject, "PlaneStrain">(*new ElasticIsotropic<2,PlaneType::Strain>(tag, E, v, rho)); - // builder->addTaggedObject(*new ElasticIsotropicPlaneStress2D(tag, E, v, rho)); - // builder->addTaggedObject, "PlaneStress">(*new ElasticIsotropic<2,PlaneType::Stress>(tag, E, v, rho)); - - return TCL_OK; - } - - else if (strcmp(argv[1], "ElasticCrossAnisotropic") == 0) - { - if (argc < 8) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial ElasticCrossAnisotropic tag? Ehh? Ehv? nuhv? nuvv? Ghv? " - << "\n"; - return TCL_ERROR; - } - - int tag; - double Eh, Ev, nuhv, nuhh, Ghv; - double rho = 0.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid ElasticCrossAnisotropic tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &Eh) != TCL_OK) { - opserr << "WARNING invalid Eh\n"; - opserr << "nDMaterial ElasticCrossAnisotropic: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &Ev) != TCL_OK) { - opserr << "WARNING invalid Ev\n"; - opserr << "nDMaterial ElasticCrossAnisotropic: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &nuhv) != TCL_OK) { - opserr << "WARNING invalid nuhv\n"; - opserr << "nDMaterial ElasticCrossAnisotropic: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &nuhh) != TCL_OK) { - opserr << "WARNING invalid nuhh\n"; - opserr << "nDMaterial ElasticCrossAnisotropic: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[7], &Ghv) != TCL_OK) { - opserr << "WARNING invalid Ghv\n"; - opserr << "nDMaterial ElasticCrossAnisotropic: " << tag << "\n"; - return TCL_ERROR; - } - - if (argc > 8 && Tcl_GetDouble(interp, argv[8], &rho) != TCL_OK) { - opserr << "WARNING invalid rho\n"; - opserr << "nDMaterial ElasticCrossAnisotropic: " << tag << "\n"; - return TCL_ERROR; - } - - // theMaterial = new ElasticCrossAnisotropic(tag, Eh, Ev, nuhv, nuhh, Ghv, rho); - } -} -#endif - diff --git a/SRC/runtime/commands/modeling/material/fedeas.cpp b/SRC/runtime/commands/modeling/material/fedeas.cpp index 53a84fc96a..7043853aac 100644 --- a/SRC/runtime/commands/modeling/material/fedeas.cpp +++ b/SRC/runtime/commands/modeling/material/fedeas.cpp @@ -676,571 +676,3 @@ TclCommand_newFedeasConcrete(ClientData clientData, Tcl_Interp *interp, } - - -#if 0 - - -int -TclBasicBuilder_addUniaxialConcrete(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) -{ - - BasicModelBuilder *builder = static_cast(clientData); - - if (argc < 3) { - opserr << "WARNING insufficient number of arguments\n"; - return TCL_ERROR; - } - - // enum Positions { - // E, End - // }; - - - UniaxialMaterial *theMaterial = nullptr; - - double fpc, epsc0, fpcu, epscu; - double rat, ft, Ets; - int tag; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial tag\n"; - return TCL_ERROR; - } - - if (strcmp(argv[1], "Concrete1") == 0 || - strcmp(argv[1], "concrete01") == 0) { - - if (argc < 7) { - opserr << "WARNING invalid number of arguments\n"; - opserr - << "Want: uniaxialMaterial Concrete01 tag? fpc? epsc0? fpcu? epscu?" - << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &fpc) != TCL_OK) { - opserr << "WARNING invalid fpc\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[4], &epsc0) != TCL_OK) { - opserr << "WARNING invalid epsc0\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[5], &fpcu) != TCL_OK) { - opserr << "WARNING invalid fpcu\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[6], &epscu) != TCL_OK) { - opserr << "WARNING invalid epscu\n"; - return TCL_ERROR; - } - - theMaterial = new Concrete01(tag, fpc, epsc0, fpcu, epscu); - } - - else if (strcmp(argv[1], "concr2") == 0) { - if (argc < 10) { - opserr << "WARNING invalid number of arguments\n"; - opserr << "Want: uniaxialMaterial Concrete02 tag? fpc? epsc0? fpcu? epscu? rat? ft? Ets?" - << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &fpc) != TCL_OK) { - opserr << "WARNING invalid fpc\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[4], &epsc0) != TCL_OK) { - opserr << "WARNING invalid epsc0\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[5], &fpcu) != TCL_OK) { - opserr << "WARNING invalid fpcu\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[6], &epscu) != TCL_OK) { - opserr << "WARNING invalid epscu\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[7], &rat) != TCL_OK) { - opserr << "WARNING invalid rat\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[8], &ft) != TCL_OK) { - opserr << "WARNING invalid Ft\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[9], &Ets) != TCL_OK) { - opserr << "WARNING invalid Ets\n"; - return TCL_ERROR; - } - - theMaterial = - new Concrete02(tag, fpc, epsc0, fpcu, epscu, rat, ft, Ets); - } - - return builder->addTaggedObject(*theMaterial); -} - - - -#include -#include -#include -#include -#include -#include -#include -int -Cmd(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) - { - if (strcmp(argv[1], "Hardening1") == 0 || - strcmp(argv[1], "Hardening01") == 0) { - if (argc < 7) { - opserr << "WARNING invalid number of arguments\n"; - opserr << "Want: uniaxialMaterial Hardening01 tag? E? sigY? Hiso? Hkin?" - << endln; - return TCL_ERROR; - } - - double E, sigY, Hiso, Hkin; - - if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { - opserr << "WARNING invalid E\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[4], &sigY) != TCL_OK) { - opserr << "WARNING invalid sigY\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[5], &Hiso) != TCL_OK) { - opserr << "WARNING invalid Hiso\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[6], &Hkin) != TCL_OK) { - opserr << "WARNING invalid Hkin\n"; - return TCL_ERROR; - } - - theMaterial = new FedeasHardeningMaterial(tag, E, sigY, Hiso, Hkin); - } - - else if (strcmp(argv[1], "Bond1") == 0 || strcmp(argv[1], "Bond01") == 0) { - if (argc < 15) { - opserr << "WARNING invalid number of arguments\n"; - opserr << "Want: uniaxialMaterial Bond01 tag? u1p? q1p? u2p? u3p? q3p? " - "u1n? q1n? u2n? u3n? q3n? s0? bb?" - << endln; - return TCL_ERROR; - } - - double u1p, q1p, u2p, u3p, q3p; - double u1n, q1n, u2n, u3n, q3n; - double s0, bb; - - if (Tcl_GetDouble(interp, argv[3], &u1p) != TCL_OK) { - opserr << "WARNING invalid u1p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[4], &q1p) != TCL_OK) { - opserr << "WARNING invalid q1p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[5], &u2p) != TCL_OK) { - opserr << "WARNING invalid u2p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[6], &u3p) != TCL_OK) { - opserr << "WARNING invalid u3p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[7], &q3p) != TCL_OK) { - opserr << "WARNING invalid q3p\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[8], &u1n) != TCL_OK) { - opserr << "WARNING invalid u1n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[9], &q1n) != TCL_OK) { - opserr << "WARNING invalid q1n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[10], &u2n) != TCL_OK) { - opserr << "WARNING invalid u2n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[11], &u3n) != TCL_OK) { - opserr << "WARNING invalid u3n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[12], &q3n) != TCL_OK) { - opserr << "WARNING invalid q3n\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[13], &s0) != TCL_OK) { - opserr << "WARNING invalid s0\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[14], &bb) != TCL_OK) { - opserr << "WARNING invalid bb\n"; - return TCL_ERROR; - } - - theMaterial = new FedeasBond1Material(tag, u1p, q1p, u2p, u3p, q3p, u1n, - q1n, u2n, u3n, q3n, s0, bb); - } - - else if (strcmp(argv[1], "Bond2") == 0 || strcmp(argv[1], "Bond02") == 0) { - if (argc < 17) { - - opserr << "WARNING invalid number of arguments\n"; - opserr << "Want: uniaxialMaterial Bond02 tag? u1p? q1p? u2p? u3p? q3p? " - "u1n? q1n? u2n? u3n? q3n? s0? bb? alp? aln?" - << endln; - return TCL_ERROR; - } - - double u1p, q1p, u2p, u3p, q3p; - double u1n, q1n, u2n, u3n, q3n; - double s0, bb, alp, aln; - - if (Tcl_GetDouble(interp, argv[3], &u1p) != TCL_OK) { - opserr << "WARNING invalid u1p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[4], &q1p) != TCL_OK) { - opserr << "WARNING invalid q1p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[5], &u2p) != TCL_OK) { - opserr << "WARNING invalid u2p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[6], &u3p) != TCL_OK) { - opserr << "WARNING invalid u3p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[7], &q3p) != TCL_OK) { - opserr << "WARNING invalid q3p\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[8], &u1n) != TCL_OK) { - opserr << "WARNING invalid u1n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[9], &q1n) != TCL_OK) { - opserr << "WARNING invalid q1n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[10], &u2n) != TCL_OK) { - opserr << "WARNING invalid u2n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[11], &u3n) != TCL_OK) { - opserr << "WARNING invalid u3n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[12], &q3n) != TCL_OK) { - opserr << "WARNING invalid q3n\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[13], &s0) != TCL_OK) { - opserr << "WARNING invalid s0\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[14], &bb) != TCL_OK) { - opserr << "WARNING invalid bb\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[15], &alp) != TCL_OK) { - opserr << "WARNING invalid alp\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[16], &aln) != TCL_OK) { - opserr << "WARNING invalid aln\n"; - return TCL_ERROR; - } - - theMaterial = new FedeasBond2Material(tag, u1p, q1p, u2p, u3p, q3p, u1n, - q1n, u2n, u3n, q3n, s0, bb, alp, aln); - } - - else if (strcmp(argv[1], "Concrete3") == 0 || - strcmp(argv[1], "Concrete03") == 0) { - if (argc < 13) { - opserr << "WARNING invalid number of arguments\n"; - opserr << "Want: uniaxialMaterial Concrete03 tag? fpc? epsc0? fpcu? " - "epscu? rat? ft? epst0? ft0? beta? epstu?" - << endln; - return TCL_ERROR; - } - - double fpc, epsc0, fpcu, epscu; - double rat, ft, epst0, ft0, beta, epstu; - - if (Tcl_GetDouble(interp, argv[3], &fpc) != TCL_OK) { - opserr << "WARNING invalid fpc\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[4], &epsc0) != TCL_OK) { - opserr << "WARNING invalid epsc0\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[5], &fpcu) != TCL_OK) { - opserr << "WARNING invalid fpcu\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[6], &epscu) != TCL_OK) { - opserr << "WARNING invalid epscu\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[7], &rat) != TCL_OK) { - opserr << "WARNING invalid rat\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[8], &ft) != TCL_OK) { - opserr << "WARNING invalid ft\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[9], &epst0) != TCL_OK) { - opserr << "WARNING invalid epst0\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[10], &ft0) != TCL_OK) { - opserr << "WARNING invalid ft0\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[11], &beta) != TCL_OK) { - opserr << "WARNING invalid beta\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[12], &epstu) != TCL_OK) { - opserr << "WARNING invalid epstu\n"; - return TCL_ERROR; - } - - theMaterial = new FedeasConcr3Material(tag, fpc, epsc0, fpcu, epscu, rat, - ft, epst0, ft0, beta, epstu); - } - - else if (strcmp(argv[1], "Hysteretic1") == 0 || - strcmp(argv[1], "Hysteretic01") == 0) { - if (argc < 15) { - opserr << "WARNING invalid number of arguments\n"; - opserr << "Want: uniaxialMaterial Hysteretic01 tag? s1p? e1p? s2p? e2p? " - "s1n? e1n? s2n? e1n? px? py? d1? d2?" - << endln; - return TCL_ERROR; - } - - double s1p, e1p, s2p, e2p; - double s1n, e1n, s2n, e2n; - double px, py, d1, d2; - - if (Tcl_GetDouble(interp, argv[3], &s1p) != TCL_OK) { - opserr << "WARNING invalid s1p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[4], &e1p) != TCL_OK) { - opserr << "WARNING invalid e1p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[5], &s2p) != TCL_OK) { - opserr << "WARNING invalid s2p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[6], &e2p) != TCL_OK) { - opserr << "WARNING invalid e2p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[7], &s1n) != TCL_OK) { - opserr << "WARNING invalid s1n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[8], &e1n) != TCL_OK) { - opserr << "WARNING invalid e1n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[9], &s2n) != TCL_OK) { - opserr << "WARNING invalid s2n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[10], &e2n) != TCL_OK) { - opserr << "WARNING invalid e2n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[11], &px) != TCL_OK) { - opserr << "WARNING invalid px\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[12], &py) != TCL_OK) { - opserr << "WARNING invalid py\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[13], &d1) != TCL_OK) { - opserr << "WARNING invalid d1\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[14], &d2) != TCL_OK) { - opserr << "WARNING invalid d2\n"; - return TCL_ERROR; - } - - theMaterial = new FedeasHyster1Material(tag, s1p, e1p, s2p, e2p, s1n, e1n, - s2n, e2n, px, py, d1, d2); - } - - else if (strcmp(argv[1], "Hysteretic2") == 0 || - strcmp(argv[1], "Hysteretic02") == 0) { - if (argc < 19) { - opserr << "WARNING invalid number of arguments\n"; - opserr << "Want: uniaxialMaterial Hysteretic02 tag? s1p? e1p? s2p? e2p? " - "s3p? e3p? s1n? e1n? s2n? e1n? s3n? e3n? px? py? d1? d2?" - << endln; - return TCL_ERROR; - } - - double s1p, e1p, s2p, e2p, s3p, e3p; - double s1n, e1n, s2n, e2n, s3n, e3n; - double px, py, d1, d2; - - if (Tcl_GetDouble(interp, argv[3], &s1p) != TCL_OK) { - opserr << "WARNING invalid s1p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[4], &e1p) != TCL_OK) { - opserr << "WARNING invalid e1p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[5], &s2p) != TCL_OK) { - opserr << "WARNING invalid s2p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[6], &e2p) != TCL_OK) { - opserr << "WARNING invalid e2p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[7], &s3p) != TCL_OK) { - opserr << "WARNING invalid s2p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[8], &e3p) != TCL_OK) { - opserr << "WARNING invalid e2p\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[9], &s1n) != TCL_OK) { - opserr << "WARNING invalid s1n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[10], &e1n) != TCL_OK) { - opserr << "WARNING invalid e1n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[11], &s2n) != TCL_OK) { - opserr << "WARNING invalid s2n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[12], &e2n) != TCL_OK) { - opserr << "WARNING invalid e2n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[13], &s3n) != TCL_OK) { - opserr << "WARNING invalid s2n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[14], &e3n) != TCL_OK) { - opserr << "WARNING invalid e2n\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[15], &px) != TCL_OK) { - opserr << "WARNING invalid px\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[16], &py) != TCL_OK) { - opserr << "WARNING invalid py\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[17], &d1) != TCL_OK) { - opserr << "WARNING invalid d1\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[18], &d2) != TCL_OK) { - opserr << "WARNING invalid d2\n"; - return TCL_ERROR; - } - - theMaterial = - new FedeasHyster2Material(tag, s1p, e1p, s2p, e2p, s3p, e3p, s1n, e1n, - s2n, e2n, s3n, e3n, px, py, d1, d2); - } - - else if (strcmp(argv[1], "ConcretePlasticDamage") == 0 || - strcmp(argv[1], "PlasticDamage") == 0) { - if (argc < 11) { - opserr << "WARNING invalid number of arguments\n"; - opserr << "Want: uniaxialMaterial ConcretePlasticDamage tag? $Ec $Gf $Gc " - "$ft $fcy $fc $ktcr $relax" - << endln; - return TCL_ERROR; - } - - double Ec, Ft, Fc, ft_max, fcy, fc, ktcr, relax; - - if (Tcl_GetDouble(interp, argv[3], &Ec) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid Ec\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[4], &Ft) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid Ft\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[5], &Fc) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid Fc\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[6], &ft_max) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid ft_max\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[7], &fcy) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid fcy\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[8], &fc) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid fc\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[9], &ktcr) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid Ktcr\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[10], &relax) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "invalid relax\n"; - return TCL_ERROR; - } - - theMaterial = new PlasticDamageMaterial(tag, Ec, Ft, Fc, ft_max, fcy, fc, - ktcr, relax); - } - else { - opserr << "WARNING invalid uniaxialMaterial type\n"; - return TCL_ERROR; - } -} -#endif diff --git a/SRC/runtime/commands/modeling/material/material.cpp b/SRC/runtime/commands/modeling/material/material.cpp index 5ce800b466..7cc1943efb 100644 --- a/SRC/runtime/commands/modeling/material/material.cpp +++ b/SRC/runtime/commands/modeling/material/material.cpp @@ -71,776 +71,6 @@ TclCommand_addMaterial(ClientData clientData, Tcl_Interp* interp, if (cmd != MaterialLibrary.end()) return (*cmd->second)(clientData, interp, argc, &argv[0]); - -#if 0 - // Check argv[1] for ND material type - - // Pointer to an ND material that will be added to the model builder - NDMaterial* theMaterial = nullptr; - - if (strcmp(argv[1], "PressureDependentElastic3D") == 0) { - //Jul. 07, 2001 Boris Jeremic & ZHaohui Yang jeremic|zhyang@ucdavis.edu - // Pressure dependent elastic material - if (argc < 6) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PressureDependentElastic3D tag? E? v? rho?" << "\n"; - return TCL_ERROR; - } - - int tag = 0; - double E = 0.0; - double v = 0.0; - double rho = 0.0; - double expp = 0.0; - double prp = 0.0; - double pop = 0.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid PressureDependentElastic3D tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { - opserr << "WARNING invalid E\n"; - opserr << "nDMaterial PressureDependentElastic3D: E" << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &v) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: v" << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &rho) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: rho" << tag << "\n"; - return TCL_ERROR; - } - - if (argc == 6) { - theMaterial = new PressureDependentElastic3D(tag, E, v, rho); - } else if (argc == 7) { - //get the exponent of the pressure sensitive elastic material) - if (Tcl_GetDouble(interp, argv[6], &expp) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: " << tag << "\n"; - return TCL_ERROR; - } - theMaterial = new PressureDependentElastic3D(tag, E, v, rho, expp); - } else if (argc == 8) { - //get the exponent pressure of the pressure sensitive elastic material) - if (Tcl_GetDouble(interp, argv[6], &expp) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: expp" << tag << "\n"; - return TCL_ERROR; - } - //get the reference pressure of the pressure sensitive elastic material) - if (Tcl_GetDouble(interp, argv[7], &prp) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: prp " << tag << "\n"; - return TCL_ERROR; - } - theMaterial = new PressureDependentElastic3D(tag, E, v, rho, expp, prp); - } else if (argc >= 9) { - //get the exponent of the pressure sensitive elastic material) - if (Tcl_GetDouble(interp, argv[6], &expp) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: expp" << tag << "\n"; - return TCL_ERROR; - } - //get the reference pressure of the pressure sensitive elastic material) - if (Tcl_GetDouble(interp, argv[7], &prp) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: prp" << tag << "\n"; - return TCL_ERROR; - } - //get the cutoff pressure po of the pressure sensitive elastic material) - if (Tcl_GetDouble(interp, argv[8], &pop) != TCL_OK) { - opserr << "WARNING invalid v\n"; - opserr << "nDMaterial PressureDependentElastic3D: pop" << tag << "\n"; - return TCL_ERROR; - } - theMaterial = new PressureDependentElastic3D(tag, E, v, rho, expp, prp, pop); - } - - } - - - else if ((strcmp(argv[1], "MultiaxialCyclicPlasticity") == 0) || - (strcmp(argv[1], "MCP") == 0)) { - - // - // MultiAxialCyclicPlasticity Model by Gang Wang - // - // nDMaterial MultiaxialCyclicPlasticity $tag, $rho, $K, $G, - // $Su , $Ho , $h, $m, $beta, $KCoeff - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - if (argc < 12) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial MultiaxialCyclicPlasticity tag? rho? K? G? Su? Ho? h? m? beta? " - "KCoeff? " - << "\n"; - return TCL_ERROR; - } - - int tag; - double K, G, rho, Su, Ho, h, m, beta, Kcoeff; - double eta = 0.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid MultiaxialCyclicPlasticity tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &rho) != TCL_OK) { - opserr << "WARNING invalid rho\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &K) != TCL_OK) { - opserr << "WARNING invalid K\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &G) != TCL_OK) { - opserr << "WARNING invalid G\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - - if (Tcl_GetDouble(interp, argv[6], &Su) != TCL_OK) { - opserr << "WARNING invalid alpha1\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[7], &Ho) != TCL_OK) { - opserr << "WARNING invalid Ho\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[8], &h) != TCL_OK) { - opserr << "WARNING invalid h\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[9], &m) != TCL_OK) { - opserr << "WARNING invalid m\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[10], &beta) != TCL_OK) { - opserr << "WARNING invalid beta\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[11], &Kcoeff) != TCL_OK) { - opserr << "WARNING invalid Kcoeff\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - - if (argc > 12 && Tcl_GetDouble(interp, argv[12], &eta) != TCL_OK) { - opserr << "WARNING invalid eta\n"; - opserr << "nDMaterial MultiaxialCyclicPlasticity: " << tag << "\n"; - return TCL_ERROR; - } - - theMaterial = - new MultiaxialCyclicPlasticity(tag, 0, rho, K, G, Su, Ho, h, m, beta, Kcoeff, eta); - } - - - // Pressure Independend Multi-yield, by ZHY - else if (strcmp(argv[1], "PressureIndependMultiYield") == 0) { - const int numParam = 6; - const int totParam = 10; - int tag; - double param[totParam]; - param[6] = 0.0; - param[7] = 100.; - param[8] = 0.0; - param[9] = 20; - - char* arg[] = {"nd", - "rho", - "refShearModul", - "refBulkModul", - "cohesi", - "peakShearStra", - "frictionAng (=0)", - "refPress (=100)", - "pressDependCoe (=0.0)", - "numberOfYieldSurf (=20)"}; - if (argc < (3 + numParam)) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PressureIndependMultiYield tag? " << arg[0]; - opserr << "? " - << "\n"; - opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " - << "\n"; - opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " - << "\n"; - opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid PressureIndependMultiYield tag" << "\n"; - return TCL_ERROR; - } - - for (int i = 3; (i < argc && i < 13); i++) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - - static double* gredu = 0; - // user defined yield surfaces - if (param[9] < 0 && param[9] > -40) { - param[9] = -int(param[9]); - gredu = new double[int(2 * param[9])]; - for (int i = 0; i < 2 * param[9]; i++) - if (Tcl_GetDouble(interp, argv[i + 13], &gredu[i]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - } - - PressureIndependMultiYield* temp = - new PressureIndependMultiYield(tag, param[0], param[1], param[2], param[3], param[4], - param[5], param[6], param[7], param[8], param[9], gredu); - theMaterial = temp; - - if (gredu != 0) { - delete[] gredu; - gredu = 0; - } - } - - // Pressure Dependend Multi-yield, by ZHY - else if (strcmp(argv[1], "PressureDependMultiYield") == 0) { - const int numParam = 15; - const int totParam = 24; - int tag; - double param[totParam]; - param[15] = 20; - param[16] = 0.6; - param[17] = 0.9; - param[18] = 0.02; - param[19] = 0.7; - param[20] = 101.; - param[21] = .3; - param[22] = 0.; - param[23] = 1.; - - char* arg[] = {"nd", - "rho", - "refShearModul", - "refBulkModul", - "frictionAng", - "peakShearStra", - "refPress", - "pressDependCoe", - "phaseTransformAngle", - "contractionParam1", - "dilationParam1", - "dilationParam2", - "liquefactionParam1", - "liquefactionParam2", - "liquefactionParam4", - "numberOfYieldSurf (=20)", - "e (=0.6)", - "volLimit1 (=0.9)", - "volLimit2 (=0.02)", - "volLimit3 (=0.7)", - "Atmospheric pressure (=101)", - "cohesi (=.5)", - "Hv (=0)", - "Pv (=1.)"}; - if (argc < (3 + numParam)) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PressureDependMultiYield tag? " << arg[0]; - opserr << "? " - << "\n"; - opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " - << "\n"; - opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " - << "\n"; - opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " - << "\n"; - opserr << arg[10] << "? " << arg[11] << "? " << arg[12] << "? " - << "\n"; - opserr << arg[13] << "? " << arg[14] << "? " << arg[15] << "? " - << "\n"; - opserr << arg[16] << "? " << arg[17] << "? " << arg[18] << "? " - << "\n"; - opserr << arg[19] << "? " << arg[20] << "? " << arg[21] << "? " << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid PressureDependMultiYield tag" << "\n"; - return TCL_ERROR; - } - - for (int i = 3; (i < argc && i < 19); i++) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureDependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - - static double* gredu = 0; - // user defined yield surfaces - if (param[15] < 0 && param[15] > -40) { - param[15] = -int(param[15]); - gredu = new double[int(2 * param[15])]; - - for (int i = 0; i < 2 * param[15]; i++) - if (Tcl_GetDouble(interp, argv[i + 19], &gredu[i]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - } - - if (gredu != 0) { - for (int i = 19 + int(2 * param[15]); i < argc; i++) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3 - int(2 * param[15])]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[15])] << "\n"; - opserr << "nDMaterial PressureDependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - } else { - for (int i = 19; i < argc; i++) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[15])] << "\n"; - opserr << "nDMaterial PressureDependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - } - - PressureDependMultiYield* temp = new PressureDependMultiYield( - tag, param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7], - param[8], param[9], param[10], param[11], param[12], param[13], param[14], param[15], gredu, - param[16], param[17], param[18], param[19], param[20], param[21], param[22], param[23]); - - theMaterial = temp; - if (gredu != 0) { - delete[] gredu; - gredu = 0; - } - } - - // Pressure Dependend Multi-yield, by ZHY - else if (strcmp(argv[1], "PressureDependMultiYield02") == 0) { - const int numParam = 13; - const int totParam = 26; - int tag; - double param[totParam]; - param[numParam] = 20; - param[numParam + 1] = 5.0; - param[numParam + 2] = 3.; - param[numParam + 3] = 1.; - param[numParam + 4] = 0.; - param[numParam + 5] = 0.6; - param[numParam + 6] = 0.9; - param[numParam + 7] = 0.02; - param[numParam + 8] = 0.7; - param[numParam + 9] = 101.; - param[numParam + 10] = 0.1; - param[numParam + 11] = 0.; - param[numParam + 12] = 1.; - - char* arg[] = {"nd", - "rho", - "refShearModul", - "refBulkModul", - "frictionAng", - "peakShearStra", - "refPress", - "pressDependCoe", - "phaseTransformAngle", - "contractionParam1", - "contractionParam3", - "dilationParam1", - "dilationParam3", - "numberOfYieldSurf (=20)", - "contractionParam2=5.0", - "dilationParam2=3.0", - "liquefactionParam1=1.0", - "liquefactionParam2=0.0", - "e (=0.6)", - "volLimit1 (=0.9)", - "volLimit2 (=0.02)", - "volLimit3 (=0.7)", - "Atmospheric pressure (=101)", - "cohesi (=.1)", - "Hv (=0)", - "Pv (=1.)"}; - if (argc < (3 + numParam)) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PressureDependMultiYield02 tag? " << arg[0]; - opserr << "? " - << "\n"; - opserr << arg[1] << "? " << arg[2] << "? " << arg[3] << "? " - << "\n"; - opserr << arg[4] << "? " << arg[5] << "? " << arg[6] << "? " - << "\n"; - opserr << arg[7] << "? " << arg[8] << "? " << arg[9] << "? " - << "\n"; - opserr << arg[10] << "? " << arg[11] << "? " << arg[12] << "? " - << "\n"; - opserr << arg[13] << "? " << arg[14] << "? " << arg[15] << "? " - << "\n"; - opserr << arg[16] << "? " << arg[17] << "? " << arg[18] << "? " - << "\n"; - opserr << arg[19] << "? " << arg[20] << "? " << arg[21] << "? " - << "\n"; - opserr << arg[22] << "? " << arg[23] << "? " << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid PressureDependMultiYield02 tag" << "\n"; - return TCL_ERROR; - } - - int in = 17; - for (int i = 3; (i < argc && i < in); i++) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureDependMultiYield02: " << tag << "\n"; - return TCL_ERROR; - } - - static double* gredu = 0; - - // user defined yield surfaces - if (param[numParam] < 0 && param[numParam] > -100) { - param[numParam] = -int(param[numParam]); - gredu = new double[int(2 * param[numParam])]; - - for (int i = 0; i < 2 * param[numParam]; i++) - if (Tcl_GetDouble(interp, argv[i + in], &gredu[i]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial PressureIndependMultiYield: " << tag << "\n"; - return TCL_ERROR; - } - } - - if (gredu != 0) { - for (int i = in + int(2 * param[numParam]); i < argc; i++) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3 - int(2 * param[numParam])]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[numParam])] << "\n"; - opserr << "nDMaterial PressureDependMultiYield02: " << tag << "\n"; - return TCL_ERROR; - } - } else { - for (int i = in; i < argc; i++) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3 - int(2 * param[numParam])] << "\n"; - opserr << "nDMaterial PressureDependMultiYield02: " << tag << "\n"; - return TCL_ERROR; - } - } - - - PressureDependMultiYield02* temp = new PressureDependMultiYield02( - tag, param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7], - param[8], param[9], param[10], param[11], param[12], param[13], gredu, param[14], param[15], - param[16], param[17], param[18], param[19], param[20], param[21], param[22], param[23], - param[24], param[25]); - - theMaterial = temp; - if (gredu != 0) { - delete[] gredu; - gredu = 0; - } - } - - // Fluid Solid Porous, by ZHY - else if (strcmp(argv[1], "FluidSolidPorous") == 0) { - - int tag; - double param[4]; - char* arg[] = {"nd", "soilMatTag", "combinedBulkModul", "Atmospheric pressure"}; - if (argc < 6) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial FluidSolidPorous tag? " << arg[0]; - opserr << "? " - << "\n"; - opserr << arg[1] << "? " << arg[2] << "? " << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid FluidSolidPorous tag" << "\n"; - return TCL_ERROR; - } - - for (int i = 3; i < 6; i++) - if (Tcl_GetDouble(interp, argv[i], ¶m[i - 3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[i - 3] << "\n"; - opserr << "nDMaterial FluidSolidPorous: " << tag << "\n"; - return TCL_ERROR; - } - - NDMaterial* soil = builder->getTypedObject(param[1]); - if (soil == 0) { - opserr << "WARNING FluidSolidPorous: couldn't get soil material "; - opserr << "tagged: " << param[1] << "\n"; - return TCL_ERROR; - } - - param[3] = 101.; - if (argc == 7) { - if (Tcl_GetDouble(interp, argv[6], ¶m[3]) != TCL_OK) { - opserr << "WARNING invalid " << arg[3] << "\n"; - opserr << "nDMaterial FluidSolidPorous: " << tag << "\n"; - return TCL_ERROR; - } - } - - theMaterial = new FluidSolidPorousMaterial(tag, param[0], *soil, param[2], param[3]); - } - - else if (strcmp(argv[1], "Template3Dep") == 0) { - theMaterial = TclModelBuilder_addTemplate3Dep(clientData, interp, argc, argv, theTclBuilder, 2); - } - - else if (strcmp(argv[1], "NewTemplate3Dep") == 0) { - theMaterial = - TclModelBuilder_addNewTemplate3Dep(clientData, interp, argc, argv, theTclBuilder, 2); - } - - else if (strcmp(argv[1], "FiniteDeformationElastic3D") == 0 || - strcmp(argv[1], "FDElastic3D") == 0) { - theMaterial = TclModelBuilder_addFiniteDeformationElastic3D(clientData, interp, argc, argv, - theTclBuilder, 1); - } - - else if (strcmp(argv[1], "FiniteDeformationEP3D") == 0 || strcmp(argv[1], "FDEP3D") == 0) { - theMaterial = - TclModelBuilder_addFiniteDeformationEP3D(clientData, interp, argc, argv, theTclBuilder, 2); - } - - - else if (strcmp(argv[1], "PlaneStressMaterial") == 0 || - strcmp(argv[1], "PlaneStress") == 0) { - if (argc < 4) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PlaneStress tag? matTag?" << "\n"; - return TCL_ERROR; - } - - int tag, matTag; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid nDMaterial PlaneStress tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << "WARNING invalid matTag" << "\n"; - opserr << "PlaneStress: " << matTag << "\n"; - return TCL_ERROR; - } - - NDMaterial* threeDMaterial = builder->getTypedObject(matTag); - if (threeDMaterial == 0) { - opserr << "WARNING nD material does not exist\n"; - opserr << "nD material: " << matTag; - opserr << "\nPlaneStress nDMaterial: " << tag << "\n"; - return TCL_ERROR; - } - - theMaterial = new PlaneStressMaterial(tag, *threeDMaterial); - } - - - else if (strcmp(argv[1], "PlateFiberMaterial") == 0 || strcmp(argv[1], "PlateFiber") == 0) { - - if (argc < 4) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial PlateFiber tag? matTag?" << "\n"; - return TCL_ERROR; - } - - int tag, matTag; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid nDMaterial PlateFiber tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << "WARNING invalid matTag" << "\n"; - opserr << "PlateFiber: " << matTag << "\n"; - return TCL_ERROR; - } - - NDMaterial* threeDMaterial = builder->getTypedObject(matTag); - if (threeDMaterial == 0) { - opserr << "WARNING nD material does not exist\n"; - opserr << "nD material: " << matTag; - opserr << "\nPlateFiber nDMaterial: " << tag << "\n"; - return TCL_ERROR; - } - - theMaterial = new PlateFiberMaterial(tag, *threeDMaterial); - } - - else if (strcmp(argv[1], "BeamFiberMaterial") == 0 || - strcmp(argv[1], "BeamFiber") == 0) { - if (argc < 4) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial BeamFiber tag? matTag?" << "\n"; - return TCL_ERROR; - } - - int tag, matTag; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid nDMaterial BeamFiber tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << "WARNING invalid matTag" << "\n"; - opserr << "BeamFiber: " << matTag << "\n"; - return TCL_ERROR; - } - - NDMaterial* threeDMaterial = builder->getTypedObject(matTag); - if (threeDMaterial == nullptr) { - return TCL_ERROR; - } - - theMaterial = new BeamFiberMaterial(tag, *threeDMaterial); - } - - else { - theMaterial = TclModelBuilder_addFeapMaterial(clientData, interp, argc, argv, theTclBuilder); - } - - if (theMaterial == nullptr) - return TCL_ERROR; - - // Now add the material to the modelBuilder - if (theTclBuilder->addNDMaterial(*theMaterial) < 0) { - opserr << "WARNING could not add material to the domain\n"; - opserr << *theMaterial << "\n"; - delete theMaterial; - return TCL_ERROR; - } - - return TCL_OK; -#endif - return TCL_ERROR; } - - - - -#if 0 -Template3Dep* TclModelBuilder_addTemplate3Dep(ClientData clientData, Tcl_Interp* interp, int argc, - TCL_Char** argv, TclModelBuilder* theTclBuilder, - int eleArgStart); - -NewTemplate3Dep* TclModelBuilder_addNewTemplate3Dep(ClientData clientData, Tcl_Interp* interp, - int argc, TCL_Char** argv, - TclModelBuilder* theTclBuilder, - int eleArgStart); - -FiniteDeformationElastic3D* -TclModelBuilder_addFiniteDeformationElastic3D(ClientData clientData, Tcl_Interp* interp, int argc, - TCL_Char** argv, TclModelBuilder* theTclBuilder, - int eleArgStart); - -FiniteDeformationEP3D* TclModelBuilder_addFiniteDeformationEP3D(ClientData clientData, - Tcl_Interp* interp, int argc, - TCL_Char** argv, - TclModelBuilder* theTclBuilder, - int eleArgStart); - -NDMaterial* TclModelBuilder_addFeapMaterial(ClientData clientData, Tcl_Interp* interp, int argc, - TCL_Char** argv, TclModelBuilder* theTclBuilder); - - - - -template -int -TclCommand_newMinMaxND(ClientData clientData, Tcl_Interp* interp, int argc, const char**const argv) -{ - if (argc < 4) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: uniaxialMaterial MinMax tag? matTag?"; - opserr << " <-min min?> <-max max?>" << endln; - return TCL_ERROR; - } - - int tag, matTag; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial MinMax tag" << endln; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << "WARNING invalid component tag\n"; - opserr << "uniaxialMaterial MinMax: " << tag << endln; - return TCL_ERROR; - } - - // Search for min and max strains - double epsmin = NEG_INF_STRAIN; - double epsmax = POS_INF_STRAIN; - - for (int j = 4; j < argc; j++) { - if (strcmp(argv[j],"-min") == 0) { - if ((j+1) >= argc || Tcl_GetDouble (interp, argv[j+1], &epsmin) != TCL_OK) { - opserr << "WARNING invalid min\n"; - opserr << "uniaxialMaterial MinMax: " << tag << endln; - return TCL_ERROR; - } - j++; - } - if (strcmp(argv[j],"-max") == 0) { - if ((j+1) >= argc || Tcl_GetDouble (interp, argv[j+1], &epsmax) != TCL_OK) { - opserr << "WARNING invalid max\n"; - opserr << "uniaxialMaterial MinMax: " << tag << endln; - return TCL_ERROR; - } - j++; - } - } - - UniaxialMaterial *theMat = theTclBuilder->getUniaxialMaterial(matTag); - - if (theMat == 0) { - opserr << "WARNING component material does not exist\n"; - opserr << "Component material: " << matTag; - opserr << "\nuniaxialMaterial MinMax: " << tag << endln; - return TCL_ERROR; - } - - // Parsing was successful, allocate the material - theMaterial = new MinMaxNDMaterial(tag, *theMat, epsmin, epsmax); -} -#endif \ No newline at end of file diff --git a/SRC/runtime/commands/modeling/material/material.hpp b/SRC/runtime/commands/modeling/material/material.hpp index d6f549cacb..ecaa3d0655 100644 --- a/SRC/runtime/commands/modeling/material/material.hpp +++ b/SRC/runtime/commands/modeling/material/material.hpp @@ -253,9 +253,6 @@ static std::unordered_map OldMaterialCommands = { #ifdef OPS_USE_ASDPlasticMaterials {"ASDPlasticMaterial", OPS_AllASDPlasticMaterials}, #endif -#if 0 - {"CDPPlaneStressThermal", OPS_PlasticDamageConcretePlaneStressThermal}, -#endif #ifdef _HAVE_Faria1998 {"Faria1998", OPS_NewFaria1998Material}, {"Concrete", OPS_NewConcreteMaterial}, diff --git a/SRC/runtime/commands/modeling/material/nDMaterial.cpp b/SRC/runtime/commands/modeling/material/nDMaterial.cpp index 2783c0e8e7..cd81f65a59 100644 --- a/SRC/runtime/commands/modeling/material/nDMaterial.cpp +++ b/SRC/runtime/commands/modeling/material/nDMaterial.cpp @@ -54,10 +54,6 @@ #include -#if 0 -extern NDMaterial *Tcl_addWrapperNDMaterial(matObj *, ClientData, Tcl_Interp *, - int, TCL_Char **); -#endif #if defined(OPSDEF_Material_FEAP) NDMaterial *TclBasicBuilder_addFeapMaterial(ClientData clientData, @@ -1212,33 +1208,12 @@ TclCommand_addNDMaterial(ClientData clientData, Tcl_Interp *interp, // the proc may already have been loaded from a package or may exist in a // package yet to be loaded // - if (theMaterial == nullptr) { -#if 0 - // maybe material in a routine - // - - char *matType = new char[strlen(argv[1]) + 1]; - strcpy(matType, argv[1]); - matObj *matObject = OPS_GetMaterialType(matType, strlen(matType)); - - delete[] matType; - - if (matObject != 0) { - - theMaterial = Tcl_addWrapperNDMaterial(matObject, clientData, interp, - argc, argv); - - if (theMaterial == 0) - delete matObject; - } -#endif - } // // maybe material class exists in a package yet to be loaded // - if (theMaterial == 0) { + if (theMaterial == nullptr) { void *libHandle; void *(*funcPtr)(); diff --git a/SRC/runtime/commands/modeling/material/plastic.cpp b/SRC/runtime/commands/modeling/material/plastic.cpp index 04804129d1..da5574c931 100644 --- a/SRC/runtime/commands/modeling/material/plastic.cpp +++ b/SRC/runtime/commands/modeling/material/plastic.cpp @@ -759,7 +759,7 @@ TclCommand_newUniaxialJ2Plasticity(ClientData clientData, Tcl_Interp *interp, in if (argc < 7) { opserr << "WARNING invalid number of arguments\n"; opserr << "Want: uniaxialMaterial UniaxialJ2Plasticity tag? E? sigmaY? Hkin? " - << endln; + << "\n"; return TCL_ERROR; } @@ -769,7 +769,7 @@ TclCommand_newUniaxialJ2Plasticity(ClientData clientData, Tcl_Interp *interp, in if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { opserr << "WARNING invalid uniaxialMaterial UniaxialJ2Plasticity tag" - << endln; + << "\n"; return TCL_ERROR; } @@ -871,139 +871,3 @@ TclCommand_newJ2Simplified(ClientData clientData, Tcl_Interp* interp, int argc, } return TCL_OK; } - - -#if 0 - -int -TclCommand_newJ2Material(ClientData clientData, - Tcl_Interp* interp, - int argc, - const char** const argv) -{ - BasicModelBuilder* builder = static_cast(clientData); - - if (argc < 9) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial J2Plasticity tag? K? G? sig0? sigInf? delta? H? " << "\n"; - return TCL_ERROR; - } - - int tag; - double K, G, sig0, sigInf, delta, H; - double eta = 0.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid J2Plasticity tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &K) != TCL_OK) { - opserr << "WARNING invalid K\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &G) != TCL_OK) { - opserr << "WARNING invalid G\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &sig0) != TCL_OK) { - opserr << "WARNING invalid sig0\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &sigInf) != TCL_OK) { - opserr << "WARNING invalid sigInf\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[7], &delta) != TCL_OK) { - opserr << "WARNING invalid delta\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[8], &H) != TCL_OK) { - opserr << "WARNING invalid H\n"; - return TCL_ERROR; - } - if (argc > 9 && Tcl_GetDouble(interp, argv[9], &eta) != TCL_OK) { - opserr << "WARNING invalid eta\n"; - return TCL_ERROR; - } - - - // - NDMaterial* theMaterial = nullptr; - - if ((strcmp(argv[1], "J2Plasticity") == 0) || - (strcmp(argv[1], "J2") == 0)) { - theMaterial = new J2Plasticity(tag, 0, K, G, sig0, sigInf, delta, H, eta); - } - - if (theMaterial == nullptr) - return TCL_ERROR; - - if (builder->addTaggedObject(*theMaterial) != TCL_OK ) { - delete theMaterial; - return TCL_ERROR; - } - return TCL_OK; -} - -int -TclCommand_newPlasticMaterial(ClientData clientData, Tcl_Interp* interp, int argc, const char**const argv) -{ - if ((strcmp(argv[1], "J2Plasticity") == 0) || (strcmp(argv[1], "J2") == 0)) - { - if (argc < 9) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: nDMaterial J2Plasticity tag? K? G? sig0? sigInf? delta? H? " << "\n"; - return TCL_ERROR; - } - - int tag; - double K, G, sig0, sigInf, delta, H; - double eta = 0.0; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid J2Plasticity tag" << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &K) != TCL_OK) { - opserr << "WARNING invalid K\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &G) != TCL_OK) { - opserr << "WARNING invalid G\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &sig0) != TCL_OK) { - opserr << "WARNING invalid sig0\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &sigInf) != TCL_OK) { - opserr << "WARNING invalid sigInf\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[7], &delta) != TCL_OK) { - opserr << "WARNING invalid delta\n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[8], &H) != TCL_OK) { - opserr << "WARNING invalid H\n"; - return TCL_ERROR; - } - if (argc > 9 && Tcl_GetDouble(interp, argv[9], &eta) != TCL_OK) { - opserr << "WARNING invalid eta\n"; - return TCL_ERROR; - } - - theMaterial = new J2Plasticity(tag, 0, K, G, sig0, sigInf, delta, H, eta); - } -} -#endif diff --git a/SRC/runtime/commands/modeling/material/shell.cpp b/SRC/runtime/commands/modeling/material/shell.cpp index 154bd22994..a70e1f5f3b 100644 --- a/SRC/runtime/commands/modeling/material/shell.cpp +++ b/SRC/runtime/commands/modeling/material/shell.cpp @@ -46,7 +46,7 @@ TclCommand_addElasticShellSection(ClientData clientData, Tcl_Interp* interp, << "insufficient arguments\n"; opserr << "Want: section ElasticMembranePlateSection tag? E? nu? h? " " " - << endln; + << "\n"; return TCL_ERROR; } @@ -58,37 +58,37 @@ TclCommand_addElasticShellSection(ClientData clientData, Tcl_Interp* interp, if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { opserr << OpenSees::PromptValueError << "invalid section ElasticMembranePlateSection tag" - << endln; + << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { opserr << OpenSees::PromptValueError - << "invalid E" << endln; + << "invalid E" << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &nu) != TCL_OK) { opserr << OpenSees::PromptValueError - << "invalid nu" << endln; + << "invalid nu" << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &h) != TCL_OK) { opserr << OpenSees::PromptValueError - << "invalid h" << endln; + << "invalid h" << "\n"; return TCL_ERROR; } if (argc > 6 && Tcl_GetDouble(interp, argv[6], &rho) != TCL_OK) { opserr << OpenSees::PromptValueError - << "invalid rho" << endln; + << "invalid rho" << "\n"; return TCL_ERROR; } if (argc > 7 && Tcl_GetDouble(interp, argv[7], &Ep_mod) != TCL_OK) { opserr << OpenSees::PromptValueError - << "invalid Ep_mod" << endln; + << "invalid Ep_mod" << "\n"; return TCL_ERROR; } @@ -150,7 +150,7 @@ TclCommand_ShellSection(ClientData clientData, Tcl_Interp* interp, opserr << OpenSees::PromptValueError << "insufficient arguments " << "\n"; opserr << "Want: section LayeredShell tag? nLayers? mat1? h1? ... matn? hn? " - << endln; + << "\n"; return TCL_ERROR; } @@ -169,7 +169,7 @@ TclCommand_ShellSection(ClientData clientData, Tcl_Interp* interp, } if (nLayers < 3) { - opserr << "ERROR number of layers must be larger than 2" << endln; + opserr << "ERROR number of layers must be larger than 2" << "\n"; return TCL_ERROR; } @@ -184,7 +184,7 @@ TclCommand_ShellSection(ClientData clientData, Tcl_Interp* interp, for (int iLayer = 0; iLayer < nLayers; iLayer++) { int mat; if (Tcl_GetInt(interp, argv[4 + 2 * iLayer], &mat) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid material tag" << endln; + opserr << OpenSees::PromptValueError << "invalid material tag" << "\n"; status = TCL_ERROR; goto cleanup; } diff --git a/SRC/runtime/commands/modeling/material/wrapper.cpp b/SRC/runtime/commands/modeling/material/wrapper.cpp index c80bc76851..ba3d0de33d 100644 --- a/SRC/runtime/commands/modeling/material/wrapper.cpp +++ b/SRC/runtime/commands/modeling/material/wrapper.cpp @@ -1,6 +1,15 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // //===----------------------------------------------------------------------===// // @@ -139,7 +148,7 @@ TclCommand_newParallelMaterial(ClientData clientData, Tcl_Interp* interp, int ar if (argc < 4) { opserr << "WARNING insufficient arguments\n"; opserr << "Want: uniaxialMaterial Parallel tag? tag1? tag2? ..."; - opserr << " <-min min?> <-max max?>" << endln; + opserr << " <-min min?> <-max max?>" << "\n"; return TCL_ERROR; } @@ -148,7 +157,7 @@ TclCommand_newParallelMaterial(ClientData clientData, Tcl_Interp* interp, int ar BasicModelBuilder* builder = static_cast(clientData); if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial Parallel tag" << endln; + opserr << "WARNING invalid uniaxialMaterial Parallel tag" << "\n"; return TCL_ERROR; } @@ -156,7 +165,6 @@ TclCommand_newParallelMaterial(ClientData clientData, Tcl_Interp* interp, int ar if (numMaterials == 0) { opserr << "WARNING no component material(s) provided\n"; - opserr << "uniaxialMaterial Parallel: " << tag << endln; return TCL_ERROR; } diff --git a/SRC/runtime/commands/modeling/model.cpp b/SRC/runtime/commands/modeling/model.cpp index c8c0005def..aa7469c8b8 100644 --- a/SRC/runtime/commands/modeling/model.cpp +++ b/SRC/runtime/commands/modeling/model.cpp @@ -166,67 +166,6 @@ TclCommand_specifyModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL G3_AddTclAnalysisAPI(interp, *theNewBuilder); } } - -#if 0 - else if ((strcmp(argv[1], "test") == 0) || - (strcmp(argv[1], "uniaxial") == 0) || - (strcmp(argv[1], "TestUniaxial") == 0) || - (strcmp(argv[1], "testUniaxial") == 0) || - (strcmp(argv[1], "UniaxialMaterialTest") == 0)) { - int count = 1; - if (argc == 3) { - if (Tcl_GetInt(interp, argv[2], &count) != TCL_OK) { - return TCL_ERROR; - } - } - theNewBuilder = new TclUniaxialMaterialTester(*theNewDomain, interp, count); - if (theNewBuilder == 0) { - opserr << OpenSees::PromptValueError << "ran out of memory in creating " - "TclUniaxialMaterialTester model\n"; - return TCL_ERROR; - } else { - G3_setModelBuilder(rt, theNewBuilder); - } - } - - - else if ((strcmp(argv[1], "testPlaneStress") == 0) || - (strcmp(argv[1], "StressPatch") == 0) || - (strcmp(argv[1], "PlaneStressMaterialTest") == 0)) { - int count = 1; - if (argc == 3) { - if (Tcl_GetInt(interp, argv[2], &count) != TCL_OK) { - return TCL_ERROR; - } - } - - theNewBuilder = new TclPlaneStressMaterialTester(theDomain, interp, count); - if (theNewBuilder == 0) { - opserr << OpenSees::PromptValueError << "ran out of memory in creating " - "TclUniaxialMaterialTester model\n"; - return TCL_ERROR; - } - } - - else if ((strcmp(argv[1], "sectionTest") == 0) || - (strcmp(argv[1], "TestSection") == 0) || - (strcmp(argv[1], "testSection") == 0) || - (strcmp(argv[1], "SectionForceDeformationTest") == 0)) { - int count = 1; - if (argc == 3) { - if (Tcl_GetInt(interp, argv[2], &count) != TCL_OK) { - return TCL_ERROR; - } - } - theNewBuilder = new TclSectionTestBuilder(theDomain, interp, count); - if (theNewBuilder == 0) { - opserr << OpenSees::PromptValueError << "ran out of memory in creating " - "TclUniaxialMAterialTester model\n"; - return TCL_ERROR; - } - } -#endif - else { opserr << OpenSees::PromptValueError << "unknown model builder type '" << argv[1] << "' not supported" diff --git a/SRC/runtime/commands/modeling/nodes.cpp b/SRC/runtime/commands/modeling/nodes.cpp index 7cbf7ca512..cb1ae409d1 100644 --- a/SRC/runtime/commands/modeling/nodes.cpp +++ b/SRC/runtime/commands/modeling/nodes.cpp @@ -122,21 +122,6 @@ TclCommand_addNode(ClientData clientData, Tcl_Interp *interp, int argc, theNode = new HeapNode(nodeId, ndf, xLoc, yLoc); break; case 3: -#if 0 - if (getenv("NODE")) { - switch (ndf) { - case 3: - theNode = new NodeND<3, 3>(nodeId, xLoc, yLoc, zLoc); - break; - case 6: - theNode = new NodeND<3, 6>(nodeId, xLoc, yLoc, zLoc); - break; - default: - theNode = new HeapNode(nodeId, ndf, xLoc, yLoc, zLoc); - break; - } - } else -#endif theNode = new HeapNode(nodeId, ndf, xLoc, yLoc, zLoc); break; } diff --git a/SRC/runtime/commands/modeling/printing.cpp b/SRC/runtime/commands/modeling/printing.cpp index 461bd7f0a6..f951722fd3 100644 --- a/SRC/runtime/commands/modeling/printing.cpp +++ b/SRC/runtime/commands/modeling/printing.cpp @@ -294,32 +294,6 @@ printDomain(OPS_Stream &s, BasicModelBuilder* builder, int flag) return; } - -#if 0 - s << "Current Domain Information\n"; - s << "\tCurrent Time: " << theDomain->getCurrentTime(); - // s << "\ntCommitted Time: " << committedTime << endln; - s << "NODE DATA: NumNodes: " << theDomain->getNumNodes() << "\n"; - theNodes->Print(s, flag); - - s << "ELEMENT DATA: NumEle: " << theElements->getNumComponents() << "\n"; - theElements->Print(s, flag); - - s << "\nSP_Constraints: numConstraints: " << theSPs->getNumComponents() << "\n"; - theSPs->Print(s, flag); - - s << "\nPressure_Constraints: numConstraints: " << thePCs->getNumComponents() << "\n"; - thePCs->Print(s, flag); - - s << "\nMP_Constraints: numConstraints: " << theMPs->getNumComponents() << "\n"; - theMPs->Print(s, flag); - - s << "\nLOAD PATTERNS: numPatterns: " << theLoadPatterns->getNumComponents() << "\n\n"; - theLoadPatterns->Print(s, flag); - - s << "\nPARAMETERS: numParameters: " << theParameters->getNumComponents() << "\n\n"; - theParameters->Print(s, flag); -#endif } int @@ -506,7 +480,7 @@ printElement(ClientData clientData, Tcl_Interp *interp, int argc, } if (Tcl_GetInt(interp, argv[1], &flag) != TCL_OK) { opserr << OpenSees::PromptValueError << "print ele failed to get integer flag: \n"; - opserr << argv[eleArg] << endln; + opserr << argv[eleArg] << "\n"; return TCL_ERROR; } eleArg += 2; @@ -529,7 +503,7 @@ printElement(ClientData clientData, Tcl_Interp *interp, int argc, int eleTag; if (Tcl_GetInt(interp, argv[i + eleArg], &eleTag) != TCL_OK) { opserr << OpenSees::PromptValueError << "print -ele failed to get integer: " << argv[i] - << endln; + << "\n"; return TCL_ERROR; } (*theEle)(i) = eleTag; @@ -576,7 +550,7 @@ printNode(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const } if (Tcl_GetInt(interp, argv[1], &flag) != TCL_OK) { opserr << OpenSees::PromptValueError << "print node failed to get integer flag: \n"; - opserr << argv[nodeArg] << endln; + opserr << argv[nodeArg] << "\n"; return TCL_ERROR; } nodeArg += 2; @@ -733,12 +707,12 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, for (int ii = l_tmp; ii < 3; ii++) { outputFile << 0.0 << "\t"; } - outputFile << endln; + outputFile << "\n"; } - outputFile << "End coordinates" << endln << endln; + outputFile << "End coordinates" << endln << "\n"; // Print elements connectivity - outputFile << "Elements" << endln; + outputFile << "Elements" << "\n"; ElementIter &theElements = the_domain->getElements(); Element *theElement; while ((theElement = theElements()) != 0) { @@ -759,11 +733,11 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, for (int i = 0; i < nNode; ++i) { outputFile << tagNodes(i) << "\t"; } - outputFile << endln; + outputFile << "\n"; } } } - outputFile << "End elements" << endln; + outputFile << "End elements" << "\n"; } // // **** Quadrilateral Elements - 4 Nodes @@ -771,18 +745,18 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, if (hasQuad4 == 1) { // Print HEADER outputFile << "MESH \"4NMESH\" dimension 3 ElemType Quadrilateral Nnode 4" - << endln; - outputFile << "#color 0 255 0" << endln << endln; + << "\n"; + outputFile << "#color 0 255 0" << endln << "\n"; // Print node coordinates - outputFile << "Coordinates" << endln; + outputFile << "Coordinates" << "\n"; NodeIter &theNodes = the_domain->getNodes(); Node *theNode; while ((theNode = theNodes()) != 0) { int tag = theNode->getTag(); const Vector &crds = theNode->getCrds(); // outputFile << tag << "\t\t" << crds(0) << "\t" << crds(1) << "\t" << - // crds(2) << endln; + // crds(2) << "\n"; int l_tmp = crds.Size(); outputFile << tag << "\t\t"; for (int ii = 0; ii < l_tmp; ii++) { @@ -791,12 +765,12 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, for (int ii = l_tmp; ii < 3; ii++) { outputFile << 0.0 << "\t"; } - outputFile << endln; + outputFile << "\n"; } - outputFile << "End coordinates" << endln << endln; + outputFile << "End coordinates" << endln << "\n"; // Print elements connectivity - outputFile << "Elements" << endln; + outputFile << "Elements" << "\n"; ElementIter &theElements = the_domain->getElements(); Element *theElement; while ((theElement = theElements()) != 0) { @@ -818,11 +792,11 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, for (int i = 0; i < nNode; ++i) { outputFile << tagNodes(i) << "\t"; } - outputFile << endln; + outputFile << "\n"; } } } - outputFile << "End elements" << endln; + outputFile << "End elements" << "\n"; } // // **** Triangular Elements - 3 Nodes @@ -830,18 +804,18 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, if (hasTri3 == 1) { // Print HEADER outputFile << "MESH \"3NMESH\" dimension 3 ElemType Triangle Nnode 3" - << endln; - outputFile << "#color 0 255 0" << endln << endln; + << "\n"; + outputFile << "#color 0 255 0" << endln << "\n"; // Print node coordinates - outputFile << "Coordinates" << endln; + outputFile << "Coordinates" << "\n"; NodeIter &theNodes = the_domain->getNodes(); Node *theNode; while ((theNode = theNodes()) != 0) { int tag = theNode->getTag(); const Vector &crds = theNode->getCrds(); // outputFile << tag << "\t\t" << crds(0) << "\t" << crds(1) << "\t" << - // crds(2) << endln; + // crds(2) << "\n"; int l_tmp = crds.Size(); outputFile << tag << "\t\t"; for (int ii = 0; ii < l_tmp; ii++) { @@ -850,12 +824,12 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, for (int ii = l_tmp; ii < 3; ii++) { outputFile << 0.0 << "\t"; } - outputFile << endln; + outputFile << "\n"; } - outputFile << "End coordinates" << endln << endln; + outputFile << "End coordinates" << endln << "\n"; // Print elements connectivity - outputFile << "Elements" << endln; + outputFile << "Elements" << "\n"; ElementIter &theElements = the_domain->getElements(); Element *theElement; while ((theElement = theElements()) != 0) { @@ -877,11 +851,11 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, for (int i = 0; i < nNode; ++i) { outputFile << tagNodes(i) << "\t"; } - outputFile << endln; + outputFile << "\n"; } } } - outputFile << "End elements" << endln; + outputFile << "End elements" << "\n"; } // // **** Quadrilateral Elements - 9 Nodes @@ -889,11 +863,11 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, if (hasQuad9 == 1) { // Print HEADER outputFile << "MESH \"9NMESH\" dimension 3 ElemType Linear Nnode 9" - << endln; - outputFile << "#color 0 255 0" << endln << endln; + << "\n"; + outputFile << "#color 0 255 0" << endln << "\n"; // Print node coordinates - outputFile << "Coordinates" << endln; + outputFile << "Coordinates" << "\n"; NodeIter &theNodes = the_domain->getNodes(); Node *theNode; while ((theNode = theNodes()) != 0) { @@ -908,12 +882,12 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, for (int ii = l_tmp; ii < 3; ii++) { outputFile << 0.0 << "\t"; } - outputFile << endln; + outputFile << "\n"; } - outputFile << "End coordinates" << endln << endln; + outputFile << "End coordinates" << endln << "\n"; // Print elements connectivity - outputFile << "Elements" << endln; + outputFile << "Elements" << "\n"; ElementIter &theElements = the_domain->getElements(); Element *theElement; while ((theElement = theElements()) != 0) { @@ -935,11 +909,11 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, for (int i = 0; i < nNode; ++i) { outputFile << tagNodes(i) << "\t"; } - outputFile << endln; + outputFile << "\n"; } } } - outputFile << "End elements" << endln; + outputFile << "End elements" << "\n"; } // // **** Hexahedra Elements - 8 Nodes @@ -947,11 +921,11 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, if (hasBrick == 1) { // Print HEADER outputFile << "MESH \"8NMESH\" dimension 3 ElemType Hexahedra Nnode 8" - << endln; - outputFile << "#color 255 0 0" << endln << endln; + << "\n"; + outputFile << "#color 255 0 0" << endln << "\n"; // Print node coordinates - outputFile << "Coordinates" << endln; + outputFile << "Coordinates" << "\n"; NodeIter &theNodes = the_domain->getNodes(); Node *theNode; @@ -959,7 +933,7 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, int tag = theNode->getTag(); const Vector &crds = theNode->getCrds(); // outputFile << tag << "\t\t" << crds(0) << "\t" << crds(1) << "\t" << - // crds(2) << endln; + // crds(2) << "\n"; int l_tmp = crds.Size(); outputFile << tag << "\t\t"; for (int ii = 0; ii < l_tmp; ii++) { @@ -968,12 +942,12 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, for (int ii = l_tmp; ii < 3; ii++) { outputFile << 0.0 << "\t"; } - outputFile << endln; + outputFile << "\n"; } - outputFile << "End coordinates" << endln << endln; + outputFile << "End coordinates" << endln << "\n"; // Print elements connectivity - outputFile << "Elements" << endln; + outputFile << "Elements" << "\n"; ElementIter &theElements = the_domain->getElements(); Element *theElement; while ((theElement = theElements()) != 0) { @@ -995,11 +969,11 @@ printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, for (int i = 0; i < nNode; ++i) { outputFile << tagNodes(i) << "\t"; } - outputFile << endln; + outputFile << "\n"; } } } - outputFile << "End elements" << endln; + outputFile << "End elements" << "\n"; } outputFile.close(); diff --git a/SRC/runtime/commands/modeling/section.cpp b/SRC/runtime/commands/modeling/section.cpp index 7e7bf224cf..234212957d 100644 --- a/SRC/runtime/commands/modeling/section.cpp +++ b/SRC/runtime/commands/modeling/section.cpp @@ -327,13 +327,6 @@ TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, opserr << "WFSection2d has been removed; use the from_aisc utility to " << "generate AISC sections from Python.\n"; return TCL_ERROR; -#if 0 - void *theMat = OPS_WFSection2d(rt, argc, argv); - if (theMat != 0) - theSection = (SectionForceDeformation *)theMat; - else - return TCL_ERROR; -#endif } else if (strcmp(argv[1], "AddDeformation") == 0 || @@ -388,7 +381,7 @@ TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, opserr << OpenSees::PromptValueError << "insufficient arguments\n"; opserr << "Want: section Iso2spring tag? tol? k1? Fy? k2? kv? hb? Pe? " - << endln; + << "\n"; return TCL_ERROR; } @@ -397,7 +390,7 @@ TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, double Po = 0.0; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid Iso2spring tag" << endln; + opserr << OpenSees::PromptValueError << "invalid Iso2spring tag" << "\n"; return TCL_ERROR; } @@ -437,7 +430,7 @@ TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, if (argc > 10) { if (Tcl_GetDouble(interp, argv[10], &Po) != TCL_OK) { opserr << OpenSees::PromptValueError << "invalid Po\n"; - opserr << "section Iso2spring: " << tag << endln; + opserr << "section Iso2spring: " << tag << "\n"; return TCL_ERROR; } } @@ -459,13 +452,13 @@ TclCommand_addSection(ClientData clientData, Tcl_Interp *interp, // Ensure we have created the Material, out of memory if got here and no // section if (theSection == nullptr) { - opserr << OpenSees::PromptValueError << "could not create section " << argv[1] << endln; + opserr << OpenSees::PromptValueError << "could not create section " << argv[1] << "\n"; return TCL_ERROR; } // Now add the material to the modelBuilder if (builder->addTaggedObject(*theSection) < 0) { - opserr << *theSection << endln; + opserr << *theSection << "\n"; delete theSection; // invoke the material objects destructor, otherwise mem leak return TCL_ERROR; } else @@ -760,7 +753,7 @@ TclCommand_addFiberSection(ClientData clientData, Tcl_Interp *interp, int argc, if (torsion == nullptr) { opserr << OpenSees::PromptValueError << "uniaxial material does not exist\n"; opserr << "uniaxial material: " << torsionTag; - opserr << "\nFiberSection3d: " << secTag << endln; + opserr << "\nFiberSection3d: " << secTag << "\n"; return TCL_ERROR; } @@ -903,14 +896,6 @@ TclCommand_addFiberIntSection(ClientData clientData, Tcl_Interp *interp, brace = 10; // may be 5 } -#if 0 - // init the fiber section (for building) // TODO, alpha - if (initSectionCommands(clientData, interp, secTag, *torsion, Ys, Zs, 1.0) != TCL_OK) { - opserr << OpenSees::PromptValueError << "- error constructing the section\n"; - return TCL_ERROR; - } -#endif - // parse the information inside the braces (patches and reinforcing layers) if (Tcl_Eval(interp, argv[brace]) != TCL_OK) { @@ -921,18 +906,9 @@ TclCommand_addFiberIntSection(ClientData clientData, Tcl_Interp *interp, if (NDM == 3 && torsion == nullptr) { opserr << OpenSees::PromptValueError << "- no torsion specified for 3D fiber section, use -GJ or " "-torsion\n"; - opserr << "\nFiberSectionInt3d: " << secTag << endln; - return TCL_ERROR; - } - -#if 0 // TODO !!! - // build the fiber section (for analysis) - if (buildSectionInt(clientData, interp, secTag, *torsion, NStrip1, t1, - NStrip2, t2, NStrip3, t3) != TCL_OK) { - opserr << OpenSees::PromptValueError << "- error constructing the section\n"; + opserr << "\nFiberSectionInt3d: " << secTag << "\n"; return TCL_ERROR; } -#endif if (deleteTorsion) delete torsion; @@ -1725,7 +1701,7 @@ TclCommand_addUCFiberSection(ClientData clientData, Tcl_Interp *interp, UniaxialMaterial *theMaterial = G3_getUniaxialMaterialInstance(rt,matTag); if (theMaterial == 0) { opserr << "section UCFiber - no material exists with tag << " << matTag - << endln; + << "\n"; return TCL_ERROR; } @@ -1746,323 +1722,3 @@ TclCommand_addUCFiberSection(ClientData clientData, Tcl_Interp *interp, return TCL_OK; } - -#if 0 -#include -#include -int -buildSectionInt(ClientData clientData, Tcl_Interp *interp, TclBasicBuilder *theTclBasicBuilder, - int secTag, UniaxialMaterial &theTorsion, int NStrip1, - double t1, int NStrip2, double t2, int NStrip3, double t3) -{ - assert(clientData != nullptr); - BasicModelBuilder* builder = static_cast(clientData); - SectionRepres *sectionRepres = theTclBasicBuilder->getSectionRepres(secTag); - - if (sectionRepres == nullptr) { - opserr << OpenSees::PromptValueError << "cannot retrieve section\n"; - return TCL_ERROR; - } - - if (sectionRepres->getType() == SEC_TAG_FiberSection) { - // build the section - - FiberSectionRepr *fiberSectionRepr = (FiberSectionRepr *)sectionRepres; - - int i, j, k; - int numFibers; - int numHFibers; - - int numPatches; - Patch **patch; - - int numReinfLayers; - ReinfLayer **reinfLayer; - - numPatches = fiberSectionRepr->getNumPatches(); - patch = fiberSectionRepr->getPatches(); - numReinfLayers = fiberSectionRepr->getNumReinfLayers(); - reinfLayer = fiberSectionRepr->getReinfLayers(); - - int numSectionRepresFibers = fiberSectionRepr->getNumFibers(); - Fiber **sectionRepresFibers = fiberSectionRepr->getFibers(); - - int numSectionRepresHFibers = fiberSectionRepr->getNumHFibers(); - Fiber **sectionRepresHFibers = fiberSectionRepr->getHFibers(); - - numFibers = numSectionRepresFibers; - for (int i = 0; i < numPatches; ++i) - numFibers += patch[i]->getNumCells(); - - for (int i = 0; i < numReinfLayers; ++i) - numFibers += reinfLayer[i]->getNumReinfBars(); - - numHFibers = numSectionRepresHFibers; - - static Vector fiberPosition(2); - int matTag; - - ID fibersMaterial(numFibers - numSectionRepresFibers); - Matrix fibersPosition(2, numFibers - numSectionRepresFibers); - Vector fibersArea(numFibers - numSectionRepresFibers); - - int numCells; - Cell **cell; - - k = 0; - for (int i = 0; i < numPatches; ++i) { - numCells = patch[i]->getNumCells(); - matTag = patch[i]->getMaterialID(); - - cell = patch[i]->getCells(); - - for (int j = 0; j < numCells; j++) { - fibersMaterial(k) = matTag; - fibersArea(k) = cell[j]->getArea(); - fiberPosition = cell[j]->getPosition(); - fibersPosition(0, k) = fiberPosition(0); - fibersPosition(1, k) = fiberPosition(1); - k++; - } - - for (int j = 0; j < numCells; j++) - delete cell[j]; - - delete[] cell; - } - - ReinfBar *reinfBar; - int numReinfBars; - - for (int i = 0; i < numReinfLayers; ++i) { - numReinfBars = reinfLayer[i]->getNumReinfBars(); - reinfBar = reinfLayer[i]->getReinfBars(); - matTag = reinfLayer[i]->getMaterialID(); - - for (int j = 0; j < numReinfBars; j++) { - fibersMaterial(k) = matTag; - fibersArea(k) = reinfBar[j].getArea(); - fiberPosition = reinfBar[j].getPosition(); - - fibersPosition(0, k) = fiberPosition(0); - fibersPosition(1, k) = fiberPosition(1); - - k++; - } - delete[] reinfBar; - } - - UniaxialMaterial *material = nullptr; - - Fiber **fiber = new Fiber *[numFibers]; - - // copy the section repres fibers - for (i = 0; i < numSectionRepresFibers; ++i) - fiber[i] = sectionRepresFibers[i]; - - Fiber **Hfiber = new Fiber *[numHFibers]; - - // copy the section repres fibers - for (int i = 0; i < numSectionRepresHFibers; ++i) - Hfiber[i] = sectionRepresHFibers[i]; - - // creates 2d section - int NDM = builder->getNDM(); - if (NDM == 2) { - k = 0; - for (int i = numSectionRepresFibers; i < numFibers; ++i) { - material = builder->getUniaxialMaterial(fibersMaterial(k)); - if (material == nullptr) { - opserr << OpenSees::PromptValueError << "invalid material ID for patch\n"; - return TCL_ERROR; - } - - fiber[i] = new UniaxialFiber2d(k, *material, fibersArea(k), - fibersPosition(0, k)); - - k++; - } - - SectionForceDeformation *section = - new FiberSection2dInt(secTag, numFibers, fiber, numHFibers, Hfiber, - NStrip1, t1, NStrip2, t2, NStrip3, t3); - - // Delete fibers - for (int i = 0; i < numFibers; ++i) - delete fiber[i]; - - for (int i = 0; i < numHFibers; ++i) - delete Hfiber[i]; - - if (section == nullptr) { - opserr << OpenSees::PromptValueError << "cannot construct section\n"; - return TCL_ERROR; - } - - if (theTclBasicBuilder->addSection (*section) < 0) { - opserr << OpenSees::PromptValueError << "- cannot add section\n"; - return TCL_ERROR; - } - - } else if (NDM == 3) { - - static Vector fiberPosition(2); - k = 0; - for (i = numSectionRepresFibers; i < numFibers; ++i) { - material = builder->getUniaxialMaterial(fibersMaterial(k)); - if (material == nullptr) { - opserr << OpenSees::PromptValueError << "invalid material ID for patch\n"; - return TCL_ERROR; - } - - fiberPosition(0) = fibersPosition(0, k); - fiberPosition(1) = fibersPosition(1, k); - - fiber[i] = - new UniaxialFiber3d(k, *material, fibersArea(k), fiberPosition); - if (fibersArea(k) < 0) - opserr << "ERROR: " << fiberPosition(0) << " " << fiberPosition(1) - << endln; - k++; - } - - SectionForceDeformation *section = 0; - section = new FiberSection3d(secTag, numFibers, fiber, theTorsion, - options.computeCentroid); - - // Delete fibers - for (i = 0; i < numFibers; ++i) - delete fiber[i]; - - if (section == 0) { - opserr << OpenSees::PromptValueError << "- cannot construct section\n"; - return TCL_ERROR; - } - - if (theTclBasicBuilder->addSection (*section) < 0) { - opserr << OpenSees::PromptValueError << "- cannot add section\n"; - return TCL_ERROR; - } - - } else { - opserr << OpenSees::PromptValueError << "NDM = " << NDM - << " is incompatible with available frame elements\n"; - return TCL_ERROR; - } - - // Delete fiber array - delete[] fiber; - // delete [] Hfiber; - - } else { - opserr << OpenSees::PromptValueError << "section invalid: can only build fiber sections\n"; - return TCL_ERROR; - } - - return TCL_OK; -} -#endif - - -#if 0 -SectionForceDeformation* -G3Parse_newTubeSection(G3_Runtime* rt, int argc, G3_Char ** const argv) -{ - SectionForceDeformation *theSection = nullptr; - if (strcmp(argv[1], "Tube") == 0) { - if (argc < 8) { - opserr << OpenSees::PromptValueError << "insufficient arguments\n"; - opserr << "Want: section Tube tag? matTag? D? t? nfw? nfr?" << endln; - return nullptr; - } - - int tag, matTag; - double D, t; - int nfw, nfr; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid section Tube tag" << endln; - return nullptr; - } - - if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid section Tube matTag" << endln; - return nullptr; - } - - if (Tcl_GetDouble(interp, argv[4], &D) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid D" << endln; - opserr << "Tube section: " << tag << endln; - return nullptr; - } - - if (Tcl_GetDouble(interp, argv[5], &t) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid t" << endln; - opserr << "Tube section: " << tag << endln; - return nullptr; - } - - if (Tcl_GetInt(interp, argv[6], &nfw) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid nfw" << endln; - opserr << "Tube section: " << tag << endln; - return nullptr; - } - - if (Tcl_GetInt(interp, argv[7], &nfr) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid nfr" << endln; - opserr << "Tube section: " << tag << endln; - return nullptr; - } - - TubeSectionIntegration tubesect(D, t, nfw, nfr); - - int numFibers = tubesect.getNumFibers(); - - if (argc > 8) { - - double shape = 1.0; - if (argc > 9) { - if (Tcl_GetDouble(interp, argv[9], &shape) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid shape" << endln; - opserr << "WFSection2d section: " << tag << endln; - return nullptr; - } - } - - NDMaterial *theSteel = builder->getTypedObject(matTag); - if (theSteel == 0) - return nullptr; - - - NDMaterial **theMats = new NDMaterial *[numFibers]; - - tubesect.arrangeFibers(theMats, theSteel); - - // Parsing was successful, allocate the section - theSection = 0; - if (strcmp(argv[8], "-nd") == 0) - theSection = - new NDFiberSection3d(tag, numFibers, theMats, tubesect, shape); - if (strcmp(argv[8], "-ndWarping") == 0) - theSection = new NDFiberSectionWarping2d(tag, numFibers, theMats, - tubesect, shape); - - delete[] theMats; - } else { - UniaxialMaterial *theSteel = builder->getTypedObject(matTag); - if (theSteel == 0) - return nullptr; - - UniaxialMaterial **theMats = new UniaxialMaterial *[numFibers]; - - tubesect.arrangeFibers(theMats, theSteel); - - // Parsing was successful, allocate the section - theSection = new FiberSection2d(tag, numFibers, theMats, tubesect); - - delete[] theMats; - } - } -} -#endif - diff --git a/SRC/runtime/commands/modeling/section/truss.cpp b/SRC/runtime/commands/modeling/section/truss.cpp index a446da2a96..ccab27a5c8 100644 --- a/SRC/runtime/commands/modeling/section/truss.cpp +++ b/SRC/runtime/commands/modeling/section/truss.cpp @@ -83,120 +83,3 @@ TclCommand_addUniaxialSection(ClientData clientData, Tcl_Interp *interp, return builder->addTaggedObject(*new SectionAggregator(tag, 1, theMats, codeID)); } - -#if 0 - -int -TclCommand_addTrussSection(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) -{ - BasicModelBuilder *builder = static_cast(clientData); - enum class Positions : int { - Material, Area, End - }; - ArgumentTracker tracker; - std::set positional; - - - // section Type? $tag $material $area - if (argc < 5) { - opserr << OpenSees::PromptValueError - << "incorrect number of arguments\n"; - return TCL_ERROR; - } - - int tag; - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << OpenSees::PromptValueError - << "failed to read integer tag\n"; - return TCL_ERROR; - } - - int mtag; - double area; - for (int i=3; igetTypedObject(mtag); - if (mptr == nullptr) - return TCL_ERROR; - - UniaxialMaterial* pptr = nullptr; - if (strcmp(argv[1], "Uniaxial") == 0) { - area = 1.0; - } - else if (strcmp(argv[1], "PlaneStress") == 0) { - if (!(pptr = mptr->getCopy("PlaneStress"))) { - pptr = new PlaneStressMaterial(tag, *mptr); - } - } - else { - opserr << OpenSees::PromptValueError - << "unknown plane section\n"; - return TCL_ERROR; - } - - builder->addTaggedObject>(*(new TrussSection(tag, *pptr, area))); - - return TCL_OK; -} -#endif \ No newline at end of file diff --git a/SRC/runtime/commands/modeling/uniaxial.cpp b/SRC/runtime/commands/modeling/uniaxial.cpp index 5f61bafa86..e33f44d6c4 100644 --- a/SRC/runtime/commands/modeling/uniaxial.cpp +++ b/SRC/runtime/commands/modeling/uniaxial.cpp @@ -43,23 +43,6 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, -#if 0 -extern void *OPS_PlateBearingConnectionThermal(G3_Runtime*); - -extern int TclCommand_ConfinedConcrete02(ClientData clientData, Tcl_Interp -*interp, int argc, TCL_Char ** const argv, TclBasicBuilder -*theTclBuilder); - -extern UniaxialMaterial *Tcl_AddLimitStateMaterial(ClientData clientData, - Tcl_Interp *interp, int argc, - TCL_Char **arg); - - -extern UniaxialMaterial * -Tcl_addWrapperUniaxialMaterial(matObj *, ClientData clientData, - Tcl_Interp *interp, int argc, TCL_Char ** const argv); -#endif - typedef struct uniaxialPackageCommand { char *funcName; void *(*funcPtr)(); @@ -174,24 +157,6 @@ TclCommand_addUniaxialMaterial(ClientData clientData, Tcl_Interp *interp, // package yet to be loaded // if (theMaterial == nullptr) { -#if 0 - // - // maybe material in a routine - // - char *matType = new char[strlen(argv[1]) + 1]; - strcpy(matType, argv[1]); - matObj *matObject = OPS_GetMaterialType(matType, strlen(matType)); - - delete[] matType; - - if (matObject != 0) { - - theMaterial = Tcl_addWrapperUniaxialMaterial(matObject, clientData, interp, argc, argv); - - if (theMaterial == 0) - delete matObject; - } -#endif } // @@ -550,39 +515,3 @@ TclDispatch_newUniaxialPinching4(ClientData clientData, Tcl_Interp* interp, int } return TCL_OK; } - - -#if 0 - else if (strcmp(argv[1], "Backbone") == 0) { - if (argc < 4) { - opserr << OpenSees::PromptValueError << "insufficient arguments\n"; - opserr << "Want: uniaxialMaterial Backbone tag? bbTag?" << "\n"; - return TCL_ERROR; - } - - int tag, bbTag; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid tag\n"; - opserr << "Backbone material: " << tag << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &bbTag) != TCL_OK) { - opserr << OpenSees::PromptValueError << "invalid bTag\n"; - opserr << "Backbone material: " << tag << "\n"; - return TCL_ERROR; - } - - HystereticBackbone *backbone = OPS_getHystereticBackbone(bbTag); - - if (backbone == 0) { - opserr << OpenSees::PromptValueError << "backbone does not exist\n"; - opserr << "backbone: " << bbTag; - opserr << "\nuniaxialMaterial Backbone: " << tag << "\n"; - return TCL_ERROR; - } - - theMaterial = new BackboneMaterial(tag, *backbone); - } -#endif diff --git a/SRC/runtime/commands/modeling/uniaxial.hpp b/SRC/runtime/commands/modeling/uniaxial.hpp index 9c085fffee..51eba1b7c6 100644 --- a/SRC/runtime/commands/modeling/uniaxial.hpp +++ b/SRC/runtime/commands/modeling/uniaxial.hpp @@ -131,19 +131,6 @@ extern void *OPS_ConcretewBeta(); extern Tcl_CmdProc Create_OOHystereticMaterial; - - -#if 0 -const char** DeprecatedUniaxialMaterials { - {"Bilin02", "This material is superceded by \"IMKBilin\" and \"HystereticSM\""}, - {"CFSSSWP", ""}, - {"CFSWSWP", ""}, - {"APDVFD", ""}, - {"APDMD", ""}, - {"APDFMD", ""}, -}; -#endif - typedef UniaxialMaterial*(G3_TclUniaxialPackage)(ClientData, Tcl_Interp *, int, TCL_Char ** const); G3_TclUniaxialPackage TclBasicBuilder_addFedeasMaterial; G3_TclUniaxialPackage TclBasicBuilder_addSnapMaterial; @@ -152,9 +139,6 @@ std::unordered_map tcl_uniaxial_package_ta {"DRAIN", TclBasicBuilder_addDrainMaterial }, {"SNAP", TclBasicBuilder_addSnapMaterial }, {"snap", TclBasicBuilder_addSnapMaterial }, -// #if defined(_STEEL2) || defined(OPSDEF_UNIAXIAL_FEDEAS) -//{"FEDEAS", TclBasicBuilder_addFedeasMaterial}, -// #endif }; @@ -297,11 +281,6 @@ std::unordered_map uniaxial_dispatch { {"ConcreteZ01Material", dispatch }, {"ConcreteZ01", dispatch }, - - -#if 0 - { "ConcretewBeta", dispatch } -#endif // // Viscous // diff --git a/SRC/runtime/commands/modeling/uniaxialMaterial.cpp b/SRC/runtime/commands/modeling/uniaxialMaterial.cpp index 81b1cc0a72..a2c6d80303 100644 --- a/SRC/runtime/commands/modeling/uniaxialMaterial.cpp +++ b/SRC/runtime/commands/modeling/uniaxialMaterial.cpp @@ -155,7 +155,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (argc < 3) { opserr << "WARNING insufficient number of uniaxial material arguments\n"; opserr << "Want: uniaxialMaterial type? tag? " - << endln; + << "\n"; return TCL_ERROR; } @@ -194,15 +194,6 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp return TCL_ERROR; #endif -#if 0 - } else if (strcmp(argv[1],"HoehlerStanton") == 0) { - void *theMat = OPS_HoehlerStanton(rt, argc, argv); - if (theMat != 0) - theMaterial = (UniaxialMaterial *)theMat; - else - return TCL_ERROR; -#endif - } else if (strcmp(argv[1], "ReinforcingSteel") == 0) { void *theMat = OPS_ReinforcingSteel(rt, argc, argv); @@ -275,7 +266,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp } else if (strcmp(argv[1], "Elastic2") == 0) { if (argc < 4 || argc > 5) { opserr << "WARNING invalid number of arguments\n"; - opserr << "Want: uniaxialMaterial Elastic tag? E? " << endln; + opserr << "Want: uniaxialMaterial Elastic tag? E? " << "\n"; return TCL_ERROR; } @@ -284,20 +275,20 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp double eta = 0.0; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial Elastic tag" << endln; + opserr << "WARNING invalid uniaxialMaterial Elastic tag" << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { opserr << "WARNING invalid E\n"; - opserr << "uniaxiaMaterial Elastic: " << tag << endln; + opserr << "uniaxiaMaterial Elastic: " << tag << "\n"; return TCL_ERROR; } if (argc == 5) { if (Tcl_GetDouble(interp, argv[4], &eta) != TCL_OK) { opserr << "WARNING invalid eta\n"; - opserr << "uniaxialMaterial Elastic: " << tag << endln; + opserr << "uniaxialMaterial Elastic: " << tag << "\n"; return TCL_ERROR; } } @@ -308,7 +299,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp } else if (strcmp(argv[1], "ENT") == 0) { if (argc < 4) { opserr << "WARNING invalid number of arguments\n"; - opserr << "Want: uniaxialMaterial ENT tag? E?" << endln; + opserr << "Want: uniaxialMaterial ENT tag? E?" << "\n"; return TCL_ERROR; } @@ -316,13 +307,13 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp double E; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial ENT tag" << endln; + opserr << "WARNING invalid uniaxialMaterial ENT tag" << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { opserr << "WARNING invalid E\n"; - opserr << "uniaxiaMaterial ENT: " << tag << endln; + opserr << "uniaxiaMaterial ENT: " << tag << "\n"; return TCL_ERROR; } @@ -344,14 +335,14 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (argc < 9) { opserr << "WARNING insufficient arguments\n"; opserr << "Want: uniaxialMaterial Steel03 tag? fy? E0? b? r? cR1 cR2?"; - opserr << " " << endln; + opserr << " " << "\n"; return TCL_ERROR; } int tag; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial Steel03 tag" << endln; + opserr << "WARNING invalid uniaxialMaterial Steel03 tag" << "\n"; return TCL_ERROR; } @@ -393,31 +384,31 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (argc > 9) { if (argc < 13) { opserr << "WARNING insufficient number of hardening parameters\n"; - opserr << "uniaxialMaterial Steel03: " << tag << endln; + opserr << "uniaxialMaterial Steel03: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[9], &a1) != TCL_OK) { opserr << "WARNING invalid a1\n"; - opserr << "uniaxialMaterial Steel03: " << tag << endln; + opserr << "uniaxialMaterial Steel03: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[10], &a2) != TCL_OK) { opserr << "WARNING invalid a2\n"; - opserr << "uniaxialMaterial Steel03: " << tag << endln; + opserr << "uniaxialMaterial Steel03: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[11], &a3) != TCL_OK) { opserr << "WARNING invalid a3\n"; - opserr << "uniaxialMaterial Steel03: " << tag << endln; + opserr << "uniaxialMaterial Steel03: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[12], &a4) != TCL_OK) { opserr << "WARNING invalid a4\n"; - opserr << "uniaxialMaterial Steel03: " << tag << endln; + opserr << "uniaxialMaterial Steel03: " << tag << "\n"; return TCL_ERROR; } @@ -440,19 +431,19 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp } else if (strcmp(argv[1], "Concrete04") == 0) { - // opserr << argc << endln; + // opserr << argc << "\n"; if (argc != 10 && argc != 9 && argc != 7) { opserr << "WARNING insufficient arguments\n"; opserr << "Want: uniaxialMaterial Concrete04 tag? fpc? epsc0? epscu? " "Ec0? >" - << endln; + << "\n"; return TCL_ERROR; } int tag; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial Concrete04 tag" << endln; + opserr << "WARNING invalid uniaxialMaterial Concrete04 tag" << "\n"; return TCL_ERROR; } @@ -510,14 +501,14 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp opserr << "WARNING insufficient arguments\n"; opserr << "Want: uniaxialMaterial Concrete06 tag? fc? eo? r? k? alphaC? " "fcr? ecr? b? alphaT?" - << endln; + << "\n"; return TCL_ERROR; } int tag; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial tag" << endln; + opserr << "WARNING invalid uniaxialMaterial tag" << "\n"; return TCL_ERROR; } @@ -526,55 +517,55 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (Tcl_GetDouble(interp, argv[3], &fc) != TCL_OK) { opserr << "WARNING invalid fc\n"; - opserr << "Concrete06 material: " << tag << endln; + opserr << "Concrete06 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &eo) != TCL_OK) { opserr << "WARNING invalid eo\n"; - opserr << "Concrete06 material: " << tag << endln; + opserr << "Concrete06 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &r) != TCL_OK) { opserr << "WARNING invalid r\n"; - opserr << "Concrete06 material: " << tag << endln; + opserr << "Concrete06 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[6], &k) != TCL_OK) { opserr << "WARNING invalid k\n"; - opserr << "Concrete06 material: " << tag << endln; + opserr << "Concrete06 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[7], &alphaC) != TCL_OK) { opserr << "WARNING invalid alphaC\n"; - opserr << "Concrete06 material: " << tag << endln; + opserr << "Concrete06 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[8], &fcr) != TCL_OK) { opserr << "WARNING invalid fcr\n"; - opserr << "Concrete06 material: " << tag << endln; + opserr << "Concrete06 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[9], &ecr) != TCL_OK) { opserr << "WARNING invalid ecr\n"; - opserr << "Concrete06 material: " << tag << endln; + opserr << "Concrete06 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[10], &b) != TCL_OK) { opserr << "WARNING invalid b\n"; - opserr << "Concrete06 material: " << tag << endln; + opserr << "Concrete06 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[11], &alphaT) != TCL_OK) { opserr << "WARNING invalid alphaT\n"; - opserr << "Concrete06 material: " << tag << endln; + opserr << "Concrete06 material: " << tag << "\n"; return TCL_ERROR; } @@ -651,7 +642,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp else if (strcmp(argv[1], "PathIndependent") == 0) { if (argc < 4) { opserr << "WARNING insufficient arguments\n"; - opserr << "Want: uniaxialMaterial PathIndependent tag? matTag?" << endln; + opserr << "Want: uniaxialMaterial PathIndependent tag? matTag?" << "\n"; return TCL_ERROR; } @@ -659,13 +650,13 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { opserr << "WARNING invalid tag\n"; - opserr << "PathIndependent material: " << tag << endln; + opserr << "PathIndependent material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { opserr << "WARNING invalid matTag\n"; - opserr << "PathIndependent material: " << tag << endln; + opserr << "PathIndependent material: " << tag << "\n"; return TCL_ERROR; } @@ -680,7 +671,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp else if (strcmp(argv[1], "Backbone") == 0) { if (argc < 4) { opserr << "WARNING insufficient arguments\n"; - opserr << "Want: uniaxialMaterial Backbone tag? bbTag?" << endln; + opserr << "Want: uniaxialMaterial Backbone tag? bbTag?" << "\n"; return TCL_ERROR; } @@ -688,13 +679,13 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { opserr << "WARNING invalid tag\n"; - opserr << "Backbone material: " << tag << endln; + opserr << "Backbone material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &bbTag) != TCL_OK) { opserr << "WARNING invalid bTag\n"; - opserr << "Backbone material: " << tag << endln; + opserr << "Backbone material: " << tag << "\n"; return TCL_ERROR; } @@ -703,7 +694,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (backbone == 0) { opserr << "WARNING backbone does not exist\n"; opserr << "backbone: " << bbTag; - opserr << "\nuniaxialMaterial Backbone: " << tag << endln; + opserr << "\nuniaxialMaterial Backbone: " << tag << "\n"; return TCL_ERROR; } @@ -714,21 +705,21 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (argc < 4) { opserr << "WARNING insufficient arguments\n"; opserr << "Want: uniaxialMaterial Fatigue tag? matTag?"; - opserr << " <-D_max dmax?> <-e0 e0?> <-m m?>" << endln; - opserr << " <-min min?> <-max max?>" << endln; + opserr << " <-D_max dmax?> <-e0 e0?> <-m m?>" << "\n"; + opserr << " <-min min?> <-max max?>" << "\n"; return TCL_ERROR; } int tag, matTag; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial Fatigue tag" << endln; + opserr << "WARNING invalid uniaxialMaterial Fatigue tag" << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], &matTag) != TCL_OK) { opserr << "WARNING invalid component tag\n"; - opserr << "uniaxialMaterial Fatigue: " << tag << endln; + opserr << "uniaxialMaterial Fatigue: " << tag << "\n"; return TCL_ERROR; } @@ -743,35 +734,35 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if ((j + 1 >= argc) || (Tcl_GetDouble(interp, argv[j + 1], &Dmax) != TCL_OK)) { opserr << "WARNING invalid -Dmax"; - opserr << "uniaxialMaterial Fatigue: " << tag << endln; + opserr << "uniaxialMaterial Fatigue: " << tag << "\n"; return TCL_ERROR; } } else if (strcmp(argv[j], "-E0") == 0) { if ((j + 1 >= argc) || (Tcl_GetDouble(interp, argv[j + 1], &E0) != TCL_OK)) { opserr << "WARNING invalid -E0"; - opserr << "uniaxialMaterial Fatigue: " << tag << endln; + opserr << "uniaxialMaterial Fatigue: " << tag << "\n"; return TCL_ERROR; } } else if (strcmp(argv[j], "-m") == 0) { if ((j + 1 >= argc) || (Tcl_GetDouble(interp, argv[j + 1], &m) != TCL_OK)) { opserr << "WARNING invalid -m"; - opserr << "uniaxialMaterial Fatigue: " << tag << endln; + opserr << "uniaxialMaterial Fatigue: " << tag << "\n"; return TCL_ERROR; } } else if (strcmp(argv[j], "-min") == 0) { if ((j + 1 >= argc) || (Tcl_GetDouble(interp, argv[j + 1], &epsmin) != TCL_OK)) { opserr << "WARNING invalid -min "; - opserr << "uniaxialMaterial Fatigue: " << tag << endln; + opserr << "uniaxialMaterial Fatigue: " << tag << "\n"; return TCL_ERROR; } } else if (strcmp(argv[j], "-max") == 0) { if ((j + 1 >= argc) || (Tcl_GetDouble(interp, argv[j + 1], &epsmax) != TCL_OK)) { opserr << "WARNING invalid -max"; - opserr << "uniaxialMaterial Fatigue: " << tag << endln; + opserr << "uniaxialMaterial Fatigue: " << tag << "\n"; return TCL_ERROR; } } @@ -877,225 +868,225 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp int i = 2; if (Tcl_GetInt(interp, argv[i++], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial Pinching4 tag" << endln; + opserr << "WARNING invalid uniaxialMaterial Pinching4 tag" << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress1p) != TCL_OK) { opserr << "WARNING invalid stress1p\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain1p) != TCL_OK) { opserr << "WARNING invalid strain1p\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress2p) != TCL_OK) { opserr << "WARNING invalid stress2p\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain2p) != TCL_OK) { opserr << "WARNING invalid strain2p\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress3p) != TCL_OK) { opserr << "WARNING invalid stress3p\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain3p) != TCL_OK) { opserr << "WARNING invalid strain3p\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress4p) != TCL_OK) { opserr << "WARNING invalid stress4p\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain4p) != TCL_OK) { opserr << "WARNING invalid strain4p\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (argc == 42) { if (Tcl_GetDouble(interp, argv[i++], &stress1n) != TCL_OK) { opserr << "WARNING invalid stress1n\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain1n) != TCL_OK) { opserr << "WARNING invalid strain1n\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress2n) != TCL_OK) { opserr << "WARNING invalid stress2n\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain2n) != TCL_OK) { opserr << "WARNING invalid strain2n\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress3n) != TCL_OK) { opserr << "WARNING invalid stress3n\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain3n) != TCL_OK) { opserr << "WARNING invalid strain3n\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress4n) != TCL_OK) { opserr << "WARNING invalid stress4n\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain4n) != TCL_OK) { opserr << "WARNING invalid strain4n\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } } if (Tcl_GetDouble(interp, argv[i++], &rDispP) != TCL_OK) { opserr << "WARNING invalid rDispP\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &rForceP) != TCL_OK) { opserr << "WARNING invalid rForceP\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &uForceP) != TCL_OK) { opserr << "WARNING invalid uForceP\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (argc == 42) { if (Tcl_GetDouble(interp, argv[i++], &rDispN) != TCL_OK) { opserr << "WARNING invalid rDispN\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &rForceN) != TCL_OK) { opserr << "WARNING invalid rForceN\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &uForceN) != TCL_OK) { opserr << "WARNING invalid uForceN\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } } if (Tcl_GetDouble(interp, argv[i++], &gammaK1) != TCL_OK) { opserr << "WARNING invalid gammaK1\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaK2) != TCL_OK) { opserr << "WARNING invalid gammaK2\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaK3) != TCL_OK) { opserr << "WARNING invalid gammaK3\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaK4) != TCL_OK) { opserr << "WARNING invalid gammaK4\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaKLimit) != TCL_OK) { opserr << "WARNING invalid gammaKLimit\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaD1) != TCL_OK) { opserr << "WARNING invalid gammaD1\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaD2) != TCL_OK) { opserr << "WARNING invalid gammaD2\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaD3) != TCL_OK) { opserr << "WARNING invalid gammaD3\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaD4) != TCL_OK) { opserr << "WARNING invalid gammaD4\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaDLimit) != TCL_OK) { opserr << "WARNING invalid gammaDLimit\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaF1) != TCL_OK) { opserr << "WARNING invalid gammaF1\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaF2) != TCL_OK) { opserr << "WARNING invalid gammaF2\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaF3) != TCL_OK) { opserr << "WARNING invalid gammaF3\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaF4) != TCL_OK) { opserr << "WARNING invalid gammaF4\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaFLimit) != TCL_OK) { opserr << "WARNING invalid gammaFLimit\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaE) != TCL_OK) { opserr << "WARNING invalid gammaE\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } @@ -1113,7 +1104,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp tDmg = 0; } else { opserr << "WARNING invalid type of damage calculation specified\n"; - opserr << "Pinching4 material: " << tag << endln; + opserr << "Pinching4 material: " << tag << "\n"; return TCL_ERROR; } @@ -1142,7 +1133,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp opserr << "WARNING insufficient arguments\n"; opserr << "Want: uniaxialMaterial BarSlip tag? fc? fy? Es? fu? Eh? db? " "ld? nb? width? depth? bsflag? type? " - << endln; + << "\n"; return TCL_ERROR; } @@ -1153,57 +1144,57 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (Tcl_GetInt(interp, argv[argStart++], &tag) != TCL_OK) { opserr << "WARNING invalid tag\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argStart++], &fc) != TCL_OK) { opserr << "WARNING invalid fc\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argStart++], &fy) != TCL_OK) { opserr << "WARNING invalid fy\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argStart++], &Es) != TCL_OK) { opserr << "WARNING invalid Es\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argStart++], &fu) != TCL_OK) { opserr << "WARNING invalid fu\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argStart++], &Eh) != TCL_OK) { opserr << "WARNING invalid Eh\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argStart++], &db) != TCL_OK) { opserr << "WARNING invalid db\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argStart++], &ld) != TCL_OK) { opserr << "WARNING invalid ld\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetInt(interp, argv[argStart++], &nb) != TCL_OK) { opserr << "WARNING invalid nbars\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argStart++], &width) != TCL_OK) { opserr << "WARNING invalid width\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[argStart++], &depth) != TCL_OK) { opserr << "WARNING invalid depth\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } @@ -1222,7 +1213,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp } } else { opserr << "WARNING invalid bond strength specified\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } y++; @@ -1254,7 +1245,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp } } else { opserr << "WARNING invalid location of bar specified\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } if (argc == 17) { @@ -1283,7 +1274,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp } else { opserr << "WARNING invalid damage specified\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } @@ -1323,7 +1314,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp } } else { opserr << "WARNING invalid unit specified\n"; - opserr << "BarSlip: " << tag << endln; + opserr << "BarSlip: " << tag << "\n"; return TCL_ERROR; } } @@ -1369,231 +1360,231 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp int i = 2; if (Tcl_GetInt(interp, argv[i++], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial ShearPanel tag" << endln; + opserr << "WARNING invalid uniaxialMaterial ShearPanel tag" << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress1p) != TCL_OK) { opserr << "WARNING invalid stress1p\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain1p) != TCL_OK) { opserr << "WARNING invalid strain1p\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress2p) != TCL_OK) { opserr << "WARNING invalid stress2p\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain2p) != TCL_OK) { opserr << "WARNING invalid strain2p\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress3p) != TCL_OK) { opserr << "WARNING invalid stress3p\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain3p) != TCL_OK) { opserr << "WARNING invalid strain3p\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress4p) != TCL_OK) { opserr << "WARNING invalid stress4p\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain4p) != TCL_OK) { opserr << "WARNING invalid strain4p\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (argc == 42) { if (Tcl_GetDouble(interp, argv[i++], &stress1n) != TCL_OK) { opserr << "WARNING invalid stress1n\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain1n) != TCL_OK) { opserr << "WARNING invalid strain1n\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress2n) != TCL_OK) { opserr << "WARNING invalid stress2n\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain2n) != TCL_OK) { opserr << "WARNING invalid strain2n\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress3n) != TCL_OK) { opserr << "WARNING invalid stress3n\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain3n) != TCL_OK) { opserr << "WARNING invalid strain3n\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &stress4n) != TCL_OK) { opserr << "WARNING invalid stress4n\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &strain4n) != TCL_OK) { opserr << "WARNING invalid strain4n\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } } if (Tcl_GetDouble(interp, argv[i++], &rDispP) != TCL_OK) { opserr << "WARNING invalid rDispP\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &rForceP) != TCL_OK) { opserr << "WARNING invalid rForceP\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &uForceP) != TCL_OK) { opserr << "WARNING invalid uForceP\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (argc == 42) { if (Tcl_GetDouble(interp, argv[i++], &rDispN) != TCL_OK) { opserr << "WARNING invalid rDispN\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &rForceN) != TCL_OK) { opserr << "WARNING invalid rForceN\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &uForceN) != TCL_OK) { opserr << "WARNING invalid uForceN\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } } if (Tcl_GetDouble(interp, argv[i++], &gammaK1) != TCL_OK) { opserr << "WARNING invalid gammaK1\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaK2) != TCL_OK) { opserr << "WARNING invalid gammaK2\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaK3) != TCL_OK) { opserr << "WARNING invalid gammaK3\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaK4) != TCL_OK) { opserr << "WARNING invalid gammaK4\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaKLimit) != TCL_OK) { opserr << "WARNING invalid gammaKLimit\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaD1) != TCL_OK) { opserr << "WARNING invalid gammaD1\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaD2) != TCL_OK) { opserr << "WARNING invalid gammaD2\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaD3) != TCL_OK) { opserr << "WARNING invalid gammaD3\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaD4) != TCL_OK) { opserr << "WARNING invalid gammaD4\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaDLimit) != TCL_OK) { opserr << "WARNING invalid gammaDLimit\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaF1) != TCL_OK) { opserr << "WARNING invalid gammaF1\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaF2) != TCL_OK) { opserr << "WARNING invalid gammaF2\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaF3) != TCL_OK) { opserr << "WARNING invalid gammaF3\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaF4) != TCL_OK) { opserr << "WARNING invalid gammaF4\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaFLimit) != TCL_OK) { opserr << "WARNING invalid gammaFLimit\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &gammaE) != TCL_OK) { opserr << "WARNING invalid gammaE\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[i++], &yStr) != TCL_OK) { opserr << "WARNING invalid yield stress\n"; - opserr << "ShearPanel material: " << tag << endln; + opserr << "ShearPanel material: " << tag << "\n"; return TCL_ERROR; } @@ -1622,14 +1613,14 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp opserr << "WARNING insufficient arguments\n"; opserr << "Want: uniaxialMaterial Concrete01 tag? fpc? epsc0? fpcu? " "epscu? " - << endln; + << "\n"; return TCL_ERROR; } int tag; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial Concrete01 tag" << endln; + opserr << "WARNING invalid uniaxialMaterial Concrete01 tag" << "\n"; return TCL_ERROR; } @@ -1638,25 +1629,25 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (Tcl_GetDouble(interp, argv[3], &fpc) != TCL_OK) { opserr << "WARNING invalid fpc\n"; - opserr << "Concrete01 material: " << tag << endln; + opserr << "Concrete01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &epsc0) != TCL_OK) { opserr << "WARNING invalid epsc0\n"; - opserr << "Concrete01 material: " << tag << endln; + opserr << "Concrete01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &fpcu) != TCL_OK) { opserr << "WARNING invalid fpcu\n"; - opserr << "Concrete01 material: " << tag << endln; + opserr << "Concrete01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[6], &epscu) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "Concrete01 material: " << tag << endln; + opserr << "Concrete01 material: " << tag << "\n"; return TCL_ERROR; } @@ -1667,7 +1658,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp double endStrainSITC; if (Tcl_GetDouble(interp, argv[7], &endStrainSITC) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "Concrete01 material: " << tag << endln; + opserr << "Concrete01 material: " << tag << "\n"; return TCL_ERROR; } theMaterial = @@ -1689,82 +1680,82 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp ALPHAT2, ALPHAC, ALPHACU, BETAT, BETAC; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial ECC01 tag" << endln; + opserr << "WARNING invalid uniaxialMaterial ECC01 tag" << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3], &SIGT0) != TCL_OK) { opserr << "WARNING invalid SIGTO\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &EPST0) != TCL_OK) { opserr << "WARNING invalid EPSTO\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &SIGT1) != TCL_OK) { opserr << "WARNING invalid SIGT1\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[6], &EPST1) != TCL_OK) { opserr << "WARNING invalid EPST1\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[7], &EPST2) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[8], &SIGC0) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[9], &EPSC0) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[10], &EPSC1) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[11], &ALPHAT1) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[12], &ALPHAT2) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[13], &ALPHAC) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[14], &ALPHACU) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[15], &BETAT) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[16], &BETAC) != TCL_OK) { opserr << "WARNING invalid epscu\n"; - opserr << "ECC01 material: " << tag << endln; + opserr << "ECC01 material: " << tag << "\n"; return TCL_ERROR; } @@ -1786,7 +1777,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp opserr << "WARNING insufficient arguments\n"; opserr << "Want: uniaxialMaterial SelfCentering tag? k1? k2? ActF? beta? " "" - << endln; + << "\n"; return TCL_ERROR; } @@ -1794,38 +1785,38 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp double k1, k2, ActF, beta, rBear, SlipDef, BearDef; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial SelfCentering tag" << endln; + opserr << "WARNING invalid uniaxialMaterial SelfCentering tag" << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3], &k1) != TCL_OK) { opserr << "WARNING invalid k1\n"; - opserr << "uniaxialMaterial SelfCentering: " << tag << endln; + opserr << "uniaxialMaterial SelfCentering: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &k2) != TCL_OK) { opserr << "WARNING invalid k2\n"; - opserr << "uniaxialMaterial SelfCentering: " << tag << endln; + opserr << "uniaxialMaterial SelfCentering: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &ActF) != TCL_OK) { opserr << "WARNING invalid ActF\n"; - opserr << "uniaxialMaterial SelfCentering: " << tag << endln; + opserr << "uniaxialMaterial SelfCentering: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[6], &beta) != TCL_OK) { opserr << "WARNING invalid beta\n"; - opserr << "uniaxialMaterial SelfCentering: " << tag << endln; + opserr << "uniaxialMaterial SelfCentering: " << tag << "\n"; return TCL_ERROR; } if (argc == 8) { if (Tcl_GetDouble(interp, argv[7], &SlipDef) != TCL_OK) { opserr << "WARNING invalid SlipDef\n"; - opserr << "uniaxialMaterial SelfCentering: " << tag << endln; + opserr << "uniaxialMaterial SelfCentering: " << tag << "\n"; return TCL_ERROR; } // Parsing was successful, allocate the material @@ -1836,17 +1827,17 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp else if (argc > 8) { if (Tcl_GetDouble(interp, argv[7], &SlipDef) != TCL_OK) { opserr << "WARNING invalid SlipDef\n"; - opserr << "uniaxialMaterial SelfCentering: " << tag << endln; + opserr << "uniaxialMaterial SelfCentering: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[8], &BearDef) != TCL_OK) { opserr << "WARNING invalid BearDef\n"; - opserr << "uniaxialMaterial SelfCentering: " << tag << endln; + opserr << "uniaxialMaterial SelfCentering: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[9], &rBear) != TCL_OK) { opserr << "WARNING invalid rBear\n"; - opserr << "uniaxialMaterial SelfCentering: " << tag << endln; + opserr << "uniaxialMaterial SelfCentering: " << tag << "\n"; return TCL_ERROR; } // Parsing was successful, allocate the material @@ -1865,14 +1856,14 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (argc < 4) { opserr << "WARNING insufficient arguments\n"; opserr << "Want: uniaxialMaterial SteelMP tag? fy? E0? b? "; - opserr << " " << endln; + opserr << " " << "\n"; return TCL_ERROR; } int tag; if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid uniaxialMaterial SteelMP tag" << endln; + opserr << "WARNING invalid uniaxialMaterial SteelMP tag" << "\n"; return TCL_ERROR; } @@ -1881,19 +1872,19 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (Tcl_GetDouble(interp, argv[3], &fy) != TCL_OK) { opserr << "WARNING invalid fy\n"; - opserr << "uniaxialMaterial SteelMP: " << tag << endln; + opserr << "uniaxialMaterial SteelMP: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &E) != TCL_OK) { opserr << "WARNING invalid E0\n"; - opserr << "uniaxialMaterial SteelMP: " << tag << endln; + opserr << "uniaxialMaterial SteelMP: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &b) != TCL_OK) { opserr << "WARNING invalid b\n"; - opserr << "uniaxialMaterial SteelMP: " << tag << endln; + opserr << "uniaxialMaterial SteelMP: " << tag << "\n"; return TCL_ERROR; } @@ -1913,31 +1904,31 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (argc > 6) { if (Tcl_GetDouble(interp, argv[6], &r) != TCL_OK) { opserr << "WARNING invalid r\n"; - opserr << "uniaxialMaterial SteelMP: " << tag << endln; + opserr << "uniaxialMaterial SteelMP: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[7], &coeffR1) != TCL_OK) { opserr << "WARNING invalid CR1\n"; - opserr << "uniaxialMaterial SteelMP: " << tag << endln; + opserr << "uniaxialMaterial SteelMP: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[8], &coeffR2) != TCL_OK) { opserr << "WARNING invalid CR2\n"; - opserr << "uniaxialMaterial SteelMP: " << tag << endln; + opserr << "uniaxialMaterial SteelMP: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[9], &a1) != TCL_OK) { opserr << "WARNING invalid a1\n"; - opserr << "uniaxialMaterial SteelMP: " << tag << endln; + opserr << "uniaxialMaterial SteelMP: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[10], &a2) != TCL_OK) { opserr << "WARNING invalid a2\n"; - opserr << "uniaxialMaterial SteelMP: " << tag << endln; + opserr << "uniaxialMaterial SteelMP: " << tag << "\n"; return TCL_ERROR; } } // if @@ -1950,7 +1941,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp opserr << "WARNING invalid number of arguments\n"; opserr << "Want: uniaxialMaterial SmoothPSConcrete tag? fc? fu? Ec? " " " - << endln; + << "\n"; return TCL_ERROR; } @@ -1962,46 +1953,46 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { opserr << "WARNING invalid uniaxialMaterial SmoothPSConcrete tag" - << endln; + << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3], &fc) != TCL_OK) { opserr << "WARNING invalid fc\n"; - opserr << "uniaxiaMaterial SmoothPSConcrete: " << tag << endln; + opserr << "uniaxiaMaterial SmoothPSConcrete: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[4], &fu) != TCL_OK) { opserr << "WARNING invalid fu\n"; - opserr << "uniaxiaMaterial SmoothPSConcrete: " << tag << endln; + opserr << "uniaxiaMaterial SmoothPSConcrete: " << tag << "\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[5], &Ec) != TCL_OK) { opserr << "WARNING invalid Ec\n"; - opserr << "uniaxiaMaterial SmoothPSConcrete: " << tag << endln; + opserr << "uniaxiaMaterial SmoothPSConcrete: " << tag << "\n"; return TCL_ERROR; } if (argc >= 7) if (Tcl_GetDouble(interp, argv[6], &eps0) != TCL_OK) { opserr << "WARNING invalid eps0\n"; - opserr << "uniaxialMaterial SmoothPSConcrete: " << tag << endln; + opserr << "uniaxialMaterial SmoothPSConcrete: " << tag << "\n"; return TCL_ERROR; } if (argc >= 8) if (Tcl_GetDouble(interp, argv[7], &epsu) != TCL_OK) { opserr << "WARNING invalid epsu\n"; - opserr << "uniaxialMaterial SmoothPSConcrete: " << tag << endln; + opserr << "uniaxialMaterial SmoothPSConcrete: " << tag << "\n"; return TCL_ERROR; } if (argc >= 9) if (Tcl_GetDouble(interp, argv[8], &eta) != TCL_OK) { opserr << "WARNING invalid eta\n"; - opserr << "uniaxialMaterial SmoothPSConcrete: " << tag << endln; + opserr << "uniaxialMaterial SmoothPSConcrete: " << tag << "\n"; return TCL_ERROR; } @@ -2073,7 +2064,7 @@ TclBasicBuilderUniaxialMaterialCommand(ClientData clientData, Tcl_Interp *interp // if still here the element command does not exist // if (theMaterial == nullptr) { - opserr << "WARNING could not create uniaxialMaterial " << argv[1] << endln; + opserr << "WARNING could not create uniaxialMaterial " << argv[1] << "\n"; return TCL_ERROR; } diff --git a/SRC/runtime/commands/modeling/utilities/blockND.cpp b/SRC/runtime/commands/modeling/utilities/blockND.cpp index e4bb9a46d9..be8f818707 100644 --- a/SRC/runtime/commands/modeling/utilities/blockND.cpp +++ b/SRC/runtime/commands/modeling/utilities/blockND.cpp @@ -167,21 +167,6 @@ TclCommand_doBlock2D(ClientData clientData, theNode = new Node(nodeID, ndf, nodeCoords(0), nodeCoords(1)); } else if (ndm == 3) { -#if 0 - if (getenv("NODE")) { - switch (ndf) { - case 3: - theNode = new NodeND<3, 3>(nodeID, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - break; - case 6: - theNode = new NodeND<3, 6>(nodeID, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - break; - default: - theNode = new HeapNode(nodeID, ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - break; - } - } else -#endif // theNode = new HeapNode(nodeID, ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); theNode = new Node(nodeID,ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); } @@ -343,21 +328,6 @@ TclCommand_doBlock3D(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, const Vector &nodeCoords = theBlock.getNodalCoords(ii,jj,kk); // Node* theNode = nullptr; -#if 0 - if (getenv("NODE")) { - switch (ndf) { - case 3: - theNode = new NodeND<3, 3>(nodeID, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - break; - case 6: - theNode = new NodeND<3, 6>(nodeID, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - break; - default: - theNode = new HeapNode(nodeID, ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); - break; - } - } else -#endif // theNode = new HeapNode(nodeID, ndf, nodeCoords(0), nodeCoords(1), nodeCoords(2)); theNode = new Node(nodeID,ndf,nodeCoords(0),nodeCoords(1),nodeCoords(2)); diff --git a/SRC/runtime/commands/parallel/partition.cpp b/SRC/runtime/commands/parallel/partition.cpp index cf307b1484..d2f628b19a 100644 --- a/SRC/runtime/commands/parallel/partition.cpp +++ b/SRC/runtime/commands/parallel/partition.cpp @@ -145,22 +145,6 @@ partitionModel(PartitionRuntime& part, int eleTag) Subdomain *theSub = nullptr; void* the_static_analysis = nullptr; -#if 0 - // create the appropriate domain decomposition analysis - while ((theSub = theSubdomains()) != nullptr) { - if (the_static_analysis != nullptr) { - theSubAnalysis = new StaticDomainDecompositionAnalysis( - *theSub, *theHandler, *theNumberer, *the_analysis_model, *theAlgorithm, - *theSOE, *theStaticIntegrator, theTest, false); - - } else { - theSubAnalysis = new TransientDomainDecompositionAnalysis( - *theSub, *theHandler, *theNumberer, *the_analysis_model, *theAlgorithm, - *theSOE, *theTransientIntegrator, theTest, false); - } - theSub->setDomainDecompAnalysis(*theSubAnalysis); - } -#endif return result; } diff --git a/SRC/runtime/commands/parallel/sequential.cpp b/SRC/runtime/commands/parallel/sequential.cpp index bffcab3444..8d40c79c9e 100644 --- a/SRC/runtime/commands/parallel/sequential.cpp +++ b/SRC/runtime/commands/parallel/sequential.cpp @@ -70,52 +70,3 @@ opsRecvSequential(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char return TCL_OK; } - - -#if 0 -int -opsSendSequential(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - if (argc < 2) - return TCL_OK; - - int otherPID = -1; - int myPID = theMachineBroker->getPID(); - int np = theMachineBroker->getNP(); - const char *dataToSend = argv[argc - 1]; - int msgLength = strlen(dataToSend) + 1; - - const char *gMsg = dataToSend; - // strcpy(gMsg, dataToSend); - - if (strcmp(argv[1], "-pid") == 0 && argc > 3) { - - if (Tcl_GetInt(interp, argv[2], &otherPID) != TCL_OK) { - opserr << "send -pid pid? data? - pid: " << argv[2] << " invalid\n"; - return TCL_ERROR; - } - - if (otherPID > -1 && otherPID != myPID && otherPID < np) { - - MPI_Send((void *)(&msgLength), 1, MPI_INT, otherPID, 0, MPI_COMM_WORLD); - MPI_Send((void *)gMsg, msgLength, MPI_CHAR, otherPID, 1, MPI_COMM_WORLD); - - } else { - opserr << "send -pid pid? data? - pid: " << otherPID << " invalid\n"; - return TCL_ERROR; - } - - } else { - if (myPID == 0) { - MPI_Bcast((void *)(&msgLength), 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast((void *)gMsg, msgLength, MPI_CHAR, 0, MPI_COMM_WORLD); - } else { - opserr << "send data - only process 0 can do a broadcast - you may need " - "to kill the application"; - return TCL_ERROR; - } - } - return TCL_OK; -} - -#endif diff --git a/SRC/runtime/commands/strings.cpp b/SRC/runtime/commands/strings.cpp index 7ff0769c4e..be1c445f43 100644 --- a/SRC/runtime/commands/strings.cpp +++ b/SRC/runtime/commands/strings.cpp @@ -6,27 +6,6 @@ // https://xara.so //===----------------------------------------------------------------------===// // -#if 0 -static const char* -classic_banner = R"( - - OpenSees -- Open System For Earthquake Engineering Simulation - Pacific Earthquake Engineering Research Center - Version 3.4.0 64-Bit - - (c) Copyright 1999-2022 The Regents of the University of California - All Rights Reserved - (Copyright and Disclaimer @ http://www.berkeley.edu/OpenSees/copyright.html) - -)"; - -static const char* -peer_banner = R"( - OpenSees -- Open System For Earthquake Engineering Simulation - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - Pacific Earthquake Engineering Research Center -)"; -#endif static const char* unicode_banner diff --git a/SRC/runtime/python/OpenSeesPyRT.cpp b/SRC/runtime/python/OpenSeesPyRT.cpp index 159df84ada..c351fa5c97 100644 --- a/SRC/runtime/python/OpenSeesPyRT.cpp +++ b/SRC/runtime/python/OpenSeesPyRT.cpp @@ -43,16 +43,6 @@ namespace py = pybind11; #define ARRAY_FLAGS py::array::c_style|py::array::forcecast -#if 0 -std::unique_ptr -getRuntime(py::object interpaddr) { - void *interp_addr; - interp_addr = (void*)PyLong_AsVoidPtr(interpaddr.ptr()); - return std::unique_ptr(G3_getRuntime((Tcl_Interp*)interp_addr)); -} // , py::return_value_policy::reference -#endif - - std::unique_ptr get_builder(py::object interpaddr) { void *interp_addr; @@ -504,22 +494,6 @@ init_obj_module(py::module &m) py::class_(m, "_Runtime") ; -#if 0 - py::class_(m, "_StaticAnalysis") - .def (py::init([](G3_Runtime *runtime, G3_Config conf) { - return *((StaticAnalysis*)runtime->newStaticAnalysis(conf)); - })) - .def ("analyze", &StaticAnalysis::analyze) - ; - - py::class_(m, "_DirectIntegrationAnalysis") - .def (py::init([](G3_Runtime *runtime, G3_Config conf) { - return *((DirectIntegrationAnalysis*)runtime->newTransientAnalysis(conf)); - })) - .def ("analyze", &DirectIntegrationAnalysis::analyze) - ; -#endif // // Module-Level Functions diff --git a/SRC/runtime/runtime/TclPackageClassBroker.cpp b/SRC/runtime/runtime/TclPackageClassBroker.cpp index c39d74cdf5..93e49b513f 100644 --- a/SRC/runtime/runtime/TclPackageClassBroker.cpp +++ b/SRC/runtime/runtime/TclPackageClassBroker.cpp @@ -547,7 +547,7 @@ TclPackageClassBroker::getNewActor(int classTag, Channel *theChannel) default: opserr << "TclPackageClassBroker::getNewActor - "; opserr << " - no ActorType type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -565,7 +565,7 @@ TclPackageClassBroker::getPtrNewPartitionedModelBuilder(Subdomain &theSubdomain, default: opserr << "TclPackageClassBroker::getPtrNewPartitionedModelBuilder - "; opserr << " - no PartitionedModelBuilder type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -583,7 +583,7 @@ TclPackageClassBroker::getPtrNewGraphNumberer(int classTag) default: opserr << "TclPackageClassBroker::getPtrNewGraphNumberer - "; opserr << " - no GraphNumberer type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -711,7 +711,7 @@ TclPackageClassBroker::getNewElement(int classTag) default: opserr << "TclPackageClassBroker::getNewElement - "; opserr << " - no Element type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -730,7 +730,7 @@ TclPackageClassBroker::getNewNode(int classTag) default: opserr << "TclPackageClassBroker::getNewNode - "; opserr << " - no Node type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -748,7 +748,7 @@ TclPackageClassBroker::getNewMP(int classTag) default: opserr << "TclPackageClassBroker::getNewMP - "; opserr << " - no MP_Constraint type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -769,7 +769,7 @@ TclPackageClassBroker::getNewSP(int classTag) default: opserr << "TclPackageClassBroker::getNewSP - "; opserr << " - no SP_Constraint type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -784,7 +784,7 @@ TclPackageClassBroker::getNewPC(int classTag) default: opserr << "TclPackageClassBroker::getNewPC - "; opserr << " - no Pressure_Constraint type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -819,7 +819,7 @@ TclPackageClassBroker::getNewElementalLoad(int classTag) default: opserr << "TclPackageClassBroker::getNewNodalLoad - "; opserr << " - no NodalLoad type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } @@ -845,7 +845,7 @@ TclPackageClassBroker::getNewCrdTransf(int classTag) default: opserr << "TclPackageClassBroker::getCrdTransf - "; opserr << " - no CrdTransf type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -908,7 +908,7 @@ TclPackageClassBroker::getNewBeamIntegration(int classTag) default: opserr << "TclPackageClassBroker::getBeamIntegration - "; opserr << " - no BeamIntegration type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1132,7 +1132,7 @@ TclPackageClassBroker::getNewUniaxialMaterial(int classTag) opserr << "TclPackageClassBroker::getNewUniaxialMaterial - "; opserr << " - no UniaxialMaterial type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1185,7 +1185,7 @@ TclPackageClassBroker::getNewSection(int classTag) default: opserr << "TclPackageClassBroker::getNewSection - "; opserr << " - no section type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1337,7 +1337,7 @@ TclPackageClassBroker::getNewNDMaterial(int classTag) default: opserr << "TclPackageClassBroker::getNewNDMaterial - "; opserr << " - no NDMaterial type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1349,7 +1349,7 @@ TclPackageClassBroker::getNewFiber(int classTag) default: opserr << "TclPackageClassBroker::getNewFiber - "; opserr << " - no Fiber type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1376,7 +1376,7 @@ TclPackageClassBroker::getNewFrictionModel(int classTag) default: opserr << "TclPackageClassBroker::getNewFrictionModel - "; opserr << " - no FrictionModel type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1412,7 +1412,7 @@ TclPackageClassBroker::getNewConvergenceTest(int classTag) default: opserr << "TclPackageClassBroker::getNewConvergenceTest - "; opserr << " - no ConvergenceTest type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1442,7 +1442,7 @@ TclPackageClassBroker::getNewLoadPattern(int classTag) default: opserr << "TclPackageClassBroker::getPtrLoadPattern - "; opserr << " - no Load type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1461,7 +1461,7 @@ TclPackageClassBroker::getNewGroundMotion(int classTag) default: opserr << "TclPackageClassBroker::getPtrGroundMotion - "; opserr << " - no Load type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1494,7 +1494,7 @@ TclPackageClassBroker::getNewTimeSeries(int classTag) default: opserr << "TclPackageClassBroker::getPtrTimeSeries - "; opserr << " - no Load type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1509,7 +1509,7 @@ TclPackageClassBroker::getNewTimeSeriesIntegrator(int classTag) default: opserr << "TclPackageClassBroker::getPtrTimeSeriesIntegrator - "; opserr << " - no Load type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1524,7 +1524,7 @@ TclPackageClassBroker::getPtrNewMatrix(int classTag, int noRows, int noCols) default: opserr << "TclPackageClassBroker::getPtrNewMatrix - "; opserr << " - no NodalLoad type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1539,7 +1539,7 @@ TclPackageClassBroker::getPtrNewVector(int classTag, int size) default: opserr << "TclPackageClassBroker::getPtrNewVector - "; opserr << " - no Vector type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1554,7 +1554,7 @@ TclPackageClassBroker::getPtrNewID(int classTag, int size) default: opserr << "TclPackageClassBroker::getPtrNewID - "; opserr << " - no ID type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1596,7 +1596,7 @@ TclPackageClassBroker::getPtrNewStream(int classTag) default: opserr << "TclPackageClassBroker::getPtrNewStream - "; opserr << " - no DataOutputHandler type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1635,7 +1635,7 @@ TclPackageClassBroker::getPtrNewRecorder(int classTag) default: opserr << "TclPackageClassBroker::getNewRecordr - "; opserr << " - no Recorder type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1665,7 +1665,7 @@ TclPackageClassBroker::getNewConstraintHandler(int classTag) default: opserr << "TclPackageClassBroker::getNewConstraintHandler - "; opserr << " - no ConstraintHandler type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1704,7 +1704,7 @@ TclPackageClassBroker::getNewEquiSolnAlgo(int classTag) default: opserr << "TclPackageClassBroker::getNewEquiSolnAlgo - "; opserr << " - no EquiSolnAlgo type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1716,7 +1716,7 @@ TclPackageClassBroker::getAccelerator(int classTag) default: opserr << "TclPackageClassBroker::getAccelerator - "; opserr << " - no EquiSolnAlgo type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1740,7 +1740,7 @@ TclPackageClassBroker::getLineSearch(int classTag) default: opserr << "TclPackageClassBroker::getNewEquiSolnAlgo - "; opserr << " - no EquiSolnAlgo type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1755,7 +1755,7 @@ TclPackageClassBroker::getNewDomainDecompAlgo(int classTag) default: opserr << "TclPackageClassBroker::getNewDomainDecompAlgo - "; opserr << " - no DomainDecompAlgo type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1766,10 +1766,6 @@ TclPackageClassBroker::getNewStaticIntegrator(int classTag) switch (classTag) { case INTEGRATOR_TAGS_LoadControl: return new LoadControl(1.0, 1, 1.0, .10); // must recvSelf -#if 0 - case INTEGRATOR_TAGS_StagedLoadControl: - return new StagedLoadControl(1.0, 1, 1.0, .10); // must recvSelf -#endif #ifdef _PARALLEL_PROCESSING case INTEGRATOR_TAGS_DistributedDisplacementControl: return new DistributedDisplacementControl(); // must recvSelf @@ -1781,7 +1777,7 @@ TclPackageClassBroker::getNewStaticIntegrator(int classTag) default: opserr << "TclPackageClassBroker::getNewStaticIntegrator - "; opserr << " - no StaticIntegrator type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1895,7 +1891,7 @@ TclPackageClassBroker::getNewTransientIntegrator(int classTag) default: opserr << "TclPackageClassBroker::getNewTransientIntegrator - "; opserr << " - no TransientIntegrator type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1921,7 +1917,7 @@ TclPackageClassBroker::getNewIncrementalIntegrator(int classTag) default: opserr << "TclPackageClassBroker::getNewIncrementalIntegrator - "; opserr << " - no IncrementalIntegrator type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } @@ -1981,7 +1977,7 @@ TclPackageClassBroker::getNewLinearSOE(int classTagSOE) default: opserr << "TclPackageClassBroker::getNewLinearSOE - "; opserr << " - no LinearSOE type exists for class tag "; - opserr << classTagSOE << endln; + opserr << classTagSOE << "\n"; return 0; } } @@ -1996,7 +1992,7 @@ TclPackageClassBroker::getNewEigenSOE(int classTagSOE) default: opserr << "TclPackageClassBroker::getNewEigenSOE - "; opserr << " - no EigenSOE type exists for class tag "; - opserr << classTagSOE << endln; + opserr << classTagSOE << "\n"; return 0; } } @@ -2024,14 +2020,14 @@ TclPackageClassBroker::getPtrNewDDLinearSOE(int classTagSOE, } else { opserr << "TclPackageClassBroker::getNewLinearSOE - "; opserr << " - no ProfileSPD Domain Solver type exists for class tag "; - opserr << classTagDDSolver << endln; + opserr << classTagDDSolver << "\n"; return 0; } default: opserr << "TclPackageClassBroker::getNewLinearSOE - "; opserr << " - no LinearSOE type exists for class tag "; - opserr << classTagSOE << endln; + opserr << classTagSOE << "\n"; return 0; } } @@ -2055,7 +2051,7 @@ TclPackageClassBroker::getNewDomainDecompAnalysis(int classTag, default: opserr << "TclPackageClassBroker::getNewDomainDecompAnalysis "; opserr << " - no DomainDecompAnalysis type exists for class tag "; - opserr << classTag << endln; + opserr << classTag << "\n"; return 0; } } From 6b4613746646b25fbe462a9fd17b890c4573b8e3 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:39:22 -0700 Subject: [PATCH 229/261] clean up --- .../domain/TclUpdateMaterialCommand.cpp | 92 ------- .../domain/TclUpdateMaterialStageCommand.cpp | 225 ------------------ SRC/runtime/commands/domain/commands.cpp | 9 +- SRC/runtime/commands/domain/commands.h | 11 +- SRC/runtime/commands/domain/domain.cpp | 10 +- SRC/runtime/commands/domain/element.cpp | 9 +- SRC/runtime/commands/domain/parameter.cpp | 10 +- SRC/runtime/commands/domain/recorder.cpp | 10 +- SRC/runtime/commands/domain/response.cpp | 10 +- SRC/runtime/commands/domain/rigid_links.cpp | 9 +- SRC/runtime/commands/domain/runtime.cpp | 10 +- SRC/runtime/commands/domain/sensitivity.cpp | 12 +- SRC/runtime/commands/domain/staging.cpp | 49 ---- SRC/runtime/commands/modeling/element.hpp | 11 +- SRC/runtime/commands/modeling/mesh.cpp | 82 ------- SRC/runtime/commands/modeling/model.cpp | 10 +- SRC/runtime/commands/modeling/printing.cpp | 10 +- SRC/runtime/commands/modeling/section.cpp | 9 +- SRC/runtime/commands/modeling/uniaxial.cpp | 9 +- .../commands/modeling/uniaxialMaterial.cpp | 9 +- SRC/runtime/commands/packages.cpp | 11 +- SRC/runtime/commands/packages.h | 10 +- SRC/runtime/commands/parallel/CMakeLists.txt | 2 - SRC/runtime/commands/parallel/communicate.cpp | 16 +- SRC/runtime/commands/parallel/machine.cpp | 12 +- SRC/runtime/commands/parallel/partition.cpp | 10 +- SRC/runtime/commands/parallel/sequential.cpp | 10 +- SRC/runtime/commands/strings.cpp | 9 +- SRC/runtime/commands/utilities/formats.cpp | 10 +- .../utilities/{linalg.hh => linalg.h} | 16 +- SRC/runtime/commands/utilities/progress.cpp | 10 +- .../commands/utilities/sdofResponse.cpp | 10 +- SRC/runtime/commands/utilities/txt2bin.cpp | 15 ++ SRC/runtime/commands/utilities/utilities.cpp | 17 +- SRC/runtime/parsing/InputAPI.h | 15 ++ SRC/runtime/parsing/InterpreterAPI.cpp | 9 +- SRC/runtime/runtime/BasicAnalysisBuilder.cpp | 9 +- SRC/runtime/runtime/BasicModelBuilder.h | 10 +- SRC/runtime/runtime/G3_Runtime.h | 9 +- SRC/runtime/runtime/Notes.md | 91 ------- SRC/runtime/runtime/TclPackageClassBroker.cpp | 13 +- SRC/runtime/runtime/TclPackageClassBroker.h | 11 +- 42 files changed, 351 insertions(+), 580 deletions(-) delete mode 100644 SRC/runtime/commands/domain/TclUpdateMaterialCommand.cpp delete mode 100644 SRC/runtime/commands/domain/TclUpdateMaterialStageCommand.cpp delete mode 100644 SRC/runtime/commands/domain/staging.cpp delete mode 100644 SRC/runtime/commands/modeling/mesh.cpp rename SRC/runtime/commands/utilities/{linalg.hh => linalg.h} (95%) delete mode 100644 SRC/runtime/runtime/Notes.md diff --git a/SRC/runtime/commands/domain/TclUpdateMaterialCommand.cpp b/SRC/runtime/commands/domain/TclUpdateMaterialCommand.cpp deleted file mode 100644 index 869ae1abd4..0000000000 --- a/SRC/runtime/commands/domain/TclUpdateMaterialCommand.cpp +++ /dev/null @@ -1,92 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// -//===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// -// Description: This command is used to update the parameters of -// PressureDependMultiYield or PressureIndependMultiYield material. Currently, -// two material parameters, reference low-strain shear modulus Gr and reference -// bulk modulus Br, can be modified during an analysis. -// -// Written: fmk -// -#include -#include -#include -#include -// #include -#include - - -int -TclCommand_UpdateMaterialsCommand(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain* theDomain = static_cast(clientData); - - if (argc < 5) { - opserr << "WARNING insufficient number of UpdateMaterialStage arguments\n"; - opserr << "Want: UpdateMaterialStage material matTag? stage value?" - << "\n"; - return TCL_ERROR; - } - - if (strcmp(argv[1], "-material") != 0) { - opserr << "WARNING UpdateMaterialStage: Only accept parameter '-material' " - "for now" - << "\n"; - return TCL_ERROR; - } - - int materialTag, value; - double valueD; - - if (Tcl_GetInt(interp, argv[2], &materialTag) != TCL_OK) { - opserr << "WARNING MYSstage: invalid material tag" << "\n"; - return TCL_ERROR; - } - - int parTag = theDomain->getNumParameters(); - parTag++; - - if (argc > 5) { - if (strcmp(argv[5], "-parameter") == 0) { - if (Tcl_GetInt(interp, argv[6], &parTag) != TCL_OK) { - opserr << "WARNING UpdateMaterialStage: invalid parameter tag" << "\n"; - return TCL_ERROR; - } - } - } - - MatParameter *theParameter = new MatParameter(parTag, materialTag, argv[3]); - - if (theDomain->addParameter(theParameter) == false) { - opserr << "WARNING could not add updateMaterialStage - " - "MaterialStageParameter to domain" - << "\n"; - return TCL_ERROR; - } - - int res = 0; - if (Tcl_GetInt(interp, argv[4], &value) != TCL_OK) { - - if (Tcl_GetDouble(interp, argv[4], &valueD) != TCL_OK) { - opserr << "WARNING UpdateMaterialStage: could not read value" << "\n"; - return TCL_ERROR; - } else { - - res = theDomain->updateParameter(parTag, valueD); - - theDomain->removeParameter(parTag); - } - } else { - - res = theDomain->updateParameter(parTag, value); - - theDomain->removeParameter(parTag); - } - return res; -} diff --git a/SRC/runtime/commands/domain/TclUpdateMaterialStageCommand.cpp b/SRC/runtime/commands/domain/TclUpdateMaterialStageCommand.cpp deleted file mode 100644 index e77b1ee810..0000000000 --- a/SRC/runtime/commands/domain/TclUpdateMaterialStageCommand.cpp +++ /dev/null @@ -1,225 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// -//===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// -// Description: This command is used to update the following materials: -// - PressureDependMultiYield, -// - PressureDependMultiYield02, -// - PressureIndependMultiYield, or -// - FluidSolidPorous -// -// To conduct a seismic analysis, two stages should be followed. -// First, during the application of gravity load (and static loads if any), set -// material stage to 0, and material behavior is linear elastic (with Gr and Br -// as elastic moduli). A FluidSolidPorous material does not contribute to the -// material response if its stage is set to 0. After the application of gravity -// load, set material stage to 1 or 2. In case of stage 2, all the elastic -// material properties are then internally determined at the current effective -// confinement, and remain constant thereafter. In the subsequent dynamic -// (fast) loading phase(s), the deviatoric stress-strain response is -// elastic-plastic (stage 1) or linear-elastic (stage 2), and the volumetric -// response remains linear-elastic. Please visit -// http://cyclic.ucsd.edu/opensees for examples. -// -// Written: ZHY -// -// $Revision: 1.16 $ -// $Date: 2007-10-16 00:15:07 $ -// -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -int -TclCommand_updateMaterialStage(ClientData clientData, - Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - - // UpdateMaterialStage material matTag? stage value? - - BasicModelBuilder* builder = (BasicModelBuilder*)clientData; - Domain* domain = builder->getDomain(); - - if (argc < 5) { - opserr << "WARNING insufficient number of UpdateMaterialStage arguments" - << "\n"; - return TCL_ERROR; - } - - if (strcmp(argv[1], "-material") != 0) { - opserr << "WARNING unknown argument " << argv[1] - << "\n"; - return TCL_ERROR; - } - - int materialTag, value; - - if (Tcl_GetInt(interp, argv[2], &materialTag) != TCL_OK) { - opserr << "WARNING MYSstage: invalid material tag" - << "\n"; - return TCL_ERROR; - } - - int parTag = domain->getNumParameters(); - parTag++; - - if (argc > 6) { - // updateMaterialStage -material matTag? ? ? -parameter $tag? - if (strcmp(argv[5], "-parameter") == 0) { - if (Tcl_GetInt(interp, argv[6], &parTag) != TCL_OK) { - opserr << "WARNING UpdateMaterialStage: invalid parameter tag used" - << "\n"; - return TCL_ERROR; - } - } - } - - - MaterialStageParameter *theParameter = new MaterialStageParameter(parTag, materialTag); - if (domain->addParameter(theParameter) == false) { - opserr << "WARNING could not add updateMaterialStage - " - "MaterialStageParameter to domain" - << "\n"; - return TCL_ERROR; - } - - if (strcmp(argv[3], "-stage") != 0) { - opserr - << "WARNING UpdateMaterialStage: Only accept parameter '-stage' for now" - << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[4], &value) != TCL_OK) { - opserr << "WARNING UpdateMaterialStage: invalid parameter value" << "\n"; - return TCL_ERROR; - } - - domain->updateParameter(parTag, value); - - domain->removeParameter(parTag); - - delete theParameter; - - return TCL_OK; -} - - -int -TclBasicBuilderUpdateParameterCommand(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char ** const argv) -{ - - BasicModelBuilder* builder = (BasicModelBuilder*)clientData; - - if (argc < 5) { - opserr << "WARNING insufficient number of updateParameter arguments\n"; - opserr << "Want: updateParameter -material matNum? -param? newValue?" - << "\n"; - return TCL_ERROR; - } - - if (strcmp(argv[1], "-material") != 0) { - opserr - << "WARNING UpdateParameter: Only accept parameter '-material' for now" - << "\n"; - return TCL_ERROR; - } - - int tag, id; - double value; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING UpdateParameter: invalid material tag" << "\n"; - return TCL_ERROR; - } - - // TODO: This will print an error message if not found; maybe - // getTypedObject should accept flag that tells it not to print - NDMaterial *a = builder->getTypedObject(tag); - - if (a == 0) { - // opserr << "WARNING UpdateParameter: couldn't get NDmaterial tagged: " << - // tag << "\n"; return TCL_ERROR; - UniaxialMaterial *a = builder->getTypedObject(tag); - if (a == 0) { - opserr - << "WARNING UpdateParameter: couldn't get Uniaxialmaterial tagged: " - << tag << "\n"; - return TCL_ERROR; - } - if (strcmp(argv[3], "-E") == 0) { - if (Tcl_GetDouble(interp, argv[4], &value) != TCL_OK) { - opserr << "WARNING UpdateParameter: invalid parameter value" << "\n"; - return TCL_ERROR; - } - Information info; - info.setDouble(value); - a->updateParameter(0, info); - } else if (strcmp(argv[3], "-fy") == 0) { - if (Tcl_GetDouble(interp, argv[4], &value) != TCL_OK) { - opserr << "WARNING UpdateParameter: invalid parameter value" << "\n"; - return TCL_ERROR; - } - Information info; - info.setDouble(value); - a->updateParameter(1, info); - } else { - opserr << "WARNING UpdateParameter: Only accept parameter '-E' or '-fy' " - "for now" - << "\n"; - return TCL_ERROR; - } - return TCL_OK; - } - - if (strcmp(argv[3], "-refG") == 0) - id = 10; - else if (strcmp(argv[3], "-refB") == 0) - id = 11; - else { - opserr << "WARNING UpdateParameter: Only accept parameter '-refG' or " - "'-refB' for now" - << "\n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &value) != TCL_OK) { - opserr << "WARNING UpdateParameter: invalid parameter value" << "\n"; - return TCL_ERROR; - } - - const char *c = a->getType(); - - if (strcmp(c, "PlaneStrain") == 0 || strcmp(c, "ThreeDimensional") == 0) { - Information info; - info.setDouble(value); - a->updateParameter(id, info); - } else { - opserr << "WARNING UpdateParameter: The tagged is not a " << "\n"; - opserr << "PressureDependMultiYield/PressureIndependMultiYield/" - "FluidSolidPorous material. " - << "\n"; - return TCL_ERROR; - } - - return TCL_OK; -} diff --git a/SRC/runtime/commands/domain/commands.cpp b/SRC/runtime/commands/domain/commands.cpp index ac3c02fff7..b35d00a0fc 100644 --- a/SRC/runtime/commands/domain/commands.cpp +++ b/SRC/runtime/commands/domain/commands.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Description: This file contains the functions that will be called by diff --git a/SRC/runtime/commands/domain/commands.h b/SRC/runtime/commands/domain/commands.h index 5d509df6b7..ea8953c42e 100644 --- a/SRC/runtime/commands/domain/commands.h +++ b/SRC/runtime/commands/domain/commands.h @@ -1,11 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// - +// // domain/node.cpp Tcl_CmdProc nodeCoord; Tcl_CmdProc nodeDOFs; diff --git a/SRC/runtime/commands/domain/domain.cpp b/SRC/runtime/commands/domain/domain.cpp index 01dead67d4..3712f30e7f 100644 --- a/SRC/runtime/commands/domain/domain.cpp +++ b/SRC/runtime/commands/domain/domain.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // Description: Domain manipulation commands which do not require // additional namespacing. // diff --git a/SRC/runtime/commands/domain/element.cpp b/SRC/runtime/commands/domain/element.cpp index 522f38c325..6cf6661b3a 100644 --- a/SRC/runtime/commands/domain/element.cpp +++ b/SRC/runtime/commands/domain/element.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // #include diff --git a/SRC/runtime/commands/domain/parameter.cpp b/SRC/runtime/commands/domain/parameter.cpp index 5017198462..bd608b66ba 100644 --- a/SRC/runtime/commands/domain/parameter.cpp +++ b/SRC/runtime/commands/domain/parameter.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// #include #include #include diff --git a/SRC/runtime/commands/domain/recorder.cpp b/SRC/runtime/commands/domain/recorder.cpp index 095329c4bd..bd30261f35 100644 --- a/SRC/runtime/commands/domain/recorder.cpp +++ b/SRC/runtime/commands/domain/recorder.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // Description: This file contains the function that is invoked // by the interpreter when the comand 'record' is invoked by the // user. diff --git a/SRC/runtime/commands/domain/response.cpp b/SRC/runtime/commands/domain/response.cpp index 18a7e28368..a309498b5c 100644 --- a/SRC/runtime/commands/domain/response.cpp +++ b/SRC/runtime/commands/domain/response.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// #include #include #include diff --git a/SRC/runtime/commands/domain/rigid_links.cpp b/SRC/runtime/commands/domain/rigid_links.cpp index de6426da40..2f4a153a8f 100644 --- a/SRC/runtime/commands/domain/rigid_links.cpp +++ b/SRC/runtime/commands/domain/rigid_links.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Author: fmk, cmp diff --git a/SRC/runtime/commands/domain/runtime.cpp b/SRC/runtime/commands/domain/runtime.cpp index 4fb42d0e07..63479af404 100644 --- a/SRC/runtime/commands/domain/runtime.cpp +++ b/SRC/runtime/commands/domain/runtime.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // These commands expect a Domain* as their clientData. // // Written: cmp diff --git a/SRC/runtime/commands/domain/sensitivity.cpp b/SRC/runtime/commands/domain/sensitivity.cpp index 1a83960d23..32a0b34437 100644 --- a/SRC/runtime/commands/domain/sensitivity.cpp +++ b/SRC/runtime/commands/domain/sensitivity.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// #include #include diff --git a/SRC/runtime/commands/domain/staging.cpp b/SRC/runtime/commands/domain/staging.cpp deleted file mode 100644 index 5eec8ead18..0000000000 --- a/SRC/runtime/commands/domain/staging.cpp +++ /dev/null @@ -1,49 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// -//===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// -int -elementActivate(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain* the_domain = (Domain*)clientData; - - int eleTag; - int argLoc = 1; - int Nelements = argc; - ID activate_us(0, Nelements); - - while (argLoc < argc && Tcl_GetInt(interp, argv[argLoc], &eleTag) == TCL_OK) { - activate_us.insert(eleTag); - ++argLoc; - } - - the_domain->activateElements(activate_us); - - return TCL_OK; -} - -int -elementDeactivate(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - Domain* the_domain = (Domain*)clientData; - - int eleTag; - int argLoc = 1; - int Nelements = argc; - ID deactivate_us(0, Nelements); - - while (argLoc < argc && Tcl_GetInt(interp, argv[argLoc], &eleTag) == TCL_OK) { - deactivate_us.insert(eleTag); - ++argLoc; - } - - the_domain->deactivateElements(deactivate_us); - return TCL_OK; -} diff --git a/SRC/runtime/commands/modeling/element.hpp b/SRC/runtime/commands/modeling/element.hpp index a61ccf54dc..8a66c8c174 100644 --- a/SRC/runtime/commands/modeling/element.hpp +++ b/SRC/runtime/commands/modeling/element.hpp @@ -1,6 +1,15 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // //===----------------------------------------------------------------------===// // diff --git a/SRC/runtime/commands/modeling/mesh.cpp b/SRC/runtime/commands/modeling/mesh.cpp deleted file mode 100644 index 6784d419a3..0000000000 --- a/SRC/runtime/commands/modeling/mesh.cpp +++ /dev/null @@ -1,82 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// OpenSees - Open System for Earthquake Engineering Simulation -// -//===----------------------------------------------------------------------===// -// -// -extern int OPS_LineMesh(Domain& domain, int ndm); -extern int OPS_TriMesh(Domain& domain); -extern int OPS_TriReMesh(Domain& domain, int ndf); - -int -TclCommand_mesh(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - assert(clientData != nullptr); - - // make sure corect number of arguments on command line - if (argc < 2) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: mesh type? ...>\n"; - return TCL_ERROR; - } - - OPS_ResetInput(clientData, interp, 2, argc, argv, theTclDomain, - theTclBuilder); - - // mesh type - int res = 0; - // if (strcmp(argv[1], "line") == 0) { - // res = OPS_LineMesh(*theTclDomain,ndm); - // } else if (strcmp(argv[1], "tri") == 0) { - // res = OPS_TriMesh(*theTclDomain); - // } else { - // opserr<<"WARNING: mesh type "<\n"; - return TCL_ERROR; - } - - OPS_ResetInput(clientData, interp, 2, argc, argv, theTclDomain, - theTclBuilder); - - // mesh type - int res = 0; - if (strcmp(argv[1], "line") == 0) { - //res = OPS_LineMesh(*theTclDomain,ndm); - } else if (strcmp(argv[1], "tri") == 0) { - res = OPS_TriReMesh(*theTclDomain,ndf); - } else { - opserr<<"WARNING: remesh type "< #include #include diff --git a/SRC/runtime/commands/parallel/machine.cpp b/SRC/runtime/commands/parallel/machine.cpp index 25c17d4403..9379b450c1 100644 --- a/SRC/runtime/commands/parallel/machine.cpp +++ b/SRC/runtime/commands/parallel/machine.cpp @@ -1,8 +1,18 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara +// https://xara.so // //===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// #include #include #include diff --git a/SRC/runtime/commands/parallel/partition.cpp b/SRC/runtime/commands/parallel/partition.cpp index d2f628b19a..5886b30917 100644 --- a/SRC/runtime/commands/parallel/partition.cpp +++ b/SRC/runtime/commands/parallel/partition.cpp @@ -1,11 +1,19 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // +// #include #include #include diff --git a/SRC/runtime/commands/parallel/sequential.cpp b/SRC/runtime/commands/parallel/sequential.cpp index 8d40c79c9e..06b34dc996 100644 --- a/SRC/runtime/commands/parallel/sequential.cpp +++ b/SRC/runtime/commands/parallel/sequential.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // Description: This unit contains implementations of parallel commands // for use in non-parallel interpreters // diff --git a/SRC/runtime/commands/strings.cpp b/SRC/runtime/commands/strings.cpp index be1c445f43..9d9bfb7c63 100644 --- a/SRC/runtime/commands/strings.cpp +++ b/SRC/runtime/commands/strings.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // diff --git a/SRC/runtime/commands/utilities/formats.cpp b/SRC/runtime/commands/utilities/formats.cpp index 147513132b..455c6fb001 100644 --- a/SRC/runtime/commands/utilities/formats.cpp +++ b/SRC/runtime/commands/utilities/formats.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // Description: This file provides basic file format handling commands, // such as naive XML processing and binary conversion. // diff --git a/SRC/runtime/commands/utilities/linalg.hh b/SRC/runtime/commands/utilities/linalg.h similarity index 95% rename from SRC/runtime/commands/utilities/linalg.hh rename to SRC/runtime/commands/utilities/linalg.h index 7ad4ada106..5674718228 100644 --- a/SRC/runtime/commands/utilities/linalg.hh +++ b/SRC/runtime/commands/utilities/linalg.h @@ -1,4 +1,18 @@ - +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// const char *linalg[] = {R"END( namespace eval OpenSees { namespace export verify diff --git a/SRC/runtime/commands/utilities/progress.cpp b/SRC/runtime/commands/utilities/progress.cpp index 44d42b96e2..f9d96620ff 100644 --- a/SRC/runtime/commands/utilities/progress.cpp +++ b/SRC/runtime/commands/utilities/progress.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // Description: This file provides progress bar functionality to the // interpreter. // diff --git a/SRC/runtime/commands/utilities/sdofResponse.cpp b/SRC/runtime/commands/utilities/sdofResponse.cpp index 80787eecc3..4c9bb8156c 100644 --- a/SRC/runtime/commands/utilities/sdofResponse.cpp +++ b/SRC/runtime/commands/utilities/sdofResponse.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // ============= ==================================================== // m mass // zeta damping ratio diff --git a/SRC/runtime/commands/utilities/txt2bin.cpp b/SRC/runtime/commands/utilities/txt2bin.cpp index c5a3ac4ad5..b29076c636 100644 --- a/SRC/runtime/commands/utilities/txt2bin.cpp +++ b/SRC/runtime/commands/utilities/txt2bin.cpp @@ -1,3 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// #include #include #include diff --git a/SRC/runtime/commands/utilities/utilities.cpp b/SRC/runtime/commands/utilities/utilities.cpp index 4fc3633ccb..6333d0ecd8 100644 --- a/SRC/runtime/commands/utilities/utilities.cpp +++ b/SRC/runtime/commands/utilities/utilities.cpp @@ -1,5 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// #include -#include "utilities/linalg.hh" +#include "utilities/linalg.h" int init_g3_tcl_utils(Tcl_Interp* interp) { diff --git a/SRC/runtime/parsing/InputAPI.h b/SRC/runtime/parsing/InputAPI.h index 929e3018d7..9e1931adc1 100644 --- a/SRC/runtime/parsing/InputAPI.h +++ b/SRC/runtime/parsing/InputAPI.h @@ -1,3 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// #ifndef G3PARSE_H #define G3PARSE_H #ifndef G3_RUNTIME_H diff --git a/SRC/runtime/parsing/InterpreterAPI.cpp b/SRC/runtime/parsing/InterpreterAPI.cpp index 17d3e531db..6fe584bc2a 100644 --- a/SRC/runtime/parsing/InterpreterAPI.cpp +++ b/SRC/runtime/parsing/InterpreterAPI.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // #include diff --git a/SRC/runtime/runtime/BasicAnalysisBuilder.cpp b/SRC/runtime/runtime/BasicAnalysisBuilder.cpp index 34063dafc7..59c8703adc 100644 --- a/SRC/runtime/runtime/BasicAnalysisBuilder.cpp +++ b/SRC/runtime/runtime/BasicAnalysisBuilder.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Written: Claudio Perez diff --git a/SRC/runtime/runtime/BasicModelBuilder.h b/SRC/runtime/runtime/BasicModelBuilder.h index ad2e48274e..e2a8291b71 100644 --- a/SRC/runtime/runtime/BasicModelBuilder.h +++ b/SRC/runtime/runtime/BasicModelBuilder.h @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // Description: This file contains the class definition for // BasicModelBuilder. A BasicModelBuilder aims to be a threadsafe // alternative to the TclBasicBuilder class. This class adds the commands to diff --git a/SRC/runtime/runtime/G3_Runtime.h b/SRC/runtime/runtime/G3_Runtime.h index b9b712b1ba..1c5002b787 100644 --- a/SRC/runtime/runtime/G3_Runtime.h +++ b/SRC/runtime/runtime/G3_Runtime.h @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // written: cmp diff --git a/SRC/runtime/runtime/Notes.md b/SRC/runtime/runtime/Notes.md deleted file mode 100644 index 946c67fdc9..0000000000 --- a/SRC/runtime/runtime/Notes.md +++ /dev/null @@ -1,91 +0,0 @@ - - -- `LibraryBroker` - - -``` - static library = G3_Library( - LibraryBroker(&uniaxial_material_library), - LibraryBroker(&multiaxial_material_library), - ); - -read -parse -build -define -broker -invoke call -create make new -insert save add -delete wipe del -update - -remove wipe clean - read build get - scan - show - load - dump - clear - count - erase - print - - -del -add -get -set -put -log -let -new - -->callObj(tag, task, resp) -> state -->callObj(obj, task, resp) -->makeObj(tag) -->readObj(argc, argv) -> Obj* - -->saveObj(obj) -->wipeObj(tag) - -->pullObj(obj) -->yankObj(obj) - - - static broker = G3_Broker(library); - - T* library->readNew(builder*, argc, argv); - library->makeNew(); - - -newObj(tag) -getObj(argc, argv); -addObj(getObj(argc, argv)); - - - G3_RuntimeBroker(library) - - - - - G3_ModelBuilder() - model_builder->makeNew(inst_tag) - model_builder->tag(X*) - model_builder->readNew(argc, argv); - - - runtime_broker->newEmpty(class_tag); -``` - - - - -ElemRoutine(rt, state, task, argc, argv) - - - - - - - - diff --git a/SRC/runtime/runtime/TclPackageClassBroker.cpp b/SRC/runtime/runtime/TclPackageClassBroker.cpp index 93e49b513f..99e58f829e 100644 --- a/SRC/runtime/runtime/TclPackageClassBroker.cpp +++ b/SRC/runtime/runtime/TclPackageClassBroker.cpp @@ -1,16 +1,23 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// -// Purpose: This file contains the class definition for TclPackageClassBroker. +// +// Description: This file contains the class definition for TclPackageClassBroker. // TclPackageClassBroker is is an object broker class that is meant to become // a threadsafe replacement for the BrokerAllClasses class. // All methods are virtual to allow for subclasses; which can be // used by programmers when introducing new subclasses of the main objects. -//===----------------------------------------------------------------------===// // #ifdef _PARALLEL_PROCESSING # include diff --git a/SRC/runtime/runtime/TclPackageClassBroker.h b/SRC/runtime/runtime/TclPackageClassBroker.h index 2f1d483827..9e76082803 100644 --- a/SRC/runtime/runtime/TclPackageClassBroker.h +++ b/SRC/runtime/runtime/TclPackageClassBroker.h @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // Written: cmp // Revision: A // @@ -13,7 +21,6 @@ // method. All methods are virtual to allow for subclasses; which can be // used by programmers when introducing new subclasses of the main objects. // -// What: "@(#) TclPackageClassBroker.h, revA" #ifndef TclPackageClassBroker_h #define TclPackageClassBroker_h From 55e9745c656b7e17f2da3568d5f099a5ca7282e6 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:40:44 -0700 Subject: [PATCH 230/261] clean up --- .../runtime/legacy/Renderer/CMakeLists.txt | 20 -- .../runtime/legacy/Renderer/ColorMap.h | 58 ----- .../runtime/legacy/Renderer/PlainMap.cpp | 208 ------------------ .../runtime/legacy/Renderer/PlainMap.h | 64 ------ .../runtime/legacy/Renderer/Renderer.cpp | 205 ----------------- .../runtime/legacy/Renderer/Renderer.h | 97 -------- 6 files changed, 652 deletions(-) delete mode 100644 SRC/runtime/runtime/legacy/Renderer/CMakeLists.txt delete mode 100644 SRC/runtime/runtime/legacy/Renderer/ColorMap.h delete mode 100644 SRC/runtime/runtime/legacy/Renderer/PlainMap.cpp delete mode 100644 SRC/runtime/runtime/legacy/Renderer/PlainMap.h delete mode 100644 SRC/runtime/runtime/legacy/Renderer/Renderer.cpp delete mode 100644 SRC/runtime/runtime/legacy/Renderer/Renderer.h diff --git a/SRC/runtime/runtime/legacy/Renderer/CMakeLists.txt b/SRC/runtime/runtime/legacy/Renderer/CMakeLists.txt deleted file mode 100644 index 8e4f4a30df..0000000000 --- a/SRC/runtime/runtime/legacy/Renderer/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -#============================================================================== -# -# OpenSees -- Open System For Earthquake Engineering Simulation -# Pacific Earthquake Engineering Research Center -# -#============================================================================== - - -add_library(OPS_Renderer OBJECT EXCLUDE_FROM_ALL) - -target_sources(OPS_Renderer - PRIVATE - PlainMap.cpp - Renderer.cpp - PUBLIC - PlainMap.h - Renderer.h -) - -target_include_directories(OPS_Renderer PUBLIC ${CMAKE_CURRENT_LIST_DIR}) diff --git a/SRC/runtime/runtime/legacy/Renderer/ColorMap.h b/SRC/runtime/runtime/legacy/Renderer/ColorMap.h deleted file mode 100644 index 9c86cbdbe1..0000000000 --- a/SRC/runtime/runtime/legacy/Renderer/ColorMap.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -// $Revision: 1.2 $ -// $Date: 2001-07-26 00:56:05 $ -// $Source: /usr/local/cvs/OpenSees/SRC/renderer/ColorMap.h,v $ - - -// File: ~/graphics/ColorMap.h -// -// Written: fmk -// Created: 10/98 -// Revision: A -// -// Description: This file contains the class definition for ColorMap. -// ColorMap is an abstract base class. An ColorMap object is used -// to determine the r,g,b values given an input value. -// -// What: "@(#) ColorMap.h, revA" - -#ifndef ColorMap_h -#define ColorMap_h - -class ColorMap -{ - public: - ColorMap() {}; - virtual ~ColorMap() {}; - virtual float getRed(float value) =0; - virtual float getGreen(float value) =0; - virtual float getBlue(float value) =0; - virtual int getRGB(float value, float &red, float &green, float &blue) =0; - virtual int startImage() =0; - protected: - - private: -}; - - -#endif - diff --git a/SRC/runtime/runtime/legacy/Renderer/PlainMap.cpp b/SRC/runtime/runtime/legacy/Renderer/PlainMap.cpp deleted file mode 100644 index b945edf975..0000000000 --- a/SRC/runtime/runtime/legacy/Renderer/PlainMap.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -// $Revision: 1.3 $ -// $Date: 2003-02-14 23:01:58 $ -// $Source: /usr/local/cvs/OpenSees/SRC/renderer/PlainMap.cpp,v $ - -// Written: fmk -// Created: 10/98 -// -// Description: This file contains the class definition for PlainMap. -// PlainMap is an abstract base class. An PlainMap object is used -// to determine the r,g,b values given an input value. -// -// What: "@(#) PlainMap.h, revA" - -#include "PlainMap.h" -#include -#include -#include - -static float jet[64*3] = { - 0, 0, 0.5625, - 0, 0, 0.6250, - 0, 0, 0.6875, - 0, 0, 0.7500, - 0, 0, 0.8125, - 0, 0, 0.8750, - 0, 0, 0.9375, - 0, 0, 1.0000, - 0, 0.0625, 1.0000, - 0, 0.1250, 1.0000, - 0, 0.1875, 1.0000, - 0, 0.2500, 1.0000, - 0, 0.3125, 1.0000, - 0, 0.3750, 1.0000, - 0, 0.4375, 1.0000, - 0, 0.5000, 1.0000, - 0, 0.5625, 1.0000, - 0, 0.6250, 1.0000, - 0, 0.6875, 1.0000, - 0, 0.7500, 1.0000, - 0, 0.8125, 1.0000, - 0, 0.8750, 1.0000, - 0, 0.9375, 1.0000, - 0, 1.0000, 1.0000, - 0.0625, 1.0000, 1.0000, - 0.1250, 1.0000, 0.9375, - 0.1875, 1.0000, 0.8750, - 0.2500, 1.0000, 0.8125, - 0.3125, 1.0000, 0.7500, - 0.3750, 1.0000, 0.6875, - 0.4375, 1.0000, 0.6250, - 0.5000, 1.0000, 0.5625, - 0.5625, 1.0000, 0.5000, - 0.6250, 1.0000, 0.4375, - 0.6875, 1.0000, 0.3750, - 0.7500, 1.0000, 0.3125, - 0.8125, 1.0000, 0.2500, - 0.8750, 1.0000, 0.1875, - 0.9375, 1.0000, 0.1250, - 1.0000, 1.0000, 0.0625, - 1.0000, 1.0000, 0, - 1.0000, 0.9375, 0, - 1.0000, 0.8750, 0, - 1.0000, 0.8125, 0, - 1.0000, 0.7500, 0, - 1.0000, 0.6875, 0, - 1.0000, 0.6250, 0, - 1.0000, 0.5625, 0, - 1.0000, 0.5000, 0, - 1.0000, 0.4375, 0, - 1.0000, 0.3750, 0, - 1.0000, 0.3125, 0, - 1.0000, 0.2500, 0, - 1.0000, 0.1875, 0, - 1.0000, 0.1250, 0, - 1.0000, 0.0625, 0, - 1.0000, 0, 0, - 0.9375, 0, 0, - 0.8750, 0, 0, - 0.8125, 0, 0, - 0.7500, 0, 0, - 0.6875, 0, 0, - 0.6250, 0, 0, - 0.5625, 0, 0}; - - - -PlainMap::PlainMap() - :max(0.0), min(0.0), maxLast(0.0), minLast(0.0) -{ - data = jet; - sizeData = 64; -} - - -float -PlainMap::getRed(float value){ - if (value > max) - max = value; - else if (value < min) - min = value; - - if (maxLast == minLast) { - int index = sizeData/2; - return data[index*3-3]; - - } else if (value > maxLast) - return data[sizeData*3-3]; - else if (value < minLast) - return data[0]; - else { - int index = (floor)((value-minLast)*sizeData/((maxLast-minLast))); - return data[index*3-3]; - } - - return 0.0; -} - - -float -PlainMap::getGreen(float value) { - if (value > max) - max = value; - else if (value < min) - min = value; - - if (maxLast == minLast) { - int index = sizeData/2; - return data[index*3-2]; - - } else if (value > maxLast) - return data[sizeData*3-2]; - else if (value < minLast) - return data[1]; - else { - int index = (floor)((value-minLast)*sizeData/((maxLast-minLast))); - return data[index*3-2]; - } - - return 0.0; -} - -float -PlainMap::getBlue(float value) { - if (value > max) - max = value; - else if (value < min) - min = value; - - if (maxLast == minLast) { - int index = sizeData/2; - return data[index*3-1]; - - } else if (value > maxLast) - return data[sizeData*3-1]; - else if (value < minLast) - return data[2]; - else { - int index = (floor)((value-minLast)*sizeData/((maxLast-minLast))); - return data[index*3-1]; - } - - return 0.0; -} - -int -PlainMap::getRGB(float value, float &red, float &blue, float &green) { - red = this->getRed(value); - green = this->getGreen(value); - blue = this->getBlue(value); - return 0; -} - - - -int -PlainMap::startImage() -{ - maxLast = max; - minLast = min; - max = 0; - min = 0; - - if (maxLast > -minLast) - maxLast = -minLast; - if (minLast < -maxLast) - minLast = -maxLast; - return 0; -} diff --git a/SRC/runtime/runtime/legacy/Renderer/PlainMap.h b/SRC/runtime/runtime/legacy/Renderer/PlainMap.h deleted file mode 100644 index 5436ff1c8c..0000000000 --- a/SRC/runtime/runtime/legacy/Renderer/PlainMap.h +++ /dev/null @@ -1,64 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -// $Revision: 1.2 $ -// $Date: 2001-07-26 00:56:05 $ -// $Source: /usr/local/cvs/OpenSees/SRC/renderer/PlainMap.h,v $ - - -// File: ~/graphics/PlainMap.h -// -// Written: fmk -// Created: 10/98 -// Revision: A -// -// Description: This file contains the class definition for PlainMap. -// PlainMap is an abstract base class. An PlainMap object is used -// to determine the r,g,b values given an input value. -// -// What: "@(#) PlainMap.h, revA" - -#ifndef PlainMap_h -#define PlainMap_h - -#include "ColorMap.h" - -class PlainMap: public ColorMap -{ - public: - PlainMap(); - float getRed(float value); - float getGreen(float value); - float getBlue(float value); - int getRGB(float value, float &red, float &green, float &blue); - int startImage(); - - protected: - - private: - float max, min; - float maxLast, minLast; - float *data; - int sizeData; -}; - - -#endif - diff --git a/SRC/runtime/runtime/legacy/Renderer/Renderer.cpp b/SRC/runtime/runtime/legacy/Renderer/Renderer.cpp deleted file mode 100644 index 9c362cd047..0000000000 --- a/SRC/runtime/runtime/legacy/Renderer/Renderer.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ****************************************************************** */ -// -// Written: fmk -// Created: 10/98 -// Revision: A -// -// Description: This file contains the class interface for Renderer. -// Renderer is an abstract base class. An Renderer object is used -// to create an image of the domain. -// -#include "Renderer.h" -#include "ColorMap.h" -#include -#include - -#include -#include - -#include - -int Renderer::numRenderers(0); -char **Renderer::theTitles =0; -Renderer **Renderer::theRenderers =0; - -Renderer::Renderer(ColorMap &_theMap) - :theMap(&_theMap) -{ - -} - - -Renderer::Renderer(const char *title, ColorMap &_theMap) - :theMap(&_theMap) -{ - int loc = -1; - - // look for an empty slot - for (int i=0; isaveImage(fileName); - - return 0; -} - -int -Renderer::drawVector(const Vector &position, const Vector &value, double factor, int tag) -{ - return 0; -} - - -void -Renderer::setColorMap(ColorMap &map) -{ - theMap = ↦ -} - -int -Renderer::drawCube(const Matrix &points, const Vector &values, int tag, int mode) -{ - - static Matrix polyData(4,3); - static Vector polyValues(4); - // draw the 6 faces - - int a,b,c,d; - - a=2; b=3; c=7; d=6; - for (int i=0; i<3; i++) { - polyData(0,i) = points(a,i); - polyData(1,i) = points(b,i); - polyData(2,i) = points(c,i); - polyData(3,i) = points(d,i); - } - polyValues(0) = values(a); - polyValues(1) = values(b); - polyValues(2) = values(c); - polyValues(3) = values(d); - this->drawPolygon(polyData, polyValues, tag, mode); - - a=5; b=4; c=0; d=1; - for (int i=0; i<3; i++) { - polyData(0,i) = points(a,i); - polyData(1,i) = points(b,i); - polyData(2,i) = points(c,i); - polyData(3,i) = points(d,i); - } - polyValues(0) = values(a); - polyValues(1) = values(b); - polyValues(2) = values(c); - polyValues(3) = values(d); - this->drawPolygon(polyData, polyValues, tag, mode); - - a=6; b=7; c=4; d=5; - for (int i=0; i<3; i++) { - polyData(0,i) = points(a,i); - polyData(1,i) = points(b,i); - polyData(2,i) = points(c,i); - polyData(3,i) = points(d,i); - } - polyValues(0) = values(a); - polyValues(1) = values(b); - polyValues(2) = values(c); - polyValues(3) = values(d); - this->drawPolygon(polyData, polyValues, tag, mode); - - a=1; b=0; c=3; d=2; - for (int i=0; i<3; i++) { - polyData(0,i) = points(a,i); - polyData(1,i) = points(b,i); - polyData(2,i) = points(c,i); - polyData(3,i) = points(d,i); - } - polyValues(0) = values(a); - polyValues(1) = values(b); - polyValues(2) = values(c); - polyValues(3) = values(d); - this->drawPolygon(polyData, polyValues, tag, mode); - - a=7; b=3; c=0; d=4; - for (int i=0; i<3; i++) { - polyData(0,i) = points(a,i); - polyData(1,i) = points(b,i); - polyData(2,i) = points(c,i); - polyData(3,i) = points(d,i); - } - polyValues(0) = values(a); - polyValues(1) = values(b); - polyValues(2) = values(c); - polyValues(3) = values(d); - this->drawPolygon(polyData, polyValues, tag, mode); - - a=2; b=6; c=5; d=1; - for (int i=0; i<3; i++) { - polyData(0,i) = points(a,i); - polyData(1,i) = points(b,i); - polyData(2,i) = points(c,i); - polyData(3,i) = points(d,i); - } - polyValues(0) = values(a); - polyValues(1) = values(b); - polyValues(2) = values(c); - polyValues(3) = values(d); - return this->drawPolygon(polyData, polyValues, tag, mode); -} - diff --git a/SRC/runtime/runtime/legacy/Renderer/Renderer.h b/SRC/runtime/runtime/legacy/Renderer/Renderer.h deleted file mode 100644 index ea7e9b9014..0000000000 --- a/SRC/runtime/runtime/legacy/Renderer/Renderer.h +++ /dev/null @@ -1,97 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ****************************************************************** */ -// -// Description: This file contains the class definition for Renderer. -// Renderer is an abstract base class. An Renderer object is used -// to process 3d graphics. -// -// Written: fmk -// Created: 10/98 -// Revision: A -// -#ifndef Renderer_h -#define Renderer_h - -class Vector; -class Matrix; -class ColorMap; - -class Renderer -{ - public: - Renderer(ColorMap &theMap); - Renderer(const char *title, ColorMap &theMap); - ~Renderer(); - - // method to set the color map - void setColorMap(ColorMap &theMap); - - // method to clear the current image - int clearImage() {return -1;} - int saveImage(const char *imageName); - int saveImage(const char *title, const char *imageName); - - // methods to be invoked when image processing is to start or is finished - int startImage() {return -1;} - int doneImage() {return -1;} - - // methods invoked by the objects to display themselves - int drawPoint(const Vector &, float , int tag = 0, int mode = 0, int width = 1) {return -1;} - int drawPoint(const Vector &, const Vector &, int tag = 0, int mode = 0, int width = 1) {return -1;} - - int drawLine(const Vector &, const Vector &, - float V1, float V2, int tag = 0, int mode = 0) {return -1;} - int drawLine(const Vector &, const Vector &, - const Vector &, const Vector &, int tag = 0, int mode = 0) {return -1;} - - int drawCube(const Matrix &, const Vector &, int tag = 0, int mode = 0); - - int drawPolygon(const Matrix &, const Vector &, int tag = 0, int mode = 0) {return -1;} - int drawPolygon(const Matrix &, const Matrix &, int tag = 0, int mode = 0) {return -1;} - - int drawVector(const Vector &position, const Vector &value, double fcator = 1.0, int tag = 0); - - - int drawText(const Vector &, char *, int , - char horizontalJustify = 'l', - char verticalJustify = 'b') {return -1;} - - // - // the following are for setting up the viewing system - // - - // the following are in world coordinates & define view coord system - int setVRP(float , float , float ) {return -1;} // point on view plane - int setVPN(float , float , float ) {return -1;} // view plane normal - int setVUP(float , float , float ) {return -1;} // view-up vector - - // the following are in view coordinates - int setViewWindow(float, float, float, float) {return -1;} // view bounds - // umin, umax, vmin, vmax - - // location of near and far clipping planes from view plane - int setPlaneDist(float, float) {return -1;} - - int setProjectionMode(const char *) {return -1;} //parallel or perspective - int setFillMode(const char *) {return -1;} // wire or fill - int setLineWidth(int) {return -1;} // line width - - // eye location if perspective, dirn to +ViewPlane if parallel - int setPRP(float , float , float ) {return -1;} - - // the following are in normalized coordinates - int setPortWindow(float, float, float, float) {return -1;} // view port - // left, right, bottom, top [-1,1,-1,1] - protected: - ColorMap *theMap; - - private: - static int numRenderers; - static char **theTitles; - static Renderer **theRenderers; -}; - -#endif - From 818ef4c7e33dd5eea539c575d4cb974f958e5986 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:42:44 -0700 Subject: [PATCH 231/261] add logging and executables --- SRC/runtime/executable/CMakeLists.txt | 23 ++ SRC/runtime/executable/main.cpp | 362 ++++++++++++++++++++++++++ SRC/runtime/executable/static.cpp | 332 +++++++++++++++++++++++ SRC/runtime/executable/tclAppInit.cpp | 219 ++++++++++++++++ SRC/runtime/logging/AnsiColors.h | 89 +++++++ SRC/runtime/logging/CMakeLists.txt | 17 ++ SRC/runtime/logging/Logging.h | 62 +++++ SRC/runtime/logging/logging.cpp | 108 ++++++++ 8 files changed, 1212 insertions(+) create mode 100644 SRC/runtime/executable/CMakeLists.txt create mode 100644 SRC/runtime/executable/main.cpp create mode 100644 SRC/runtime/executable/static.cpp create mode 100644 SRC/runtime/executable/tclAppInit.cpp create mode 100644 SRC/runtime/logging/AnsiColors.h create mode 100644 SRC/runtime/logging/CMakeLists.txt create mode 100644 SRC/runtime/logging/Logging.h create mode 100644 SRC/runtime/logging/logging.cpp diff --git a/SRC/runtime/executable/CMakeLists.txt b/SRC/runtime/executable/CMakeLists.txt new file mode 100644 index 0000000000..e94194f1b2 --- /dev/null +++ b/SRC/runtime/executable/CMakeLists.txt @@ -0,0 +1,23 @@ +#============================================================================== +# +# OpenSees -- Open System For Earthquake Engineering Simulation +# Pacific Earthquake Engineering Research Center +# +#============================================================================== + +add_executable(xara_repl main.cpp) +set_target_properties(xara_repl PROPERTIES + OUTPUT_NAME "xara" +) +if (WIN32) + target_link_libraries(xara_repl PRIVATE Netapi32.lib) + target_link_libraries(xara_repl PRIVATE ${TCL_LIBRARIES} OpenSeesRT) +else() + target_link_libraries(xara_repl PRIVATE ${TCL_LIBRARY} OpenSeesRT) +endif() + +add_executable(xara_static static.cpp) +set_target_properties(xara_static PROPERTIES + OUTPUT_NAME "xaras" +) +target_link_libraries(xara_static PUBLIC ${TCL_LIBRARY} OpenSeesRT_Static OPS_Runtime) \ No newline at end of file diff --git a/SRC/runtime/executable/main.cpp b/SRC/runtime/executable/main.cpp new file mode 100644 index 0000000000..58b2ee8ead --- /dev/null +++ b/SRC/runtime/executable/main.cpp @@ -0,0 +1,362 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//----------------------------------------------------------------------------// +#include +#include +#include + +#ifndef _WIN32 +# include +#endif + +#ifdef USE_TCL_STUBS +#undef USE_TCL_STUBS +#endif + +extern "C" { +#include +#include + #ifdef _TCL85 + #define TclFormatInt(buf, n) sprintf((buf),"%ld", (long)(n)) + #else + EXTERN int TclFormatInt _ANSI_ARGS_((char *buffer, long n)); + #endif + EXTERN int TclObjCommandComplete _ANSI_ARGS_((Tcl_Obj *cmdPtr)); +} + + +# undef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLEXPORT + +/* + * The following code ensures that tclLink.c is linked whenever + * Tcl is linked. Without this code there's no reference to the + * code in that file from anywhere in Tcl, so it may not be + * linked into the application. + */ +// #ifdef _TCL85 +// int (*tclDummyLinkVarPtr)(Tcl_Interp *interp, const char *a, +// char *b, int c) = Tcl_LinkVar; +// #else +// int (*tclDummyLinkVarPtr)(Tcl_Interp *interp, char *a, +// char *b, int c) = Tcl_LinkVar; +// #endif + +/* + * Declarations for various library procedures and variables (don't want + * to include tclPort.h here, because people might copy this file out of + * the Tcl source directory to make their own modified versions). + * Note: "exit" should really be declared here, but there's no way to + * declare it without causing conflicts with other definitions elsewher + * on some systems, so it's better just to leave it out. + */ + +#ifdef _WIN32 +extern "C" int isatty _ANSI_ARGS_((int fd)); +//extern "C" char * strcpy _ANSI_ARGS_((char *dst, CONST char *src)) throw(); +#endif + +static int +LoadOpenSeesRT(Tcl_Interp* interp) +{ + char* path = getenv("OPENSEESRT_LIB"); + if (path) { + std::string path_string{path}; + std::string statement = std::string("import ") + path_string; + int status = Tcl_Eval(interp, statement.c_str()); + + if (status == TCL_OK) { + // Library was loaded, now set variable in interpreter + Tcl_Eval(interp, ( + std::string("set OPENSEESRT_LIB ") + path_string + ).c_str() + ); + return status; + } + } else { + return TCL_ERROR; + } + + return TCL_OK; +} + + +static char *tclStartupScriptFileName = NULL; + +void +TclSetStartupScriptFileName(char *fileName) +{ + tclStartupScriptFileName = fileName; +} + +char * +TclGetStartupScriptFileName() +{ + return tclStartupScriptFileName; +} + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * Main program for the xara interactive shell. + * + * Side effects: + * This procedure initializes the Tcl world and then starts + * interpreting commands. + * + *---------------------------------------------------------------------- + */ + +static bool OPS_showHeader = false; + +int +main(int argc, char **argv) +{ + Tcl_Obj *resultPtr; + Tcl_Obj *commandPtr = NULL; + char buffer[1000], *args; + int code, gotPartial, tty, length; + int exitCode = 0; + Tcl_Channel inChannel, outChannel, errChannel; + Tcl_Interp *interp; + Tcl_DString argString; + + interp = Tcl_CreateInterp(); + if (Tcl_InitStubs(interp, "8.5-10", 0) == NULL) { + fprintf(stderr, "Tcl_InitStubs failed: %s\n", Tcl_GetStringResult(interp)); + exit(1); + } + + + if (OPS_showHeader) { + fprintf(stderr,"\n\n"); + fprintf(stderr," OpenSees -- Open System For Earthquake Engineering Simulation\n"); + fprintf(stderr," Pacific Earthquake Engineering Research Center\n"); + // fprintf(stderr," Version %s %s\n\n", OPS_VERSION, WIN_ARCH); + + fprintf(stderr," (c) Copyright 1999-2025 The Regents of the University of California\n"); + fprintf(stderr," All Rights Reserved\n"); + fprintf(stderr," (Copyright and Disclaimer @ http://www.berkeley.edu/OpenSees/copyright.html)\n\n\n"); + } + + + // Tcl_FindExecutable(argv[0]); + + Tcl_Eval(interp, "rename load import;"); + Tcl_Eval(interp, "interp alias {} load {} import;"); + + +#ifdef TCL_MEM_DEBUG + Tcl_InitMemory(interp); +#endif + + /* + * Make command-line arguments available in the Tcl variables "argc" + * and "argv". If the first argument doesn't start with a "-" then + * strip it off and use it as the name of a script file to process. + */ + tclStartupScriptFileName = argv[1]; + if (tclStartupScriptFileName == NULL) { + if ((argc > 1) && (argv[1][0] != '-')) { + tclStartupScriptFileName = argv[1]; + argc--; + argv++; + } + } + + args = Tcl_Merge(argc-1, argv+1); + Tcl_ExternalToUtfDString(NULL, args, -1, &argString); + Tcl_SetVar(interp, "argv", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY); + Tcl_DStringFree(&argString); + ckfree(args); + + + if (tclStartupScriptFileName == NULL) { + Tcl_ExternalToUtfDString(NULL, argv[0], -1, &argString); + } else { + tclStartupScriptFileName = Tcl_ExternalToUtfDString(NULL, + tclStartupScriptFileName, -1, &argString); + } + + // TclFormatInt(buffer, argc-1); + // Tcl_SetVar(interp, "argc", buffer, TCL_GLOBAL_ONLY); + // Tcl_SetVar(interp, "argv0", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY); + + /* + * Set the "tcl_interactive" variable. + */ + + tty = isatty(0); + char one[2] = "1"; + char zero[2] = "0"; + + Tcl_SetVar(interp, "tcl_interactive", + ((tclStartupScriptFileName == NULL) && tty) ? one : zero, + TCL_GLOBAL_ONLY); + + // + // Load the OpenSeesRT library + // + if (LoadOpenSeesRT(interp) != TCL_OK) { + fprintf(stderr, "Error loading OpenSeesRT library: %s\n", + Tcl_GetStringResult(interp)); + } + +// +// if ((*appInitProc)(interp) != TCL_OK) { +// errChannel = Tcl_GetStdChannel(TCL_STDERR); +// if (errChannel) { +// Tcl_WriteChars(errChannel, +// "application-specific initialization failed: ", -1); +// Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); +// Tcl_WriteChars(errChannel, "\n", 1); +// } +// } +// + + /* + * If a script file was specified then just source that file + * and quit. + */ + + if (tclStartupScriptFileName != NULL) { + +// if (numParam == 0) + code = Tcl_EvalFile(interp, tclStartupScriptFileName); +// else +// code = EvalFileWithParameters(interp, tclStartupScriptFileName, 0, 0, 0, 1); + + if (code != TCL_OK) { + errChannel = Tcl_GetStdChannel(TCL_STDERR); + if (errChannel) { + // + // The following statement guarantees that the errorInfo + // variable is set properly. + // + Tcl_AddErrorInfo(interp, ""); + Tcl_WriteObj(errChannel, Tcl_GetVar2Ex(interp, "errorInfo", + NULL, TCL_GLOBAL_ONLY)); + Tcl_WriteChars(errChannel, "\n", 1); + } + exitCode = 1; + } + goto done; + } + /* + * Process commands from stdin until there's an end-of-file. Note + * that we need to fetch the standard channels again after every + * eval, since they may have been changed. + */ + + commandPtr = Tcl_NewObj(); + Tcl_IncrRefCount(commandPtr); + + inChannel = Tcl_GetStdChannel(TCL_STDIN); + outChannel = Tcl_GetStdChannel(TCL_STDOUT); + gotPartial = 0; + + while (1) { + if (tty) { + Tcl_Obj *promptCmdPtr; + + char one[12] = "tcl_prompt1"; + char two[12] = "tcl_prompt2"; + promptCmdPtr = Tcl_GetVar2Ex(interp, + (gotPartial ? one : two), + NULL, TCL_GLOBAL_ONLY); + if (promptCmdPtr == NULL) { + defaultPrompt: + if (!gotPartial && outChannel) { + Tcl_WriteChars(outChannel, "OpenSees > ", 11); + } + } else { + + code = Tcl_EvalObjEx(interp, promptCmdPtr, 0); + + inChannel = Tcl_GetStdChannel(TCL_STDIN); + outChannel = Tcl_GetStdChannel(TCL_STDOUT); + errChannel = Tcl_GetStdChannel(TCL_STDERR); + if (code != TCL_OK) { + if (errChannel) { + Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); + Tcl_WriteChars(errChannel, "\n", 1); + } + Tcl_AddErrorInfo(interp, + "\n (script that generates prompt)"); + goto defaultPrompt; + } + } + if (outChannel) { + Tcl_Flush(outChannel); + } + } + if (!inChannel) { + goto done; + } + length = Tcl_GetsObj(inChannel, commandPtr); + if (length < 0) { + goto done; + } + if ((length == 0) && Tcl_Eof(inChannel) && (!gotPartial)) { + goto done; + } + + /* + * Add the newline removed by Tcl_GetsObj back to the string. + */ + + Tcl_AppendToObj(commandPtr, "\n", 1); + // if (!TclObjCommandComplete(commandPtr)) { + // gotPartial = 1; + // continue; + // } + + gotPartial = 0; + code = Tcl_RecordAndEvalObj(interp, commandPtr, 0); + inChannel = Tcl_GetStdChannel(TCL_STDIN); + outChannel = Tcl_GetStdChannel(TCL_STDOUT); + errChannel = Tcl_GetStdChannel(TCL_STDERR); + Tcl_DecrRefCount(commandPtr); + commandPtr = Tcl_NewObj(); + Tcl_IncrRefCount(commandPtr); + if (code != TCL_OK) { + if (errChannel) { + Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); + Tcl_WriteChars(errChannel, "\n", 1); + } + } else if (tty) { + resultPtr = Tcl_GetObjResult(interp); + Tcl_GetStringFromObj(resultPtr, &length); + if ((length > 0) && outChannel) { + Tcl_WriteObj(outChannel, resultPtr); + Tcl_WriteChars(outChannel, "\n", 1); + } + } + } + + done: + + if (commandPtr != NULL) { + Tcl_DecrRefCount(commandPtr); + } + +#if defined(_PARALLEL_PROCESSING) || defined( _PARALLEL_INTERPRETERS) + return; +#endif + + /* + * Rather than calling exit, invoke the "exit" command so that + * users can replace "exit" with some other command to do additional + * cleanup on exit. The Tcl_Eval call should never return. + */ + Tcl_Eval(interp, buffer); + + Tcl_Eval(interp, "quit"); + + return exitCode; +} diff --git a/SRC/runtime/executable/static.cpp b/SRC/runtime/executable/static.cpp new file mode 100644 index 0000000000..2e842988f2 --- /dev/null +++ b/SRC/runtime/executable/static.cpp @@ -0,0 +1,332 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//----------------------------------------------------------------------------// +#include +#include +#include + +#ifndef _WIN32 +# include +#endif + +#ifdef USE_TCL_STUBS +#undef USE_TCL_STUBS +#endif + +extern "C" { +#include +#include + #ifdef _TCL85 + #define TclFormatInt(buf, n) sprintf((buf),"%ld", (long)(n)) + #else + EXTERN int TclFormatInt _ANSI_ARGS_((char *buffer, long n)); + #endif + EXTERN int TclObjCommandComplete _ANSI_ARGS_((Tcl_Obj *cmdPtr)); +} + +extern "C" int +#ifdef _WIN32 +__declspec(dllexport) +#endif +Openseesrt_Init(Tcl_Interp *interp); + +# undef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLEXPORT + +/* + * The following code ensures that tclLink.c is linked whenever + * Tcl is linked. Without this code there's no reference to the + * code in that file from anywhere in Tcl, so it may not be + * linked into the application. + */ +// #ifdef _TCL85 +// int (*tclDummyLinkVarPtr)(Tcl_Interp *interp, const char *a, +// char *b, int c) = Tcl_LinkVar; +// #elif _TCL84 +// int (*tclDummyLinkVarPtr)(Tcl_Interp *interp, const char *a, +// char *b, int c) = Tcl_LinkVar; +// #else +// int (*tclDummyLinkVarPtr)(Tcl_Interp *interp, char *a, +// char *b, int c) = Tcl_LinkVar; +// #endif + +/* + * Declarations for various library procedures and variables (don't want + * to include tclPort.h here, because people might copy this file out of + * the Tcl source directory to make their own modified versions). + * Note: "exit" should really be declared here, but there's no way to + * declare it without causing conflicts with other definitions elsewher + * on some systems, so it's better just to leave it out. + */ + +#ifdef _WIN32 +extern "C" int isatty _ANSI_ARGS_((int fd)); +//extern "C" char * strcpy _ANSI_ARGS_((char *dst, CONST char *src)) throw(); +#endif + +static char *tclStartupScriptFileName = NULL; + +void +TclSetStartupScriptFileName(char *fileName) +{ + tclStartupScriptFileName = fileName; +} + +char * +TclGetStartupScriptFileName() +{ + return tclStartupScriptFileName; +} + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * Main program for the xara interactive shell. + * + * Side effects: + * This procedure initializes the Tcl world and then starts + * interpreting commands. + * + *---------------------------------------------------------------------- + */ + +static bool OPS_showHeader = false; + +int +main(int argc, char **argv) +{ + Tcl_Obj *resultPtr; + Tcl_Obj *commandPtr = NULL; + char buffer[1000], *args; + int code, gotPartial, tty, length; + int exitCode = 0; + Tcl_Channel inChannel, outChannel, errChannel; + Tcl_DString argString; + + Tcl_Interp *interp = Tcl_CreateInterp(); + if (Tcl_InitStubs(interp, "8.5-10", 0) == NULL) { + fprintf(stderr, "Tcl_InitStubs failed: %s\n", Tcl_GetStringResult(interp)); + exit(1); + } + + + if (OPS_showHeader) { + fprintf(stderr,"\n\n"); + fprintf(stderr," OpenSees -- Open System For Earthquake Engineering Simulation\n"); + fprintf(stderr," Pacific Earthquake Engineering Research Center\n"); + // fprintf(stderr," Version %s %s\n\n", OPS_VERSION, WIN_ARCH); + + fprintf(stderr," (c) Copyright 1999-2025 The Regents of the University of California\n"); + fprintf(stderr," All Rights Reserved\n"); + fprintf(stderr," (Copyright and Disclaimer @ http://www.berkeley.edu/OpenSees/copyright.html)\n\n\n"); + } + + + // Tcl_FindExecutable(argv[0]); + + Tcl_Eval(interp, "rename load import;"); + Tcl_Eval(interp, "interp alias {} load {} import;"); + + +#ifdef TCL_MEM_DEBUG + Tcl_InitMemory(interp); +#endif + + /* + * Make command-line arguments available in the Tcl variables "argc" + * and "argv". If the first argument doesn't start with a "-" then + * strip it off and use it as the name of a script file to process. + */ + tclStartupScriptFileName = argv[1]; + if (tclStartupScriptFileName == NULL) { + if ((argc > 1) && (argv[1][0] != '-')) { + tclStartupScriptFileName = argv[1]; + argc--; + argv++; + } + } + + args = Tcl_Merge(argc-1, argv+1); + Tcl_ExternalToUtfDString(NULL, args, -1, &argString); + Tcl_SetVar(interp, "argv", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY); + Tcl_DStringFree(&argString); + ckfree(args); + + + if (tclStartupScriptFileName == NULL) { + Tcl_ExternalToUtfDString(NULL, argv[0], -1, &argString); + } else { + tclStartupScriptFileName = Tcl_ExternalToUtfDString(NULL, + tclStartupScriptFileName, -1, &argString); + } + + // TclFormatInt(buffer, argc-1); + // Tcl_SetVar(interp, "argc", buffer, TCL_GLOBAL_ONLY); + // Tcl_SetVar(interp, "argv0", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY); + + /* + * Set the "tcl_interactive" variable. + */ + + tty = isatty(0); + char one[2] = "1"; + char zero[2] = "0"; + + Tcl_SetVar(interp, "tcl_interactive", + ((tclStartupScriptFileName == NULL) && tty) ? one : zero, + TCL_GLOBAL_ONLY); + + // + // Load the OpenSeesRT library + // + if (Openseesrt_Init(interp) != TCL_OK) { + fprintf(stderr, "Error loading OpenSeesRT library: %s\n", + Tcl_GetStringResult(interp)); + } + + /* + * If a script file was specified then just source that file + * and quit. + */ + + if (tclStartupScriptFileName != NULL) { + +// if (numParam == 0) + code = Tcl_EvalFile(interp, tclStartupScriptFileName); +// else +// code = EvalFileWithParameters(interp, tclStartupScriptFileName, 0, 0, 0, 1); + + if (code != TCL_OK) { + errChannel = Tcl_GetStdChannel(TCL_STDERR); + if (errChannel) { + // + // The following statement guarantees that the errorInfo + // variable is set properly. + // + Tcl_AddErrorInfo(interp, ""); + Tcl_WriteObj(errChannel, Tcl_GetVar2Ex(interp, "errorInfo", + NULL, TCL_GLOBAL_ONLY)); + Tcl_WriteChars(errChannel, "\n", 1); + } + exitCode = 1; + } + goto done; + } + /* + * Process commands from stdin until there's an end-of-file. Note + * that we need to fetch the standard channels again after every + * eval, since they may have been changed. + */ + + commandPtr = Tcl_NewObj(); + Tcl_IncrRefCount(commandPtr); + + inChannel = Tcl_GetStdChannel(TCL_STDIN); + outChannel = Tcl_GetStdChannel(TCL_STDOUT); + gotPartial = 0; + + while (1) { + if (tty) { + Tcl_Obj *promptCmdPtr; + + char one[12] = "tcl_prompt1"; + char two[12] = "tcl_prompt2"; + promptCmdPtr = Tcl_GetVar2Ex(interp, + (gotPartial ? one : two), + NULL, TCL_GLOBAL_ONLY); + if (promptCmdPtr == NULL) { + defaultPrompt: + if (!gotPartial && outChannel) { + Tcl_WriteChars(outChannel, "OpenSees > ", 11); + } + } else { + + code = Tcl_EvalObjEx(interp, promptCmdPtr, 0); + + inChannel = Tcl_GetStdChannel(TCL_STDIN); + outChannel = Tcl_GetStdChannel(TCL_STDOUT); + errChannel = Tcl_GetStdChannel(TCL_STDERR); + if (code != TCL_OK) { + if (errChannel) { + Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); + Tcl_WriteChars(errChannel, "\n", 1); + } + Tcl_AddErrorInfo(interp, + "\n (script that generates prompt)"); + goto defaultPrompt; + } + } + if (outChannel) { + Tcl_Flush(outChannel); + } + } + if (!inChannel) { + goto done; + } + length = Tcl_GetsObj(inChannel, commandPtr); + if (length < 0) { + goto done; + } + if ((length == 0) && Tcl_Eof(inChannel) && (!gotPartial)) { + goto done; + } + + /* + * Add the newline removed by Tcl_GetsObj back to the string. + */ + + Tcl_AppendToObj(commandPtr, "\n", 1); + // if (!TclObjCommandComplete(commandPtr)) { + // gotPartial = 1; + // continue; + // } + + gotPartial = 0; + code = Tcl_RecordAndEvalObj(interp, commandPtr, 0); + inChannel = Tcl_GetStdChannel(TCL_STDIN); + outChannel = Tcl_GetStdChannel(TCL_STDOUT); + errChannel = Tcl_GetStdChannel(TCL_STDERR); + Tcl_DecrRefCount(commandPtr); + commandPtr = Tcl_NewObj(); + Tcl_IncrRefCount(commandPtr); + if (code != TCL_OK) { + if (errChannel) { + Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); + Tcl_WriteChars(errChannel, "\n", 1); + } + } else if (tty) { + resultPtr = Tcl_GetObjResult(interp); + Tcl_GetStringFromObj(resultPtr, &length); + if ((length > 0) && outChannel) { + Tcl_WriteObj(outChannel, resultPtr); + Tcl_WriteChars(outChannel, "\n", 1); + } + } + } + + done: + + if (commandPtr != NULL) { + Tcl_DecrRefCount(commandPtr); + } + +#if defined(_PARALLEL_PROCESSING) || defined( _PARALLEL_INTERPRETERS) + return; +#endif + + /* + * Rather than calling exit, invoke the "exit" command so that + * users can replace "exit" with some other command to do additional + * cleanup on exit. The Tcl_Eval call should never return. + */ + Tcl_Eval(interp, buffer); + + Tcl_Eval(interp, "quit"); + + return exitCode; +} diff --git a/SRC/runtime/executable/tclAppInit.cpp b/SRC/runtime/executable/tclAppInit.cpp new file mode 100644 index 0000000000..5606aa1a5e --- /dev/null +++ b/SRC/runtime/executable/tclAppInit.cpp @@ -0,0 +1,219 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +/* + * tclAppInit.c -- + * + * Provides a default version of the main program and Tcl_AppInit + * procedure for Tcl applications (without Tk). + * + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-1999 by Scriptics Corporation. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclAppInit.cpp,v 1.16 2009-01-15 00:12:37 fmk Exp $ + */ + +extern "C" { +#include +} + +#include "runtime/commands/commands.h" +extern int OpenSeesAppInit(Tcl_Interp *interp); + +/* + * The following variable is a special hack that is needed in order for + * Sun shared libraries to be used for Tcl. + */ + +#ifdef _UNIX +//extern "C" int matherr(); +//int *tclDummyMathPtr = (int *) matherr; +#endif + + +#ifdef TCL_TEST + +extern "C" { +#include "tclInt.h" +} + +extern int Procbodytest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +extern int Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp *interp)); +extern int TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +extern int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +#ifdef TCL_THREADS +extern int TclThread_Init _ANSI_ARGS_((Tcl_Interp *interp)); +#endif + +#endif /* TCL_TEST */ + +#ifdef TCL_XT_TEST +extern void XtToolkitInitialize _ANSI_ARGS_((void)); +extern int Tclxttest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +#endif + + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * This is the main program for the application. + * + * Results: + * None: Tcl_Main never returns here, so this procedure never + * returns either. + * + * Side effects: + * Whatever the application does. + * + *---------------------------------------------------------------------- + */ + +extern void g3TclMain(int argc, char **argv, Tcl_AppInitProc *appInitProc, int rank, int np); + +int +main(int argc, char **argv) +{ + /* + * The following #if block allows you to change the AppInit + * function by using a #define of TCL_LOCAL_APPINIT instead + * of rewriting this entire file. The #if checks for that + * #define and uses Tcl_AppInit if it doesn't exist. + */ + +#ifndef TCL_LOCAL_APPINIT +#define TCL_LOCAL_APPINIT Tcl_AppInit +#endif + + /* fmk - comment out the following block to get to compile + extern "C" int TCL_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp)); + fmk - end commented block */ + + /* + * The following #if block allows you to change how Tcl finds the startup + * script, prime the library or encoding paths, fiddle with the argv, + * etc., without needing to rewrite Tcl_Main() + */ + +#ifdef TCL_LOCAL_MAIN_HOOK + extern int TCL_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv)); +#endif + +#ifdef TCL_XT_TEST + XtToolkitInitialize(); +#endif + +#ifdef TCL_LOCAL_MAIN_HOOK + TCL_LOCAL_MAIN_HOOK(&argc, &argv); +#endif + + g3TclMain(argc, argv, TCL_LOCAL_APPINIT, 0, 1); + + return 0; /* Needed only to prevent compiler warning. */ +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_AppInit -- + * + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error + * message in the interp's result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + + + +int Tcl_AppInit(Tcl_Interp *interp) +{ + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + +#ifdef TCL_TEST +#ifdef TCL_XT_TEST + if (Tclxttest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } +#endif + if (Tcltest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, + (Tcl_PackageInitProc *) NULL); + if (TclObjTest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } +#ifdef TCL_THREADS + if (TclThread_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } +#endif + if (Procbodytest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init, + Procbodytest_SafeInit); +#endif /* TCL_TEST */ + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. + */ + + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + */ + + if (OpenSeesAppInit(interp) < 0) + return TCL_ERROR; + + /* + * Specify a user-specific startup file to invoke if the application + * is run interactively. Typically the startup file is "~/.apprc" + * where "app" is the name of the application. If this line is deleted + * then no user-specific startup file will be run under any conditions. + */ + + Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY); + return TCL_OK; +} + + diff --git a/SRC/runtime/logging/AnsiColors.h b/SRC/runtime/logging/AnsiColors.h new file mode 100644 index 0000000000..395a532cd0 --- /dev/null +++ b/SRC/runtime/logging/AnsiColors.h @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//----------------------------------------------------------------------------// +// +// Description: This file defines macros that expand into ANSI escape sequences +// for colored output +// +// References: +// +// ANSI X3.64 (ISO/IEC 6429). +// + +// Regular text +#define BLK "\033[0;30m" +#define RED "\033[0;31m" +#define GRN "\033[0;32m" +#define YEL "\033[0;33m" +#define BLU "\033[0;34m" +#define MAG "\033[0;35m" +#define CYN "\033[0;36m" +#define WHT "\033[0;37m" + +// Regular bold text +#define BBLK "\033[1;30m" +#define BRED "\033[1;31m" +#define BGRN "\033[1;32m" +#define BYEL "\033[1;33m" +#define BBLU "\033[1;34m" +#define BMAG "\033[1;35m" +#define BCYN "\033[1;36m" +#define BWHT "\033[1;37m" + +// Regular underline text +#define UBLK "\033[4;30m" +#define URED "\033[4;31m" +#define UGRN "\033[4;32m" +#define UYEL "\033[4;33m" +#define UBLU "\033[4;34m" +#define UMAG "\033[4;35m" +#define UCYN "\033[4;36m" +#define UWHT "\033[4;37m" + +// Regular background +#define BLKB "\033[40m" +#define REDB "\033[41m" +#define GRNB "\033[42m" +#define YELB "\033[43m" +#define BLUB "\033[44m" +#define MAGB "\033[45m" +#define CYNB "\033[46m" +#define WHTB "\033[47m" + +// High intensty background +#define BLKHB "\033[0;100m" +#define REDHB "\033[0;101m" +#define GRNHB "\033[0;102m" +#define YELHB "\033[0;103m" +#define BLUHB "\033[0;104m" +#define MAGHB "\033[0;105m" +#define CYNHB "\033[0;106m" +#define WHTHB "\033[0;107m" + +// High intensty text +#define HBLK "\033[0;90m" +#define HRED "\033[0;91m" +#define HGRN "\033[0;92m" +#define HYEL "\033[0;93m" +#define HBLU "\033[0;94m" +#define HMAG "\033[0;95m" +#define HCYN "\033[0;96m" +#define HWHT "\033[0;97m" + +// Bold high intensity text +#define BHBLK "\033[1;90m" +#define BHRED "\033[1;91m" +#define BHGRN "\033[1;92m" +#define BHYEL "\033[1;93m" +#define BHBLU "\033[1;94m" +#define BHMAG "\033[1;95m" +#define BHCYN "\033[1;96m" +#define BHWHT "\033[1;97m" + +// Reset +#define COLOR_RESET "\033[0m" + + diff --git a/SRC/runtime/logging/CMakeLists.txt b/SRC/runtime/logging/CMakeLists.txt new file mode 100644 index 0000000000..9ef7beb197 --- /dev/null +++ b/SRC/runtime/logging/CMakeLists.txt @@ -0,0 +1,17 @@ +#===================================================================== +# +# OpenSees -- Open System For Earthquake Engineering Simulation +# Pacific Earthquake Engineering Research Center +# +#===================================================================== + +target_include_directories(OPS_Logging PUBLIC ${CMAKE_CURRENT_LIST_DIR}) + +target_sources(OPS_Logging + PRIVATE + "logging.cpp" + PUBLIC + "Logging.h" + "AnsiColors.h" +) + diff --git a/SRC/runtime/logging/Logging.h b/SRC/runtime/logging/Logging.h new file mode 100644 index 0000000000..bf98f936aa --- /dev/null +++ b/SRC/runtime/logging/Logging.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include + +class OPS_Stream; +namespace OpenSees { + extern OPS_Stream *opserrPtr; + extern OPS_Stream *opslogPtr; + extern OPS_Stream *opswrnPtr; + extern OPS_Stream *opsdbgPtr; +} + + +#define opsdbg (*OpenSees::opsdbgPtr) +#define opswrn ((*OpenSees::opswrnPtr) << G3_WARN_PROMPT) +#define opslog (*OpenSees::opslogPtr) +#ifndef opserr +# define opserr (*OpenSees::opserrPtr) +# define endln "\n" +#endif +#define LOG_TEST ":: " +#define LOG_ITERATE BLU " ITERATE" COLOR_RESET " :: " +#define LOG_FAILURE RED " FAILURE" COLOR_RESET " :: " +#define LOG_SUCCESS GRN " SUCCESS" COLOR_RESET " :: " +#define LOG_CONTINUE "\n " + + + +class G3_Runtime; + +extern const char *G3_WARN_PROMPT; +extern const char *G3_DEBUG_PROMPT; + +namespace OpenSees { +// NOTE: These are defined in logging.cpp + + // maybe change "Prompt" to "Signal" + extern const char * SignalMessageEnd; + extern const char * PromptParseError; + extern const char * PromptValueError; + extern const char * PromptModelError; + extern const char * SignalWarning; + extern const char * PromptAnalysisFailure; + extern const char * PromptAnalysisSuccess; + extern const char * PromptAnalysisIterate; +}; + + +enum G3_Stream { + G3_StdOut, G3_StdIn, G3_StdErr, G3_Null +}; + +enum G3_StreamLevel { + G3_LevelError, + G3_LevelDebug, + G3_LevelLog, + G3_LevelWarn +}; + +int G3_SetStreamColor(G3_Runtime* rt, int strm, int flag); +int G3_SetStreamLevel(int stream, bool on); + diff --git a/SRC/runtime/logging/logging.cpp b/SRC/runtime/logging/logging.cpp new file mode 100644 index 0000000000..96008c332b --- /dev/null +++ b/SRC/runtime/logging/logging.cpp @@ -0,0 +1,108 @@ +#include +#include +#include +class G3_Runtime; + + +#include +#include +#include + + +#include "Logging.h" + + +namespace OpenSees { + +StandardStream sserr; +DummyStream ssnul; +OPS_Stream *opserrPtr = &sserr; +OPS_Stream *opsdbgPtr = &ssnul; +OPS_Stream *opslogPtr = &ssnul; +OPS_Stream *opswrnPtr = &sserr; + +namespace Internal { + const char * WarnPromptColor = RED "WARNING " COLOR_RESET; + const char * WarnPromptNoColor = "WARNING "; + + const char * ErrorPromptColor = BRED "ERROR " COLOR_RESET; + const char * ErrorPromptNoColor = "ERROR "; + + const char * DebugPromptColor = GRN "DEBUG " COLOR_RESET; + const char * DebugPromptNoColor = "DEBUG "; + + const char * AnalysisIterateColor = BLU " ITERATE" COLOR_RESET " :: "; + const char * AnalysisIterateNoColor = " ITERATE" " :: "; + + const char * AnalysisFailureColor = RED " FAILURE" COLOR_RESET " :: "; + const char * AnalysisFailureNoColor = " FAILURE" " :: "; + + const char * AnalysisSuccessColor = GRN " SUCCESS" COLOR_RESET " :: "; + const char * AnalysisSuccessNoColor = " SUCCESS" " :: "; + +} // namespace OpenSees::Internal + + // Default to no color + const char * SignalMessageEnd = "\n"; + const char * PromptParseError = Internal::ErrorPromptNoColor; + const char * PromptValueError = PromptParseError; + const char * PromptModelError = PromptParseError; + const char * SignalWarning = Internal::WarnPromptNoColor; + + const char * PromptDomainFailure = Internal::AnalysisFailureNoColor; + const char * PromptAnalysisFailure = Internal::AnalysisFailureNoColor; + const char * PromptAnalysisSuccess = Internal::AnalysisSuccessNoColor; + const char * PromptAnalysisIterate = Internal::AnalysisIterateNoColor; + +} // namespace OpenSees + +const char * G3_WARN_PROMPT = OpenSees::Internal::WarnPromptNoColor; +const char * G3_ERROR_PROMPT = OpenSees::Internal::ErrorPromptNoColor; +const char * G3_DEBUG_PROMPT = OpenSees::Internal::DebugPromptNoColor; + +int +G3_SetStreamLevel(int stream, bool on) +{ + + OPS_Stream **theStream; + switch (stream) { + case G3_LevelError: theStream = &OpenSees::opserrPtr; break; + case G3_LevelDebug: theStream = &OpenSees::opsdbgPtr; break; + case G3_LevelWarn : theStream = &OpenSees::opswrnPtr; break; + default: + return -1; + } + + if (on) { + *theStream = &OpenSees::sserr; + } else { + *theStream = &OpenSees::ssnul; + } + return 0; +} + +int G3_SetStreamColor(G3_Runtime* rt, int strm, int flag) +{ + if (flag == 1) { + G3_WARN_PROMPT = OpenSees::Internal::WarnPromptColor; + OpenSees::SignalWarning = OpenSees::Internal::WarnPromptColor; + G3_DEBUG_PROMPT = OpenSees::Internal::DebugPromptColor; + OpenSees::PromptParseError = OpenSees::Internal::ErrorPromptColor; + OpenSees::PromptValueError = OpenSees::Internal::ErrorPromptColor; + OpenSees::PromptModelError = OpenSees::Internal::ErrorPromptColor; + OpenSees::PromptAnalysisFailure = OpenSees::Internal::AnalysisFailureColor; + OpenSees::PromptAnalysisSuccess = OpenSees::Internal::AnalysisSuccessColor; + OpenSees::PromptAnalysisIterate = OpenSees::Internal::AnalysisIterateColor; + + } else if (flag == 0) { + G3_WARN_PROMPT = OpenSees::Internal::WarnPromptNoColor; + OpenSees::SignalWarning = OpenSees::Internal::WarnPromptNoColor; + G3_DEBUG_PROMPT = OpenSees::Internal::DebugPromptNoColor; + OpenSees::PromptParseError = OpenSees::Internal::ErrorPromptNoColor; + OpenSees::PromptAnalysisFailure = OpenSees::Internal::AnalysisFailureNoColor; + OpenSees::PromptAnalysisSuccess = OpenSees::Internal::AnalysisSuccessNoColor; + OpenSees::PromptAnalysisIterate = OpenSees::Internal::AnalysisIterateNoColor; + } + + return 0; +} From a30b30f4a4a942c54ac3a1980185be91ad0e8908 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:44:14 -0700 Subject: [PATCH 232/261] more banners --- SRC/runtime/commands/analysis/analysis.cpp | 9 ++++++++- SRC/runtime/commands/analysis/ctest.cpp | 9 ++++++++- SRC/runtime/commands/analysis/integrator.h | 10 +++++++++- SRC/runtime/commands/analysis/numberer.cpp | 12 ++++++++++-- SRC/runtime/commands/analysis/sensitivity.cpp | 10 +++++++++- SRC/runtime/commands/analysis/transient.cpp | 11 ++++++++++- 6 files changed, 54 insertions(+), 7 deletions(-) diff --git a/SRC/runtime/commands/analysis/analysis.cpp b/SRC/runtime/commands/analysis/analysis.cpp index d48c4584dc..2b3b6deda2 100644 --- a/SRC/runtime/commands/analysis/analysis.cpp +++ b/SRC/runtime/commands/analysis/analysis.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Description: This file contains functions that are responsible diff --git a/SRC/runtime/commands/analysis/ctest.cpp b/SRC/runtime/commands/analysis/ctest.cpp index ae90f69866..a3c2c75e5c 100644 --- a/SRC/runtime/commands/analysis/ctest.cpp +++ b/SRC/runtime/commands/analysis/ctest.cpp @@ -1,9 +1,16 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// // // Description: This file implements the selection of a convergence test. diff --git a/SRC/runtime/commands/analysis/integrator.h b/SRC/runtime/commands/analysis/integrator.h index fcc8e9d283..5f2f023d10 100644 --- a/SRC/runtime/commands/analysis/integrator.h +++ b/SRC/runtime/commands/analysis/integrator.h @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // All dispatching macros and templates are defined in integrator.cpp before // this file is included. // diff --git a/SRC/runtime/commands/analysis/numberer.cpp b/SRC/runtime/commands/analysis/numberer.cpp index 3c764e11ce..26076364eb 100644 --- a/SRC/runtime/commands/analysis/numberer.cpp +++ b/SRC/runtime/commands/analysis/numberer.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// // Description: This file implements the selection of a Numberer object, // which is used to optimally number the degrees of freedom of a problem. // diff --git a/SRC/runtime/commands/analysis/sensitivity.cpp b/SRC/runtime/commands/analysis/sensitivity.cpp index 22d75ec5bd..1552adda8c 100644 --- a/SRC/runtime/commands/analysis/sensitivity.cpp +++ b/SRC/runtime/commands/analysis/sensitivity.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// #include #include #include diff --git a/SRC/runtime/commands/analysis/transient.cpp b/SRC/runtime/commands/analysis/transient.cpp index c5cac7396c..1c8f2039d6 100644 --- a/SRC/runtime/commands/analysis/transient.cpp +++ b/SRC/runtime/commands/analysis/transient.cpp @@ -1,6 +1,15 @@ //===----------------------------------------------------------------------===// // -// OpenSees - Open System for Earthquake Engineering Simulation +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause // //===----------------------------------------------------------------------===// // From 2565346b6d0213dafa86bb915486f74edaaf47bc Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:46:45 -0700 Subject: [PATCH 233/261] add copyright in banners --- SRC/runtime/commands/analysis/integrator.h | 1 - SRC/runtime/commands/analysis/solver.hpp | 5 ----- SRC/runtime/commands/domain/loading/series.cpp | 12 ------------ SRC/runtime/commands/modeling/material/elastic.cpp | 1 - SRC/runtime/commands/modeling/material/material.cpp | 7 ------- SRC/runtime/commands/modeling/section.cpp | 1 - SRC/runtime/commands/parallel/partition.cpp | 10 ---------- 7 files changed, 37 deletions(-) diff --git a/SRC/runtime/commands/analysis/integrator.h b/SRC/runtime/commands/analysis/integrator.h index 5f2f023d10..2bdf157f59 100644 --- a/SRC/runtime/commands/analysis/integrator.h +++ b/SRC/runtime/commands/analysis/integrator.h @@ -58,7 +58,6 @@ OPS_Routine OPS_WilsonTheta; // integrators #include -// #include #include #include diff --git a/SRC/runtime/commands/analysis/solver.hpp b/SRC/runtime/commands/analysis/solver.hpp index 64f9bfc966..27cd7ea9d6 100644 --- a/SRC/runtime/commands/analysis/solver.hpp +++ b/SRC/runtime/commands/analysis/solver.hpp @@ -47,14 +47,9 @@ #include // #include -// #include -// #include #include #include -#if defined(_PETSC) -LinearSOE *TclCommand_newPetscSOE(int, TCL_Char**); -#endif #if defined(_PARALLEL_PROCESSING) // parallel soe & solvers diff --git a/SRC/runtime/commands/domain/loading/series.cpp b/SRC/runtime/commands/domain/loading/series.cpp index 51df870189..71d0e5bea3 100644 --- a/SRC/runtime/commands/domain/loading/series.cpp +++ b/SRC/runtime/commands/domain/loading/series.cpp @@ -20,7 +20,6 @@ #include #include #include -// #include #include #include @@ -31,20 +30,9 @@ #include #include #include -// #include -// #include -// extern OPS_Routine OPS_ConstantSeries; -// extern OPS_Routine OPS_LinearSeries; -// extern OPS_Routine OPS_TrigSeries; -// extern OPS_Routine OPS_PulseSeries; -// extern OPS_Routine OPS_PeerMotion; -// extern OPS_Routine OPS_PeerNGAMotion; -// extern OPS_Routine OPS_TriangleSeries; -// extern OPS_Routine OPS_RectangularSeries; - extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp *interp, int cArg, int mArg, TCL_Char ** const argv, Domain *domain); diff --git a/SRC/runtime/commands/modeling/material/elastic.cpp b/SRC/runtime/commands/modeling/material/elastic.cpp index 64ad1dfcc2..b61c391779 100644 --- a/SRC/runtime/commands/modeling/material/elastic.cpp +++ b/SRC/runtime/commands/modeling/material/elastic.cpp @@ -44,7 +44,6 @@ #include #include -// #include #include #include diff --git a/SRC/runtime/commands/modeling/material/material.cpp b/SRC/runtime/commands/modeling/material/material.cpp index 7cc1943efb..1a581f803c 100644 --- a/SRC/runtime/commands/modeling/material/material.cpp +++ b/SRC/runtime/commands/modeling/material/material.cpp @@ -30,17 +30,10 @@ #include #include #include -// #include - -// #include -// #include -// #include -// #include Tcl_CmdProc TclCommand_newPlasticMaterial; Tcl_CmdProc TclCommand_newElasticMaterial; -// Tcl_CmdProc TclCommand_newIsotropicMaterial; diff --git a/SRC/runtime/commands/modeling/section.cpp b/SRC/runtime/commands/modeling/section.cpp index b341ce3cde..8e83cfca3f 100644 --- a/SRC/runtime/commands/modeling/section.cpp +++ b/SRC/runtime/commands/modeling/section.cpp @@ -48,7 +48,6 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, #include #include #include -// #include #include #include #include diff --git a/SRC/runtime/commands/parallel/partition.cpp b/SRC/runtime/commands/parallel/partition.cpp index 5886b30917..b99f3412ac 100644 --- a/SRC/runtime/commands/parallel/partition.cpp +++ b/SRC/runtime/commands/parallel/partition.cpp @@ -17,14 +17,9 @@ #include #include #include -// #include #include #include -// # include -// # include -// # include -// # include #include #include #include @@ -37,16 +32,11 @@ #include #include -// # define MPIPP_H -// # include -// # include - struct PartitionRuntime { MachineBroker *machine = nullptr; FEM_ObjectBroker *broker = nullptr; DomainPartitioner *DOMAIN_partitioner = nullptr; GraphPartitioner *GRAPH_partitioner = nullptr; -// LoadBalancer *balancer = nullptr; Channel **channels = nullptr; int num_subdomains = 0; bool partitioned = false; From d211dc76a86fcd3ff5025df9a3688beeaf651cc5 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:50:38 -0700 Subject: [PATCH 234/261] clean up --- SRC/runtime/commands/analysis/algorithm.cpp | 29 --------------- SRC/runtime/commands/domain/domain.cpp | 39 --------------------- SRC/runtime/commands/domain/sensitivity.cpp | 3 +- SRC/runtime/parsing/InterpreterAPI.cpp | 3 -- 4 files changed, 1 insertion(+), 73 deletions(-) diff --git a/SRC/runtime/commands/analysis/algorithm.cpp b/SRC/runtime/commands/analysis/algorithm.cpp index fb3986d745..b3e5b46991 100644 --- a/SRC/runtime/commands/analysis/algorithm.cpp +++ b/SRC/runtime/commands/analysis/algorithm.cpp @@ -823,36 +823,7 @@ int TclCommand_algorithmRecorder(ClientData clientData, Tcl_Interp *interp, Tcl_Size argc, TCL_Char ** const argv) { -#if 1 return TCL_ERROR; -#else - Recorder *theRecorder = nullptr; - BasicAnalysisBuilder* builder = (BasicAnalysisBuilder*)clientData; - Domain* domain = builder->getDomain(); - EquiSolnAlgo *theAlgo; - TclCreateRecorder(clientData, interp, argc, argv, *domain, &theRecorder); - - if (theRecorder == nullptr) { - char buffer[] = "-1"; - Tcl_SetResult(interp, buffer, TCL_VOLATILE); - return TCL_ERROR; - } - - // add the recorder to the domain, - // NOTE: will not be called with theALgo == 0 - if (theAlgo != nullptr) { - if ((theAlgo->addRecorder(*theRecorder)) < 0) { - opserr << "WARNING could not add to domain - recorder " << argv[1] - << "\n"; - delete theRecorder; - return TCL_ERROR; - } - } - - int recorderTag = theRecorder->getTag(); - Tcl_SetObjResult(interp, Tcl_NewIntObj(recorderTag)); - return TCL_OK; -#endif } int diff --git a/SRC/runtime/commands/domain/domain.cpp b/SRC/runtime/commands/domain/domain.cpp index 3712f30e7f..17a5724398 100644 --- a/SRC/runtime/commands/domain/domain.cpp +++ b/SRC/runtime/commands/domain/domain.cpp @@ -265,45 +265,6 @@ removeObject(ClientData clientData, Tcl_Interp *interp, int argc, } } -#ifdef _RELIABILITY - // AddingSensitivity:BEGIN /////////////////////////////////////// - else if (strcmp(Tcl_GetString(objv[1]), "randomVariable") == 0) { - int rvTag; - if (Tcl_GetIntFromObj(interp, objv[2], &rvTag) != TCL_OK) { - opserr << "WARNING invalid input: rvTag \n"; - return TCL_ERROR; - } - ReliabilityDomain *theReliabilityDomain = - theReliabilityBuilder->getReliabilityDomain(); - theReliabilityDomain->removeRandomVariable(rvTag); - } else if (strcmp(Tcl_GetString(objv[1]), "performanceFunction") == 0) { - int lsfTag; - if (Tcl_GetIntFromObj(interp, objv[2], &lsfTag) != TCL_OK) { - opserr << "WARNING invalid input: lsfTag \n"; - return TCL_ERROR; - } - ReliabilityDomain *theReliabilityDomain = - theReliabilityBuilder->getReliabilityDomain(); - theReliabilityDomain->removeLimitStateFunction(lsfTag); - } else if (strcmp(Tcl_GetString(objv[1]), "cutset") == 0) { - int cutTag; - if (Tcl_GetIntFromObj(interp, objv[2], &cutTag) != TCL_OK) { - opserr << "WARNING invalid input: cutTag \n"; - return TCL_ERROR; - } - ReliabilityDomain *theReliabilityDomain = - theReliabilityBuilder->getReliabilityDomain(); - theReliabilityDomain->removeCutset(cutTag); - } else if (strcmp(Tcl_GetString(objv[1]), "sensitivityAlgorithm") == 0) { - if (theSensitivityAlgorithm != 0) { - // the_static_analysis->setSensitivityAlgorithm(0); - theSensitivityAlgorithm = 0; - theSensitivityIntegrator = 0; - } - } -// AddingSensitivity:END /////////////////////////////////////// -#endif - else opserr << "WARNING remove " << Tcl_GetString(objv[1]) << " not supported" << "\n"; diff --git a/SRC/runtime/commands/domain/sensitivity.cpp b/SRC/runtime/commands/domain/sensitivity.cpp index 32a0b34437..029644f523 100644 --- a/SRC/runtime/commands/domain/sensitivity.cpp +++ b/SRC/runtime/commands/domain/sensitivity.cpp @@ -245,7 +245,6 @@ int sensSectionForce(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) { -#if 1 // def _RELIABILITY assert(clientData != nullptr); Domain *theDomain = (Domain *)clientData; @@ -333,7 +332,7 @@ sensSectionForce(ClientData clientData, Tcl_Interp *interp, int argc, theParam->activate(false); delete theResponse; -#endif + return TCL_OK; } diff --git a/SRC/runtime/parsing/InterpreterAPI.cpp b/SRC/runtime/parsing/InterpreterAPI.cpp index 6fe584bc2a..40c8842779 100644 --- a/SRC/runtime/parsing/InterpreterAPI.cpp +++ b/SRC/runtime/parsing/InterpreterAPI.cpp @@ -339,13 +339,10 @@ TimeSeries *G3_getTimeSeries(G3_Runtime *rt, int tag) BasicModelBuilder *builder = G3_getSafeBuilder(rt); if (builder) { series = builder->getTypedObject(tag); - // TODO -#if 1 if (series) return series->getCopy(); else return nullptr; -#endif } else { return nullptr; } From 6177e5bd21a1e67688529d0b33d7f733000e1f18 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:52:23 -0700 Subject: [PATCH 235/261] remote database --- .../domain/database/TclBerkeleyDB.cpp | 46 ---- .../domain/database/TclDatabaseCommands.cpp | 225 ------------------ .../commands/domain/database/TclMySQL.cpp | 104 -------- .../commands/domain/database/database.cpp | 12 - 4 files changed, 387 deletions(-) delete mode 100644 SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp delete mode 100644 SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp delete mode 100644 SRC/runtime/commands/domain/database/TclMySQL.cpp delete mode 100644 SRC/runtime/commands/domain/database/database.cpp diff --git a/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp b/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp deleted file mode 100644 index 0c20272813..0000000000 --- a/SRC/runtime/commands/domain/database/TclBerkeleyDB.cpp +++ /dev/null @@ -1,46 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// -//===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// -// -// Description: This file contains the function invoked when the user invokes -// the MySQL command in the interpreter. -// -// Written: fmk -// -#include -#include -#include -#include - -#include - -#ifdef _USRDLL -#define DllExport _declspec(dllexport) -#else -#define DllExport -#endif - -extern "C" DllExport int -TclCommand_BerkeleyDB(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv, Domain *theDomain, - FEM_ObjectBroker *theBroker, FE_Datastore **theDatabase) -{ - - // delete the old database - if (*theDatabase != 0) - delete (*theDatabase); - - (*theDatabase) = new BerkeleyDbDatastore(argv[2], *theDomain, *theBroker); - - if (*theDatabase == 0) { - opserr << "WARNING database MySql dabaseName? - out of memory\n"; - return TCL_ERROR; - } - - return TCL_OK; -} - diff --git a/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp b/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp deleted file mode 100644 index 869af3b376..0000000000 --- a/SRC/runtime/commands/domain/database/TclDatabaseCommands.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -// -// Written: fmk -// Created: 03/00 -// Revision: A -// -// Description: This file contains the function that is invoked -// by the interpreter when the comand 'database' is invoked by the -// user. -// -// What: "@(#) commands.C, revA" - -#include - -#include -#include -#include -#include - -#include -#include - -// known databases -#include - -// linked list of struct for other types of -// databases that can be added dynamically - -#include - -typedef struct databasePackageCommand { - char *funcName; - int (*funcPtr)(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv, Domain *, FEM_ObjectBroker *, - FE_Datastore **); - struct databasePackageCommand *next; -} DatabasePackageCommand; - -// static variables -static DatabasePackageCommand *theDatabasePackageCommands = NULL; -static bool createdDatabaseCommands = false; - -int save(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv); - -int restore(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv); - -extern FE_Datastore *theDatabase; - -int -TclAddDatabase(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv, - Domain &theDomain, FEM_ObjectBroker &theBroker) -{ - if (createdDatabaseCommands == false) { - - // create the commands to commit and reset - Tcl_CreateCommand(interp, "save", save, (ClientData)NULL, - (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "restore", restore, (ClientData)NULL, - (Tcl_CmdDeleteProc *)NULL); - - createdDatabaseCommands = true; - } - - // make sure at least one other argument to contain integrator - if (argc < 2) { - opserr << "WARNING need to specify a Database type; valid type File, " - "MySQL, BerkeleyDB \n"; - return TCL_ERROR; - } - - // - // check argv[1] for type of Database, parse in rest of arguments - // needed for the type of Database, create the object and add to Domain - // - - // a File Database - if (strcmp(argv[1], "File") == 0) { - if (argc < 3) { - opserr << "WARNING database File fileName? "; - return TCL_ERROR; - } - - // delete the old database - if (theDatabase != 0) - delete theDatabase; - - theDatabase = new FileDatastore(argv[2], theDomain, theBroker); - // check we instantiated a database .. if not ran out of memory - if (theDatabase == nullptr) { - opserr << "WARNING ran out of memory - database File " << argv[2] - << "\n"; - return TCL_ERROR; - } - - return TCL_OK; - } else { - - // - // maybe a database package - // - - // try existing loaded packages - - DatabasePackageCommand *dataCommands = theDatabasePackageCommands; - bool found = false; - while (dataCommands != NULL && found == false) { - if (strcmp(argv[1], dataCommands->funcName) == 0) { - int result = (*(dataCommands->funcPtr))( - clientData, interp, argc, argv, &theDomain, &theBroker, &theDatabase); - return result; - } else - dataCommands = dataCommands->next; - } - - // load new package - - void *libHandle; - int (*funcPtr)(ClientData, Tcl_Interp *, int , - TCL_Char ** const argv, Domain *, FEM_ObjectBroker *, - FE_Datastore **); - int databaseNameLength = strlen(argv[1]); - char *tclFuncName = new char[databaseNameLength + 12]; - strcpy(tclFuncName, "TclCommand_"); - strcpy(&tclFuncName[11], argv[1]); - - int res = - getLibraryFunction(argv[1], tclFuncName, &libHandle, (void **)&funcPtr); - - if (res == 0) { - char *databaseName = new char[databaseNameLength + 1]; - strcpy(databaseName, argv[1]); - DatabasePackageCommand *theDataCommand = new DatabasePackageCommand; - theDataCommand->funcPtr = funcPtr; - theDataCommand->funcName = databaseName; - theDataCommand->next = theDatabasePackageCommands; - theDatabasePackageCommands = theDataCommand; - - int result = (*funcPtr)(clientData, interp, argc, argv, &theDomain, - &theBroker, &theDatabase); - return result; - } - } - opserr << "WARNING No database type exists "; - opserr << "for database of type:" << argv[1] << "valid database type File\n"; - - return TCL_ERROR; -} - -int -save(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - - if (theDatabase == nullptr) { - opserr << "WARNING: save - no database has been constructed\n"; - return TCL_OK; - } - - // make sure at least one other argument to contain type of system - if (argc < 2) { - opserr << "WARNING save no commit tag - want save commitTag?"; - return TCL_OK; - } - - // check argv[1] for commitTag - int commitTag; - if (Tcl_GetInt(interp, argv[1], &commitTag) != TCL_OK) { - opserr << "WARNING - save could not read commitTag " << argv[1] << "\n"; - return TCL_OK; - } - - if (theDatabase->commitState(commitTag) < 0) { - opserr << "WARNING - database failed to commitState \n"; - return TCL_ERROR; - } - - return TCL_OK; -} - -int -restore(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char ** const argv) -{ - - if (theDatabase == 0) { - opserr << "WARNING: restore - no database has been constructed\n"; - return TCL_OK; - } - - // make sure at least one other argument to contain type of system - if (argc < 2) { - opserr << "WARNING restore no commit tag - want restore commitTag?"; - return TCL_OK; - } - - // check argv[1] for commitTag - int commitTag; - if (Tcl_GetInt(interp, argv[1], &commitTag) != TCL_OK) { - opserr << "WARNING - restore could not read commitTag " << argv[1] << "\n"; - return TCL_OK; - } - - if (theDatabase->restoreState(commitTag) < 0) { - opserr << "WARNING - database failed to restoreState \n"; - return TCL_ERROR; - } - - return TCL_OK; -} diff --git a/SRC/runtime/commands/domain/database/TclMySQL.cpp b/SRC/runtime/commands/domain/database/TclMySQL.cpp deleted file mode 100644 index 1dc5c91003..0000000000 --- a/SRC/runtime/commands/domain/database/TclMySQL.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -// -// Written: fmk -// -// Description: This file contains the function invoked when the user invokes -// the MySQL command in the interpreter. -// -// What: "@(#) TclCommand_MySQL.C, revA" - -#include -#include -#include -#include - -#include - -#ifdef _USRDLL -#define DllExport _declspec(dllexport) -#else -#define DllExport -#endif - -extern "C" DllExport int -TclCommand_MySQL(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv, Domain *theDomain, - FEM_ObjectBroker *theBroker, FE_Datastore **theDatabase) -{ - - if (argc < 3) { - opserr << "WARNING database MySql dabaseName? "; - return TCL_ERROR; - } - - // delete the old database - if (*theDatabase != 0) - delete (*theDatabase); - - if (argc == 3) - (*theDatabase) = new MySqlDatastore(argv[2], *theDomain, *theBroker); - else { - const char *database = argv[2]; - const char *host = NULL; - const char *user = NULL; - const char *passwd = NULL; - const char *socket = NULL; - int port = 0; - int clientFlag = 0; - - int counter = 3; - while (counter < argc) { - if (strcmp(argv[counter], "-host") == 0) { - host = argv[counter + 1]; - counter += 2; - } else if (strcmp(argv[counter], "-user") == 0) { - user = argv[counter + 1]; - counter += 2; - } else if (strcmp(argv[counter], "-passwd") == 0) { - passwd = argv[counter + 1]; - counter += 2; - } else if (strcmp(argv[counter], "-socket") == 0) { - socket = argv[counter + 1]; - counter += 2; - } else if (strcmp(argv[counter], "-port") == 0) { - if (Tcl_GetInt(interp, argv[counter + 1], &port) != TCL_OK) - return TCL_ERROR; - counter += 2; - } else if (strcmp(argv[counter], "-clientFlag") == 0) { - if (Tcl_GetInt(interp, argv[counter + 1], &clientFlag) != TCL_OK) - return TCL_ERROR; - counter += 2; - } else { - counter++; - } - } - (*theDatabase) = - new MySqlDatastore(database, host, user, passwd, port, socket, - clientFlag, *theDomain, *theBroker); - } - - if (*theDatabase == 0) { - opserr << "WARNING database MySql dabaseName? - out of memory\n"; - return TCL_ERROR; - } - - return TCL_OK; -} diff --git a/SRC/runtime/commands/domain/database/database.cpp b/SRC/runtime/commands/domain/database/database.cpp deleted file mode 100644 index f09305980f..0000000000 --- a/SRC/runtime/commands/domain/database/database.cpp +++ /dev/null @@ -1,12 +0,0 @@ - -extern int TclAddDatabase(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv, Domain &theDomain, - FEM_ObjectBroker &theBroker); - -int -addDatabase(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - return TclAddDatabase(clientData, interp, argc, argv, theDomain, theBroker); -} - From 94941a23ff050dad33c0f56f3e5eb6f72fc995c2 Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 31 Aug 2025 17:07:01 -0700 Subject: [PATCH 236/261] more copyright --- SRC/runtime/commands/analysis/modal/modal.cpp | 18 +++++- .../loading/TclSeriesIntegratorCommand.cpp | 11 +++- .../domain/loading/groundExcitation.cpp | 58 ------------------- .../commands/domain/loading/groundMotion.cpp | 10 +++- .../commands/domain/loading/pattern.cpp | 10 +++- .../commands/domain/loading/series.cpp | 10 +++- 6 files changed, 51 insertions(+), 66 deletions(-) delete mode 100644 SRC/runtime/commands/domain/loading/groundExcitation.cpp diff --git a/SRC/runtime/commands/analysis/modal/modal.cpp b/SRC/runtime/commands/analysis/modal/modal.cpp index 85bb9f80ff..f540ee2195 100644 --- a/SRC/runtime/commands/analysis/modal/modal.cpp +++ b/SRC/runtime/commands/analysis/modal/modal.cpp @@ -1,3 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// xara +// https://xara.so +// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// #include #include #include @@ -336,8 +351,7 @@ responseSpectrumAnalysis(ClientData clientData, } } - // ok, create the response spectrum analysis and run it here... - // no need to store it + // Create the response spectrum analysis and run it ResponseSpectrumAnalysis rsa(modal_props, ts, Tn, Sa, dir, scale); int result; if (single_mode) diff --git a/SRC/runtime/commands/domain/loading/TclSeriesIntegratorCommand.cpp b/SRC/runtime/commands/domain/loading/TclSeriesIntegratorCommand.cpp index e1d1a4c20b..ac496d0f87 100644 --- a/SRC/runtime/commands/domain/loading/TclSeriesIntegratorCommand.cpp +++ b/SRC/runtime/commands/domain/loading/TclSeriesIntegratorCommand.cpp @@ -1,12 +1,17 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// -// Description: This file contains the function invoked when the user invokes -// the groundMotion command in the interpreter. // // Written: fmk // Created: 11/00 diff --git a/SRC/runtime/commands/domain/loading/groundExcitation.cpp b/SRC/runtime/commands/domain/loading/groundExcitation.cpp deleted file mode 100644 index 910f28ff94..0000000000 --- a/SRC/runtime/commands/domain/loading/groundExcitation.cpp +++ /dev/null @@ -1,58 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// xara -// -//===----------------------------------------------------------------------===// -// https://xara.so -//===----------------------------------------------------------------------===// -// -#if 0 -int -groundExcitation(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char ** const argv) -{ - G3_Runtime *rt = G3_getRuntime(interp); - Domain* the_domain = G3_getDomain(rt); - - // make sure at least one other argument to contain integrator - if (argc < 2) { - opserr << "WARNING need to specify the commitTag \n"; - return TCL_ERROR; - } - - if (strcmp(argv[1],"Single") == 0) { - if (argc < 4) { - opserr << "WARNING quake single dof motion\n"; - return TCL_ERROR; - } - - int dof; - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) - return TCL_ERROR; - - // read in the ground motion - GroundMotion *theMotion; - if (strcmp(argv[3],"ElCentro") == 0) { - double fact = 1.0; - if (argc == 5) { - if (Tcl_GetDouble(interp, argv[4], &fact) != TCL_OK) - return TCL_ERROR; - } - theMotion = new ElCentroGroundMotion(fact); - } else { - opserr << "WARNING quake Single motion - no motion type exists \n"; - return TCL_ERROR; - } - - Load *theLoad = new SingleExcitation(*theMotion, dof, nextTag++); - the_domain->addOtherLoad(theLoad); - return TCL_OK; - } - - else { - opserr << "WARNING No quake type exists \n"; - return TCL_ERROR; - } -} -#endif - diff --git a/SRC/runtime/commands/domain/loading/groundMotion.cpp b/SRC/runtime/commands/domain/loading/groundMotion.cpp index 2f8a101f98..b02332f5d0 100644 --- a/SRC/runtime/commands/domain/loading/groundMotion.cpp +++ b/SRC/runtime/commands/domain/loading/groundMotion.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // Description: This file contains the function invoked when the user invokes // the GroundMotion command in the interpreter. // diff --git a/SRC/runtime/commands/domain/loading/pattern.cpp b/SRC/runtime/commands/domain/loading/pattern.cpp index 4d5c015f53..405d0ed676 100644 --- a/SRC/runtime/commands/domain/loading/pattern.cpp +++ b/SRC/runtime/commands/domain/loading/pattern.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // Description: This file contains the function invoked when the user invokes // the "pattern" command in the interpreter. // diff --git a/SRC/runtime/commands/domain/loading/series.cpp b/SRC/runtime/commands/domain/loading/series.cpp index 71d0e5bea3..c98cb25b4d 100644 --- a/SRC/runtime/commands/domain/loading/series.cpp +++ b/SRC/runtime/commands/domain/loading/series.cpp @@ -1,10 +1,18 @@ //===----------------------------------------------------------------------===// // // xara +// https://xara.so // //===----------------------------------------------------------------------===// -// https://xara.so +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// //===----------------------------------------------------------------------===// +// // Description: This file contains the function invoked when the user invokes // the pattern command in the interpreter. It is invoked by the // TclBasicBuilder_addPattern function. From 9fafa57731f7548a5a5ad72939f3b9e61d4d1c2e Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 31 Aug 2025 17:07:49 -0700 Subject: [PATCH 237/261] clean --- SRC/runtime/executable/tclAppInit.cpp | 219 -------------------------- 1 file changed, 219 deletions(-) delete mode 100644 SRC/runtime/executable/tclAppInit.cpp diff --git a/SRC/runtime/executable/tclAppInit.cpp b/SRC/runtime/executable/tclAppInit.cpp deleted file mode 100644 index 5606aa1a5e..0000000000 --- a/SRC/runtime/executable/tclAppInit.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ -/* - * tclAppInit.c -- - * - * Provides a default version of the main program and Tcl_AppInit - * procedure for Tcl applications (without Tk). - * - * Copyright (c) 1993 The Regents of the University of California. - * Copyright (c) 1994-1997 Sun Microsystems, Inc. - * Copyright (c) 1998-1999 by Scriptics Corporation. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclAppInit.cpp,v 1.16 2009-01-15 00:12:37 fmk Exp $ - */ - -extern "C" { -#include -} - -#include "runtime/commands/commands.h" -extern int OpenSeesAppInit(Tcl_Interp *interp); - -/* - * The following variable is a special hack that is needed in order for - * Sun shared libraries to be used for Tcl. - */ - -#ifdef _UNIX -//extern "C" int matherr(); -//int *tclDummyMathPtr = (int *) matherr; -#endif - - -#ifdef TCL_TEST - -extern "C" { -#include "tclInt.h" -} - -extern int Procbodytest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -extern int Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp *interp)); -extern int TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -extern int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -#ifdef TCL_THREADS -extern int TclThread_Init _ANSI_ARGS_((Tcl_Interp *interp)); -#endif - -#endif /* TCL_TEST */ - -#ifdef TCL_XT_TEST -extern void XtToolkitInitialize _ANSI_ARGS_((void)); -extern int Tclxttest_Init _ANSI_ARGS_((Tcl_Interp *interp)); -#endif - - -/* - *---------------------------------------------------------------------- - * - * main -- - * - * This is the main program for the application. - * - * Results: - * None: Tcl_Main never returns here, so this procedure never - * returns either. - * - * Side effects: - * Whatever the application does. - * - *---------------------------------------------------------------------- - */ - -extern void g3TclMain(int argc, char **argv, Tcl_AppInitProc *appInitProc, int rank, int np); - -int -main(int argc, char **argv) -{ - /* - * The following #if block allows you to change the AppInit - * function by using a #define of TCL_LOCAL_APPINIT instead - * of rewriting this entire file. The #if checks for that - * #define and uses Tcl_AppInit if it doesn't exist. - */ - -#ifndef TCL_LOCAL_APPINIT -#define TCL_LOCAL_APPINIT Tcl_AppInit -#endif - - /* fmk - comment out the following block to get to compile - extern "C" int TCL_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp)); - fmk - end commented block */ - - /* - * The following #if block allows you to change how Tcl finds the startup - * script, prime the library or encoding paths, fiddle with the argv, - * etc., without needing to rewrite Tcl_Main() - */ - -#ifdef TCL_LOCAL_MAIN_HOOK - extern int TCL_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv)); -#endif - -#ifdef TCL_XT_TEST - XtToolkitInitialize(); -#endif - -#ifdef TCL_LOCAL_MAIN_HOOK - TCL_LOCAL_MAIN_HOOK(&argc, &argv); -#endif - - g3TclMain(argc, argv, TCL_LOCAL_APPINIT, 0, 1); - - return 0; /* Needed only to prevent compiler warning. */ -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_AppInit -- - * - * This procedure performs application-specific initialization. - * Most applications, especially those that incorporate additional - * packages, will have their own version of this procedure. - * - * Results: - * Returns a standard Tcl completion code, and leaves an error - * message in the interp's result if an error occurs. - * - * Side effects: - * Depends on the startup script. - * - *---------------------------------------------------------------------- - */ - - - -int Tcl_AppInit(Tcl_Interp *interp) -{ - if (Tcl_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - -#ifdef TCL_TEST -#ifdef TCL_XT_TEST - if (Tclxttest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } -#endif - if (Tcltest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, - (Tcl_PackageInitProc *) NULL); - if (TclObjTest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } -#ifdef TCL_THREADS - if (TclThread_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } -#endif - if (Procbodytest_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init, - Procbodytest_SafeInit); -#endif /* TCL_TEST */ - - /* - * Call the init procedures for included packages. Each call should - * look like this: - * - * if (Mod_Init(interp) == TCL_ERROR) { - * return TCL_ERROR; - * } - * - * where "Mod" is the name of the module. - */ - - /* - * Call Tcl_CreateCommand for application-specific commands, if - * they weren't already created by the init procedures called above. - */ - - if (OpenSeesAppInit(interp) < 0) - return TCL_ERROR; - - /* - * Specify a user-specific startup file to invoke if the application - * is run interactively. Typically the startup file is "~/.apprc" - * where "app" is the name of the application. If this line is deleted - * then no user-specific startup file will be run under any conditions. - */ - - Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY); - return TCL_OK; -} - - From 1a94c9c2c5f28502f17eeb36db43e03f5ce4552f Mon Sep 17 00:00:00 2001 From: Claudio Perez <50180406+claudioperez@users.noreply.github.com> Date: Sun, 31 Aug 2025 17:16:59 -0700 Subject: [PATCH 238/261] cleaning --- SRC/runtime/executable/main.cpp | 414 +++++++++++++---------------- SRC/runtime/executable/static.cpp | 423 ++++++++++++++---------------- 2 files changed, 383 insertions(+), 454 deletions(-) diff --git a/SRC/runtime/executable/main.cpp b/SRC/runtime/executable/main.cpp index 58b2ee8ead..f8f9d2e630 100644 --- a/SRC/runtime/executable/main.cpp +++ b/SRC/runtime/executable/main.cpp @@ -3,7 +3,16 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// #include #include #include @@ -31,19 +40,6 @@ extern "C" { # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLEXPORT -/* - * The following code ensures that tclLink.c is linked whenever - * Tcl is linked. Without this code there's no reference to the - * code in that file from anywhere in Tcl, so it may not be - * linked into the application. - */ -// #ifdef _TCL85 -// int (*tclDummyLinkVarPtr)(Tcl_Interp *interp, const char *a, -// char *b, int c) = Tcl_LinkVar; -// #else -// int (*tclDummyLinkVarPtr)(Tcl_Interp *interp, char *a, -// char *b, int c) = Tcl_LinkVar; -// #endif /* * Declarations for various library procedures and variables (don't want @@ -71,8 +67,8 @@ LoadOpenSeesRT(Tcl_Interp* interp) if (status == TCL_OK) { // Library was loaded, now set variable in interpreter Tcl_Eval(interp, ( - std::string("set OPENSEESRT_LIB ") + path_string - ).c_str() + std::string("set OPENSEESRT_LIB ") + path_string + ).c_str() ); return status; } @@ -101,13 +97,7 @@ TclGetStartupScriptFileName() /* *---------------------------------------------------------------------- * - * main -- - * - * Main program for the xara interactive shell. - * - * Side effects: - * This procedure initializes the Tcl world and then starts - * interpreting commands. + * Main program for the xara interactive shell. * *---------------------------------------------------------------------- */ @@ -117,246 +107,214 @@ static bool OPS_showHeader = false; int main(int argc, char **argv) { - Tcl_Obj *resultPtr; - Tcl_Obj *commandPtr = NULL; - char buffer[1000], *args; - int code, gotPartial, tty, length; - int exitCode = 0; - Tcl_Channel inChannel, outChannel, errChannel; - Tcl_Interp *interp; - Tcl_DString argString; - - interp = Tcl_CreateInterp(); - if (Tcl_InitStubs(interp, "8.5-10", 0) == NULL) { - fprintf(stderr, "Tcl_InitStubs failed: %s\n", Tcl_GetStringResult(interp)); - exit(1); - } - - - if (OPS_showHeader) { - fprintf(stderr,"\n\n"); - fprintf(stderr," OpenSees -- Open System For Earthquake Engineering Simulation\n"); - fprintf(stderr," Pacific Earthquake Engineering Research Center\n"); - // fprintf(stderr," Version %s %s\n\n", OPS_VERSION, WIN_ARCH); - - fprintf(stderr," (c) Copyright 1999-2025 The Regents of the University of California\n"); - fprintf(stderr," All Rights Reserved\n"); - fprintf(stderr," (Copyright and Disclaimer @ http://www.berkeley.edu/OpenSees/copyright.html)\n\n\n"); - } - - - // Tcl_FindExecutable(argv[0]); + Tcl_Obj *resultPtr; + Tcl_Obj *commandPtr = NULL; + char buffer[1000], *args; + int code, gotPartial, tty, length; + int exitCode = 0; + Tcl_Channel inChannel, outChannel, errChannel; + Tcl_Interp *interp; + Tcl_DString argString; + + interp = Tcl_CreateInterp(); + if (Tcl_InitStubs(interp, "8.5-10", 0) == NULL) { + fprintf(stderr, "Tcl_InitStubs failed: %s\n", Tcl_GetStringResult(interp)); + exit(1); + } - Tcl_Eval(interp, "rename load import;"); - Tcl_Eval(interp, "interp alias {} load {} import;"); + if (OPS_showHeader) { + fprintf(stderr,"\n\n"); + fprintf(stderr," OpenSees -- Open System For Earthquake Engineering Simulation\n"); + fprintf(stderr," Pacific Earthquake Engineering Research Center\n"); + + fprintf(stderr," (c) Copyright 1999-2025 The Regents of the University of California\n"); + fprintf(stderr," All Rights Reserved\n"); + fprintf(stderr," (Copyright and Disclaimer @ http://www.berkeley.edu/OpenSees/copyright.html)\n\n\n"); + } -#ifdef TCL_MEM_DEBUG - Tcl_InitMemory(interp); -#endif - /* - * Make command-line arguments available in the Tcl variables "argc" - * and "argv". If the first argument doesn't start with a "-" then - * strip it off and use it as the name of a script file to process. - */ - tclStartupScriptFileName = argv[1]; - if (tclStartupScriptFileName == NULL) { - if ((argc > 1) && (argv[1][0] != '-')) { - tclStartupScriptFileName = argv[1]; - argc--; - argv++; - } + Tcl_Eval(interp, "rename load import;"); + Tcl_Eval(interp, "interp alias {} load {} import;"); + + /* + * Make command-line arguments available in the Tcl variables "argc" + * and "argv". If the first argument doesn't start with a "-" then + * strip it off and use it as the name of a script file to process. + */ + tclStartupScriptFileName = argv[1]; + if (tclStartupScriptFileName == NULL) { + if ((argc > 1) && (argv[1][0] != '-')) { + tclStartupScriptFileName = argv[1]; + argc--; + argv++; } + } - args = Tcl_Merge(argc-1, argv+1); - Tcl_ExternalToUtfDString(NULL, args, -1, &argString); - Tcl_SetVar(interp, "argv", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY); - Tcl_DStringFree(&argString); - ckfree(args); - - - if (tclStartupScriptFileName == NULL) { - Tcl_ExternalToUtfDString(NULL, argv[0], -1, &argString); - } else { - tclStartupScriptFileName = Tcl_ExternalToUtfDString(NULL, - tclStartupScriptFileName, -1, &argString); - } + args = Tcl_Merge(argc-1, argv+1); + Tcl_ExternalToUtfDString(NULL, args, -1, &argString); + Tcl_SetVar(interp, "argv", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY); + Tcl_DStringFree(&argString); + ckfree(args); - // TclFormatInt(buffer, argc-1); - // Tcl_SetVar(interp, "argc", buffer, TCL_GLOBAL_ONLY); - // Tcl_SetVar(interp, "argv0", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY); - /* - * Set the "tcl_interactive" variable. - */ + if (tclStartupScriptFileName == NULL) { + Tcl_ExternalToUtfDString(NULL, argv[0], -1, &argString); + } else { + tclStartupScriptFileName = Tcl_ExternalToUtfDString(NULL, + tclStartupScriptFileName, -1, &argString); + } - tty = isatty(0); - char one[2] = "1"; - char zero[2] = "0"; + /* + * Set the "tcl_interactive" variable. + */ + + tty = isatty(0); + char one[2] = "1"; + char zero[2] = "0"; + + Tcl_SetVar(interp, "tcl_interactive", + ((tclStartupScriptFileName == NULL) && tty) ? one : zero, + TCL_GLOBAL_ONLY); + + // + // Load the OpenSeesRT library + // + if (LoadOpenSeesRT(interp) != TCL_OK) { + fprintf(stderr, "Error loading OpenSeesRT library: %s\n", + Tcl_GetStringResult(interp)); + } - Tcl_SetVar(interp, "tcl_interactive", - ((tclStartupScriptFileName == NULL) && tty) ? one : zero, - TCL_GLOBAL_ONLY); - - // - // Load the OpenSeesRT library - // - if (LoadOpenSeesRT(interp) != TCL_OK) { - fprintf(stderr, "Error loading OpenSeesRT library: %s\n", - Tcl_GetStringResult(interp)); - } -// -// if ((*appInitProc)(interp) != TCL_OK) { -// errChannel = Tcl_GetStdChannel(TCL_STDERR); -// if (errChannel) { -// Tcl_WriteChars(errChannel, -// "application-specific initialization failed: ", -1); -// Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); -// Tcl_WriteChars(errChannel, "\n", 1); -// } -// } -// + /* + * If a script file was specified then just source that file + * and quit. + */ - /* - * If a script file was specified then just source that file - * and quit. - */ + if (tclStartupScriptFileName != NULL) { - if (tclStartupScriptFileName != NULL) { - -// if (numParam == 0) - code = Tcl_EvalFile(interp, tclStartupScriptFileName); -// else -// code = EvalFileWithParameters(interp, tclStartupScriptFileName, 0, 0, 0, 1); - - if (code != TCL_OK) { - errChannel = Tcl_GetStdChannel(TCL_STDERR); - if (errChannel) { - // - // The following statement guarantees that the errorInfo - // variable is set properly. - // - Tcl_AddErrorInfo(interp, ""); - Tcl_WriteObj(errChannel, Tcl_GetVar2Ex(interp, "errorInfo", - NULL, TCL_GLOBAL_ONLY)); - Tcl_WriteChars(errChannel, "\n", 1); - } - exitCode = 1; + code = Tcl_EvalFile(interp, tclStartupScriptFileName); + + if (code != TCL_OK) { + errChannel = Tcl_GetStdChannel(TCL_STDERR); + if (errChannel) { + // + // The following statement guarantees that the errorInfo + // variable is set properly. + // + Tcl_AddErrorInfo(interp, ""); + Tcl_WriteObj(errChannel, Tcl_GetVar2Ex(interp, "errorInfo", + NULL, TCL_GLOBAL_ONLY)); + Tcl_WriteChars(errChannel, "\n", 1); } - goto done; + exitCode = 1; } - /* - * Process commands from stdin until there's an end-of-file. Note - * that we need to fetch the standard channels again after every - * eval, since they may have been changed. - */ - - commandPtr = Tcl_NewObj(); - Tcl_IncrRefCount(commandPtr); - - inChannel = Tcl_GetStdChannel(TCL_STDIN); - outChannel = Tcl_GetStdChannel(TCL_STDOUT); - gotPartial = 0; + goto done; + } - while (1) { - if (tty) { - Tcl_Obj *promptCmdPtr; - - char one[12] = "tcl_prompt1"; - char two[12] = "tcl_prompt2"; - promptCmdPtr = Tcl_GetVar2Ex(interp, - (gotPartial ? one : two), - NULL, TCL_GLOBAL_ONLY); - if (promptCmdPtr == NULL) { - defaultPrompt: - if (!gotPartial && outChannel) { - Tcl_WriteChars(outChannel, "OpenSees > ", 11); - } - } else { - - code = Tcl_EvalObjEx(interp, promptCmdPtr, 0); - - inChannel = Tcl_GetStdChannel(TCL_STDIN); - outChannel = Tcl_GetStdChannel(TCL_STDOUT); - errChannel = Tcl_GetStdChannel(TCL_STDERR); - if (code != TCL_OK) { - if (errChannel) { - Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); - Tcl_WriteChars(errChannel, "\n", 1); - } - Tcl_AddErrorInfo(interp, - "\n (script that generates prompt)"); - goto defaultPrompt; - } - } - if (outChannel) { - Tcl_Flush(outChannel); - } - } - if (!inChannel) { - goto done; - } - length = Tcl_GetsObj(inChannel, commandPtr); - if (length < 0) { - goto done; - } - if ((length == 0) && Tcl_Eof(inChannel) && (!gotPartial)) { - goto done; + /* + * Process commands from stdin until there's an end-of-file. Note + * that we need to fetch the standard channels again after every + * eval, since they may have been changed. + */ + commandPtr = Tcl_NewObj(); + Tcl_IncrRefCount(commandPtr); + + inChannel = Tcl_GetStdChannel(TCL_STDIN); + outChannel = Tcl_GetStdChannel(TCL_STDOUT); + gotPartial = 0; + + while (true) { + if (tty) { + Tcl_Obj *promptCmdPtr; + + char one[12] = "tcl_prompt1"; + char two[12] = "tcl_prompt2"; + promptCmdPtr = Tcl_GetVar2Ex(interp, + (gotPartial ? one : two), + NULL, TCL_GLOBAL_ONLY); + if (promptCmdPtr == NULL) { + defaultPrompt: + if (!gotPartial && outChannel) { + Tcl_WriteChars(outChannel, "OpenSees > ", 11); } - - /* - * Add the newline removed by Tcl_GetsObj back to the string. - */ + } else { + + code = Tcl_EvalObjEx(interp, promptCmdPtr, 0); - Tcl_AppendToObj(commandPtr, "\n", 1); - // if (!TclObjCommandComplete(commandPtr)) { - // gotPartial = 1; - // continue; - // } - - gotPartial = 0; - code = Tcl_RecordAndEvalObj(interp, commandPtr, 0); inChannel = Tcl_GetStdChannel(TCL_STDIN); outChannel = Tcl_GetStdChannel(TCL_STDOUT); errChannel = Tcl_GetStdChannel(TCL_STDERR); - Tcl_DecrRefCount(commandPtr); - commandPtr = Tcl_NewObj(); - Tcl_IncrRefCount(commandPtr); if (code != TCL_OK) { if (errChannel) { Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); Tcl_WriteChars(errChannel, "\n", 1); } - } else if (tty) { - resultPtr = Tcl_GetObjResult(interp); - Tcl_GetStringFromObj(resultPtr, &length); - if ((length > 0) && outChannel) { - Tcl_WriteObj(outChannel, resultPtr); - Tcl_WriteChars(outChannel, "\n", 1); - } + Tcl_AddErrorInfo(interp, + "\n (script that generates prompt)"); + goto defaultPrompt; } + } + if (outChannel) + Tcl_Flush(outChannel); } + if (!inChannel) + goto done; + + length = Tcl_GetsObj(inChannel, commandPtr); + if (length < 0) + goto done; + + if ((length == 0) && Tcl_Eof(inChannel) && (!gotPartial)) + goto done; - done: + + /* + * Add the newline removed by Tcl_GetsObj back to the string. + */ + + Tcl_AppendToObj(commandPtr, "\n", 1); - if (commandPtr != NULL) { - Tcl_DecrRefCount(commandPtr); + gotPartial = 0; + code = Tcl_RecordAndEvalObj(interp, commandPtr, 0); + inChannel = Tcl_GetStdChannel(TCL_STDIN); + outChannel = Tcl_GetStdChannel(TCL_STDOUT); + errChannel = Tcl_GetStdChannel(TCL_STDERR); + Tcl_DecrRefCount(commandPtr); + commandPtr = Tcl_NewObj(); + Tcl_IncrRefCount(commandPtr); + if (code != TCL_OK) { + if (errChannel) { + Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); + Tcl_WriteChars(errChannel, "\n", 1); + } + } else if (tty) { + resultPtr = Tcl_GetObjResult(interp); + Tcl_GetStringFromObj(resultPtr, &length); + if ((length > 0) && outChannel) { + Tcl_WriteObj(outChannel, resultPtr); + Tcl_WriteChars(outChannel, "\n", 1); + } } + } + +done: + + if (commandPtr != NULL) + Tcl_DecrRefCount(commandPtr); #if defined(_PARALLEL_PROCESSING) || defined( _PARALLEL_INTERPRETERS) - return; + return; #endif - /* - * Rather than calling exit, invoke the "exit" command so that - * users can replace "exit" with some other command to do additional - * cleanup on exit. The Tcl_Eval call should never return. - */ - Tcl_Eval(interp, buffer); + /* + * Rather than calling exit, invoke the "exit" command so that + * users can replace "exit" with some other command to do additional + * cleanup on exit. The Tcl_Eval call should never return. + */ + Tcl_Eval(interp, buffer); - Tcl_Eval(interp, "quit"); + Tcl_Eval(interp, "quit"); - return exitCode; + return exitCode; } diff --git a/SRC/runtime/executable/static.cpp b/SRC/runtime/executable/static.cpp index 2e842988f2..89c0c559be 100644 --- a/SRC/runtime/executable/static.cpp +++ b/SRC/runtime/executable/static.cpp @@ -3,7 +3,16 @@ // xara // https://xara.so // -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2025, OpenSees/Xara Developers +// All rights reserved. No warranty, explicit or implicit, is provided. +// +// This source code is licensed under the BSD 2-Clause License. +// See LICENSE file or https://opensource.org/licenses/BSD-2-Clause +// +//===----------------------------------------------------------------------===// +// #include #include #include @@ -36,22 +45,6 @@ Openseesrt_Init(Tcl_Interp *interp); # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLEXPORT -/* - * The following code ensures that tclLink.c is linked whenever - * Tcl is linked. Without this code there's no reference to the - * code in that file from anywhere in Tcl, so it may not be - * linked into the application. - */ -// #ifdef _TCL85 -// int (*tclDummyLinkVarPtr)(Tcl_Interp *interp, const char *a, -// char *b, int c) = Tcl_LinkVar; -// #elif _TCL84 -// int (*tclDummyLinkVarPtr)(Tcl_Interp *interp, const char *a, -// char *b, int c) = Tcl_LinkVar; -// #else -// int (*tclDummyLinkVarPtr)(Tcl_Interp *interp, char *a, -// char *b, int c) = Tcl_LinkVar; -// #endif /* * Declarations for various library procedures and variables (don't want @@ -84,249 +77,227 @@ TclGetStartupScriptFileName() /* *---------------------------------------------------------------------- * - * main -- - * - * Main program for the xara interactive shell. - * - * Side effects: - * This procedure initializes the Tcl world and then starts - * interpreting commands. - * + * Main program for the xara interactive shell. + * *---------------------------------------------------------------------- */ -static bool OPS_showHeader = false; int main(int argc, char **argv) { - Tcl_Obj *resultPtr; - Tcl_Obj *commandPtr = NULL; - char buffer[1000], *args; - int code, gotPartial, tty, length; - int exitCode = 0; - Tcl_Channel inChannel, outChannel, errChannel; - Tcl_DString argString; - - Tcl_Interp *interp = Tcl_CreateInterp(); - if (Tcl_InitStubs(interp, "8.5-10", 0) == NULL) { - fprintf(stderr, "Tcl_InitStubs failed: %s\n", Tcl_GetStringResult(interp)); - exit(1); - } - - - if (OPS_showHeader) { - fprintf(stderr,"\n\n"); - fprintf(stderr," OpenSees -- Open System For Earthquake Engineering Simulation\n"); - fprintf(stderr," Pacific Earthquake Engineering Research Center\n"); - // fprintf(stderr," Version %s %s\n\n", OPS_VERSION, WIN_ARCH); - - fprintf(stderr," (c) Copyright 1999-2025 The Regents of the University of California\n"); - fprintf(stderr," All Rights Reserved\n"); - fprintf(stderr," (Copyright and Disclaimer @ http://www.berkeley.edu/OpenSees/copyright.html)\n\n\n"); - } - - - // Tcl_FindExecutable(argv[0]); + Tcl_Obj *resultPtr; + Tcl_Obj *commandPtr = NULL; + char buffer[1000], *args; + int code, gotPartial, tty, length; + int exitCode = 0; + Tcl_Channel inChannel, outChannel, errChannel; + Tcl_DString argString; + static bool OPS_showHeader = false; + + Tcl_Interp *interp = Tcl_CreateInterp(); + if (Tcl_InitStubs(interp, "8.5-10", 0) == NULL) { + fprintf(stderr, "Tcl_InitStubs failed: %s\n", Tcl_GetStringResult(interp)); + exit(1); + } + + + if (OPS_showHeader) { + fprintf(stderr,"\n\n"); + fprintf(stderr," OpenSees -- Open System For Earthquake Engineering Simulation\n"); + fprintf(stderr," Pacific Earthquake Engineering Research Center\n"); + + fprintf(stderr," (c) Copyright 1999-2025 The Regents of the University of California\n"); + fprintf(stderr," All Rights Reserved\n"); + fprintf(stderr," (Copyright and Disclaimer @ http://www.berkeley.edu/OpenSees/copyright.html)\n\n\n"); + } - Tcl_Eval(interp, "rename load import;"); - Tcl_Eval(interp, "interp alias {} load {} import;"); + Tcl_Eval(interp, "rename load import;"); + Tcl_Eval(interp, "interp alias {} load {} import;"); #ifdef TCL_MEM_DEBUG - Tcl_InitMemory(interp); + Tcl_InitMemory(interp); #endif - /* - * Make command-line arguments available in the Tcl variables "argc" - * and "argv". If the first argument doesn't start with a "-" then - * strip it off and use it as the name of a script file to process. - */ - tclStartupScriptFileName = argv[1]; - if (tclStartupScriptFileName == NULL) { - if ((argc > 1) && (argv[1][0] != '-')) { - tclStartupScriptFileName = argv[1]; - argc--; - argv++; - } - } - - args = Tcl_Merge(argc-1, argv+1); - Tcl_ExternalToUtfDString(NULL, args, -1, &argString); - Tcl_SetVar(interp, "argv", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY); - Tcl_DStringFree(&argString); - ckfree(args); - - - if (tclStartupScriptFileName == NULL) { - Tcl_ExternalToUtfDString(NULL, argv[0], -1, &argString); - } else { - tclStartupScriptFileName = Tcl_ExternalToUtfDString(NULL, - tclStartupScriptFileName, -1, &argString); + /* + * Make command-line arguments available in the Tcl variables "argc" + * and "argv". If the first argument doesn't start with a "-" then + * strip it off and use it as the name of a script file to process. + */ + tclStartupScriptFileName = argv[1]; + if (tclStartupScriptFileName == NULL) { + if ((argc > 1) && (argv[1][0] != '-')) { + tclStartupScriptFileName = argv[1]; + argc--; + argv++; } - - // TclFormatInt(buffer, argc-1); - // Tcl_SetVar(interp, "argc", buffer, TCL_GLOBAL_ONLY); - // Tcl_SetVar(interp, "argv0", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY); - - /* - * Set the "tcl_interactive" variable. - */ - - tty = isatty(0); - char one[2] = "1"; - char zero[2] = "0"; - - Tcl_SetVar(interp, "tcl_interactive", - ((tclStartupScriptFileName == NULL) && tty) ? one : zero, - TCL_GLOBAL_ONLY); + } + + args = Tcl_Merge(argc-1, argv+1); + Tcl_ExternalToUtfDString(NULL, args, -1, &argString); + Tcl_SetVar(interp, "argv", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY); + Tcl_DStringFree(&argString); + ckfree(args); + + + if (tclStartupScriptFileName == NULL) { + Tcl_ExternalToUtfDString(NULL, argv[0], -1, &argString); + } else { + tclStartupScriptFileName = Tcl_ExternalToUtfDString(NULL, + tclStartupScriptFileName, -1, &argString); + } + + /* + * Set the "tcl_interactive" variable. + */ + + tty = isatty(0); + char one[2] = "1"; + char zero[2] = "0"; + + Tcl_SetVar(interp, "tcl_interactive", + ((tclStartupScriptFileName == NULL) && tty) ? one : zero, + TCL_GLOBAL_ONLY); + + // + // Load the OpenSeesRT library + // + if (Openseesrt_Init(interp) != TCL_OK) { + fprintf(stderr, "Error loading OpenSeesRT library: %s\n", + Tcl_GetStringResult(interp)); + } + + /* + * If a script file was specified then just source that file + * and quit. + */ + + if (tclStartupScriptFileName != NULL) { + + code = Tcl_EvalFile(interp, tclStartupScriptFileName); - // - // Load the OpenSeesRT library - // - if (Openseesrt_Init(interp) != TCL_OK) { - fprintf(stderr, "Error loading OpenSeesRT library: %s\n", - Tcl_GetStringResult(interp)); + if (code != TCL_OK) { + errChannel = Tcl_GetStdChannel(TCL_STDERR); + if (errChannel) { + // + // The following statement guarantees that the errorInfo + // variable is set properly. + // + Tcl_AddErrorInfo(interp, ""); + Tcl_WriteObj(errChannel, Tcl_GetVar2Ex(interp, "errorInfo", + NULL, TCL_GLOBAL_ONLY)); + Tcl_WriteChars(errChannel, "\n", 1); + } + exitCode = 1; } - - /* - * If a script file was specified then just source that file - * and quit. - */ - - if (tclStartupScriptFileName != NULL) { - -// if (numParam == 0) - code = Tcl_EvalFile(interp, tclStartupScriptFileName); -// else -// code = EvalFileWithParameters(interp, tclStartupScriptFileName, 0, 0, 0, 1); + goto done; + } + /* + * Process commands from stdin until there's an end-of-file. Note + * that we need to fetch the standard channels again after every + * eval, since they may have been changed. + */ + + commandPtr = Tcl_NewObj(); + Tcl_IncrRefCount(commandPtr); + + inChannel = Tcl_GetStdChannel(TCL_STDIN); + outChannel = Tcl_GetStdChannel(TCL_STDOUT); + gotPartial = 0; + + while (true) { + if (tty) { + Tcl_Obj *promptCmdPtr; - if (code != TCL_OK) { - errChannel = Tcl_GetStdChannel(TCL_STDERR); + char one[12] = "tcl_prompt1"; + char two[12] = "tcl_prompt2"; + promptCmdPtr = Tcl_GetVar2Ex(interp, + (gotPartial ? one : two), + NULL, TCL_GLOBAL_ONLY); + if (promptCmdPtr == NULL) { + defaultPrompt: + if (!gotPartial && outChannel) { + Tcl_WriteChars(outChannel, "OpenSees > ", 11); + } + } else { + + code = Tcl_EvalObjEx(interp, promptCmdPtr, 0); + + inChannel = Tcl_GetStdChannel(TCL_STDIN); + outChannel = Tcl_GetStdChannel(TCL_STDOUT); + errChannel = Tcl_GetStdChannel(TCL_STDERR); + if (code != TCL_OK) { if (errChannel) { - // - // The following statement guarantees that the errorInfo - // variable is set properly. - // - Tcl_AddErrorInfo(interp, ""); - Tcl_WriteObj(errChannel, Tcl_GetVar2Ex(interp, "errorInfo", - NULL, TCL_GLOBAL_ONLY)); - Tcl_WriteChars(errChannel, "\n", 1); + Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); + Tcl_WriteChars(errChannel, "\n", 1); } - exitCode = 1; + Tcl_AddErrorInfo(interp, + "\n (script that generates prompt)"); + goto defaultPrompt; + } } + if (outChannel) { + Tcl_Flush(outChannel); + } + } + if (!inChannel) { + goto done; + } + length = Tcl_GetsObj(inChannel, commandPtr); + if (length < 0) { + goto done; + } + if ((length == 0) && Tcl_Eof(inChannel) && (!gotPartial)) { goto done; } + /* - * Process commands from stdin until there's an end-of-file. Note - * that we need to fetch the standard channels again after every - * eval, since they may have been changed. + * Add the newline removed by Tcl_GetsObj back to the string. */ - - commandPtr = Tcl_NewObj(); - Tcl_IncrRefCount(commandPtr); + Tcl_AppendToObj(commandPtr, "\n", 1); + + gotPartial = 0; + code = Tcl_RecordAndEvalObj(interp, commandPtr, 0); inChannel = Tcl_GetStdChannel(TCL_STDIN); outChannel = Tcl_GetStdChannel(TCL_STDOUT); - gotPartial = 0; - - while (1) { - if (tty) { - Tcl_Obj *promptCmdPtr; - - char one[12] = "tcl_prompt1"; - char two[12] = "tcl_prompt2"; - promptCmdPtr = Tcl_GetVar2Ex(interp, - (gotPartial ? one : two), - NULL, TCL_GLOBAL_ONLY); - if (promptCmdPtr == NULL) { - defaultPrompt: - if (!gotPartial && outChannel) { - Tcl_WriteChars(outChannel, "OpenSees > ", 11); - } - } else { - - code = Tcl_EvalObjEx(interp, promptCmdPtr, 0); - - inChannel = Tcl_GetStdChannel(TCL_STDIN); - outChannel = Tcl_GetStdChannel(TCL_STDOUT); - errChannel = Tcl_GetStdChannel(TCL_STDERR); - if (code != TCL_OK) { - if (errChannel) { - Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); - Tcl_WriteChars(errChannel, "\n", 1); - } - Tcl_AddErrorInfo(interp, - "\n (script that generates prompt)"); - goto defaultPrompt; - } - } - if (outChannel) { - Tcl_Flush(outChannel); - } - } - if (!inChannel) { - goto done; - } - length = Tcl_GetsObj(inChannel, commandPtr); - if (length < 0) { - goto done; - } - if ((length == 0) && Tcl_Eof(inChannel) && (!gotPartial)) { - goto done; - } - - /* - * Add the newline removed by Tcl_GetsObj back to the string. - */ - - Tcl_AppendToObj(commandPtr, "\n", 1); - // if (!TclObjCommandComplete(commandPtr)) { - // gotPartial = 1; - // continue; - // } - - gotPartial = 0; - code = Tcl_RecordAndEvalObj(interp, commandPtr, 0); - inChannel = Tcl_GetStdChannel(TCL_STDIN); - outChannel = Tcl_GetStdChannel(TCL_STDOUT); - errChannel = Tcl_GetStdChannel(TCL_STDERR); - Tcl_DecrRefCount(commandPtr); - commandPtr = Tcl_NewObj(); - Tcl_IncrRefCount(commandPtr); - if (code != TCL_OK) { - if (errChannel) { - Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); - Tcl_WriteChars(errChannel, "\n", 1); - } - } else if (tty) { - resultPtr = Tcl_GetObjResult(interp); - Tcl_GetStringFromObj(resultPtr, &length); - if ((length > 0) && outChannel) { - Tcl_WriteObj(outChannel, resultPtr); - Tcl_WriteChars(outChannel, "\n", 1); - } - } + errChannel = Tcl_GetStdChannel(TCL_STDERR); + Tcl_DecrRefCount(commandPtr); + commandPtr = Tcl_NewObj(); + Tcl_IncrRefCount(commandPtr); + if (code != TCL_OK) { + if (errChannel) { + Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); + Tcl_WriteChars(errChannel, "\n", 1); + } + } else if (tty) { + resultPtr = Tcl_GetObjResult(interp); + Tcl_GetStringFromObj(resultPtr, &length); + if ((length > 0) && outChannel) { + Tcl_WriteObj(outChannel, resultPtr); + Tcl_WriteChars(outChannel, "\n", 1); + } } + } - done: +done: - if (commandPtr != NULL) { - Tcl_DecrRefCount(commandPtr); - } + if (commandPtr != NULL) + Tcl_DecrRefCount(commandPtr); #if defined(_PARALLEL_PROCESSING) || defined( _PARALLEL_INTERPRETERS) - return; + return; #endif - /* - * Rather than calling exit, invoke the "exit" command so that - * users can replace "exit" with some other command to do additional - * cleanup on exit. The Tcl_Eval call should never return. - */ - Tcl_Eval(interp, buffer); + /* + * Rather than calling exit, invoke the "exit" command so that + * users can replace "exit" with some other command to do additional + * cleanup on exit. The Tcl_Eval call should never return. + */ + Tcl_Eval(interp, buffer); - Tcl_Eval(interp, "quit"); + Tcl_Eval(interp, "quit"); - return exitCode; + return exitCode; } From aacc1a3b9af7919d1aa9ef703c236f0150427b7f Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 1 Sep 2025 07:56:58 -0700 Subject: [PATCH 239/261] Update build_cmake.yml --- .github/workflows/build_cmake.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index b6c74adf87..cc4d3520e3 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -160,6 +160,12 @@ jobs: export PYTHONPATH="./build/lib/" python3 -c "import sys; print(sys.path)" python3 ./EXAMPLES/ExamplePython/example_variable_analysis.py + - name: Run pytest in tests/ folder + run: | + python3 -m pip install pytest + cd tests + cp lib/opensees.so . + pytest -v - name: Upload Artifacts uses: actions/upload-artifact@v4 with: From 9fcba833d0df9bd80ead5758a30b38bef1956be2 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 1 Sep 2025 07:58:15 -0700 Subject: [PATCH 240/261] Update build_cmake.yml --- .github/workflows/build_cmake.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index cc4d3520e3..87fe992310 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -163,8 +163,8 @@ jobs: - name: Run pytest in tests/ folder run: | python3 -m pip install pytest + cp lib/opensees.so tests/ cd tests - cp lib/opensees.so . pytest -v - name: Upload Artifacts uses: actions/upload-artifact@v4 From a081cb0ce92951d54317ef554838d44b0b3116e5 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 1 Sep 2025 08:11:32 -0700 Subject: [PATCH 241/261] Update build_cmake.yml --- .github/workflows/build_cmake.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 87fe992310..d5b385a89d 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -163,7 +163,7 @@ jobs: - name: Run pytest in tests/ folder run: | python3 -m pip install pytest - cp lib/opensees.so tests/ + cp build/lib/opensees.so tests/ cd tests pytest -v - name: Upload Artifacts From 123996102166623a66fbd8c1ee7a4488744191d9 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Tue, 2 Sep 2025 14:18:03 -0700 Subject: [PATCH 242/261] Update InitStressMaterial.cpp Making tolerance relative to initial stress (again) --- SRC/material/uniaxial/InitStressMaterial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/material/uniaxial/InitStressMaterial.cpp b/SRC/material/uniaxial/InitStressMaterial.cpp index 643b0d7d14..0511aed829 100644 --- a/SRC/material/uniaxial/InitStressMaterial.cpp +++ b/SRC/material/uniaxial/InitStressMaterial.cpp @@ -82,7 +82,7 @@ int InitStressMaterial::findInitialStrain(void) { // determine the initial strain - double tol = 1e-12; + double tol = (sigInit == 0.0) ? 1e-12 : fabs(sigInit)*1e-12; double dSig = sigInit; double tStrain = 0.0, tStress = 0.0; int count = 0; From 57c698573903c253f2e2a3a99faae786385ba06f Mon Sep 17 00:00:00 2001 From: Javad Date: Fri, 5 Sep 2025 15:02:10 -0400 Subject: [PATCH 243/261] Adding CreepShrinkageACI209 uniaxial material - Add CreepShrinkageACI209.{h,cpp} - Register command in SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp - Add MAT_TAG_CreepShrinkageACI209 (236) in SRC/classTags.h - Update SRC/material/uniaxial/CMakeLists.txt --- SRC/classTags.h | 1 + .../OpenSeesUniaxialMaterialCommands.cpp | 3 + SRC/material/uniaxial/CMakeLists.txt | 2 + .../uniaxial/CreepShrinkageACI209.cpp | 712 ++++++++++++++++++ SRC/material/uniaxial/CreepShrinkageACI209.h | 134 ++++ 5 files changed, 852 insertions(+) create mode 100644 SRC/material/uniaxial/CreepShrinkageACI209.cpp create mode 100644 SRC/material/uniaxial/CreepShrinkageACI209.h diff --git a/SRC/classTags.h b/SRC/classTags.h index 8dcf509b0c..1bf6557203 100644 --- a/SRC/classTags.h +++ b/SRC/classTags.h @@ -259,6 +259,7 @@ #define MAT_TAG_TzSandCPT 233 #define MAT_TAG_QbSandCPT 234 #define MAT_TAG_ASDSteel1DMaterial 235 +#define MAT_TAG_CreepShrinkageACI209 236 #define MAT_TAG_FedeasMaterial 1000 #define MAT_TAG_FedeasBond1 1001 diff --git a/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp b/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp index 6932446fa9..bb646df9b8 100644 --- a/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp +++ b/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp @@ -264,6 +264,7 @@ void* OPS_TDConcreteNL(void); void* OPS_TDConcreteMC10(void); void* OPS_TDConcreteMC10NL(void); void* OPS_CreepMaterial(void); +void* OPS_CreepShrinkageACI209(void); void* OPS_CoulombDamperMaterial(); void* OPS_GMG_CyclicReinforcedConcrete(); @@ -625,6 +626,8 @@ static int setUpUniaxialMaterials(void) { std::make_pair("TDConcreteMC10NL", &OPS_TDConcreteMC10NL)); uniaxialMaterialsMap.insert( std::make_pair("Creep", &OPS_CreepMaterial)); + uniaxialMaterialsMap.insert( + std::make_pair("CreepShrinkageACI209", &OPS_CreepShrinkageACI209)); uniaxialMaterialsMap.insert( std::make_pair("CoulombDamper", &OPS_CoulombDamperMaterial)); uniaxialMaterialsMap.insert(std::make_pair( diff --git a/SRC/material/uniaxial/CMakeLists.txt b/SRC/material/uniaxial/CMakeLists.txt index a78d03e16a..1cce125760 100644 --- a/SRC/material/uniaxial/CMakeLists.txt +++ b/SRC/material/uniaxial/CMakeLists.txt @@ -103,6 +103,7 @@ target_sources(OPS_Material ConfinedConcrete01.cpp ContinuumUniaxial.cpp CreepMaterial.cpp + CreepShrinkageACI209.cpp CubicSpline.cpp DamperMaterial.cpp DegradingPinchedBW.cpp @@ -231,6 +232,7 @@ target_sources(OPS_Material ConfinedConcrete01.h ContinuumUniaxial.h CreepMaterial.h + CreepShrinkageACI209.h CubicSpline.h DamperMaterial.h DegradingPinchedBW.h diff --git a/SRC/material/uniaxial/CreepShrinkageACI209.cpp b/SRC/material/uniaxial/CreepShrinkageACI209.cpp new file mode 100644 index 0000000000..cacc5bdcea --- /dev/null +++ b/SRC/material/uniaxial/CreepShrinkageACI209.cpp @@ -0,0 +1,712 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + + //---------------------------------------------------------------------------------------------------------------------------- + // Developed by: + // Javad Esmaeelpour (jesmaeel@tennessee.edu) + // Mark D. Denavit (mdenavit@utk.edu) + // Michael H. Scott (michael.scott@oregonstate.edu) + // + // Based on TDConcrete implementations by: + // Adam M. Knaack (adam.knaack@schaefer-inc.com) + // Schaefer-Inc, Cincinnati, Ohio, USA + // Nikola D. Tosic (ntosic@imk.grf.bg.ac.rs) + // Department for Materials and Structure, Faculty of Civil Engineering, University of Belgrade, Serbia + // Yahya C. Kurama (ykurama@nd.edu) + // Department of Civil and Environmental Engineering and Earth Sciences, College of Engineering, University of Notre Dame, Notre Dame, Indiana, USA + //---------------------------------------------------------------------------------------------------------------------------- + + //---------------------------------------------------------------------------------------------------------------------------- + // Description: This file contains the source code of CreepShrinkageACI209. + // CreepShrinkageACI209 is a wrapper that imposes creep and shrinkage evoluation equations + // to any uniaxialMaterial. + //---------------------------------------------------------------------------------------------------------------------------- + +#include +#include +#include +#include + + +#include "CreepShrinkageACI209.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static int numCreepShrinkageACI209 = 0; + +void * +OPS_CreepShrinkageACI209() { + if (numCreepShrinkageACI209 == 0) { + numCreepShrinkageACI209 = 1; + } + + UniaxialMaterial *theMaterial = 0; + + int iData; + int numData; + int numArgs; + + numArgs = OPS_GetNumRemainingInputArgs(); + + if (numArgs == 13) { + double dData[12]; + + numData = 1; + if (OPS_GetIntInput(&numData, &iData) != 0) { + opserr << "WARNING: invalid uniaxialMaterial CreepShrinkageACI209 tag\n"; + return 0; + } + + numData = 12; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "WARNING: invalid material property definition\n"; + return 0; + } + + theMaterial = new CreepShrinkageACI209(iData,dData[0],dData[1],dData[2],dData[3],dData[4],dData[5],dData[6],dData[7],dData[8],dData[9],dData[10],dData[11]); + if (theMaterial == 0) { + opserr << "WARNING: could not create uniaxialMaterial of type CreepShrinkageACI209 \n"; + return 0; + } + + return theMaterial; + } + if (numArgs == 10) { + double dData[14]; + + numData = 1; + if (OPS_GetIntInput(&numData, &iData) != 0) { + opserr << "WARNING: invalid uniaxialMaterial CreepShrinkageACI209 tag\n"; + return 0; + } + + int wrappedMatl; + if (OPS_GetIntInput(&numData, &wrappedMatl) != 0) { + opserr << "WARNING: invalid uniaxialMaterial CreepShrinkageACI209 wrapped material tag\n"; + return 0; + } + + UniaxialMaterial *matl = OPS_getUniaxialMaterial(wrappedMatl); + if (matl == 0) { + opserr << "WARNING: CreepShrinkageACI209 - unable to find material with tag " << wrappedMatl << endln; + return 0; + } + + numData = 8; + if (OPS_GetDoubleInput(&numData, &dData[6]) != 0) { + opserr << "WARNING: invalid material property definition\n"; + return 0; + } + + theMaterial = new CreepShrinkageACI209(iData,*matl,dData[6],dData[7],dData[8],dData[9],dData[10],dData[11],dData[12],dData[13]); + if (theMaterial == 0) { + opserr << "WARNING: could not create uniaxialMaterial of type CreepShrinkageACI209 \n"; + return 0; + } + + return theMaterial; + } + + return 0; +} + +CreepShrinkageACI209::CreepShrinkageACI209(int tag, double _fc, double _fcu, double _epscu, double _Ec, double _age, double _epsshu, double _epssha, double _tcr, double _epscru, double _epscra, double _epscrd, double _tcast): + UniaxialMaterial(tag, MAT_TAG_CreepShrinkageACI209), wrappedMaterial(0), + Ec(_Ec), age(_age), epsshu(_epsshu), epssha(_epssha), tcr(_tcr), epscru(_epscru), epscra(_epscra), epscrd(_epscrd), tcast(_tcast), maxSize(startSize), + DSIG_i(0), TIME_i(0), committedCreepStress(0.0) +{ + wrappedMaterial = new Concrete02IS(0,Ec,-fabs(_fc),2*(-fabs(_fc))/Ec,_fcu,_epscu); + + epsshu = -fabs(epsshu); + epscru = fabs(epscru); + + this->revertToStart(); + this->expandArrays(); + DSIG_i[0] = 0.0; + TIME_i[0] = getCurrentTime(); +} + +void +CreepShrinkageACI209::expandArrays() +{ + + if (DSIG_i == 0) + DSIG_i = new double[maxSize]; + + if (TIME_i == 0) + TIME_i = new double[maxSize]; + + if (historyPointCount+1 >= maxSize) { + maxSize += growSize; + + double *c = new double[maxSize]; + double *e = new double[maxSize]; + for (int i = 0; i <= historyPointCount; i++) { + c[i] = DSIG_i[i]; + e[i] = TIME_i[i]; + } + + if (DSIG_i != 0) + delete [] DSIG_i; + if (TIME_i != 0) + delete [] TIME_i; + DSIG_i = c; + TIME_i = e; + } +} + +CreepShrinkageACI209::CreepShrinkageACI209(int tag, UniaxialMaterial &matl, double _age, double _epsshu, double _epssha, double _tcr, double _epscru, double _epscra, double _epscrd, double _tcast): + UniaxialMaterial(tag, MAT_TAG_CreepShrinkageACI209), wrappedMaterial(0), + age(_age), epsshu(_epsshu), epssha(_epssha), tcr(_tcr), epscru(_epscru), epscra(_epscra), epscrd(_epscrd), tcast(_tcast), maxSize(startSize), + DSIG_i(0), TIME_i(0), committedCreepStress(0.0) +{ + wrappedMaterial = matl.getCopy(); + if (wrappedMaterial == 0) { + opserr << "CreepShrinkageACI209::CreepShrinkageACI209 - failed to get copy of material" << endln; + exit(-1); + } + + Ec = wrappedMaterial->getInitialTangent(); + + epsshu = -fabs(epsshu); + epscru = fabs(epscru); + + this->revertToStart(); + + this->expandArrays(); + DSIG_i[0] = 0.0; + TIME_i[0] = getCurrentTime(); +} + +CreepShrinkageACI209::CreepShrinkageACI209(void): + UniaxialMaterial(0, MAT_TAG_CreepShrinkageACI209), wrappedMaterial(0), maxSize(startSize), + DSIG_i(0), TIME_i(0), committedCreepStress(0.0) +{ +} + +CreepShrinkageACI209::~CreepShrinkageACI209(void) +{ + if (wrappedMaterial != 0) + delete wrappedMaterial; + if (DSIG_i != 0) + delete [] DSIG_i; + if (TIME_i != 0) + delete [] TIME_i; +} + +UniaxialMaterial* CreepShrinkageACI209::getCopy(void) +{ + CreepShrinkageACI209 *theCopy = new CreepShrinkageACI209(this->getTag(), *wrappedMaterial, + age, epsshu, epssha, tcr, epscru, epscra, epscrd, tcast); + + // Copy state variables + theCopy->trialStress = trialStress; + theCopy->trialTangent = trialTangent; + theCopy->trialTotalStrain = trialTotalStrain; + theCopy->trialCreepStrain = trialCreepStrain; + theCopy->trialShrinkageStrain = trialShrinkageStrain; + theCopy->trialMechanicalStrain = trialMechanicalStrain; + + theCopy->committedStress = committedStress; + theCopy->committedTangent = committedTangent; + theCopy->committedCreepStrain = committedCreepStrain; + theCopy->committedCreepStress = committedCreepStress; + theCopy->committedShrinkageStrain = committedShrinkageStrain; + theCopy->committedMechanicalStrain = committedMechanicalStrain; + theCopy->committedTotalStrain = committedTotalStrain; + + theCopy->iterationInStep = iterationInStep; + theCopy->historyPointCount = historyPointCount; + + // Ensure array capacity and copy history + theCopy->maxSize = maxSize; + theCopy->DSIG_i = new double[maxSize]; + theCopy->TIME_i = new double[maxSize]; + + for (int i = 0; i <= historyPointCount; i++) { + theCopy->DSIG_i[i] = DSIG_i[i]; + theCopy->TIME_i[i] = TIME_i[i]; + } + + return theCopy; +} + +double +CreepShrinkageACI209::getInitialTangent(void) +{ + return wrappedMaterial->getInitialTangent(); +} + +double +CreepShrinkageACI209::getCurrentTime(void) +{ + double currentTime = 0.0; + Domain * theDomain = ops_TheActiveDomain; + if (theDomain != 0) { + currentTime = theDomain->getCurrentTime(); + } + return currentTime; +} + +double +CreepShrinkageACI209::setCreepStrain(double time) +{ + double creep = 0.0, phi = 0.0; + const double denom_tcr = 1.25 * pow(tcr, -0.118); + double tmtp = 0.0; + double a; + double f2; + double f3; + + for (int i = 1; i <= historyPointCount; ++i) { + tmtp = time - TIME_i[i]; + if (tmtp <= 0.0) continue; // Guard against negative time. + + a = pow(tmtp, epscra); + f2 = (epscru * a) / (epscrd + a); + f3 = (1.25 * pow(TIME_i[i] - tcast, -0.118)) / denom_tcr; + phi = f2 * f3; + + creep += phi * DSIG_i[i] / Ec; + } + return creep; +} + +double +CreepShrinkageACI209::setShrink(double time) +{ + double tD = age; + double shrink = 0.0; + if (time-(tD) < 0) { + shrink = 0.0; + } else { + shrink = (time-(tD)) / (epssha + (time - (tD))) * epsshu; + } + return shrink; +} + +int +CreepShrinkageACI209::setTrialStrain(double strain, double strainRate) +{ + double t = getCurrentTime(); + + + // Enforce non-negative time only when creep is enabled. + if (ops_Creep == 1 && t < 0.0) { + opserr << "CreepShrinkageACI209::setTrialStrain - Negative time (" << t + << ") not allowed when creep is active.\n"; + return -1; + } + + trialTotalStrain = strain; + + if (ops_Creep == 1) { + if (fabs(t-TIME_i[historyPointCount]) <= 0.0001) { + trialCreepStrain = committedCreepStrain; + trialShrinkageStrain = committedShrinkageStrain; + } else { + if (iterationInStep < 1) { + trialCreepStrain = setCreepStrain(t); + trialShrinkageStrain = setShrink(t); + } + } + } else { + trialCreepStrain = committedCreepStrain; + trialShrinkageStrain = committedShrinkageStrain; + } + + trialMechanicalStrain = trialTotalStrain - trialCreepStrain - trialShrinkageStrain; + wrappedMaterial->setTrialStrain(trialMechanicalStrain, strainRate); + trialStress = wrappedMaterial->getStress(); + trialTangent = wrappedMaterial->getTangent(); + + iterationInStep ++; + return 0; +} + +double +CreepShrinkageACI209::getStrain(void) +{ + return trialTotalStrain; +} + +double +CreepShrinkageACI209::getStress(void) +{ + return trialStress; +} + +double +CreepShrinkageACI209::getTangent(void) +{ + return trialTangent; +} + + +int CreepShrinkageACI209::commitState(void) +{ + iterationInStep = 0; + + if (ops_Creep == 1 && fabs(trialStress - committedCreepStress) > 1e-12) { + double dSig = trialStress - committedCreepStress; + this->expandArrays(); + historyPointCount++; + DSIG_i[historyPointCount] = dSig; + TIME_i[historyPointCount] = getCurrentTime(); + + committedCreepStress = trialStress; + } + + committedTangent = trialTangent; + committedStress = trialStress; + committedTotalStrain = trialTotalStrain; + committedShrinkageStrain = trialShrinkageStrain; + committedCreepStrain = trialCreepStrain; + committedMechanicalStrain = trialMechanicalStrain; + + wrappedMaterial->commitState(); + return 0; +} + + +int + CreepShrinkageACI209::revertToLastCommit(void) +{ + // Restore trial state to last committed state + trialTotalStrain = committedTotalStrain; + trialShrinkageStrain = committedShrinkageStrain; + trialCreepStrain = committedCreepStrain; + trialMechanicalStrain = committedMechanicalStrain; + + trialTangent = committedTangent; + trialStress = committedStress; + + wrappedMaterial->revertToLastCommit(); + + return 0; +} + +int +CreepShrinkageACI209::revertToStart(void) +{ + + committedTangent = Ec; + committedStress = 0.0; + trialStress = 0.0; + committedCreepStress = 0.0; + trialTangent = Ec; + + + historyPointCount = 0; + + + trialTotalStrain = 0.0; + committedTotalStrain = 0.0; + trialCreepStrain = 0.0; + trialShrinkageStrain = 0.0; + trialMechanicalStrain = 0.0; + committedCreepStrain = 0.0; + committedShrinkageStrain = 0.0; + committedMechanicalStrain = 0.0; + + iterationInStep = 0; + + if (wrappedMaterial) + wrappedMaterial->revertToStart(); + + return 0; +} + +int +CreepShrinkageACI209::sendSelf(int commitTag, Channel &theChannel) +{ + int res = 0; + int dbTag = this->getDbTag(); + static ID classTags(4); + + classTags(0) = wrappedMaterial->getClassTag(); + int matDbTag = wrappedMaterial->getDbTag(); + if (matDbTag == 0) { + matDbTag = theChannel.getDbTag(); + if (matDbTag != 0) + wrappedMaterial->setDbTag(matDbTag); + } + classTags(1) = matDbTag; + classTags(2) = this->getTag(); + classTags(3) = maxSize; + + res = theChannel.sendID(dbTag, commitTag, classTags); + if (res < 0) { + opserr << "CreepShrinkageACI209::sendSelf -- could not send ID" << endln; + return res; + } + + Vector data(27 + maxSize*2); + int i = 0; + data(i++) = tcr; + data(i++) = Ec; + data(i++) = age; + data(i++) = epsshu; + data(i++) = epssha; + data(i++) = epscra; + data(i++) = epscru; + data(i++) = epscrd; + data(i++) = tcast; + + data(i++) = committedStress; + data(i++) = committedTangent; + data(i++) = committedCreepStress; + + data(i++) = historyPointCount; + data(i++) = trialCreepStrain; + data(i++) = trialShrinkageStrain; + data(i++) = trialMechanicalStrain; + data(i++) = committedMechanicalStrain; + data(i++) = committedCreepStrain; + data(i++) = committedShrinkageStrain; + data(i++) = trialTotalStrain; + data(i++) = committedTotalStrain; + data(i++) = iterationInStep; + + for (int j = 0; j < maxSize; j++, i++) + data(i) = DSIG_i[j]; + for (int j = 0; j < maxSize; j++, i++) + data(i) = TIME_i[j]; + + res = theChannel.sendVector(this->getDbTag(), commitTag, data); + if (res < 0) { + opserr << "CreepShrinkageACI209::sendSelf - failed to send Vector" << endln; + return res; + } + + res = wrappedMaterial->sendSelf(commitTag, theChannel); + if (res < 0) { + opserr << "CreepShrinkageACI209::sendSelf -- could not send UniaxialMaterial" << endln; + return res; + } + + return res; +} + +int +CreepShrinkageACI209::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int res = 0; + static ID idata(4); + int dbTag = this->getDbTag(); + + res = theChannel.recvID(dbTag, commitTag, idata); + if (res < 0) { + opserr << "CreepShrinkageACI209::recvSelf() - failed to receive data\n"; + return res; + } + + this->setTag(idata(2)); + maxSize = idata(3); + + Vector data(27 + maxSize*2); + + if (theChannel.recvVector(this->getDbTag(), commitTag, data) < 0) { + opserr << "CreepShrinkageACI209::recvSelf() - failed to recvSelf\n"; + return -1; + } + + int i = 0; + tcr = data(i++); + Ec = data(i++); + age = data(i++); + epsshu = data(i++); + epssha = data(i++); + epscra = data(i++); + epscru = data(i++); + epscrd = data(i++); + tcast = data(i++); + + committedStress = data(i++); + committedTangent = data(i++); + committedCreepStress = data(i++); + + historyPointCount = data(i++); + trialCreepStrain = data(i++); + trialShrinkageStrain = data(i++); + trialMechanicalStrain = data(i++); + committedMechanicalStrain = data(i++); + committedCreepStrain = data(i++); + committedShrinkageStrain = data(i++); + trialTotalStrain = data(i++); + committedTotalStrain = data(i++); + iterationInStep = data(i++); + + if (DSIG_i != 0) delete [] DSIG_i; + DSIG_i = new double [maxSize]; + if (TIME_i != 0) delete [] TIME_i; + TIME_i = new double [maxSize]; + + for (int j = 0; j < maxSize; j++, i++) + DSIG_i[j] = data(i); + for (int j = 0; j < maxSize; j++, i++) + TIME_i[j] = data(i); + + trialTangent = committedTangent; + trialStress = committedStress; + + int matClassTag = idata(0); + + if (wrappedMaterial == 0) { + wrappedMaterial = theBroker.getNewUniaxialMaterial(matClassTag); + if (wrappedMaterial == 0) { + opserr << "CreepShrinkageACI209::recvSelf -- could not get a UniaxialMaterial" << endln; + return -1; + } + } + + dbTag = idata(1); + if (wrappedMaterial->getClassTag() != matClassTag) { + delete wrappedMaterial; + wrappedMaterial = theBroker.getNewUniaxialMaterial(matClassTag); + if (wrappedMaterial == 0) { + opserr << "CreepShrinkageACI209::recvSelf -- could not get a UniaxialMaterial" << endln; + return -1; + } + } + + wrappedMaterial->setDbTag(dbTag); + res = wrappedMaterial->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "CreepShrinkageACI209::recvSelf -- count not receive Uniaxialmaterial" << endln; + return res; + } + + return res; +} + +void +CreepShrinkageACI209::Print(OPS_Stream &s, int flag) +{ + s << "CreepShrinkageACI209:(strain, stress, tangent) " << trialTotalStrain << " " << trialStress << " " << trialTangent << endln; +} + + +int +CreepShrinkageACI209::getVariable(const char *varName, Information &theInfo) +{ + return -1; +} + +Response* CreepShrinkageACI209::setResponse(const char **argv, int argc, + OPS_Stream &theOutput) +{ + Response *theResponse = 0; + + theOutput.tag("UniaxialMaterialOutput"); + theOutput.attr("matType", this->getClassType()); + theOutput.attr("matTag", this->getTag()); + + if (strcmp(argv[0],"stress") == 0) { + theOutput.tag("ResponseType", "sigma11"); + theResponse = new MaterialResponse(this, 1, this->getStress()); + } else if (strcmp(argv[0],"tangent") == 0) { + theOutput.tag("ResponseType", "C11"); + theResponse = new MaterialResponse(this, 2, this->getTangent()); + } else if (strcmp(argv[0],"strain") == 0) { + theOutput.tag("ResponseType", "eps11"); + theResponse = new MaterialResponse(this, 3, this->getStrain()); + } else if ((strcmp(argv[0],"stressStrain") == 0) || (strcmp(argv[0],"stressANDstrain") == 0)) { + theOutput.tag("ResponseType", "sig11"); + theOutput.tag("ResponseType", "eps11"); + theResponse = new MaterialResponse(this, 4, Vector(2)); + } else if (strcmp(argv[0],"CreepStressStrainTangent")==0) { + theOutput.tag("ResponseType", "sig11"); + theOutput.tag("ResponseType", "eps11"); + theOutput.tag("ResponseType", "C11"); + theOutput.tag("ResponseType", "CreepStrain"); + theOutput.tag("ResponseType", "MechStrain"); + theOutput.tag("ResponseType", "ShrinkStrain"); + theResponse = new MaterialResponse(this, 6, Vector(6)); + } else if (strcmp(argv[0],"stressStrainTangent") == 0) { + theOutput.tag("ResponseType", "sig11"); + theOutput.tag("ResponseType", "eps11"); + theOutput.tag("ResponseType", "C11"); + theResponse = new MaterialResponse(this, 5, Vector(3)); + } + + theOutput.endTag(); + return theResponse; +} + +int +CreepShrinkageACI209::getResponse(int responseID, Information &matInfo) +{ + static Vector stressStrain(2); + static Vector stressStrainTangent(3); + static Vector CreepStressStrainTangent(6); + + switch (responseID) { + case 1: + matInfo.setDouble(trialStress); + return 0; + + case 2: + matInfo.setDouble(trialTangent); + return 0; + + case 3: + matInfo.setDouble(trialTotalStrain); + return 0; + + case 4: + stressStrain(0) = trialStress; + stressStrain(1) = trialTotalStrain; + matInfo.setVector(stressStrain); + return 0; + + case 5: + stressStrainTangent(0) = trialStress; + stressStrainTangent(1) = trialTotalStrain; + stressStrainTangent(2) = trialTangent; + matInfo.setVector(stressStrainTangent); + return 0; + + case 6: + CreepStressStrainTangent(0) = trialStress; + CreepStressStrainTangent(1) = trialTotalStrain; + CreepStressStrainTangent(2) = trialTangent; + CreepStressStrainTangent(3) = trialCreepStrain; + CreepStressStrainTangent(4) = trialMechanicalStrain; + CreepStressStrainTangent(5) = trialShrinkageStrain; + matInfo.setVector(CreepStressStrainTangent); + return 0; + + default: + return -1; + } +} \ No newline at end of file diff --git a/SRC/material/uniaxial/CreepShrinkageACI209.h b/SRC/material/uniaxial/CreepShrinkageACI209.h new file mode 100644 index 0000000000..0c01e0dd1e --- /dev/null +++ b/SRC/material/uniaxial/CreepShrinkageACI209.h @@ -0,0 +1,134 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + + //---------------------------------------------------------------------------------------------------------------------------- + // Developed by: + // Javad Esmaeelpour (jesmaeel@tennessee.edu) + // Mark D. Denavit (mdenavit@utk.edu) + // Michael H. Scott (michael.scott@oregonstate.edu) + // + // Based on TDConcrete implementations by: + // Adam M. Knaack (adam.knaack@schaefer-inc.com) + // Schaefer-Inc, Cincinnati, Ohio, USA + // Nikola D. Tosic (ntosic@imk.grf.bg.ac.rs) + // Department for Materials and Structure, Faculty of Civil Engineering, University of Belgrade, Serbia + // Yahya C. Kurama (ykurama@nd.edu) + // Department of Civil and Environmental Engineering and Earth Sciences, College of Engineering, University of Notre Dame, Notre Dame, Indiana, USA + //---------------------------------------------------------------------------------------------------------------------------- + + //---------------------------------------------------------------------------------------------------------------------------- + // Description: This file contains the source code of CreepShrinkageACI209. + // CreepShrinkageACI209 is a wrapper that imposes creep and shrinkage evoluation equations + // to any uniaxialMaterial. + //---------------------------------------------------------------------------------------------------------------------------- + +#ifndef CreepShrinkageACI209_h +#define CreepShrinkageACI209_h + +#include +#include + +class CreepShrinkageACI209 : public UniaxialMaterial +{ +public: + // -- Core UniaxialMaterial Interface + CreepShrinkageACI209(int tag, double _fc, double _fcu, double _epscu, double _Ec, double _age, double _epsshu, double _epssha, double _tcr, double _epscru, double _epscra, double _epscrd, double _tcast); + CreepShrinkageACI209(int tag, UniaxialMaterial &matl, double _age, double _epsshu, double _epssha, double _tcr, double _epscru, double _epscra, double _epscrd, double _tcast); + CreepShrinkageACI209(void); + virtual ~CreepShrinkageACI209(); + + const char *getClassType(void) const {return "CreepShrinkageACI209";}; + double getInitialTangent(void); + UniaxialMaterial *getCopy(void); + + int setTrialStrain(double strain, double strainRate = 0.0); + double getStrain(void); + double getStress(void); + double getTangent(void); + + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + + void Print(OPS_Stream &s, int flag =0); + + int getVariable(const char *variable, Information &); + + // -- Functions for Recorders + Response *setResponse(const char **argv, int argc,OPS_Stream &theOutput); + int getResponse(int responseID, Information &matInfo); + +protected: + +private: + // -- Private Functions (Implementation Details) + double setCreepStrain(double time); // creep strain at global time + double getCurrentTime(void); // Current analysis time from the active OpenSees Domain. + double setShrink(double time); // Shrinkage strain at global time + void expandArrays(void); // Ensures capacity for the stress/time history arrays. + + + // -- Member Variables + UniaxialMaterial *wrappedMaterial; + + // matpar : Concrete FIXED PROPERTIES + + double tcr; // Tcr, creep age at loading used for phiu + double Ec; // Concrete modulus at loading + double age; // tD, analysis time when drying starts + double epsshu; // (eps_sh)u, ultimate shrinkage strain (ACI 209R Eq. 2-7) + double epssha; // f, shrinkage time-shape parameter (ACI 209R Eq. 2-7) + double epscra; // psi, creep time-shape parameter (ACI 209R Eq. 2-6) + double epscru; // phiu, ultimate creep coefficient (ACI 209R Eq. 2-6) + double epscrd; // d, creep time-shape parameter (ACI 209R Eq. 2-6) + double tcast; // Casting time in global analysis clock + + + double trialStress; // Current trial stress from wrapped material + double trialTangent; // Current trial tangent from wrapped material + double trialTotalStrain; // Total applied strain (input) + double trialCreepStrain; // Computed creep strain component + double trialShrinkageStrain; // Computed shrinkage strain component + double trialMechanicalStrain; // Mechanical strain sent to wrapped material + + double committedStress; // Last committed stress + double committedTangent; // Last committed tangent + double committedCreepStress; // Last committed creep stress + double committedCreepStrain; // Last committed creep strain + double committedShrinkageStrain; // Last committed shrinkage strain + double committedMechanicalStrain; // Last committed mechanical strain + double committedTotalStrain; // Last committed total strain + + int historyPointCount; // Number of points in stress-time history + int iterationInStep; // Iteration counter to avoid recomputing within same step + + enum{startSize=500, growSize=200}; + int maxSize; // Current allocated size of history arrays + + double *DSIG_i; // Stress increment history array [historyPointCount] + double *TIME_i; // Time history array [historyPointCount] +}; + + +#endif \ No newline at end of file From c18d95d4efce833220667b0b358b9f228cb92acb Mon Sep 17 00:00:00 2001 From: Michael Scott Date: Thu, 11 Sep 2025 13:20:41 -0700 Subject: [PATCH 244/261] Adding CreepShrinkageACI209 to Makefiles --- SRC/Makefile | 1 + SRC/material/uniaxial/Makefile | 1 + 2 files changed, 2 insertions(+) diff --git a/SRC/Makefile b/SRC/Makefile index 5d387c8e22..e7fdd5e2f3 100644 --- a/SRC/Makefile +++ b/SRC/Makefile @@ -888,6 +888,7 @@ MATERIAL_LIBS = $(FE)/material/Material.o \ $(FE)/material/uniaxial/TDConcreteMC10.o \ $(FE)/material/uniaxial/TDConcreteMC10NL.o \ $(FE)/material/uniaxial/CreepMaterial.o \ + $(FE)/material/uniaxial/CreepShrinkageACI209.o \ $(FE)/material/uniaxial/DegradingPinchedBW.o \ $(FE)/material/uniaxial/HystereticPoly.o \ $(FE)/material/uniaxial/HystereticSmooth.o \ diff --git a/SRC/material/uniaxial/Makefile b/SRC/material/uniaxial/Makefile index d702c16ab5..10c95f59ad 100644 --- a/SRC/material/uniaxial/Makefile +++ b/SRC/material/uniaxial/Makefile @@ -165,6 +165,7 @@ OBJS = UniaxialMaterial.o \ FlagShapeMaterial.o \ GMG_CyclicReinforcedConcrete.o \ CreepMaterial.o \ + CreepShrinkageACI209.o \ APDFMD.o \ APDMD.o \ APDVFD.o \ From 7f4ce6df18197b320a1135abaabdbb938986329f Mon Sep 17 00:00:00 2001 From: Michael Scott Date: Thu, 11 Sep 2025 14:44:26 -0700 Subject: [PATCH 245/261] Adding CreepShrinkageACI209 to VS project --- Win64/proj/material/material.vcxproj | 3 ++- Win64/proj/material/material.vcxproj.filters | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Win64/proj/material/material.vcxproj b/Win64/proj/material/material.vcxproj index 7e008282ef..c7e5859782 100644 --- a/Win64/proj/material/material.vcxproj +++ b/Win64/proj/material/material.vcxproj @@ -316,6 +316,7 @@ + @@ -1104,4 +1105,4 @@ - \ No newline at end of file + diff --git a/Win64/proj/material/material.vcxproj.filters b/Win64/proj/material/material.vcxproj.filters index 93f007111e..6098b76e46 100644 --- a/Win64/proj/material/material.vcxproj.filters +++ b/Win64/proj/material/material.vcxproj.filters @@ -1529,6 +1529,9 @@ uniaxial + + uniaxial + nD\OrthotropicRotatingAngleConcreteT2DMaterial01 @@ -2847,4 +2850,4 @@ nD - \ No newline at end of file + From 1d06117cb5ac5d3e419c571442c0a00e215bac6f Mon Sep 17 00:00:00 2001 From: Michael Scott Date: Fri, 12 Sep 2025 13:33:10 -0700 Subject: [PATCH 246/261] Putting #ifdefs around ItpackSolver() --- SRC/interpreter/OpenSeesCommands.cpp | 4 ++++ SRC/tcl/commands.cpp | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/SRC/interpreter/OpenSeesCommands.cpp b/SRC/interpreter/OpenSeesCommands.cpp index de1f2458fa..f8d129e6df 100644 --- a/SRC/interpreter/OpenSeesCommands.cpp +++ b/SRC/interpreter/OpenSeesCommands.cpp @@ -108,8 +108,10 @@ UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #endif #include +#ifdef _ITPACK #include #include +#endif #ifdef _PARALLEL_INTERPRETERS bool setMPIDSOEFlag = false; @@ -1475,8 +1477,10 @@ int OPS_System() } else if (strcmp(type,"Mumps") == 0) { theSOE = (LinearSOE*)OPS_MumpsSolver(); #endif +#ifdef _ITPACK } else if (strcmp(type,"Itpack") == 0) { theSOE = (LinearSOE*)OPS_ItpackLinSolver(); +#endif } else { opserr<<"WARNING unknown system type "< +#ifdef _ITPACK #include #include +#endif #include #include @@ -3432,7 +3434,8 @@ specifySOE(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) // theSOE = new UmfpackGenLinSOE(*theSolver, factLVALUE, factorOnce, printTime); theSOE = new UmfpackGenLinSOE(*theSolver); } - + +#ifdef _ITPACK else if (strcmp(argv[1],"Itpack") == 0) { // now must determine the type of solver to create from rest of args @@ -3444,7 +3447,8 @@ specifySOE(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) ItpackLinSolver *theSolver = new ItpackLinSolver(method); theSOE = new ItpackLinSOE(*theSolver); } - +#endif + else if (strcmp(argv[1],"FullGeneral") == 0) { // now must determine the type of solver to create from rest of args FullGenLinLapackSolver *theSolver = new FullGenLinLapackSolver(); From 8a2663d026e7b87c52350255b93d98aeaac825d0 Mon Sep 17 00:00:00 2001 From: Shahram Shaygani Date: Sat, 13 Sep 2025 12:24:57 +0330 Subject: [PATCH 247/261] Editing makefile for Ubuntu and adding HOME directory --- MAKES/Makefile.def.EC2-UBUNTU | 3 +++ MAKES/Makefile.def.Ubuntu20.04 | 3 +++ 2 files changed, 6 insertions(+) diff --git a/MAKES/Makefile.def.EC2-UBUNTU b/MAKES/Makefile.def.EC2-UBUNTU index 249632c0f5..1a6f9b11be 100644 --- a/MAKES/Makefile.def.EC2-UBUNTU +++ b/MAKES/Makefile.def.EC2-UBUNTU @@ -89,6 +89,9 @@ RELIABILITY_FLAG = -D_RELIABILITY # remove the directory from DIRS. BASE = ./usr/local +# Uncomment the HOME directory and if OpnSees is cloned to the +# path /home/ubuntu/OpenSees the HOME directory should be /home/ubuntu +# HOME = /home/ubuntu FE = $(HOME)/OpenSees/SRC AMDdir = $(HOME)/OpenSees/OTHER/AMD diff --git a/MAKES/Makefile.def.Ubuntu20.04 b/MAKES/Makefile.def.Ubuntu20.04 index 890a8863e4..f0a80ab9d2 100644 --- a/MAKES/Makefile.def.Ubuntu20.04 +++ b/MAKES/Makefile.def.Ubuntu20.04 @@ -62,6 +62,9 @@ RELIABILITY = NO_RELIABILITY # remove the directory from DIRS. BASE = ./usr/local +# Uncomment the HOME directory and if OpnSees is cloned to the +# path /home/ubuntu/OpenSees the HOME directory should be /home/ubuntu +# HOME = /home/ubuntu FE = $(HOME)/OpenSees/SRC AMDdir = $(HOME)/OpenSees/OTHER/AMD From ce097750303513ca515fa4fe6131d3e3c4961630 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Wed, 24 Sep 2025 16:46:28 -0700 Subject: [PATCH 248/261] Adding LAPACK files for dsygvx --- OTHER/LAPACK/Makefile | 4 +- OTHER/LAPACK/disnan.f | 77 ++++++ OTHER/LAPACK/dlaisnan.f | 88 +++++++ OTHER/LAPACK/dlansy.f | 240 +++++++++++++++++ OTHER/LAPACK/dlarf1l.f | 252 ++++++++++++++++++ OTHER/LAPACK/dlatrd.f | 343 +++++++++++++++++++++++++ OTHER/LAPACK/dorg2l.f | 196 ++++++++++++++ OTHER/LAPACK/dorgql.f | 294 +++++++++++++++++++++ OTHER/LAPACK/dorgtr.f | 253 ++++++++++++++++++ OTHER/LAPACK/dorm2l.f | 270 +++++++++++++++++++ OTHER/LAPACK/dormql.f | 340 ++++++++++++++++++++++++ OTHER/LAPACK/dormtr.f | 310 ++++++++++++++++++++++ OTHER/LAPACK/dsyevx.f | 555 ++++++++++++++++++++++++++++++++++++++++ OTHER/LAPACK/dsygs2.f | 285 +++++++++++++++++++++ OTHER/LAPACK/dsygst.f | 327 +++++++++++++++++++++++ OTHER/LAPACK/dsytd2.f | 323 +++++++++++++++++++++++ OTHER/LAPACK/dsytrd.f | 375 +++++++++++++++++++++++++++ OTHER/LAPACK/iladlc.f | 115 +++++++++ OTHER/LAPACK/iladlr.f | 118 +++++++++ 19 files changed, 4764 insertions(+), 1 deletion(-) create mode 100644 OTHER/LAPACK/disnan.f create mode 100644 OTHER/LAPACK/dlaisnan.f create mode 100644 OTHER/LAPACK/dlansy.f create mode 100644 OTHER/LAPACK/dlarf1l.f create mode 100644 OTHER/LAPACK/dlatrd.f create mode 100644 OTHER/LAPACK/dorg2l.f create mode 100644 OTHER/LAPACK/dorgql.f create mode 100644 OTHER/LAPACK/dorgtr.f create mode 100644 OTHER/LAPACK/dorm2l.f create mode 100644 OTHER/LAPACK/dormql.f create mode 100644 OTHER/LAPACK/dormtr.f create mode 100644 OTHER/LAPACK/dsyevx.f create mode 100644 OTHER/LAPACK/dsygs2.f create mode 100644 OTHER/LAPACK/dsygst.f create mode 100644 OTHER/LAPACK/dsytd2.f create mode 100644 OTHER/LAPACK/dsytrd.f create mode 100644 OTHER/LAPACK/iladlc.f create mode 100644 OTHER/LAPACK/iladlr.f diff --git a/OTHER/LAPACK/Makefile b/OTHER/LAPACK/Makefile index 59da8e04de..e0c54dce06 100644 --- a/OTHER/LAPACK/Makefile +++ b/OTHER/LAPACK/Makefile @@ -21,7 +21,9 @@ DOBJ = dgeqr2.o dlabad.o dlacon.o dlacpy.o dladiv.o dlae2.o dlaev2.o\ dla_geamv.o dlacn2.o dla_lin_berr.o drscl.o dlatrs.o dla_rpvgrw.o dla_gerpvgrw.o \ BLAS_dgemv2_x.o BLAS_dgemv2_x-f2c.o \ BLAS_dgemv_x.o BLAS_dgemv_x-f2c.o BLAS_error.o BLAS_error.o \ - dsygvx.o + dsygvx.o dsygst.o dsygs2.o dsyevx.o dormtr.o dorgtr.o dorgql.o \ + dorg2l.o dormql.o dorm2l.o dlansy.o dlarf1l.o iladlr.o iladlc.o \ + disnan.o dlaisnan.o dsytrd.o dlatrd.o dsytd2.o diff --git a/OTHER/LAPACK/disnan.f b/OTHER/LAPACK/disnan.f new file mode 100644 index 0000000000..fd59cfd5c1 --- /dev/null +++ b/OTHER/LAPACK/disnan.f @@ -0,0 +1,77 @@ +*> \brief \b DISNAN tests input for NaN. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DISNAN + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* LOGICAL FUNCTION DISNAN( DIN ) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION, INTENT(IN) :: DIN +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DISNAN returns .TRUE. if its argument is NaN, and .FALSE. +*> otherwise. To be replaced by the Fortran 2003 intrinsic in the +*> future. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] DIN +*> \verbatim +*> DIN is DOUBLE PRECISION +*> Input to test for NaN. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup isnan +* +* ===================================================================== + LOGICAL FUNCTION DISNAN( DIN ) +* +* -- LAPACK auxiliary routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + DOUBLE PRECISION, INTENT(IN) :: DIN +* .. +* +* ===================================================================== +* +* .. External Functions .. + LOGICAL DLAISNAN + EXTERNAL DLAISNAN +* .. +* .. Executable Statements .. + DISNAN = DLAISNAN(DIN,DIN) + RETURN + END diff --git a/OTHER/LAPACK/dlaisnan.f b/OTHER/LAPACK/dlaisnan.f new file mode 100644 index 0000000000..d879d9e409 --- /dev/null +++ b/OTHER/LAPACK/dlaisnan.f @@ -0,0 +1,88 @@ +*> \brief \b DLAISNAN tests input for NaN by comparing two arguments for inequality. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLAISNAN + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* LOGICAL FUNCTION DLAISNAN( DIN1, DIN2 ) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION, INTENT(IN) :: DIN1, DIN2 +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> This routine is not for general use. It exists solely to avoid +*> over-optimization in DISNAN. +*> +*> DLAISNAN checks for NaNs by comparing its two arguments for +*> inequality. NaN is the only floating-point value where NaN != NaN +*> returns .TRUE. To check for NaNs, pass the same variable as both +*> arguments. +*> +*> A compiler must assume that the two arguments are +*> not the same variable, and the test will not be optimized away. +*> Interprocedural or whole-program optimization may delete this +*> test. The ISNAN functions will be replaced by the correct +*> Fortran 03 intrinsic once the intrinsic is widely available. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] DIN1 +*> \verbatim +*> DIN1 is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] DIN2 +*> \verbatim +*> DIN2 is DOUBLE PRECISION +*> Two numbers to compare for inequality. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup laisnan +* +* ===================================================================== + LOGICAL FUNCTION DLAISNAN( DIN1, DIN2 ) +* +* -- LAPACK auxiliary routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + DOUBLE PRECISION, INTENT(IN) :: DIN1, DIN2 +* .. +* +* ===================================================================== +* +* .. Executable Statements .. + DLAISNAN = (DIN1.NE.DIN2) + RETURN + END diff --git a/OTHER/LAPACK/dlansy.f b/OTHER/LAPACK/dlansy.f new file mode 100644 index 0000000000..b6239929d9 --- /dev/null +++ b/OTHER/LAPACK/dlansy.f @@ -0,0 +1,240 @@ +*> \brief \b DLANSY returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real symmetric matrix. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLANSY + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* DOUBLE PRECISION FUNCTION DLANSY( NORM, UPLO, N, A, LDA, WORK ) +* +* .. Scalar Arguments .. +* CHARACTER NORM, UPLO +* INTEGER LDA, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), WORK( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLANSY returns the value of the one norm, or the Frobenius norm, or +*> the infinity norm, or the element of largest absolute value of a +*> real symmetric matrix A. +*> \endverbatim +*> +*> \return DLANSY +*> \verbatim +*> +*> DLANSY = ( max(abs(A(i,j))), NORM = 'M' or 'm' +*> ( +*> ( norm1(A), NORM = '1', 'O' or 'o' +*> ( +*> ( normI(A), NORM = 'I' or 'i' +*> ( +*> ( normF(A), NORM = 'F', 'f', 'E' or 'e' +*> +*> where norm1 denotes the one norm of a matrix (maximum column sum), +*> normI denotes the infinity norm of a matrix (maximum row sum) and +*> normF denotes the Frobenius norm of a matrix (square root of sum of +*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] NORM +*> \verbatim +*> NORM is CHARACTER*1 +*> Specifies the value to be returned in DLANSY as described +*> above. +*> \endverbatim +*> +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> Specifies whether the upper or lower triangular part of the +*> symmetric matrix A is to be referenced. +*> = 'U': Upper triangular part of A is referenced +*> = 'L': Lower triangular part of A is referenced +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrix A. N >= 0. When N = 0, DLANSY is +*> set to zero. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> The symmetric matrix A. If UPLO = 'U', the leading n by n +*> upper triangular part of A contains the upper triangular part +*> of the matrix A, and the strictly lower triangular part of A +*> is not referenced. If UPLO = 'L', the leading n by n lower +*> triangular part of A contains the lower triangular part of +*> the matrix A, and the strictly upper triangular part of A is +*> not referenced. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(N,1). +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)), +*> where LWORK >= N when NORM = 'I' or '1' or 'O'; otherwise, +*> WORK is not referenced. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup lanhe +* +* ===================================================================== + DOUBLE PRECISION FUNCTION DLANSY( NORM, UPLO, N, A, LDA, WORK ) +* +* -- LAPACK auxiliary routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER NORM, UPLO + INTEGER LDA, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), WORK( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, J + DOUBLE PRECISION ABSA, SCALE, SUM, VALUE +* .. +* .. External Subroutines .. + EXTERNAL DLASSQ +* .. +* .. External Functions .. + LOGICAL LSAME, DISNAN + EXTERNAL LSAME, DISNAN +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, SQRT +* .. +* .. Executable Statements .. +* + IF( N.EQ.0 ) THEN + VALUE = ZERO + ELSE IF( LSAME( NORM, 'M' ) ) THEN +* +* Find max(abs(A(i,j))). +* + VALUE = ZERO + IF( LSAME( UPLO, 'U' ) ) THEN + DO 20 J = 1, N + DO 10 I = 1, J + SUM = ABS( A( I, J ) ) + IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM + 10 CONTINUE + 20 CONTINUE + ELSE + DO 40 J = 1, N + DO 30 I = J, N + SUM = ABS( A( I, J ) ) + IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM + 30 CONTINUE + 40 CONTINUE + END IF + ELSE IF( ( LSAME( NORM, 'I' ) ) .OR. + $ ( LSAME( NORM, 'O' ) ) .OR. + $ ( NORM.EQ.'1' ) ) THEN +* +* Find normI(A) ( = norm1(A), since A is symmetric). +* + VALUE = ZERO + IF( LSAME( UPLO, 'U' ) ) THEN + DO 60 J = 1, N + SUM = ZERO + DO 50 I = 1, J - 1 + ABSA = ABS( A( I, J ) ) + SUM = SUM + ABSA + WORK( I ) = WORK( I ) + ABSA + 50 CONTINUE + WORK( J ) = SUM + ABS( A( J, J ) ) + 60 CONTINUE + DO 70 I = 1, N + SUM = WORK( I ) + IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM + 70 CONTINUE + ELSE + DO 80 I = 1, N + WORK( I ) = ZERO + 80 CONTINUE + DO 100 J = 1, N + SUM = WORK( J ) + ABS( A( J, J ) ) + DO 90 I = J + 1, N + ABSA = ABS( A( I, J ) ) + SUM = SUM + ABSA + WORK( I ) = WORK( I ) + ABSA + 90 CONTINUE + IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM + 100 CONTINUE + END IF + ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. + $ ( LSAME( NORM, 'E' ) ) ) THEN +* +* Find normF(A). +* + SCALE = ZERO + SUM = ONE + IF( LSAME( UPLO, 'U' ) ) THEN + DO 110 J = 2, N + CALL DLASSQ( J-1, A( 1, J ), 1, SCALE, SUM ) + 110 CONTINUE + ELSE + DO 120 J = 1, N - 1 + CALL DLASSQ( N-J, A( J+1, J ), 1, SCALE, SUM ) + 120 CONTINUE + END IF + SUM = 2*SUM + CALL DLASSQ( N, A, LDA+1, SCALE, SUM ) + VALUE = SCALE*SQRT( SUM ) + END IF +* + DLANSY = VALUE + RETURN +* +* End of DLANSY +* + END diff --git a/OTHER/LAPACK/dlarf1l.f b/OTHER/LAPACK/dlarf1l.f new file mode 100644 index 0000000000..80a486f79c --- /dev/null +++ b/OTHER/LAPACK/dlarf1l.f @@ -0,0 +1,252 @@ +*> \brief \b DLARF1L applies an elementary reflector to a general rectangular +* matrix assuming v(lastv) = 1 where lastv is the last non-zero +* element +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLARF1L + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLARF1L( SIDE, M, N, V, INCV, TAU, C, LDC, WORK ) +* +* .. Scalar Arguments .. +* CHARACTER SIDE +* INTEGER INCV, LDC, M, N +* DOUBLE PRECISION TAU +* .. +* .. Array Arguments .. +* DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLARF1L applies a real elementary reflector H to a real m by n matrix +*> C, from either the left or the right. H is represented in the form +*> +*> H = I - tau * v * v**T +*> +*> where tau is a real scalar and v is a real vector. +*> +*> If tau = 0, then H is taken to be the unit matrix. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] SIDE +*> \verbatim +*> SIDE is CHARACTER*1 +*> = 'L': form H * C +*> = 'R': form C * H +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the matrix C. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the matrix C. +*> \endverbatim +*> +*> \param[in] V +*> \verbatim +*> V is DOUBLE PRECISION array, dimension +*> (1 + (M-1)*abs(INCV)) if SIDE = 'L' +*> or (1 + (N-1)*abs(INCV)) if SIDE = 'R' +*> The vector v in the representation of H. V is not used if +*> TAU = 0. +*> \endverbatim +*> +*> \param[in] INCV +*> \verbatim +*> INCV is INTEGER +*> The increment between elements of v. INCV <> 0. +*> \endverbatim +*> +*> \param[in] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION +*> The value tau in the representation of H. +*> \endverbatim +*> +*> \param[in,out] C +*> \verbatim +*> C is DOUBLE PRECISION array, dimension (LDC,N) +*> On entry, the m by n matrix C. +*> On exit, C is overwritten by the matrix H * C if SIDE = 'L', +*> or C * H if SIDE = 'R'. +*> \endverbatim +*> +*> \param[in] LDC +*> \verbatim +*> LDC is INTEGER +*> The leading dimension of the array C. LDC >= max(1,M). +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension +*> (N) if SIDE = 'L' +*> or (M) if SIDE = 'R' +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup larf +* +* ===================================================================== + SUBROUTINE DLARF1L( SIDE, M, N, V, INCV, TAU, C, LDC, WORK ) +* +* -- LAPACK auxiliary routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER SIDE + INTEGER INCV, LDC, M, N + DOUBLE PRECISION TAU +* .. +* .. Array Arguments .. + DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL APPLYLEFT + INTEGER I, FIRSTV, LASTV, LASTC +* .. +* .. External Subroutines .. + EXTERNAL DGEMV, DGER +* .. +* .. External Functions .. + LOGICAL LSAME + INTEGER ILADLR, ILADLC + EXTERNAL LSAME, ILADLR, ILADLC +* .. +* .. Executable Statements .. +* + APPLYLEFT = LSAME( SIDE, 'L' ) + FIRSTV = 1 + LASTC = 0 + IF( TAU.NE.ZERO ) THEN +! Set up variables for scanning V. LASTV begins pointing to the end +! of V. + IF( APPLYLEFT ) THEN + LASTV = M + ELSE + LASTV = N + END IF + I = 1 +! Look for the last non-zero row in V. + DO WHILE( LASTV.GT.FIRSTV .AND. V( I ).EQ.ZERO ) + FIRSTV = FIRSTV + 1 + I = I + INCV + END DO + IF( APPLYLEFT ) THEN +! Scan for the last non-zero column in C(1:lastv,:). + LASTC = ILADLC(LASTV, N, C, LDC) + ELSE +! Scan for the last non-zero row in C(:,1:lastv). + LASTC = ILADLR(M, LASTV, C, LDC) + END IF + END IF + IF( LASTC.EQ.0 ) THEN + RETURN + END IF + IF( APPLYLEFT ) THEN +* +* Form H * C +* + IF( LASTV.GT.0 ) THEN + ! Check if m = 1. This means v = 1, So we just need to compute + ! C := HC = (1-\tau)C. + IF( LASTV.EQ.FIRSTV ) THEN + CALL DSCAL(LASTC, ONE - TAU, C( FIRSTV, 1), LDC) + ELSE +* +* w(1:lastc,1) := C(1:lastv,1:lastc)**T * v(1:lastv,1) +* + ! w(1:lastc,1) := C(1:lastv-1,1:lastc)**T * v(1:lastv-1,1) + CALL DGEMV( 'Transpose', LASTV-FIRSTV, LASTC, ONE, + $ C(FIRSTV,1), LDC, V(I), INCV, ZERO, + $ WORK, 1) + ! w(1:lastc,1) += C(lastv,1:lastc)**T * v(lastv,1) = C(lastv,1:lastc)**T + CALL DAXPY(LASTC, ONE, C(LASTV,1), LDC, WORK, 1) +* +* C(1:lastv,1:lastc) := C(...) - tau * v(1:lastv,1) * w(1:lastc,1)**T +* + ! C(lastv, 1:lastc) := C(...) - tau * v(lastv,1) * w(1:lastc,1)**T + ! = C(...) - tau * w(1:lastc,1)**T + CALL DAXPY(LASTC, -TAU, WORK, 1, C(LASTV,1), LDC) + ! C(1:lastv-1,1:lastc) := C(...) - tau * v(1:lastv-1,1)*w(1:lastc,1)**T + CALL DGER(LASTV-FIRSTV, LASTC, -TAU, V(I), INCV, + $ WORK, 1, C(FIRSTV,1), LDC) + END IF + END IF + ELSE +* +* Form C * H +* + IF( LASTV.GT.0 ) THEN + ! Check if n = 1. This means v = 1, so we just need to compute + ! C := CH = C(1-\tau). + IF( LASTV.EQ.FIRSTV ) THEN + CALL DSCAL(LASTC, ONE - TAU, C, 1) + ELSE +* +* w(1:lastc,1) := C(1:lastc,1:lastv) * v(1:lastv,1) +* + ! w(1:lastc,1) := C(1:lastc,1:lastv-1) * v(1:lastv-1,1) + CALL DGEMV( 'No transpose', LASTC, LASTV-FIRSTV, + $ ONE, C(1,FIRSTV), LDC, V(I), INCV, ZERO, WORK, 1 ) + ! w(1:lastc,1) += C(1:lastc,lastv) * v(lastv,1) = C(1:lastc,lastv) + CALL DAXPY(LASTC, ONE, C(1,LASTV), 1, WORK, 1) +* +* C(1:lastc,1:lastv) := C(...) - tau * w(1:lastc,1) * v(1:lastv,1)**T +* + ! C(1:lastc,lastv) := C(...) - tau * w(1:lastc,1) * v(lastv,1)**T + ! = C(...) - tau * w(1:lastc,1) + CALL DAXPY(LASTC, -TAU, WORK, 1, C(1,LASTV), 1) + ! C(1:lastc,1:lastv-1) := C(...) - tau * w(1:lastc,1) * v(1:lastv-1)**T + CALL DGER( LASTC, LASTV-FIRSTV, -TAU, WORK, 1, V(I), + $ INCV, C(1,FIRSTV), LDC ) + END IF + END IF + END IF + RETURN +* +* End of DLARF1L +* + END diff --git a/OTHER/LAPACK/dlatrd.f b/OTHER/LAPACK/dlatrd.f new file mode 100644 index 0000000000..e5737be058 --- /dev/null +++ b/OTHER/LAPACK/dlatrd.f @@ -0,0 +1,343 @@ +*> \brief \b DLATRD reduces the first nb rows and columns of a symmetric/Hermitian matrix A to real tridiagonal form by an orthogonal similarity transformation. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLATRD + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLATRD( UPLO, N, NB, A, LDA, E, TAU, W, LDW ) +* +* .. Scalar Arguments .. +* CHARACTER UPLO +* INTEGER LDA, LDW, N, NB +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), E( * ), TAU( * ), W( LDW, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLATRD reduces NB rows and columns of a real symmetric matrix A to +*> symmetric tridiagonal form by an orthogonal similarity +*> transformation Q**T * A * Q, and returns the matrices V and W which are +*> needed to apply the transformation to the unreduced part of A. +*> +*> If UPLO = 'U', DLATRD reduces the last NB rows and columns of a +*> matrix, of which the upper triangle is supplied; +*> if UPLO = 'L', DLATRD reduces the first NB rows and columns of a +*> matrix, of which the lower triangle is supplied. +*> +*> This is an auxiliary routine called by DSYTRD. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> Specifies whether the upper or lower triangular part of the +*> symmetric matrix A is stored: +*> = 'U': Upper triangular +*> = 'L': Lower triangular +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrix A. +*> \endverbatim +*> +*> \param[in] NB +*> \verbatim +*> NB is INTEGER +*> The number of rows and columns to be reduced. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> On entry, the symmetric matrix A. If UPLO = 'U', the leading +*> n-by-n upper triangular part of A contains the upper +*> triangular part of the matrix A, and the strictly lower +*> triangular part of A is not referenced. If UPLO = 'L', the +*> leading n-by-n lower triangular part of A contains the lower +*> triangular part of the matrix A, and the strictly upper +*> triangular part of A is not referenced. +*> On exit: +*> if UPLO = 'U', the last NB columns have been reduced to +*> tridiagonal form, with the diagonal elements overwriting +*> the diagonal elements of A; the elements above the diagonal +*> with the array TAU, represent the orthogonal matrix Q as a +*> product of elementary reflectors; +*> if UPLO = 'L', the first NB columns have been reduced to +*> tridiagonal form, with the diagonal elements overwriting +*> the diagonal elements of A; the elements below the diagonal +*> with the array TAU, represent the orthogonal matrix Q as a +*> product of elementary reflectors. +*> See Further Details. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= (1,N). +*> \endverbatim +*> +*> \param[out] E +*> \verbatim +*> E is DOUBLE PRECISION array, dimension (N-1) +*> If UPLO = 'U', E(n-nb:n-1) contains the superdiagonal +*> elements of the last NB columns of the reduced matrix; +*> if UPLO = 'L', E(1:nb) contains the subdiagonal elements of +*> the first NB columns of the reduced matrix. +*> \endverbatim +*> +*> \param[out] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION array, dimension (N-1) +*> The scalar factors of the elementary reflectors, stored in +*> TAU(n-nb:n-1) if UPLO = 'U', and in TAU(1:nb) if UPLO = 'L'. +*> See Further Details. +*> \endverbatim +*> +*> \param[out] W +*> \verbatim +*> W is DOUBLE PRECISION array, dimension (LDW,NB) +*> The n-by-nb matrix W required to update the unreduced part +*> of A. +*> \endverbatim +*> +*> \param[in] LDW +*> \verbatim +*> LDW is INTEGER +*> The leading dimension of the array W. LDW >= max(1,N). +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup latrd +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> If UPLO = 'U', the matrix Q is represented as a product of elementary +*> reflectors +*> +*> Q = H(n) H(n-1) . . . H(n-nb+1). +*> +*> Each H(i) has the form +*> +*> H(i) = I - tau * v * v**T +*> +*> where tau is a real scalar, and v is a real vector with +*> v(i:n) = 0 and v(i-1) = 1; v(1:i-1) is stored on exit in A(1:i-1,i), +*> and tau in TAU(i-1). +*> +*> If UPLO = 'L', the matrix Q is represented as a product of elementary +*> reflectors +*> +*> Q = H(1) H(2) . . . H(nb). +*> +*> Each H(i) has the form +*> +*> H(i) = I - tau * v * v**T +*> +*> where tau is a real scalar, and v is a real vector with +*> v(1:i) = 0 and v(i+1) = 1; v(i+1:n) is stored on exit in A(i+1:n,i), +*> and tau in TAU(i). +*> +*> The elements of the vectors v together form the n-by-nb matrix V +*> which is needed, with W, to apply the transformation to the unreduced +*> part of the matrix, using a symmetric rank-2k update of the form: +*> A := A - V*W**T - W*V**T. +*> +*> The contents of A on exit are illustrated by the following examples +*> with n = 5 and nb = 2: +*> +*> if UPLO = 'U': if UPLO = 'L': +*> +*> ( a a a v4 v5 ) ( d ) +*> ( a a v4 v5 ) ( 1 d ) +*> ( a 1 v5 ) ( v1 1 a ) +*> ( d 1 ) ( v1 v2 a a ) +*> ( d ) ( v1 v2 a a a ) +*> +*> where d denotes a diagonal element of the reduced matrix, a denotes +*> an element of the original matrix that is unchanged, and vi denotes +*> an element of the vector defining H(i). +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DLATRD( UPLO, N, NB, A, LDA, E, TAU, W, LDW ) +* +* -- LAPACK auxiliary routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER LDA, LDW, N, NB +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), E( * ), TAU( * ), W( LDW, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE, HALF + PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, HALF = 0.5D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, IW + DOUBLE PRECISION ALPHA +* .. +* .. External Subroutines .. + EXTERNAL DAXPY, DGEMV, DLARFG, DSCAL, DSYMV +* .. +* .. External Functions .. + LOGICAL LSAME + DOUBLE PRECISION DDOT + EXTERNAL LSAME, DDOT +* .. +* .. Intrinsic Functions .. + INTRINSIC MIN +* .. +* .. Executable Statements .. +* +* Quick return if possible +* + IF( N.LE.0 ) + $ RETURN +* + IF( LSAME( UPLO, 'U' ) ) THEN +* +* Reduce last NB columns of upper triangle +* + DO 10 I = N, N - NB + 1, -1 + IW = I - N + NB + IF( I.LT.N ) THEN +* +* Update A(1:i,i) +* + CALL DGEMV( 'No transpose', I, N-I, -ONE, A( 1, I+1 ), + $ LDA, W( I, IW+1 ), LDW, ONE, A( 1, I ), 1 ) + CALL DGEMV( 'No transpose', I, N-I, -ONE, W( 1, + $ IW+1 ), + $ LDW, A( I, I+1 ), LDA, ONE, A( 1, I ), 1 ) + END IF + IF( I.GT.1 ) THEN +* +* Generate elementary reflector H(i) to annihilate +* A(1:i-2,i) +* + CALL DLARFG( I-1, A( I-1, I ), A( 1, I ), 1, + $ TAU( I-1 ) ) + E( I-1 ) = A( I-1, I ) + A( I-1, I ) = ONE +* +* Compute W(1:i-1,i) +* + CALL DSYMV( 'Upper', I-1, ONE, A, LDA, A( 1, I ), 1, + $ ZERO, W( 1, IW ), 1 ) + IF( I.LT.N ) THEN + CALL DGEMV( 'Transpose', I-1, N-I, ONE, W( 1, + $ IW+1 ), + $ LDW, A( 1, I ), 1, ZERO, W( I+1, IW ), 1 ) + CALL DGEMV( 'No transpose', I-1, N-I, -ONE, + $ A( 1, I+1 ), LDA, W( I+1, IW ), 1, ONE, + $ W( 1, IW ), 1 ) + CALL DGEMV( 'Transpose', I-1, N-I, ONE, A( 1, + $ I+1 ), + $ LDA, A( 1, I ), 1, ZERO, W( I+1, IW ), 1 ) + CALL DGEMV( 'No transpose', I-1, N-I, -ONE, + $ W( 1, IW+1 ), LDW, W( I+1, IW ), 1, ONE, + $ W( 1, IW ), 1 ) + END IF + CALL DSCAL( I-1, TAU( I-1 ), W( 1, IW ), 1 ) + ALPHA = -HALF*TAU( I-1 )*DDOT( I-1, W( 1, IW ), 1, + $ A( 1, I ), 1 ) + CALL DAXPY( I-1, ALPHA, A( 1, I ), 1, W( 1, IW ), 1 ) + END IF +* + 10 CONTINUE + ELSE +* +* Reduce first NB columns of lower triangle +* + DO 20 I = 1, NB +* +* Update A(i:n,i) +* + CALL DGEMV( 'No transpose', N-I+1, I-1, -ONE, A( I, 1 ), + $ LDA, W( I, 1 ), LDW, ONE, A( I, I ), 1 ) + CALL DGEMV( 'No transpose', N-I+1, I-1, -ONE, W( I, 1 ), + $ LDW, A( I, 1 ), LDA, ONE, A( I, I ), 1 ) + IF( I.LT.N ) THEN +* +* Generate elementary reflector H(i) to annihilate +* A(i+2:n,i) +* + CALL DLARFG( N-I, A( I+1, I ), A( MIN( I+2, N ), I ), + $ 1, + $ TAU( I ) ) + E( I ) = A( I+1, I ) + A( I+1, I ) = ONE +* +* Compute W(i+1:n,i) +* + CALL DSYMV( 'Lower', N-I, ONE, A( I+1, I+1 ), LDA, + $ A( I+1, I ), 1, ZERO, W( I+1, I ), 1 ) + CALL DGEMV( 'Transpose', N-I, I-1, ONE, W( I+1, 1 ), + $ LDW, + $ A( I+1, I ), 1, ZERO, W( 1, I ), 1 ) + CALL DGEMV( 'No transpose', N-I, I-1, -ONE, A( I+1, + $ 1 ), + $ LDA, W( 1, I ), 1, ONE, W( I+1, I ), 1 ) + CALL DGEMV( 'Transpose', N-I, I-1, ONE, A( I+1, 1 ), + $ LDA, + $ A( I+1, I ), 1, ZERO, W( 1, I ), 1 ) + CALL DGEMV( 'No transpose', N-I, I-1, -ONE, W( I+1, + $ 1 ), + $ LDW, W( 1, I ), 1, ONE, W( I+1, I ), 1 ) + CALL DSCAL( N-I, TAU( I ), W( I+1, I ), 1 ) + ALPHA = -HALF*TAU( I )*DDOT( N-I, W( I+1, I ), 1, + $ A( I+1, I ), 1 ) + CALL DAXPY( N-I, ALPHA, A( I+1, I ), 1, W( I+1, I ), + $ 1 ) + END IF +* + 20 CONTINUE + END IF +* + RETURN +* +* End of DLATRD +* + END diff --git a/OTHER/LAPACK/dorg2l.f b/OTHER/LAPACK/dorg2l.f new file mode 100644 index 0000000000..b954302396 --- /dev/null +++ b/OTHER/LAPACK/dorg2l.f @@ -0,0 +1,196 @@ +*> \brief \b DORG2L generates all or part of the orthogonal matrix Q from a QL factorization determined by sgeqlf (unblocked algorithm). +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DORG2L + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DORG2L( M, N, K, A, LDA, TAU, WORK, INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, K, LDA, M, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DORG2L generates an m by n real matrix Q with orthonormal columns, +*> which is defined as the last n columns of a product of k elementary +*> reflectors of order m +*> +*> Q = H(k) . . . H(2) H(1) +*> +*> as returned by DGEQLF. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the matrix Q. M >= 0. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the matrix Q. M >= N >= 0. +*> \endverbatim +*> +*> \param[in] K +*> \verbatim +*> K is INTEGER +*> The number of elementary reflectors whose product defines the +*> matrix Q. N >= K >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> On entry, the (n-k+i)-th column must contain the vector which +*> defines the elementary reflector H(i), for i = 1,2,...,k, as +*> returned by DGEQLF in the last k columns of its array +*> argument A. +*> On exit, the m by n matrix Q. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The first dimension of the array A. LDA >= max(1,M). +*> \endverbatim +*> +*> \param[in] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION array, dimension (K) +*> TAU(i) must contain the scalar factor of the elementary +*> reflector H(i), as returned by DGEQLF. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (N) +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument has an illegal value +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup ung2l +* +* ===================================================================== + SUBROUTINE DORG2L( M, N, K, A, LDA, TAU, WORK, INFO ) +* +* -- LAPACK computational routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + INTEGER INFO, K, LDA, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, II, J, L +* .. +* .. External Subroutines .. + EXTERNAL DLARF1L, DSCAL, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 .OR. N.GT.M ) THEN + INFO = -2 + ELSE IF( K.LT.0 .OR. K.GT.N ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -5 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORG2L', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.LE.0 ) + $ RETURN +* +* Initialise columns 1:n-k to columns of the unit matrix +* + DO 20 J = 1, N - K + DO 10 L = 1, M + A( L, J ) = ZERO + 10 CONTINUE + A( M-N+J, J ) = ONE + 20 CONTINUE +* + DO 40 I = 1, K + II = N - K + I +* +* Apply H(i) to A(1:m-k+i,1:n-k+i) from the left +* + !A(M-N+II, II) = ONE + CALL DLARF1L( 'Left', M-N+II, II-1, A( 1, II ), 1, TAU( I ), + $ A, + $ LDA, WORK ) + CALL DSCAL( M-N+II-1, -TAU( I ), A( 1, II ), 1 ) + A( M-N+II, II ) = ONE - TAU( I ) +* +* Set A(m-k+i+1:m,n-k+i) to zero +* + DO 30 L = M - N + II + 1, M + A( L, II ) = ZERO + 30 CONTINUE + 40 CONTINUE + RETURN +* +* End of DORG2L +* + END diff --git a/OTHER/LAPACK/dorgql.f b/OTHER/LAPACK/dorgql.f new file mode 100644 index 0000000000..f931f5a9c8 --- /dev/null +++ b/OTHER/LAPACK/dorgql.f @@ -0,0 +1,294 @@ +*> \brief \b DORGQL +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DORGQL + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DORGQL( M, N, K, A, LDA, TAU, WORK, LWORK, INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, K, LDA, LWORK, M, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DORGQL generates an M-by-N real matrix Q with orthonormal columns, +*> which is defined as the last N columns of a product of K elementary +*> reflectors of order M +*> +*> Q = H(k) . . . H(2) H(1) +*> +*> as returned by DGEQLF. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the matrix Q. M >= 0. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the matrix Q. M >= N >= 0. +*> \endverbatim +*> +*> \param[in] K +*> \verbatim +*> K is INTEGER +*> The number of elementary reflectors whose product defines the +*> matrix Q. N >= K >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> On entry, the (n-k+i)-th column must contain the vector which +*> defines the elementary reflector H(i), for i = 1,2,...,k, as +*> returned by DGEQLF in the last k columns of its array +*> argument A. +*> On exit, the M-by-N matrix Q. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The first dimension of the array A. LDA >= max(1,M). +*> \endverbatim +*> +*> \param[in] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION array, dimension (K) +*> TAU(i) must contain the scalar factor of the elementary +*> reflector H(i), as returned by DGEQLF. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) +*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The dimension of the array WORK. LWORK >= max(1,N). +*> For optimum performance LWORK >= N*NB, where NB is the +*> optimal blocksize. +*> +*> If LWORK = -1, then a workspace query is assumed; the routine +*> only calculates the optimal size of the WORK array, returns +*> this value as the first entry of the WORK array, and no error +*> message related to LWORK is issued by XERBLA. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument has an illegal value +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup ungql +* +* ===================================================================== + SUBROUTINE DORGQL( M, N, K, A, LDA, TAU, WORK, LWORK, INFO ) +* +* -- LAPACK computational routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + INTEGER INFO, K, LDA, LWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL LQUERY + INTEGER I, IB, IINFO, IWS, J, KK, L, LDWORK, LWKOPT, + $ NB, NBMIN, NX +* .. +* .. External Subroutines .. + EXTERNAL DLARFB, DLARFT, DORG2L, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. External Functions .. + INTEGER ILAENV + EXTERNAL ILAENV +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + LQUERY = ( LWORK.EQ.-1 ) + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 .OR. N.GT.M ) THEN + INFO = -2 + ELSE IF( K.LT.0 .OR. K.GT.N ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -5 + END IF +* + IF( INFO.EQ.0 ) THEN + IF( N.EQ.0 ) THEN + LWKOPT = 1 + ELSE + NB = ILAENV( 1, 'DORGQL', ' ', M, N, K, -1 ) + LWKOPT = N*NB + END IF + WORK( 1 ) = LWKOPT +* + IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN + INFO = -8 + END IF + END IF +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORGQL', -INFO ) + RETURN + ELSE IF( LQUERY ) THEN + RETURN + END IF +* +* Quick return if possible +* + IF( N.LE.0 ) THEN + RETURN + END IF +* + NBMIN = 2 + NX = 0 + IWS = N + IF( NB.GT.1 .AND. NB.LT.K ) THEN +* +* Determine when to cross over from blocked to unblocked code. +* + NX = MAX( 0, ILAENV( 3, 'DORGQL', ' ', M, N, K, -1 ) ) + IF( NX.LT.K ) THEN +* +* Determine if workspace is large enough for blocked code. +* + LDWORK = N + IWS = LDWORK*NB + IF( LWORK.LT.IWS ) THEN +* +* Not enough workspace to use optimal NB: reduce NB and +* determine the minimum value of NB. +* + NB = LWORK / LDWORK + NBMIN = MAX( 2, ILAENV( 2, 'DORGQL', ' ', M, N, K, + $ -1 ) ) + END IF + END IF + END IF +* + IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN +* +* Use blocked code after the first block. +* The last kk columns are handled by the block method. +* + KK = MIN( K, ( ( K-NX+NB-1 ) / NB )*NB ) +* +* Set A(m-kk+1:m,1:n-kk) to zero. +* + DO 20 J = 1, N - KK + DO 10 I = M - KK + 1, M + A( I, J ) = ZERO + 10 CONTINUE + 20 CONTINUE + ELSE + KK = 0 + END IF +* +* Use unblocked code for the first or only block. +* + CALL DORG2L( M-KK, N-KK, K-KK, A, LDA, TAU, WORK, IINFO ) +* + IF( KK.GT.0 ) THEN +* +* Use blocked code +* + DO 50 I = K - KK + 1, K, NB + IB = MIN( NB, K-I+1 ) + IF( N-K+I.GT.1 ) THEN +* +* Form the triangular factor of the block reflector +* H = H(i+ib-1) . . . H(i+1) H(i) +* + CALL DLARFT( 'Backward', 'Columnwise', M-K+I+IB-1, IB, + $ A( 1, N-K+I ), LDA, TAU( I ), WORK, LDWORK ) +* +* Apply H to A(1:m-k+i+ib-1,1:n-k+i-1) from the left +* + CALL DLARFB( 'Left', 'No transpose', 'Backward', + $ 'Columnwise', M-K+I+IB-1, N-K+I-1, IB, + $ A( 1, N-K+I ), LDA, WORK, LDWORK, A, LDA, + $ WORK( IB+1 ), LDWORK ) + END IF +* +* Apply H to rows 1:m-k+i+ib-1 of current block +* + CALL DORG2L( M-K+I+IB-1, IB, IB, A( 1, N-K+I ), LDA, + $ TAU( I ), WORK, IINFO ) +* +* Set rows m-k+i+ib:m of current block to zero +* + DO 40 J = N - K + I, N - K + I + IB - 1 + DO 30 L = M - K + I + IB, M + A( L, J ) = ZERO + 30 CONTINUE + 40 CONTINUE + 50 CONTINUE + END IF +* + WORK( 1 ) = IWS + RETURN +* +* End of DORGQL +* + END diff --git a/OTHER/LAPACK/dorgtr.f b/OTHER/LAPACK/dorgtr.f new file mode 100644 index 0000000000..d19c305959 --- /dev/null +++ b/OTHER/LAPACK/dorgtr.f @@ -0,0 +1,253 @@ +*> \brief \b DORGTR +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DORGTR + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DORGTR( UPLO, N, A, LDA, TAU, WORK, LWORK, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER UPLO +* INTEGER INFO, LDA, LWORK, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DORGTR generates a real orthogonal matrix Q which is defined as the +*> product of n-1 elementary reflectors of order N, as returned by +*> DSYTRD: +*> +*> if UPLO = 'U', Q = H(n-1) . . . H(2) H(1), +*> +*> if UPLO = 'L', Q = H(1) H(2) . . . H(n-1). +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> = 'U': Upper triangle of A contains elementary reflectors +*> from DSYTRD; +*> = 'L': Lower triangle of A contains elementary reflectors +*> from DSYTRD. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrix Q. N >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> On entry, the vectors which define the elementary reflectors, +*> as returned by DSYTRD. +*> On exit, the N-by-N orthogonal matrix Q. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,N). +*> \endverbatim +*> +*> \param[in] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION array, dimension (N-1) +*> TAU(i) must contain the scalar factor of the elementary +*> reflector H(i), as returned by DSYTRD. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) +*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The dimension of the array WORK. LWORK >= max(1,N-1). +*> For optimum performance LWORK >= (N-1)*NB, where NB is +*> the optimal blocksize. +*> +*> If LWORK = -1, then a workspace query is assumed; the routine +*> only calculates the optimal size of the WORK array, returns +*> this value as the first entry of the WORK array, and no error +*> message related to LWORK is issued by XERBLA. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup ungtr +* +* ===================================================================== + SUBROUTINE DORGTR( UPLO, N, A, LDA, TAU, WORK, LWORK, INFO ) +* +* -- LAPACK computational routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER INFO, LDA, LWORK, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL LQUERY, UPPER + INTEGER I, IINFO, J, LWKOPT, NB +* .. +* .. External Functions .. + LOGICAL LSAME + INTEGER ILAENV + EXTERNAL LSAME, ILAENV +* .. +* .. External Subroutines .. + EXTERNAL DORGQL, DORGQR, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + LQUERY = ( LWORK.EQ.-1 ) + UPPER = LSAME( UPLO, 'U' ) + IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -4 + ELSE IF( LWORK.LT.MAX( 1, N-1 ) .AND. .NOT.LQUERY ) THEN + INFO = -7 + END IF +* + IF( INFO.EQ.0 ) THEN + IF( UPPER ) THEN + NB = ILAENV( 1, 'DORGQL', ' ', N-1, N-1, N-1, -1 ) + ELSE + NB = ILAENV( 1, 'DORGQR', ' ', N-1, N-1, N-1, -1 ) + END IF + LWKOPT = MAX( 1, N-1 )*NB + WORK( 1 ) = LWKOPT + END IF +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORGTR', -INFO ) + RETURN + ELSE IF( LQUERY ) THEN + RETURN + END IF +* +* Quick return if possible +* + IF( N.EQ.0 ) THEN + WORK( 1 ) = 1 + RETURN + END IF +* + IF( UPPER ) THEN +* +* Q was determined by a call to DSYTRD with UPLO = 'U' +* +* Shift the vectors which define the elementary reflectors one +* column to the left, and set the last row and column of Q to +* those of the unit matrix +* + DO 20 J = 1, N - 1 + DO 10 I = 1, J - 1 + A( I, J ) = A( I, J+1 ) + 10 CONTINUE + A( N, J ) = ZERO + 20 CONTINUE + DO 30 I = 1, N - 1 + A( I, N ) = ZERO + 30 CONTINUE + A( N, N ) = ONE +* +* Generate Q(1:n-1,1:n-1) +* + CALL DORGQL( N-1, N-1, N-1, A, LDA, TAU, WORK, LWORK, + $ IINFO ) +* + ELSE +* +* Q was determined by a call to DSYTRD with UPLO = 'L'. +* +* Shift the vectors which define the elementary reflectors one +* column to the right, and set the first row and column of Q to +* those of the unit matrix +* + DO 50 J = N, 2, -1 + A( 1, J ) = ZERO + DO 40 I = J + 1, N + A( I, J ) = A( I, J-1 ) + 40 CONTINUE + 50 CONTINUE + A( 1, 1 ) = ONE + DO 60 I = 2, N + A( I, 1 ) = ZERO + 60 CONTINUE + IF( N.GT.1 ) THEN +* +* Generate Q(2:n,2:n) +* + CALL DORGQR( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK, + $ LWORK, IINFO ) + END IF + END IF + WORK( 1 ) = LWKOPT + RETURN +* +* End of DORGTR +* + END diff --git a/OTHER/LAPACK/dorm2l.f b/OTHER/LAPACK/dorm2l.f new file mode 100644 index 0000000000..37866ed0cf --- /dev/null +++ b/OTHER/LAPACK/dorm2l.f @@ -0,0 +1,270 @@ +*> \brief \b DORM2L multiplies a general matrix by the orthogonal matrix from a QL factorization determined by sgeqlf (unblocked algorithm). +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DORM2L + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DORM2L( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, +* WORK, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER SIDE, TRANS +* INTEGER INFO, K, LDA, LDC, M, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DORM2L overwrites the general real m by n matrix C with +*> +*> Q * C if SIDE = 'L' and TRANS = 'N', or +*> +*> Q**T * C if SIDE = 'L' and TRANS = 'T', or +*> +*> C * Q if SIDE = 'R' and TRANS = 'N', or +*> +*> C * Q**T if SIDE = 'R' and TRANS = 'T', +*> +*> where Q is a real orthogonal matrix defined as the product of k +*> elementary reflectors +*> +*> Q = H(k) . . . H(2) H(1) +*> +*> as returned by DGEQLF. Q is of order m if SIDE = 'L' and of order n +*> if SIDE = 'R'. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] SIDE +*> \verbatim +*> SIDE is CHARACTER*1 +*> = 'L': apply Q or Q**T from the Left +*> = 'R': apply Q or Q**T from the Right +*> \endverbatim +*> +*> \param[in] TRANS +*> \verbatim +*> TRANS is CHARACTER*1 +*> = 'N': apply Q (No transpose) +*> = 'T': apply Q**T (Transpose) +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the matrix C. M >= 0. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the matrix C. N >= 0. +*> \endverbatim +*> +*> \param[in] K +*> \verbatim +*> K is INTEGER +*> The number of elementary reflectors whose product defines +*> the matrix Q. +*> If SIDE = 'L', M >= K >= 0; +*> if SIDE = 'R', N >= K >= 0. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,K) +*> The i-th column must contain the vector which defines the +*> elementary reflector H(i), for i = 1,2,...,k, as returned by +*> DGEQLF in the last k columns of its array argument A. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. +*> If SIDE = 'L', LDA >= max(1,M); +*> if SIDE = 'R', LDA >= max(1,N). +*> \endverbatim +*> +*> \param[in] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION array, dimension (K) +*> TAU(i) must contain the scalar factor of the elementary +*> reflector H(i), as returned by DGEQLF. +*> \endverbatim +*> +*> \param[in,out] C +*> \verbatim +*> C is DOUBLE PRECISION array, dimension (LDC,N) +*> On entry, the m by n matrix C. +*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. +*> \endverbatim +*> +*> \param[in] LDC +*> \verbatim +*> LDC is INTEGER +*> The leading dimension of the array C. LDC >= max(1,M). +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension +*> (N) if SIDE = 'L', +*> (M) if SIDE = 'R' +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup unm2l +* +* ===================================================================== + SUBROUTINE DORM2L( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, + $ WORK, INFO ) +* +* -- LAPACK computational routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER SIDE, TRANS + INTEGER INFO, K, LDA, LDC, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL LEFT, NOTRAN + INTEGER I, I1, I2, I3, MI, NI, NQ +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL DLARF1L, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + LEFT = LSAME( SIDE, 'L' ) + NOTRAN = LSAME( TRANS, 'N' ) +* +* NQ is the order of Q +* + IF( LEFT ) THEN + NQ = M + ELSE + NQ = N + END IF + IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN + INFO = -1 + ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN + INFO = -2 + ELSE IF( M.LT.0 ) THEN + INFO = -3 + ELSE IF( N.LT.0 ) THEN + INFO = -4 + ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN + INFO = -5 + ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN + INFO = -7 + ELSE IF( LDC.LT.MAX( 1, M ) ) THEN + INFO = -10 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORM2L', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) + $ RETURN +* + IF( ( LEFT .AND. NOTRAN ) .OR. ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) + $ THEN + I1 = 1 + I2 = K + I3 = 1 + ELSE + I1 = K + I2 = 1 + I3 = -1 + END IF +* + IF( LEFT ) THEN + NI = N + ELSE + MI = M + END IF +* + DO 10 I = I1, I2, I3 + IF( LEFT ) THEN +* +* H(i) is applied to C(1:m-k+i,1:n) +* + MI = M - K + I + ELSE +* +* H(i) is applied to C(1:m,1:n-k+i) +* + NI = N - K + I + END IF +* +* Apply H(i) +* + CALL DLARF1L( SIDE, MI, NI, A( 1, I ), 1, TAU( I ), C, LDC, + $ WORK ) + 10 CONTINUE + RETURN +* +* End of DORM2L +* + END diff --git a/OTHER/LAPACK/dormql.f b/OTHER/LAPACK/dormql.f new file mode 100644 index 0000000000..11022d78c6 --- /dev/null +++ b/OTHER/LAPACK/dormql.f @@ -0,0 +1,340 @@ +*> \brief \b DORMQL +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DORMQL + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DORMQL( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, +* WORK, LWORK, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER SIDE, TRANS +* INTEGER INFO, K, LDA, LDC, LWORK, M, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DORMQL overwrites the general real M-by-N matrix C with +*> +*> SIDE = 'L' SIDE = 'R' +*> TRANS = 'N': Q * C C * Q +*> TRANS = 'T': Q**T * C C * Q**T +*> +*> where Q is a real orthogonal matrix defined as the product of k +*> elementary reflectors +*> +*> Q = H(k) . . . H(2) H(1) +*> +*> as returned by DGEQLF. Q is of order M if SIDE = 'L' and of order N +*> if SIDE = 'R'. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] SIDE +*> \verbatim +*> SIDE is CHARACTER*1 +*> = 'L': apply Q or Q**T from the Left; +*> = 'R': apply Q or Q**T from the Right. +*> \endverbatim +*> +*> \param[in] TRANS +*> \verbatim +*> TRANS is CHARACTER*1 +*> = 'N': No transpose, apply Q; +*> = 'T': Transpose, apply Q**T. +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the matrix C. M >= 0. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the matrix C. N >= 0. +*> \endverbatim +*> +*> \param[in] K +*> \verbatim +*> K is INTEGER +*> The number of elementary reflectors whose product defines +*> the matrix Q. +*> If SIDE = 'L', M >= K >= 0; +*> if SIDE = 'R', N >= K >= 0. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,K) +*> The i-th column must contain the vector which defines the +*> elementary reflector H(i), for i = 1,2,...,k, as returned by +*> DGEQLF in the last k columns of its array argument A. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. +*> If SIDE = 'L', LDA >= max(1,M); +*> if SIDE = 'R', LDA >= max(1,N). +*> \endverbatim +*> +*> \param[in] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION array, dimension (K) +*> TAU(i) must contain the scalar factor of the elementary +*> reflector H(i), as returned by DGEQLF. +*> \endverbatim +*> +*> \param[in,out] C +*> \verbatim +*> C is DOUBLE PRECISION array, dimension (LDC,N) +*> On entry, the M-by-N matrix C. +*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. +*> \endverbatim +*> +*> \param[in] LDC +*> \verbatim +*> LDC is INTEGER +*> The leading dimension of the array C. LDC >= max(1,M). +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) +*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The dimension of the array WORK. +*> If SIDE = 'L', LWORK >= max(1,N); +*> if SIDE = 'R', LWORK >= max(1,M). +*> For good performance, LWORK should generally be larger. +*> +*> If LWORK = -1, then a workspace query is assumed; the routine +*> only calculates the optimal size of the WORK array, returns +*> this value as the first entry of the WORK array, and no error +*> message related to LWORK is issued by XERBLA. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup unmql +* +* ===================================================================== + SUBROUTINE DORMQL( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, + $ WORK, LWORK, INFO ) +* +* -- LAPACK computational routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER SIDE, TRANS + INTEGER INFO, K, LDA, LDC, LWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + INTEGER NBMAX, LDT, TSIZE + PARAMETER ( NBMAX = 64, LDT = NBMAX+1, + $ TSIZE = LDT*NBMAX ) +* .. +* .. Local Scalars .. + LOGICAL LEFT, LQUERY, NOTRAN + INTEGER I, I1, I2, I3, IB, IINFO, IWT, LDWORK, LWKOPT, + $ MI, NB, NBMIN, NI, NQ, NW +* .. +* .. External Functions .. + LOGICAL LSAME + INTEGER ILAENV + EXTERNAL LSAME, ILAENV +* .. +* .. External Subroutines .. + EXTERNAL DLARFB, DLARFT, DORM2L, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + LEFT = LSAME( SIDE, 'L' ) + NOTRAN = LSAME( TRANS, 'N' ) + LQUERY = ( LWORK.EQ.-1 ) +* +* NQ is the order of Q and NW is the minimum dimension of WORK +* + IF( LEFT ) THEN + NQ = M + NW = MAX( 1, N ) + ELSE + NQ = N + NW = MAX( 1, M ) + END IF + IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN + INFO = -1 + ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN + INFO = -2 + ELSE IF( M.LT.0 ) THEN + INFO = -3 + ELSE IF( N.LT.0 ) THEN + INFO = -4 + ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN + INFO = -5 + ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN + INFO = -7 + ELSE IF( LDC.LT.MAX( 1, M ) ) THEN + INFO = -10 + ELSE IF( LWORK.LT.NW .AND. .NOT.LQUERY ) THEN + INFO = -12 + END IF +* + IF( INFO.EQ.0 ) THEN +* +* Compute the workspace requirements +* + IF( M.EQ.0 .OR. N.EQ.0 ) THEN + LWKOPT = 1 + ELSE + NB = MIN( NBMAX, ILAENV( 1, 'DORMQL', SIDE // TRANS, M, + $ N, + $ K, -1 ) ) + LWKOPT = NW*NB + TSIZE + END IF + WORK( 1 ) = LWKOPT + END IF +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORMQL', -INFO ) + RETURN + ELSE IF( LQUERY ) THEN + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 ) THEN + RETURN + END IF +* + NBMIN = 2 + LDWORK = NW + IF( NB.GT.1 .AND. NB.LT.K ) THEN + IF( LWORK.LT.LWKOPT ) THEN + NB = (LWORK-TSIZE) / LDWORK + NBMIN = MAX( 2, ILAENV( 2, 'DORMQL', SIDE // TRANS, M, N, + $ K, + $ -1 ) ) + END IF + END IF +* + IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN +* +* Use unblocked code +* + CALL DORM2L( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, + $ WORK, + $ IINFO ) + ELSE +* +* Use blocked code +* + IWT = 1 + NW*NB + IF( ( LEFT .AND. NOTRAN ) .OR. + $ ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) THEN + I1 = 1 + I2 = K + I3 = NB + ELSE + I1 = ( ( K-1 ) / NB )*NB + 1 + I2 = 1 + I3 = -NB + END IF +* + IF( LEFT ) THEN + NI = N + ELSE + MI = M + END IF +* + DO 10 I = I1, I2, I3 + IB = MIN( NB, K-I+1 ) +* +* Form the triangular factor of the block reflector +* H = H(i+ib-1) . . . H(i+1) H(i) +* + CALL DLARFT( 'Backward', 'Columnwise', NQ-K+I+IB-1, IB, + $ A( 1, I ), LDA, TAU( I ), WORK( IWT ), LDT ) + IF( LEFT ) THEN +* +* H or H**T is applied to C(1:m-k+i+ib-1,1:n) +* + MI = M - K + I + IB - 1 + ELSE +* +* H or H**T is applied to C(1:m,1:n-k+i+ib-1) +* + NI = N - K + I + IB - 1 + END IF +* +* Apply H or H**T +* + CALL DLARFB( SIDE, TRANS, 'Backward', 'Columnwise', MI, + $ NI, + $ IB, A( 1, I ), LDA, WORK( IWT ), LDT, C, LDC, + $ WORK, LDWORK ) + 10 CONTINUE + END IF + WORK( 1 ) = LWKOPT + RETURN +* +* End of DORMQL +* + END diff --git a/OTHER/LAPACK/dormtr.f b/OTHER/LAPACK/dormtr.f new file mode 100644 index 0000000000..eb85afce72 --- /dev/null +++ b/OTHER/LAPACK/dormtr.f @@ -0,0 +1,310 @@ +*> \brief \b DORMTR +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DORMTR + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DORMTR( SIDE, UPLO, TRANS, M, N, A, LDA, TAU, C, LDC, +* WORK, LWORK, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER SIDE, TRANS, UPLO +* INTEGER INFO, LDA, LDC, LWORK, M, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DORMTR overwrites the general real M-by-N matrix C with +*> +*> SIDE = 'L' SIDE = 'R' +*> TRANS = 'N': Q * C C * Q +*> TRANS = 'T': Q**T * C C * Q**T +*> +*> where Q is a real orthogonal matrix of order nq, with nq = m if +*> SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of +*> nq-1 elementary reflectors, as returned by DSYTRD: +*> +*> if UPLO = 'U', Q = H(nq-1) . . . H(2) H(1); +*> +*> if UPLO = 'L', Q = H(1) H(2) . . . H(nq-1). +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] SIDE +*> \verbatim +*> SIDE is CHARACTER*1 +*> = 'L': apply Q or Q**T from the Left; +*> = 'R': apply Q or Q**T from the Right. +*> \endverbatim +*> +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> = 'U': Upper triangle of A contains elementary reflectors +*> from DSYTRD; +*> = 'L': Lower triangle of A contains elementary reflectors +*> from DSYTRD. +*> \endverbatim +*> +*> \param[in] TRANS +*> \verbatim +*> TRANS is CHARACTER*1 +*> = 'N': No transpose, apply Q; +*> = 'T': Transpose, apply Q**T. +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the matrix C. M >= 0. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the matrix C. N >= 0. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension +*> (LDA,M) if SIDE = 'L' +*> (LDA,N) if SIDE = 'R' +*> The vectors which define the elementary reflectors, as +*> returned by DSYTRD. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. +*> LDA >= max(1,M) if SIDE = 'L'; LDA >= max(1,N) if SIDE = 'R'. +*> \endverbatim +*> +*> \param[in] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION array, dimension +*> (M-1) if SIDE = 'L' +*> (N-1) if SIDE = 'R' +*> TAU(i) must contain the scalar factor of the elementary +*> reflector H(i), as returned by DSYTRD. +*> \endverbatim +*> +*> \param[in,out] C +*> \verbatim +*> C is DOUBLE PRECISION array, dimension (LDC,N) +*> On entry, the M-by-N matrix C. +*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. +*> \endverbatim +*> +*> \param[in] LDC +*> \verbatim +*> LDC is INTEGER +*> The leading dimension of the array C. LDC >= max(1,M). +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) +*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The dimension of the array WORK. +*> If SIDE = 'L', LWORK >= max(1,N); +*> if SIDE = 'R', LWORK >= max(1,M). +*> For optimum performance LWORK >= N*NB if SIDE = 'L', and +*> LWORK >= M*NB if SIDE = 'R', where NB is the optimal +*> blocksize. +*> +*> If LWORK = -1, then a workspace query is assumed; the routine +*> only calculates the optimal size of the WORK array, returns +*> this value as the first entry of the WORK array, and no error +*> message related to LWORK is issued by XERBLA. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup unmtr +* +* ===================================================================== + SUBROUTINE DORMTR( SIDE, UPLO, TRANS, M, N, A, LDA, TAU, C, + $ LDC, + $ WORK, LWORK, INFO ) +* +* -- LAPACK computational routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER SIDE, TRANS, UPLO + INTEGER INFO, LDA, LDC, LWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * ) +* .. +* +* ===================================================================== +* +* .. Local Scalars .. + LOGICAL LEFT, LQUERY, UPPER + INTEGER I1, I2, IINFO, LWKOPT, MI, NB, NI, NQ, NW +* .. +* .. External Functions .. + LOGICAL LSAME + INTEGER ILAENV + EXTERNAL LSAME, ILAENV +* .. +* .. External Subroutines .. + EXTERNAL DORMQL, DORMQR, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + LEFT = LSAME( SIDE, 'L' ) + UPPER = LSAME( UPLO, 'U' ) + LQUERY = ( LWORK.EQ.-1 ) +* +* NQ is the order of Q and NW is the minimum dimension of WORK +* + IF( LEFT ) THEN + NQ = M + NW = MAX( 1, N ) + ELSE + NQ = N + NW = MAX( 1, M ) + END IF + IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN + INFO = -1 + ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN + INFO = -2 + ELSE IF( .NOT.LSAME( TRANS, 'N' ) .AND. + $ .NOT.LSAME( TRANS, 'T' ) ) + $ THEN + INFO = -3 + ELSE IF( M.LT.0 ) THEN + INFO = -4 + ELSE IF( N.LT.0 ) THEN + INFO = -5 + ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN + INFO = -7 + ELSE IF( LDC.LT.MAX( 1, M ) ) THEN + INFO = -10 + ELSE IF( LWORK.LT.NW .AND. .NOT.LQUERY ) THEN + INFO = -12 + END IF +* + IF( INFO.EQ.0 ) THEN + IF( UPPER ) THEN + IF( LEFT ) THEN + NB = ILAENV( 1, 'DORMQL', SIDE // TRANS, M-1, N, M-1, + $ -1 ) + ELSE + NB = ILAENV( 1, 'DORMQL', SIDE // TRANS, M, N-1, N-1, + $ -1 ) + END IF + ELSE + IF( LEFT ) THEN + NB = ILAENV( 1, 'DORMQR', SIDE // TRANS, M-1, N, M-1, + $ -1 ) + ELSE + NB = ILAENV( 1, 'DORMQR', SIDE // TRANS, M, N-1, N-1, + $ -1 ) + END IF + END IF + LWKOPT = NW*NB + WORK( 1 ) = LWKOPT + END IF +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORMTR', -INFO ) + RETURN + ELSE IF( LQUERY ) THEN + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 .OR. NQ.EQ.1 ) THEN + WORK( 1 ) = 1 + RETURN + END IF +* + IF( LEFT ) THEN + MI = M - 1 + NI = N + ELSE + MI = M + NI = N - 1 + END IF +* + IF( UPPER ) THEN +* +* Q was determined by a call to DSYTRD with UPLO = 'U' +* + CALL DORMQL( SIDE, TRANS, MI, NI, NQ-1, A( 1, 2 ), LDA, TAU, + $ C, + $ LDC, WORK, LWORK, IINFO ) + ELSE +* +* Q was determined by a call to DSYTRD with UPLO = 'L' +* + IF( LEFT ) THEN + I1 = 2 + I2 = 1 + ELSE + I1 = 1 + I2 = 2 + END IF + CALL DORMQR( SIDE, TRANS, MI, NI, NQ-1, A( 2, 1 ), LDA, TAU, + $ C( I1, I2 ), LDC, WORK, LWORK, IINFO ) + END IF + WORK( 1 ) = LWKOPT + RETURN +* +* End of DORMTR +* + END diff --git a/OTHER/LAPACK/dsyevx.f b/OTHER/LAPACK/dsyevx.f new file mode 100644 index 0000000000..1f9954850f --- /dev/null +++ b/OTHER/LAPACK/dsyevx.f @@ -0,0 +1,555 @@ +*> \brief DSYEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for SY matrices +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DSYEVX + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU, +* ABSTOL, M, W, Z, LDZ, WORK, LWORK, IWORK, +* IFAIL, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER JOBZ, RANGE, UPLO +* INTEGER IL, INFO, IU, LDA, LDZ, LWORK, M, N +* DOUBLE PRECISION ABSTOL, VL, VU +* .. +* .. Array Arguments .. +* INTEGER IFAIL( * ), IWORK( * ) +* DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ), Z( LDZ, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DSYEVX computes selected eigenvalues and, optionally, eigenvectors +*> of a real symmetric matrix A. Eigenvalues and eigenvectors can be +*> selected by specifying either a range of values or a range of indices +*> for the desired eigenvalues. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] JOBZ +*> \verbatim +*> JOBZ is CHARACTER*1 +*> = 'N': Compute eigenvalues only; +*> = 'V': Compute eigenvalues and eigenvectors. +*> \endverbatim +*> +*> \param[in] RANGE +*> \verbatim +*> RANGE is CHARACTER*1 +*> = 'A': all eigenvalues will be found. +*> = 'V': all eigenvalues in the half-open interval (VL,VU] +*> will be found. +*> = 'I': the IL-th through IU-th eigenvalues will be found. +*> \endverbatim +*> +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> = 'U': Upper triangle of A is stored; +*> = 'L': Lower triangle of A is stored. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrix A. N >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA, N) +*> On entry, the symmetric matrix A. If UPLO = 'U', the +*> leading N-by-N upper triangular part of A contains the +*> upper triangular part of the matrix A. If UPLO = 'L', +*> the leading N-by-N lower triangular part of A contains +*> the lower triangular part of the matrix A. +*> On exit, the lower triangle (if UPLO='L') or the upper +*> triangle (if UPLO='U') of A, including the diagonal, is +*> destroyed. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,N). +*> \endverbatim +*> +*> \param[in] VL +*> \verbatim +*> VL is DOUBLE PRECISION +*> If RANGE='V', the lower bound of the interval to +*> be searched for eigenvalues. VL < VU. +*> Not referenced if RANGE = 'A' or 'I'. +*> \endverbatim +*> +*> \param[in] VU +*> \verbatim +*> VU is DOUBLE PRECISION +*> If RANGE='V', the upper bound of the interval to +*> be searched for eigenvalues. VL < VU. +*> Not referenced if RANGE = 'A' or 'I'. +*> \endverbatim +*> +*> \param[in] IL +*> \verbatim +*> IL is INTEGER +*> If RANGE='I', the index of the +*> smallest eigenvalue to be returned. +*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0. +*> Not referenced if RANGE = 'A' or 'V'. +*> \endverbatim +*> +*> \param[in] IU +*> \verbatim +*> IU is INTEGER +*> If RANGE='I', the index of the +*> largest eigenvalue to be returned. +*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0. +*> Not referenced if RANGE = 'A' or 'V'. +*> \endverbatim +*> +*> \param[in] ABSTOL +*> \verbatim +*> ABSTOL is DOUBLE PRECISION +*> The absolute error tolerance for the eigenvalues. +*> An approximate eigenvalue is accepted as converged +*> when it is determined to lie in an interval [a,b] +*> of width less than or equal to +*> +*> ABSTOL + EPS * max( |a|,|b| ) , +*> +*> where EPS is the machine precision. If ABSTOL is less than +*> or equal to zero, then EPS*|T| will be used in its place, +*> where |T| is the 1-norm of the tridiagonal matrix obtained +*> by reducing A to tridiagonal form. +*> +*> Eigenvalues will be computed most accurately when ABSTOL is +*> set to twice the underflow threshold 2*DLAMCH('S'), not zero. +*> If this routine returns with INFO>0, indicating that some +*> eigenvectors did not converge, try setting ABSTOL to +*> 2*DLAMCH('S'). +*> +*> See "Computing Small Singular Values of Bidiagonal Matrices +*> with Guaranteed High Relative Accuracy," by Demmel and +*> Kahan, LAPACK Working Note #3. +*> \endverbatim +*> +*> \param[out] M +*> \verbatim +*> M is INTEGER +*> The total number of eigenvalues found. 0 <= M <= N. +*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1. +*> \endverbatim +*> +*> \param[out] W +*> \verbatim +*> W is DOUBLE PRECISION array, dimension (N) +*> On normal exit, the first M elements contain the selected +*> eigenvalues in ascending order. +*> \endverbatim +*> +*> \param[out] Z +*> \verbatim +*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M)) +*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z +*> contain the orthonormal eigenvectors of the matrix A +*> corresponding to the selected eigenvalues, with the i-th +*> column of Z holding the eigenvector associated with W(i). +*> If an eigenvector fails to converge, then that column of Z +*> contains the latest approximation to the eigenvector, and the +*> index of the eigenvector is returned in IFAIL. +*> If JOBZ = 'N', then Z is not referenced. +*> Note: the user must ensure that at least max(1,M) columns are +*> supplied in the array Z; if RANGE = 'V', the exact value of M +*> is not known in advance and an upper bound must be used. +*> \endverbatim +*> +*> \param[in] LDZ +*> \verbatim +*> LDZ is INTEGER +*> The leading dimension of the array Z. LDZ >= 1, and if +*> JOBZ = 'V', LDZ >= max(1,N). +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) +*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The length of the array WORK. LWORK >= 1, when N <= 1; +*> otherwise 8*N. +*> For optimal efficiency, LWORK >= (NB+3)*N, +*> where NB is the max of the blocksize for DSYTRD and DORMTR +*> returned by ILAENV. +*> +*> If LWORK = -1, then a workspace query is assumed; the routine +*> only calculates the optimal size of the WORK array, returns +*> this value as the first entry of the WORK array, and no error +*> message related to LWORK is issued by XERBLA. +*> \endverbatim +*> +*> \param[out] IWORK +*> \verbatim +*> IWORK is INTEGER array, dimension (5*N) +*> \endverbatim +*> +*> \param[out] IFAIL +*> \verbatim +*> IFAIL is INTEGER array, dimension (N) +*> If JOBZ = 'V', then if INFO = 0, the first M elements of +*> IFAIL are zero. If INFO > 0, then IFAIL contains the +*> indices of the eigenvectors that failed to converge. +*> If JOBZ = 'N', then IFAIL is not referenced. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> > 0: if INFO = i, then i eigenvectors failed to converge. +*> Their indices are stored in array IFAIL. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup heevx +* +* ===================================================================== + SUBROUTINE DSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, + $ IU, + $ ABSTOL, M, W, Z, LDZ, WORK, LWORK, IWORK, + $ IFAIL, INFO ) +* +* -- LAPACK driver routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER JOBZ, RANGE, UPLO + INTEGER IL, INFO, IU, LDA, LDZ, LWORK, M, N + DOUBLE PRECISION ABSTOL, VL, VU +* .. +* .. Array Arguments .. + INTEGER IFAIL( * ), IWORK( * ) + DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ), Z( LDZ, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG, + $ WANTZ + CHARACTER ORDER + INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL, + $ INDISP, INDIWO, INDTAU, INDWKN, INDWRK, ISCALE, + $ ITMP1, J, JJ, LLWORK, LLWRKN, LWKMIN, + $ LWKOPT, NB, NSPLIT + DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, + $ SIGMA, SMLNUM, TMP1, VLL, VUU +* .. +* .. External Functions .. + LOGICAL LSAME + INTEGER ILAENV + DOUBLE PRECISION DLAMCH, DLANSY + EXTERNAL LSAME, ILAENV, DLAMCH, DLANSY +* .. +* .. External Subroutines .. + EXTERNAL DCOPY, DLACPY, DORGTR, DORMTR, DSCAL, + $ DSTEBZ, + $ DSTEIN, DSTEQR, DSTERF, DSWAP, DSYTRD, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN, SQRT +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + LOWER = LSAME( UPLO, 'L' ) + WANTZ = LSAME( JOBZ, 'V' ) + ALLEIG = LSAME( RANGE, 'A' ) + VALEIG = LSAME( RANGE, 'V' ) + INDEIG = LSAME( RANGE, 'I' ) + LQUERY = ( LWORK.EQ.-1 ) +* + INFO = 0 + IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN + INFO = -1 + ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THEN + INFO = -2 + ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN + INFO = -3 + ELSE IF( N.LT.0 ) THEN + INFO = -4 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -6 + ELSE + IF( VALEIG ) THEN + IF( N.GT.0 .AND. VU.LE.VL ) + $ INFO = -8 + ELSE IF( INDEIG ) THEN + IF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THEN + INFO = -9 + ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THEN + INFO = -10 + END IF + END IF + END IF + IF( INFO.EQ.0 ) THEN + IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN + INFO = -15 + END IF + END IF +* + IF( INFO.EQ.0 ) THEN + IF( N.LE.1 ) THEN + LWKMIN = 1 + LWKOPT = 1 + ELSE + LWKMIN = 8*N + NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 ) + NB = MAX( NB, ILAENV( 1, 'DORMTR', UPLO, N, -1, -1, + $ -1 ) ) + LWKOPT = MAX( LWKMIN, ( NB + 3 )*N ) + END IF + WORK( 1 ) = LWKOPT +* + IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) + $ INFO = -17 + END IF +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DSYEVX', -INFO ) + RETURN + ELSE IF( LQUERY ) THEN + RETURN + END IF +* +* Quick return if possible +* + M = 0 + IF( N.EQ.0 ) THEN + RETURN + END IF +* + IF( N.EQ.1 ) THEN + IF( ALLEIG .OR. INDEIG ) THEN + M = 1 + W( 1 ) = A( 1, 1 ) + ELSE + IF( VL.LT.A( 1, 1 ) .AND. VU.GE.A( 1, 1 ) ) THEN + M = 1 + W( 1 ) = A( 1, 1 ) + END IF + END IF + IF( WANTZ ) + $ Z( 1, 1 ) = ONE + RETURN + END IF +* +* Get machine constants. +* + SAFMIN = DLAMCH( 'Safe minimum' ) + EPS = DLAMCH( 'Precision' ) + SMLNUM = SAFMIN / EPS + BIGNUM = ONE / SMLNUM + RMIN = SQRT( SMLNUM ) + RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) ) +* +* Scale matrix to allowable range, if necessary. +* + ISCALE = 0 + ABSTLL = ABSTOL + IF( VALEIG ) THEN + VLL = VL + VUU = VU + END IF + ANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK ) + IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN + ISCALE = 1 + SIGMA = RMIN / ANRM + ELSE IF( ANRM.GT.RMAX ) THEN + ISCALE = 1 + SIGMA = RMAX / ANRM + END IF + IF( ISCALE.EQ.1 ) THEN + IF( LOWER ) THEN + DO 10 J = 1, N + CALL DSCAL( N-J+1, SIGMA, A( J, J ), 1 ) + 10 CONTINUE + ELSE + DO 20 J = 1, N + CALL DSCAL( J, SIGMA, A( 1, J ), 1 ) + 20 CONTINUE + END IF + IF( ABSTOL.GT.0 ) + $ ABSTLL = ABSTOL*SIGMA + IF( VALEIG ) THEN + VLL = VL*SIGMA + VUU = VU*SIGMA + END IF + END IF +* +* Call DSYTRD to reduce symmetric matrix to tridiagonal form. +* + INDTAU = 1 + INDE = INDTAU + N + INDD = INDE + N + INDWRK = INDD + N + LLWORK = LWORK - INDWRK + 1 + CALL DSYTRD( UPLO, N, A, LDA, WORK( INDD ), WORK( INDE ), + $ WORK( INDTAU ), WORK( INDWRK ), LLWORK, IINFO ) +* +* If all eigenvalues are desired and ABSTOL is less than or equal to +* zero, then call DSTERF or DORGTR and SSTEQR. If this fails for +* some eigenvalue, then try DSTEBZ. +* + TEST = .FALSE. + IF( INDEIG ) THEN + IF( IL.EQ.1 .AND. IU.EQ.N ) THEN + TEST = .TRUE. + END IF + END IF + IF( ( ALLEIG .OR. TEST ) .AND. ( ABSTOL.LE.ZERO ) ) THEN + CALL DCOPY( N, WORK( INDD ), 1, W, 1 ) + INDEE = INDWRK + 2*N + IF( .NOT.WANTZ ) THEN + CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 ) + CALL DSTERF( N, W, WORK( INDEE ), INFO ) + ELSE + CALL DLACPY( 'A', N, N, A, LDA, Z, LDZ ) + CALL DORGTR( UPLO, N, Z, LDZ, WORK( INDTAU ), + $ WORK( INDWRK ), LLWORK, IINFO ) + CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 ) + CALL DSTEQR( JOBZ, N, W, WORK( INDEE ), Z, LDZ, + $ WORK( INDWRK ), INFO ) + IF( INFO.EQ.0 ) THEN + DO 30 I = 1, N + IFAIL( I ) = 0 + 30 CONTINUE + END IF + END IF + IF( INFO.EQ.0 ) THEN + M = N + GO TO 40 + END IF + INFO = 0 + END IF +* +* Otherwise, call DSTEBZ and, if eigenvectors are desired, SSTEIN. +* + IF( WANTZ ) THEN + ORDER = 'B' + ELSE + ORDER = 'E' + END IF + INDIBL = 1 + INDISP = INDIBL + N + INDIWO = INDISP + N + CALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTLL, + $ WORK( INDD ), WORK( INDE ), M, NSPLIT, W, + $ IWORK( INDIBL ), IWORK( INDISP ), WORK( INDWRK ), + $ IWORK( INDIWO ), INFO ) +* + IF( WANTZ ) THEN + CALL DSTEIN( N, WORK( INDD ), WORK( INDE ), M, W, + $ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ, + $ WORK( INDWRK ), IWORK( INDIWO ), IFAIL, INFO ) +* +* Apply orthogonal matrix used in reduction to tridiagonal +* form to eigenvectors returned by DSTEIN. +* + INDWKN = INDE + LLWRKN = LWORK - INDWKN + 1 + CALL DORMTR( 'L', UPLO, 'N', N, M, A, LDA, WORK( INDTAU ), + $ Z, + $ LDZ, WORK( INDWKN ), LLWRKN, IINFO ) + END IF +* +* If matrix was scaled, then rescale eigenvalues appropriately. +* + 40 CONTINUE + IF( ISCALE.EQ.1 ) THEN + IF( INFO.EQ.0 ) THEN + IMAX = M + ELSE + IMAX = INFO - 1 + END IF + CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) + END IF +* +* If eigenvalues are not in order, then sort them, along with +* eigenvectors. +* + IF( WANTZ ) THEN + DO 60 J = 1, M - 1 + I = 0 + TMP1 = W( J ) + DO 50 JJ = J + 1, M + IF( W( JJ ).LT.TMP1 ) THEN + I = JJ + TMP1 = W( JJ ) + END IF + 50 CONTINUE +* + IF( I.NE.0 ) THEN + ITMP1 = IWORK( INDIBL+I-1 ) + W( I ) = W( J ) + IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 ) + W( J ) = TMP1 + IWORK( INDIBL+J-1 ) = ITMP1 + CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 ) + IF( INFO.NE.0 ) THEN + ITMP1 = IFAIL( I ) + IFAIL( I ) = IFAIL( J ) + IFAIL( J ) = ITMP1 + END IF + END IF + 60 CONTINUE + END IF +* +* Set WORK(1) to optimal workspace size. +* + WORK( 1 ) = LWKOPT +* + RETURN +* +* End of DSYEVX +* + END diff --git a/OTHER/LAPACK/dsygs2.f b/OTHER/LAPACK/dsygs2.f new file mode 100644 index 0000000000..dc747fcc7a --- /dev/null +++ b/OTHER/LAPACK/dsygs2.f @@ -0,0 +1,285 @@ +*> \brief \b DSYGS2 reduces a symmetric definite generalized eigenproblem to standard form, using the factorization results obtained from spotrf (unblocked algorithm). +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DSYGS2 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DSYGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER UPLO +* INTEGER INFO, ITYPE, LDA, LDB, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DSYGS2 reduces a real symmetric-definite generalized eigenproblem +*> to standard form. +*> +*> If ITYPE = 1, the problem is A*x = lambda*B*x, +*> and A is overwritten by inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T) +*> +*> If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or +*> B*A*x = lambda*x, and A is overwritten by U*A*U**T or L**T *A*L. +*> +*> B must have been previously factorized as U**T *U or L*L**T by DPOTRF. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] ITYPE +*> \verbatim +*> ITYPE is INTEGER +*> = 1: compute inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T); +*> = 2 or 3: compute U*A*U**T or L**T *A*L. +*> \endverbatim +*> +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> Specifies whether the upper or lower triangular part of the +*> symmetric matrix A is stored, and how B has been factorized. +*> = 'U': Upper triangular +*> = 'L': Lower triangular +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrices A and B. N >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> On entry, the symmetric matrix A. If UPLO = 'U', the leading +*> n by n upper triangular part of A contains the upper +*> triangular part of the matrix A, and the strictly lower +*> triangular part of A is not referenced. If UPLO = 'L', the +*> leading n by n lower triangular part of A contains the lower +*> triangular part of the matrix A, and the strictly upper +*> triangular part of A is not referenced. +*> +*> On exit, if INFO = 0, the transformed matrix, stored in the +*> same format as A. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,N). +*> \endverbatim +*> +*> \param[in] B +*> \verbatim +*> B is DOUBLE PRECISION array, dimension (LDB,N) +*> The triangular factor from the Cholesky factorization of B, +*> as returned by DPOTRF. +*> \endverbatim +*> +*> \param[in] LDB +*> \verbatim +*> LDB is INTEGER +*> The leading dimension of the array B. LDB >= max(1,N). +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit. +*> < 0: if INFO = -i, the i-th argument had an illegal value. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup hegs2 +* +* ===================================================================== + SUBROUTINE DSYGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO ) +* +* -- LAPACK computational routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER INFO, ITYPE, LDA, LDB, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, HALF + PARAMETER ( ONE = 1.0D0, HALF = 0.5D0 ) +* .. +* .. Local Scalars .. + LOGICAL UPPER + INTEGER K + DOUBLE PRECISION AKK, BKK, CT +* .. +* .. External Subroutines .. + EXTERNAL DAXPY, DSCAL, DSYR2, DTRMV, DTRSV, + $ XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + UPPER = LSAME( UPLO, 'U' ) + IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN + INFO = -1 + ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN + INFO = -2 + ELSE IF( N.LT.0 ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -5 + ELSE IF( LDB.LT.MAX( 1, N ) ) THEN + INFO = -7 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DSYGS2', -INFO ) + RETURN + END IF +* + IF( ITYPE.EQ.1 ) THEN + IF( UPPER ) THEN +* +* Compute inv(U**T)*A*inv(U) +* + DO 10 K = 1, N +* +* Update the upper triangle of A(k:n,k:n) +* + AKK = A( K, K ) + BKK = B( K, K ) + AKK = AKK / BKK**2 + A( K, K ) = AKK + IF( K.LT.N ) THEN + CALL DSCAL( N-K, ONE / BKK, A( K, K+1 ), LDA ) + CT = -HALF*AKK + CALL DAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ), + $ LDA ) + CALL DSYR2( UPLO, N-K, -ONE, A( K, K+1 ), LDA, + $ B( K, K+1 ), LDB, A( K+1, K+1 ), LDA ) + CALL DAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ), + $ LDA ) + CALL DTRSV( UPLO, 'Transpose', 'Non-unit', N-K, + $ B( K+1, K+1 ), LDB, A( K, K+1 ), LDA ) + END IF + 10 CONTINUE + ELSE +* +* Compute inv(L)*A*inv(L**T) +* + DO 20 K = 1, N +* +* Update the lower triangle of A(k:n,k:n) +* + AKK = A( K, K ) + BKK = B( K, K ) + AKK = AKK / BKK**2 + A( K, K ) = AKK + IF( K.LT.N ) THEN + CALL DSCAL( N-K, ONE / BKK, A( K+1, K ), 1 ) + CT = -HALF*AKK + CALL DAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), + $ 1 ) + CALL DSYR2( UPLO, N-K, -ONE, A( K+1, K ), 1, + $ B( K+1, K ), 1, A( K+1, K+1 ), LDA ) + CALL DAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), + $ 1 ) + CALL DTRSV( UPLO, 'No transpose', 'Non-unit', N-K, + $ B( K+1, K+1 ), LDB, A( K+1, K ), 1 ) + END IF + 20 CONTINUE + END IF + ELSE + IF( UPPER ) THEN +* +* Compute U*A*U**T +* + DO 30 K = 1, N +* +* Update the upper triangle of A(1:k,1:k) +* + AKK = A( K, K ) + BKK = B( K, K ) + CALL DTRMV( UPLO, 'No transpose', 'Non-unit', K-1, B, + $ LDB, A( 1, K ), 1 ) + CT = HALF*AKK + CALL DAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 ) + CALL DSYR2( UPLO, K-1, ONE, A( 1, K ), 1, B( 1, K ), + $ 1, + $ A, LDA ) + CALL DAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 ) + CALL DSCAL( K-1, BKK, A( 1, K ), 1 ) + A( K, K ) = AKK*BKK**2 + 30 CONTINUE + ELSE +* +* Compute L**T *A*L +* + DO 40 K = 1, N +* +* Update the lower triangle of A(1:k,1:k) +* + AKK = A( K, K ) + BKK = B( K, K ) + CALL DTRMV( UPLO, 'Transpose', 'Non-unit', K-1, B, + $ LDB, + $ A( K, 1 ), LDA ) + CT = HALF*AKK + CALL DAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA ) + CALL DSYR2( UPLO, K-1, ONE, A( K, 1 ), LDA, B( K, 1 ), + $ LDB, A, LDA ) + CALL DAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA ) + CALL DSCAL( K-1, BKK, A( K, 1 ), LDA ) + A( K, K ) = AKK*BKK**2 + 40 CONTINUE + END IF + END IF + RETURN +* +* End of DSYGS2 +* + END diff --git a/OTHER/LAPACK/dsygst.f b/OTHER/LAPACK/dsygst.f new file mode 100644 index 0000000000..eb48ee0907 --- /dev/null +++ b/OTHER/LAPACK/dsygst.f @@ -0,0 +1,327 @@ +*> \brief \b DSYGST +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DSYGST + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER UPLO +* INTEGER INFO, ITYPE, LDA, LDB, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DSYGST reduces a real symmetric-definite generalized eigenproblem +*> to standard form. +*> +*> If ITYPE = 1, the problem is A*x = lambda*B*x, +*> and A is overwritten by inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T) +*> +*> If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or +*> B*A*x = lambda*x, and A is overwritten by U*A*U**T or L**T*A*L. +*> +*> B must have been previously factorized as U**T*U or L*L**T by DPOTRF. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] ITYPE +*> \verbatim +*> ITYPE is INTEGER +*> = 1: compute inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T); +*> = 2 or 3: compute U*A*U**T or L**T*A*L. +*> \endverbatim +*> +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> = 'U': Upper triangle of A is stored and B is factored as +*> U**T*U; +*> = 'L': Lower triangle of A is stored and B is factored as +*> L*L**T. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrices A and B. N >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> On entry, the symmetric matrix A. If UPLO = 'U', the leading +*> N-by-N upper triangular part of A contains the upper +*> triangular part of the matrix A, and the strictly lower +*> triangular part of A is not referenced. If UPLO = 'L', the +*> leading N-by-N lower triangular part of A contains the lower +*> triangular part of the matrix A, and the strictly upper +*> triangular part of A is not referenced. +*> +*> On exit, if INFO = 0, the transformed matrix, stored in the +*> same format as A. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,N). +*> \endverbatim +*> +*> \param[in] B +*> \verbatim +*> B is DOUBLE PRECISION array, dimension (LDB,N) +*> The triangular factor from the Cholesky factorization of B, +*> as returned by DPOTRF. +*> \endverbatim +*> +*> \param[in] LDB +*> \verbatim +*> LDB is INTEGER +*> The leading dimension of the array B. LDB >= max(1,N). +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup hegst +* +* ===================================================================== + SUBROUTINE DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO ) +* +* -- LAPACK computational routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER INFO, ITYPE, LDA, LDB, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, HALF + PARAMETER ( ONE = 1.0D0, HALF = 0.5D0 ) +* .. +* .. Local Scalars .. + LOGICAL UPPER + INTEGER K, KB, NB +* .. +* .. External Subroutines .. + EXTERNAL DSYGS2, DSYMM, DSYR2K, DTRMM, DTRSM, + $ XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. External Functions .. + LOGICAL LSAME + INTEGER ILAENV + EXTERNAL LSAME, ILAENV +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + UPPER = LSAME( UPLO, 'U' ) + IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN + INFO = -1 + ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN + INFO = -2 + ELSE IF( N.LT.0 ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -5 + ELSE IF( LDB.LT.MAX( 1, N ) ) THEN + INFO = -7 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DSYGST', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.EQ.0 ) + $ RETURN +* +* Determine the block size for this environment. +* + NB = ILAENV( 1, 'DSYGST', UPLO, N, -1, -1, -1 ) +* + IF( NB.LE.1 .OR. NB.GE.N ) THEN +* +* Use unblocked code +* + CALL DSYGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO ) + ELSE +* +* Use blocked code +* + IF( ITYPE.EQ.1 ) THEN + IF( UPPER ) THEN +* +* Compute inv(U**T)*A*inv(U) +* + DO 10 K = 1, N, NB + KB = MIN( N-K+1, NB ) +* +* Update the upper triangle of A(k:n,k:n) +* + CALL DSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA, + $ B( K, K ), LDB, INFO ) + IF( K+KB.LE.N ) THEN + CALL DTRSM( 'Left', UPLO, 'Transpose', + $ 'Non-unit', + $ KB, N-K-KB+1, ONE, B( K, K ), LDB, + $ A( K, K+KB ), LDA ) + CALL DSYMM( 'Left', UPLO, KB, N-K-KB+1, -HALF, + $ A( K, K ), LDA, B( K, K+KB ), LDB, ONE, + $ A( K, K+KB ), LDA ) + CALL DSYR2K( UPLO, 'Transpose', N-K-KB+1, KB, + $ -ONE, + $ A( K, K+KB ), LDA, B( K, K+KB ), LDB, + $ ONE, A( K+KB, K+KB ), LDA ) + CALL DSYMM( 'Left', UPLO, KB, N-K-KB+1, -HALF, + $ A( K, K ), LDA, B( K, K+KB ), LDB, ONE, + $ A( K, K+KB ), LDA ) + CALL DTRSM( 'Right', UPLO, 'No transpose', + $ 'Non-unit', KB, N-K-KB+1, ONE, + $ B( K+KB, K+KB ), LDB, A( K, K+KB ), + $ LDA ) + END IF + 10 CONTINUE + ELSE +* +* Compute inv(L)*A*inv(L**T) +* + DO 20 K = 1, N, NB + KB = MIN( N-K+1, NB ) +* +* Update the lower triangle of A(k:n,k:n) +* + CALL DSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA, + $ B( K, K ), LDB, INFO ) + IF( K+KB.LE.N ) THEN + CALL DTRSM( 'Right', UPLO, 'Transpose', + $ 'Non-unit', + $ N-K-KB+1, KB, ONE, B( K, K ), LDB, + $ A( K+KB, K ), LDA ) + CALL DSYMM( 'Right', UPLO, N-K-KB+1, KB, -HALF, + $ A( K, K ), LDA, B( K+KB, K ), LDB, ONE, + $ A( K+KB, K ), LDA ) + CALL DSYR2K( UPLO, 'No transpose', N-K-KB+1, KB, + $ -ONE, A( K+KB, K ), LDA, B( K+KB, K ), + $ LDB, ONE, A( K+KB, K+KB ), LDA ) + CALL DSYMM( 'Right', UPLO, N-K-KB+1, KB, -HALF, + $ A( K, K ), LDA, B( K+KB, K ), LDB, ONE, + $ A( K+KB, K ), LDA ) + CALL DTRSM( 'Left', UPLO, 'No transpose', + $ 'Non-unit', N-K-KB+1, KB, ONE, + $ B( K+KB, K+KB ), LDB, A( K+KB, K ), + $ LDA ) + END IF + 20 CONTINUE + END IF + ELSE + IF( UPPER ) THEN +* +* Compute U*A*U**T +* + DO 30 K = 1, N, NB + KB = MIN( N-K+1, NB ) +* +* Update the upper triangle of A(1:k+kb-1,1:k+kb-1) +* + CALL DTRMM( 'Left', UPLO, 'No transpose', + $ 'Non-unit', + $ K-1, KB, ONE, B, LDB, A( 1, K ), LDA ) + CALL DSYMM( 'Right', UPLO, K-1, KB, HALF, A( K, + $ K ), + $ LDA, B( 1, K ), LDB, ONE, A( 1, K ), LDA ) + CALL DSYR2K( UPLO, 'No transpose', K-1, KB, ONE, + $ A( 1, K ), LDA, B( 1, K ), LDB, ONE, A, + $ LDA ) + CALL DSYMM( 'Right', UPLO, K-1, KB, HALF, A( K, + $ K ), + $ LDA, B( 1, K ), LDB, ONE, A( 1, K ), LDA ) + CALL DTRMM( 'Right', UPLO, 'Transpose', 'Non-unit', + $ K-1, KB, ONE, B( K, K ), LDB, A( 1, K ), + $ LDA ) + CALL DSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA, + $ B( K, K ), LDB, INFO ) + 30 CONTINUE + ELSE +* +* Compute L**T*A*L +* + DO 40 K = 1, N, NB + KB = MIN( N-K+1, NB ) +* +* Update the lower triangle of A(1:k+kb-1,1:k+kb-1) +* + CALL DTRMM( 'Right', UPLO, 'No transpose', + $ 'Non-unit', + $ KB, K-1, ONE, B, LDB, A( K, 1 ), LDA ) + CALL DSYMM( 'Left', UPLO, KB, K-1, HALF, A( K, K ), + $ LDA, B( K, 1 ), LDB, ONE, A( K, 1 ), LDA ) + CALL DSYR2K( UPLO, 'Transpose', K-1, KB, ONE, + $ A( K, 1 ), LDA, B( K, 1 ), LDB, ONE, A, + $ LDA ) + CALL DSYMM( 'Left', UPLO, KB, K-1, HALF, A( K, K ), + $ LDA, B( K, 1 ), LDB, ONE, A( K, 1 ), LDA ) + CALL DTRMM( 'Left', UPLO, 'Transpose', 'Non-unit', + $ KB, + $ K-1, ONE, B( K, K ), LDB, A( K, 1 ), LDA ) + CALL DSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA, + $ B( K, K ), LDB, INFO ) + 40 CONTINUE + END IF + END IF + END IF + RETURN +* +* End of DSYGST +* + END diff --git a/OTHER/LAPACK/dsytd2.f b/OTHER/LAPACK/dsytd2.f new file mode 100644 index 0000000000..e948496a12 --- /dev/null +++ b/OTHER/LAPACK/dsytd2.f @@ -0,0 +1,323 @@ +*> \brief \b DSYTD2 reduces a symmetric matrix to real symmetric tridiagonal form by an orthogonal similarity transformation (unblocked algorithm). +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DSYTD2 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DSYTD2( UPLO, N, A, LDA, D, E, TAU, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER UPLO +* INTEGER INFO, LDA, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAU( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DSYTD2 reduces a real symmetric matrix A to symmetric tridiagonal +*> form T by an orthogonal similarity transformation: Q**T * A * Q = T. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> Specifies whether the upper or lower triangular part of the +*> symmetric matrix A is stored: +*> = 'U': Upper triangular +*> = 'L': Lower triangular +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrix A. N >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> On entry, the symmetric matrix A. If UPLO = 'U', the leading +*> n-by-n upper triangular part of A contains the upper +*> triangular part of the matrix A, and the strictly lower +*> triangular part of A is not referenced. If UPLO = 'L', the +*> leading n-by-n lower triangular part of A contains the lower +*> triangular part of the matrix A, and the strictly upper +*> triangular part of A is not referenced. +*> On exit, if UPLO = 'U', the diagonal and first superdiagonal +*> of A are overwritten by the corresponding elements of the +*> tridiagonal matrix T, and the elements above the first +*> superdiagonal, with the array TAU, represent the orthogonal +*> matrix Q as a product of elementary reflectors; if UPLO +*> = 'L', the diagonal and first subdiagonal of A are over- +*> written by the corresponding elements of the tridiagonal +*> matrix T, and the elements below the first subdiagonal, with +*> the array TAU, represent the orthogonal matrix Q as a product +*> of elementary reflectors. See Further Details. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,N). +*> \endverbatim +*> +*> \param[out] D +*> \verbatim +*> D is DOUBLE PRECISION array, dimension (N) +*> The diagonal elements of the tridiagonal matrix T: +*> D(i) = A(i,i). +*> \endverbatim +*> +*> \param[out] E +*> \verbatim +*> E is DOUBLE PRECISION array, dimension (N-1) +*> The off-diagonal elements of the tridiagonal matrix T: +*> E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'. +*> \endverbatim +*> +*> \param[out] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION array, dimension (N-1) +*> The scalar factors of the elementary reflectors (see Further +*> Details). +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup hetd2 +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> If UPLO = 'U', the matrix Q is represented as a product of elementary +*> reflectors +*> +*> Q = H(n-1) . . . H(2) H(1). +*> +*> Each H(i) has the form +*> +*> H(i) = I - tau * v * v**T +*> +*> where tau is a real scalar, and v is a real vector with +*> v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in +*> A(1:i-1,i+1), and tau in TAU(i). +*> +*> If UPLO = 'L', the matrix Q is represented as a product of elementary +*> reflectors +*> +*> Q = H(1) H(2) . . . H(n-1). +*> +*> Each H(i) has the form +*> +*> H(i) = I - tau * v * v**T +*> +*> where tau is a real scalar, and v is a real vector with +*> v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i), +*> and tau in TAU(i). +*> +*> The contents of A on exit are illustrated by the following examples +*> with n = 5: +*> +*> if UPLO = 'U': if UPLO = 'L': +*> +*> ( d e v2 v3 v4 ) ( d ) +*> ( d e v3 v4 ) ( e d ) +*> ( d e v4 ) ( v1 e d ) +*> ( d e ) ( v1 v2 e d ) +*> ( d ) ( v1 v2 v3 e d ) +*> +*> where d and e denote diagonal and off-diagonal elements of T, and vi +*> denotes an element of the vector defining H(i). +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DSYTD2( UPLO, N, A, LDA, D, E, TAU, INFO ) +* +* -- LAPACK computational routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER INFO, LDA, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAU( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO, HALF + PARAMETER ( ONE = 1.0D0, ZERO = 0.0D0, + $ HALF = 1.0D0 / 2.0D0 ) +* .. +* .. Local Scalars .. + LOGICAL UPPER + INTEGER I + DOUBLE PRECISION ALPHA, TAUI +* .. +* .. External Subroutines .. + EXTERNAL DAXPY, DLARFG, DSYMV, DSYR2, XERBLA +* .. +* .. External Functions .. + LOGICAL LSAME + DOUBLE PRECISION DDOT + EXTERNAL LSAME, DDOT +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input parameters +* + INFO = 0 + UPPER = LSAME( UPLO, 'U' ) + IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -4 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DSYTD2', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.LE.0 ) + $ RETURN +* + IF( UPPER ) THEN +* +* Reduce the upper triangle of A +* + DO 10 I = N - 1, 1, -1 +* +* Generate elementary reflector H(i) = I - tau * v * v**T +* to annihilate A(1:i-1,i+1) +* + CALL DLARFG( I, A( I, I+1 ), A( 1, I+1 ), 1, TAUI ) + E( I ) = A( I, I+1 ) +* + IF( TAUI.NE.ZERO ) THEN +* +* Apply H(i) from both sides to A(1:i,1:i) +* + A( I, I+1 ) = ONE +* +* Compute x := tau * A * v storing x in TAU(1:i) +* + CALL DSYMV( UPLO, I, TAUI, A, LDA, A( 1, I+1 ), 1, + $ ZERO, + $ TAU, 1 ) +* +* Compute w := x - 1/2 * tau * (x**T * v) * v +* + ALPHA = -HALF*TAUI*DDOT( I, TAU, 1, A( 1, I+1 ), 1 ) + CALL DAXPY( I, ALPHA, A( 1, I+1 ), 1, TAU, 1 ) +* +* Apply the transformation as a rank-2 update: +* A := A - v * w**T - w * v**T +* + CALL DSYR2( UPLO, I, -ONE, A( 1, I+1 ), 1, TAU, 1, A, + $ LDA ) +* + A( I, I+1 ) = E( I ) + END IF + D( I+1 ) = A( I+1, I+1 ) + TAU( I ) = TAUI + 10 CONTINUE + D( 1 ) = A( 1, 1 ) + ELSE +* +* Reduce the lower triangle of A +* + DO 20 I = 1, N - 1 +* +* Generate elementary reflector H(i) = I - tau * v * v**T +* to annihilate A(i+2:n,i) +* + CALL DLARFG( N-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1, + $ TAUI ) + E( I ) = A( I+1, I ) +* + IF( TAUI.NE.ZERO ) THEN +* +* Apply H(i) from both sides to A(i+1:n,i+1:n) +* + A( I+1, I ) = ONE +* +* Compute x := tau * A * v storing y in TAU(i:n-1) +* + CALL DSYMV( UPLO, N-I, TAUI, A( I+1, I+1 ), LDA, + $ A( I+1, I ), 1, ZERO, TAU( I ), 1 ) +* +* Compute w := x - 1/2 * tau * (x**T * v) * v +* + ALPHA = -HALF*TAUI*DDOT( N-I, TAU( I ), 1, A( I+1, + $ I ), + $ 1 ) + CALL DAXPY( N-I, ALPHA, A( I+1, I ), 1, TAU( I ), 1 ) +* +* Apply the transformation as a rank-2 update: +* A := A - v * w**T - w * v**T +* + CALL DSYR2( UPLO, N-I, -ONE, A( I+1, I ), 1, TAU( I ), + $ 1, + $ A( I+1, I+1 ), LDA ) +* + A( I+1, I ) = E( I ) + END IF + D( I ) = A( I, I ) + TAU( I ) = TAUI + 20 CONTINUE + D( N ) = A( N, N ) + END IF +* + RETURN +* +* End of DSYTD2 +* + END diff --git a/OTHER/LAPACK/dsytrd.f b/OTHER/LAPACK/dsytrd.f new file mode 100644 index 0000000000..2b56de494b --- /dev/null +++ b/OTHER/LAPACK/dsytrd.f @@ -0,0 +1,375 @@ +*> \brief \b DSYTRD +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DSYTRD + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DSYTRD( UPLO, N, A, LDA, D, E, TAU, WORK, LWORK, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER UPLO +* INTEGER INFO, LDA, LWORK, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAU( * ), +* $ WORK( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DSYTRD reduces a real symmetric matrix A to real symmetric +*> tridiagonal form T by an orthogonal similarity transformation: +*> Q**T * A * Q = T. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> = 'U': Upper triangle of A is stored; +*> = 'L': Lower triangle of A is stored. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrix A. N >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> On entry, the symmetric matrix A. If UPLO = 'U', the leading +*> N-by-N upper triangular part of A contains the upper +*> triangular part of the matrix A, and the strictly lower +*> triangular part of A is not referenced. If UPLO = 'L', the +*> leading N-by-N lower triangular part of A contains the lower +*> triangular part of the matrix A, and the strictly upper +*> triangular part of A is not referenced. +*> On exit, if UPLO = 'U', the diagonal and first superdiagonal +*> of A are overwritten by the corresponding elements of the +*> tridiagonal matrix T, and the elements above the first +*> superdiagonal, with the array TAU, represent the orthogonal +*> matrix Q as a product of elementary reflectors; if UPLO +*> = 'L', the diagonal and first subdiagonal of A are over- +*> written by the corresponding elements of the tridiagonal +*> matrix T, and the elements below the first subdiagonal, with +*> the array TAU, represent the orthogonal matrix Q as a product +*> of elementary reflectors. See Further Details. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,N). +*> \endverbatim +*> +*> \param[out] D +*> \verbatim +*> D is DOUBLE PRECISION array, dimension (N) +*> The diagonal elements of the tridiagonal matrix T: +*> D(i) = A(i,i). +*> \endverbatim +*> +*> \param[out] E +*> \verbatim +*> E is DOUBLE PRECISION array, dimension (N-1) +*> The off-diagonal elements of the tridiagonal matrix T: +*> E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'. +*> \endverbatim +*> +*> \param[out] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION array, dimension (N-1) +*> The scalar factors of the elementary reflectors (see Further +*> Details). +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) +*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is INTEGER +*> The dimension of the array WORK. LWORK >= 1. +*> For optimum performance LWORK >= N*NB, where NB is the +*> optimal blocksize. +*> +*> If LWORK = -1, then a workspace query is assumed; the routine +*> only calculates the optimal size of the WORK array, returns +*> this value as the first entry of the WORK array, and no error +*> message related to LWORK is issued by XERBLA. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup hetrd +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> If UPLO = 'U', the matrix Q is represented as a product of elementary +*> reflectors +*> +*> Q = H(n-1) . . . H(2) H(1). +*> +*> Each H(i) has the form +*> +*> H(i) = I - tau * v * v**T +*> +*> where tau is a real scalar, and v is a real vector with +*> v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in +*> A(1:i-1,i+1), and tau in TAU(i). +*> +*> If UPLO = 'L', the matrix Q is represented as a product of elementary +*> reflectors +*> +*> Q = H(1) H(2) . . . H(n-1). +*> +*> Each H(i) has the form +*> +*> H(i) = I - tau * v * v**T +*> +*> where tau is a real scalar, and v is a real vector with +*> v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i), +*> and tau in TAU(i). +*> +*> The contents of A on exit are illustrated by the following examples +*> with n = 5: +*> +*> if UPLO = 'U': if UPLO = 'L': +*> +*> ( d e v2 v3 v4 ) ( d ) +*> ( d e v3 v4 ) ( e d ) +*> ( d e v4 ) ( v1 e d ) +*> ( d e ) ( v1 v2 e d ) +*> ( d ) ( v1 v2 v3 e d ) +*> +*> where d and e denote diagonal and off-diagonal elements of T, and vi +*> denotes an element of the vector defining H(i). +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DSYTRD( UPLO, N, A, LDA, D, E, TAU, WORK, LWORK, + $ INFO ) +* +* -- LAPACK computational routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER INFO, LDA, LWORK, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAU( * ), + $ WORK( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL LQUERY, UPPER + INTEGER I, IINFO, IWS, J, KK, LDWORK, LWKOPT, NB, + $ NBMIN, NX +* .. +* .. External Subroutines .. + EXTERNAL DLATRD, DSYR2K, DSYTD2, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. External Functions .. + LOGICAL LSAME + INTEGER ILAENV + EXTERNAL LSAME, ILAENV +* .. +* .. Executable Statements .. +* +* Test the input parameters +* + INFO = 0 + UPPER = LSAME( UPLO, 'U' ) + LQUERY = ( LWORK.EQ.-1 ) + IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -4 + ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN + INFO = -9 + END IF +* + IF( INFO.EQ.0 ) THEN +* +* Determine the block size. +* + NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 ) + LWKOPT = MAX( 1, N*NB ) + WORK( 1 ) = LWKOPT + END IF +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DSYTRD', -INFO ) + RETURN + ELSE IF( LQUERY ) THEN + RETURN + END IF +* +* Quick return if possible +* + IF( N.EQ.0 ) THEN + WORK( 1 ) = 1 + RETURN + END IF +* + NX = N + IWS = 1 + IF( NB.GT.1 .AND. NB.LT.N ) THEN +* +* Determine when to cross over from blocked to unblocked code +* (last block is always handled by unblocked code). +* + NX = MAX( NB, ILAENV( 3, 'DSYTRD', UPLO, N, -1, -1, -1 ) ) + IF( NX.LT.N ) THEN +* +* Determine if workspace is large enough for blocked code. +* + LDWORK = N + IWS = LDWORK*NB + IF( LWORK.LT.IWS ) THEN +* +* Not enough workspace to use optimal NB: determine the +* minimum value of NB, and reduce NB or force use of +* unblocked code by setting NX = N. +* + NB = MAX( LWORK / LDWORK, 1 ) + NBMIN = ILAENV( 2, 'DSYTRD', UPLO, N, -1, -1, -1 ) + IF( NB.LT.NBMIN ) + $ NX = N + END IF + ELSE + NX = N + END IF + ELSE + NB = 1 + END IF +* + IF( UPPER ) THEN +* +* Reduce the upper triangle of A. +* Columns 1:kk are handled by the unblocked method. +* + KK = N - ( ( N-NX+NB-1 ) / NB )*NB + DO 20 I = N - NB + 1, KK + 1, -NB +* +* Reduce columns i:i+nb-1 to tridiagonal form and form the +* matrix W which is needed to update the unreduced part of +* the matrix +* + CALL DLATRD( UPLO, I+NB-1, NB, A, LDA, E, TAU, WORK, + $ LDWORK ) +* +* Update the unreduced submatrix A(1:i-1,1:i-1), using an +* update of the form: A := A - V*W**T - W*V**T +* + CALL DSYR2K( UPLO, 'No transpose', I-1, NB, -ONE, A( 1, + $ I ), + $ LDA, WORK, LDWORK, ONE, A, LDA ) +* +* Copy superdiagonal elements back into A, and diagonal +* elements into D +* + DO 10 J = I, I + NB - 1 + A( J-1, J ) = E( J-1 ) + D( J ) = A( J, J ) + 10 CONTINUE + 20 CONTINUE +* +* Use unblocked code to reduce the last or only block +* + CALL DSYTD2( UPLO, KK, A, LDA, D, E, TAU, IINFO ) + ELSE +* +* Reduce the lower triangle of A +* + DO 40 I = 1, N - NX, NB +* +* Reduce columns i:i+nb-1 to tridiagonal form and form the +* matrix W which is needed to update the unreduced part of +* the matrix +* + CALL DLATRD( UPLO, N-I+1, NB, A( I, I ), LDA, E( I ), + $ TAU( I ), WORK, LDWORK ) +* +* Update the unreduced submatrix A(i+ib:n,i+ib:n), using +* an update of the form: A := A - V*W**T - W*V**T +* + CALL DSYR2K( UPLO, 'No transpose', N-I-NB+1, NB, -ONE, + $ A( I+NB, I ), LDA, WORK( NB+1 ), LDWORK, ONE, + $ A( I+NB, I+NB ), LDA ) +* +* Copy subdiagonal elements back into A, and diagonal +* elements into D +* + DO 30 J = I, I + NB - 1 + A( J+1, J ) = E( J ) + D( J ) = A( J, J ) + 30 CONTINUE + 40 CONTINUE +* +* Use unblocked code to reduce the last or only block +* + CALL DSYTD2( UPLO, N-I+1, A( I, I ), LDA, D( I ), E( I ), + $ TAU( I ), IINFO ) + END IF +* + WORK( 1 ) = LWKOPT + RETURN +* +* End of DSYTRD +* + END diff --git a/OTHER/LAPACK/iladlc.f b/OTHER/LAPACK/iladlc.f new file mode 100644 index 0000000000..c5ef963c4b --- /dev/null +++ b/OTHER/LAPACK/iladlc.f @@ -0,0 +1,115 @@ +*> \brief \b ILADLC scans a matrix for its last non-zero column. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download ILADLC + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* INTEGER FUNCTION ILADLC( M, N, A, LDA ) +* +* .. Scalar Arguments .. +* INTEGER M, N, LDA +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> ILADLC scans A for its last non-zero column. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the matrix A. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the matrix A. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> The m by n matrix A. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,M). +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup ilalc +* +* ===================================================================== + INTEGER FUNCTION ILADLC( M, N, A, LDA ) +* +* -- LAPACK auxiliary routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + INTEGER M, N, LDA +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I +* .. +* .. Executable Statements .. +* +* Quick test for the common case where one corner is non-zero. + IF( N.EQ.0 ) THEN + ILADLC = N + ELSE IF( A(1, N).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN + ILADLC = N + ELSE +* Now scan each column from the end, returning with the first non-zero. + DO ILADLC = N, 1, -1 + DO I = 1, M + IF( A(I, ILADLC).NE.ZERO ) RETURN + END DO + END DO + END IF + RETURN + END diff --git a/OTHER/LAPACK/iladlr.f b/OTHER/LAPACK/iladlr.f new file mode 100644 index 0000000000..900df1c1a7 --- /dev/null +++ b/OTHER/LAPACK/iladlr.f @@ -0,0 +1,118 @@ +*> \brief \b ILADLR scans a matrix for its last non-zero row. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download ILADLR + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* INTEGER FUNCTION ILADLR( M, N, A, LDA ) +* +* .. Scalar Arguments .. +* INTEGER M, N, LDA +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> ILADLR scans A for its last non-zero row. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the matrix A. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the matrix A. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> The m by n matrix A. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,M). +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \ingroup ilalr +* +* ===================================================================== + INTEGER FUNCTION ILADLR( M, N, A, LDA ) +* +* -- LAPACK auxiliary routine -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* +* .. Scalar Arguments .. + INTEGER M, N, LDA +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, J +* .. +* .. Executable Statements .. +* +* Quick test for the common case where one corner is non-zero. + IF( M.EQ.0 ) THEN + ILADLR = M + ELSE IF( A(M, 1).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN + ILADLR = M + ELSE +* Scan up each column tracking the last zero row seen. + ILADLR = 0 + DO J = 1, N + I=M + DO WHILE((A(MAX(I,1),J).EQ.ZERO).AND.(I.GE.1)) + I=I-1 + ENDDO + ILADLR = MAX( ILADLR, I ) + END DO + END IF + RETURN + END From aa9560bd1645fa607ab4c4e639606d5ca5be5b8f Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Wed, 24 Sep 2025 16:47:58 -0700 Subject: [PATCH 249/261] Linking dsygvx with openseespy --- SRC/Makefile | 4 +- SRC/classTags.h | 2 + SRC/interpreter/OpenSeesCommands.cpp | 13 +++ .../eigenSOE/SymmGeneralizedEigenSOE.cpp | 47 ++++------ .../eigenSOE/SymmGeneralizedEigenSOE.h | 27 ++---- .../eigenSOE/SymmGeneralizedEigenSolver.cpp | 89 ++++++++++--------- .../eigenSOE/SymmGeneralizedEigenSolver.h | 32 ++----- 7 files changed, 97 insertions(+), 117 deletions(-) diff --git a/SRC/Makefile b/SRC/Makefile index e7fdd5e2f3..d0eb0b4a23 100644 --- a/SRC/Makefile +++ b/SRC/Makefile @@ -1269,7 +1269,9 @@ SequentialSysOfEqn_LIBS = $(FE)/system_of_eqn/linearSOE/LinearSOE.o \ $(FE)/system_of_eqn/linearSOE/umfGEN/UmfpackGenLinSOE.o \ $(FE)/system_of_eqn/linearSOE/umfGEN/UmfpackGenLinSolver.o \ $(FE)/system_of_eqn/eigenSOE/FullGenEigenSOE.o \ - $(FE)/system_of_eqn/eigenSOE/FullGenEigenSolver.o + $(FE)/system_of_eqn/eigenSOE/FullGenEigenSolver.o \ + $(FE)/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.o \ + $(FE)/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.o ifeq ($(PROGRAMMING_MODE), PARALLEL_INTERPRETERS) SysOfEqn_LIBS = $(SequentialSysOfEqn_LIBS) \ diff --git a/SRC/classTags.h b/SRC/classTags.h index 1bf6557203..943bd169e2 100644 --- a/SRC/classTags.h +++ b/SRC/classTags.h @@ -51,12 +51,14 @@ #define EigenSOE_TAGS_FullGenEigenSOE 4 #define EigenSOE_TAGS_ArpackSOE 5 #define EigenSOE_TAGS_GeneralArpackSOE 6 +#define EigenSOE_TAGS_SymmGeneralizedEigenSOE 7 #define EigenSOLVER_TAGS_BandArpackSolver 1 #define EigenSOLVER_TAGS_SymArpackSolver 2 #define EigenSOLVER_TAGS_SymBandEigenSolver 3 #define EigenSOLVER_TAGS_FullGenEigenSolver 4 #define EigenSOLVER_TAGS_ArpackSolver 5 #define EigenSOLVER_TAGS_GeneralArpackSolver 6 +#define EigenSOLVER_TAGS_SymmGeneralizedEigenSolver 7 #define EigenALGORITHM_TAGS_Frequency 1 #define EigenALGORITHM_TAGS_Standard 2 diff --git a/SRC/interpreter/OpenSeesCommands.cpp b/SRC/interpreter/OpenSeesCommands.cpp index f8d129e6df..cff665352d 100644 --- a/SRC/interpreter/OpenSeesCommands.cpp +++ b/SRC/interpreter/OpenSeesCommands.cpp @@ -79,6 +79,8 @@ UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #include #include #include +#include +#include #include #include #include @@ -321,6 +323,11 @@ OpenSeesCommands::eigen(int typeSolver, double shift, FullGenEigenSolver *theEigenSolver = new FullGenEigenSolver(); theEigenSOE = new FullGenEigenSOE(*theEigenSolver, *theAnalysisModel); + } else if (typeSolver == EigenSOE_TAGS_SymmGeneralizedEigenSOE) { + + SymmGeneralizedEigenSolver *theEigenSolver = new SymmGeneralizedEigenSolver(); + theEigenSOE = new SymmGeneralizedEigenSOE(*theEigenSolver, *theAnalysisModel); + } else { theEigenSOE = new ArpackSOE(shift); @@ -2108,6 +2115,12 @@ int OPS_eigenAnalysis() (strcmp(type,"-symmBandLapackEigen") == 0)) typeSolver = EigenSOE_TAGS_SymBandEigenSOE; + else if ((strcmp(type,"symmGenLapack") == 0) || + (strcmp(type,"-symmGenLapack") == 0) || + (strcmp(type,"symmGenLapackEigen") == 0) || + (strcmp(type,"-symmGenLapackEigen") == 0)) + typeSolver = EigenSOE_TAGS_SymmGeneralizedEigenSOE; + else if ((strcmp(type, "fullGenLapack") == 0) || (strcmp(type, "-fullGenLapack") == 0) || (strcmp(type, "fullGenLapackEigen") == 0) || diff --git a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.cpp b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.cpp index 14b4b9dc5b..afbff4f3a3 100644 --- a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.cpp +++ b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.cpp @@ -18,19 +18,8 @@ ** ** ** ****************************************************************** */ -// $Revision: 1.2 $ -// $Date: 2009-05-20 17:31:36 $ -// $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/eigenSOE/FullGenEigenSOE.cpp,v $ - -// Written: Andreas Schellenberg (andreas.schellenberg@gmx.net) -// Created: 11/07 -// Revision: A -// -// Description: This file contains the implementation of the -// FullGenEigenSOE class. - -#include -#include +#include +#include #include #include #include @@ -42,9 +31,9 @@ #include using std::nothrow; -FullGenEigenSOE::FullGenEigenSOE(FullGenEigenSolver &theSolver, +SymmGeneralizedEigenSOE::SymmGeneralizedEigenSOE(SymmGeneralizedEigenSolver &theSolver, AnalysisModel &aModel) - : EigenSOE(theSolver, EigenSOE_TAGS_FullGenEigenSOE), + : EigenSOE(theSolver, EigenSOE_TAGS_SymmGeneralizedEigenSOE), size(0), A(0), Asize(0), M(0), Msize(0), factored(false), theModel(&aModel) { @@ -52,7 +41,7 @@ FullGenEigenSOE::FullGenEigenSOE(FullGenEigenSolver &theSolver, } -FullGenEigenSOE::~FullGenEigenSOE() +SymmGeneralizedEigenSOE::~SymmGeneralizedEigenSOE() { if (A != 0) delete [] A; @@ -61,13 +50,13 @@ FullGenEigenSOE::~FullGenEigenSOE() } -int FullGenEigenSOE::getNumEqn(void) const +int SymmGeneralizedEigenSOE::getNumEqn(void) const { return size; } -int FullGenEigenSOE::setSize(Graph &theGraph) +int SymmGeneralizedEigenSOE::setSize(Graph &theGraph) { int result = 0; size = theGraph.getNumVertex(); @@ -81,7 +70,7 @@ int FullGenEigenSOE::setSize(Graph &theGraph) A = new (nothrow) double[newSize]; if (A == 0) { - opserr << "WARNING FullGenEigenSOE::setSize() - " + opserr << "WARNING SymmGeneralizedEigenSOE::setSize() - " << "ran out of memory for A (size,size) (" << size << ", " << size << ")\n"; Asize = 0; size = 0; @@ -102,7 +91,7 @@ int FullGenEigenSOE::setSize(Graph &theGraph) M = new (nothrow) double[newSize]; if (M == 0) { - opserr << "WARNING FullGenEigenSOE::setSize() - " + opserr << "WARNING SymmGeneralizedEigenSOE::setSize() - " << "ran out of memory for M (size,size) (" << size << ", " << size << ")\n"; Msize = 0; size = 0; @@ -122,7 +111,7 @@ int FullGenEigenSOE::setSize(Graph &theGraph) EigenSolver *theSolver = this->getSolver(); int solverOK = theSolver->setSize(); if (solverOK < 0) { - opserr << "WARNING FullGenEigenSOE::setSize() - "; + opserr << "WARNING SymmGeneralizedEigenSOE::setSize() - "; opserr << "solver failed in setSize()\n"; return solverOK; } @@ -131,7 +120,7 @@ int FullGenEigenSOE::setSize(Graph &theGraph) } -int FullGenEigenSOE::addA(const Matrix &m, const ID &id, double fact) +int SymmGeneralizedEigenSOE::addA(const Matrix &m, const ID &id, double fact) { // check for quick return if (fact == 0.0) @@ -140,7 +129,7 @@ int FullGenEigenSOE::addA(const Matrix &m, const ID &id, double fact) // check that m and id are of similar size int idSize = id.Size(); if (idSize != m.noRows() && idSize != m.noCols()) { - opserr << "FullGenEigenSOE::addA() - Matrix and ID not of similar sizes\n"; + opserr << "SymmGeneralizedEigenSOE::addA() - Matrix and ID not of similar sizes\n"; return -1; } @@ -178,7 +167,7 @@ int FullGenEigenSOE::addA(const Matrix &m, const ID &id, double fact) } -int FullGenEigenSOE::addM(const Matrix &m, const ID &id, double fact) +int SymmGeneralizedEigenSOE::addM(const Matrix &m, const ID &id, double fact) { // check for quick return if (fact == 0.0) @@ -187,7 +176,7 @@ int FullGenEigenSOE::addM(const Matrix &m, const ID &id, double fact) // check that m and id are of similar size int idSize = id.Size(); if (idSize != m.noRows() && idSize != m.noCols()) { - opserr << "FullGenEigenSOE::addM() - Matrix and ID not of similar sizes\n"; + opserr << "SymmGeneralizedEigenSOE::addM() - Matrix and ID not of similar sizes\n"; return -1; } @@ -225,7 +214,7 @@ int FullGenEigenSOE::addM(const Matrix &m, const ID &id, double fact) } -void FullGenEigenSOE::zeroA(void) +void SymmGeneralizedEigenSOE::zeroA(void) { double *Aptr = A; for (int i = 0; i < Asize; i++) @@ -235,7 +224,7 @@ void FullGenEigenSOE::zeroA(void) } -void FullGenEigenSOE::zeroM(void) +void SymmGeneralizedEigenSOE::zeroM(void) { double *Mptr = M; for (int i = 0; i < Msize; i++) @@ -245,13 +234,13 @@ void FullGenEigenSOE::zeroM(void) } -int FullGenEigenSOE::sendSelf(int commitTag, Channel &theChannel) +int SymmGeneralizedEigenSOE::sendSelf(int commitTag, Channel &theChannel) { return 0; } -int FullGenEigenSOE::recvSelf(int commitTag, Channel &theChannel, +int SymmGeneralizedEigenSOE::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) { return 0; diff --git a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.h b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.h index 6e012fac67..944a710626 100644 --- a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.h +++ b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.h @@ -18,35 +18,22 @@ ** ** ** ****************************************************************** */ -// $Revision: 1.1 $ -// $Date: 2007-11-29 19:31:08 $ -// $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/eigenSOE/FullGenEigenSOE.h,v $ - - -#ifndef FullGenEigenSOE_h -#define FullGenEigenSOE_h - -// Written: Andreas Schellenberg (andreas.schellenberg@gmx.net) -// Created: 11/07 -// Revision: A -// -// Description: This file contains the class definition for -// FullGenEigenSOE, which stores full nonsymmetric matrices, -// A and M, for generalized eigenvalue computations. +#ifndef SymmGeneralizedEigenSOE_h +#define SymmGeneralizedEigenSOE_h #include #include class AnalysisModel; -class FullGenEigenSolver; +class SymmGeneralizedEigenSolver; -class FullGenEigenSOE : public EigenSOE +class SymmGeneralizedEigenSOE : public EigenSOE { public: - FullGenEigenSOE(FullGenEigenSolver &theSolver, + SymmGeneralizedEigenSOE(SymmGeneralizedEigenSolver &theSolver, AnalysisModel &theModel); - virtual ~FullGenEigenSOE(); + virtual ~SymmGeneralizedEigenSOE(); virtual int getNumEqn(void) const; virtual int setSize(Graph &theGraph); @@ -61,7 +48,7 @@ class FullGenEigenSOE : public EigenSOE int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); - friend class FullGenEigenSolver; + friend class SymmGeneralizedEigenSolver; protected: diff --git a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp index a4a67cd621..a39c353dbb 100644 --- a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp +++ b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp @@ -18,18 +18,7 @@ ** ** ** ****************************************************************** */ -// $Revision: 1.6 $ -// $Date: 2009-05-19 21:54:55 $ -// $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/eigenSOE/FullGenEigenSolver.cpp,v $ - -// Written: Andreas Schellenberg (andreas.schellenberg@gmx.net) -// Created: 11/07 -// Revision: A -// -// Description: This file contains the implementation of the -// FullGenEigenSolver class. - -#include +#include #include #include #include @@ -62,8 +51,8 @@ extern "C" int dsygvx_(int *ITPYE, char *JOBZ, char *RANGE, char *UPLO, #endif -FullGenEigenSolver::FullGenEigenSolver() - : EigenSolver(EigenSOLVER_TAGS_FullGenEigenSolver), +SymmGeneralizedEigenSolver::SymmGeneralizedEigenSolver() + : EigenSolver(EigenSOLVER_TAGS_SymmGeneralizedEigenSolver), theSOE(0), numEigen(0), eigenvalue(0), eigenvector(0), sortingID(0), eigenV(0) { @@ -71,7 +60,7 @@ FullGenEigenSolver::FullGenEigenSolver() } -FullGenEigenSolver::~FullGenEigenSolver() +SymmGeneralizedEigenSolver::~SymmGeneralizedEigenSolver() { if (eigenvalue != 0) delete [] eigenvalue; @@ -84,15 +73,15 @@ FullGenEigenSolver::~FullGenEigenSolver() } -int FullGenEigenSolver::solve(int nEigen, bool generalized, bool findSmallest) +int SymmGeneralizedEigenSolver::solve(int nEigen, bool generalized, bool findSmallest) { if (generalized == false) { - opserr << "FullGenEigenSolver::solve() - only solves generalized problem\n"; + opserr << "SymmGeneralizedEigenSolver::solve() - only solves generalized problem\n"; return -1; } if (theSOE == 0) { - opserr << "FullGenEigenSolver::solve()- " + opserr << "SymmGeneralizedEigenSolver::solve()- " << " No EigenSOE object has been set yet\n"; return -1; } @@ -164,6 +153,7 @@ int FullGenEigenSolver::solve(int nEigen, bool generalized, bool findSmallest) // dummy left eigenvectors double vl[1]; + double vu[1]; // leading dimension of dummy left eigenvectors int ldvl = 1; @@ -171,17 +161,17 @@ int FullGenEigenSolver::solve(int nEigen, bool generalized, bool findSmallest) // allocate memory for right eigenvectors if (eigenvector != 0) delete [] eigenvector; - eigenvector = new double [n*n]; - - // leading dimension of right eigenvectors - int ldvr = n; + eigenvector = new double [nEigen*n]; // number of eigenvalues found int m = 0; - // + // int ldz = n; - double *w = new double[n]; + double *w = eigenvalue; + double *z = eigenvector; + + double abstol = 0.0; // dimension of the workspace array int lwork = n*8; @@ -199,23 +189,34 @@ int FullGenEigenSolver::solve(int nEigen, bool generalized, bool findSmallest) // call the LAPACK eigenvalue subroutine #ifdef _WIN32 + // itype=1, jobz='V', range='I', uplo='U', n=N, Kptr=A, ldK=N, Mptr=B, ldM=N, + // vl=N/A, vu=N/A, il=1, iu=nEigen, abstol=0 + // m=out (num eigenvalues found) + // w=out (first m eigenvalues) + // z=out (first m eigenvectors) + // ldz=out (leading dimension of eigenvectors) + // work=double array of length lwork + // lwork=8*n + // iwork=int array of length 5*n + // ifail=out (0 if success, if info>0 ifail has indices of eigenvectors that failed to converge) + // info=out (0 if success, <0 arg error, >0 failed to converge) DSYGVX(&itype, jobz, range, uplo, &n, Kptr, &ldK, Mptr, &ldM, - vl, vu, &il, &iu, &abstol, &m, w, z, &ldz, - work, &lwork, iwork, &ifail, &info); + vl, vu, &il, &iu, &abstol, + &m, w, z, &ldz, work, &lwork, iwork, ifail, &info); #else dsygvx_(&itype, jobz, range, uplo, &n, Kptr, &ldK, Mptr, &ldM, vl, vu, &il, &iu, &abstol, &m, w, z, &ldz, - work, &lwork, iwork, &ifail, &info); + work, &lwork, iwork, ifail, &info); #endif if (info < 0) { - opserr << "FullGenEigenSolver::solve() - invalid argument number " + opserr << "SymmGeneralizedEigenSolver::solve() - invalid argument number " << -info << " passed to LAPACK dggev routine\n"; return info; } if (info > 0) { - opserr << "FullGenEigenSolver::solve() - the LAPACK dggev routine " + opserr << "SymmGeneralizedEigenSolver::solve() - the LAPACK dggev routine " << "returned error code " << info << endln; return -info; } @@ -230,7 +231,7 @@ int FullGenEigenSolver::solve(int nEigen, bool generalized, bool findSmallest) } else { eigenvalue[i] = -mag/beta[i]; - opserr << "FullGenEigenSolver::solve() - the eigenvalue " + opserr << "SymmGeneralizedEigenSolver::solve() - the eigenvalue " << i+1 << " is complex with magnitude " << -eigenvalue[i] << endln; } @@ -288,14 +289,14 @@ int FullGenEigenSolver::solve(int nEigen, bool generalized, bool findSmallest) for (int i=0; isize; @@ -319,7 +320,7 @@ int FullGenEigenSolver::setSize() eigenV = new Vector(size); if (eigenV == 0 || eigenV->Size() != size) { - opserr << "FullGenEigenSolver::setSize() "; + opserr << "SymmGeneralizedEigenSolver::setSize() "; opserr << " - ran out of memory for eigenVector of size "; opserr << theSOE->size << endln; return -2; @@ -330,7 +331,7 @@ int FullGenEigenSolver::setSize() } -int FullGenEigenSolver::setEigenSOE(FullGenEigenSOE &thesoe) +int SymmGeneralizedEigenSolver::setEigenSOE(SymmGeneralizedEigenSOE &thesoe) { theSOE = &thesoe; @@ -338,10 +339,10 @@ int FullGenEigenSolver::setEigenSOE(FullGenEigenSOE &thesoe) } -const Vector& FullGenEigenSolver::getEigenvector(int mode) +const Vector& SymmGeneralizedEigenSolver::getEigenvector(int mode) { if (mode <= 0 || mode > numEigen) { - opserr << "FullGenEigenSolver::getEigenVector() - mode " + opserr << "SymmGeneralizedEigenSolver::getEigenVector() - mode " << mode << " is out of range (1 - " << numEigen << ")\n"; eigenV->Zero(); return *eigenV; @@ -356,7 +357,7 @@ const Vector& FullGenEigenSolver::getEigenvector(int mode) } } else { - opserr << "FullGenEigenSolver::getEigenvector() - " + opserr << "SymmGeneralizedEigenSolver::getEigenvector() - " << "eigenvectors not computed yet\n"; eigenV->Zero(); } @@ -368,10 +369,10 @@ const Vector& FullGenEigenSolver::getEigenvector(int mode) } -double FullGenEigenSolver::getEigenvalue(int mode) +double SymmGeneralizedEigenSolver::getEigenvalue(int mode) { if (mode <= 0 || mode > numEigen) { - opserr << "FullGenEigenSolver::getEigenvalue() - mode " + opserr << "SymmGeneralizedEigenSolver::getEigenvalue() - mode " << mode << " is out of range (1 - " << numEigen << ")\n"; return 0.0; } @@ -380,27 +381,27 @@ double FullGenEigenSolver::getEigenvalue(int mode) return eigenvalue[mode-1]; } else { - opserr << "FullGenEigenSolver::getEigenvalue() - " + opserr << "SymmGeneralizedEigenSolver::getEigenvalue() - " << "eigenvalues not yet computed\n"; return 0.0; } } -int FullGenEigenSolver::sendSelf(int commitTag, Channel &theChannel) +int SymmGeneralizedEigenSolver::sendSelf(int commitTag, Channel &theChannel) { return 0; } -int FullGenEigenSolver::recvSelf(int commitTag, Channel &theChannel, +int SymmGeneralizedEigenSolver::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) { return 0; } -void FullGenEigenSolver::sort(int length, double *x, int *id) +void SymmGeneralizedEigenSolver::sort(int length, double *x, int *id) { // this is an implementation of shell sort that // additionally keeps track of the sorting order diff --git a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.h b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.h index 02e3a0f60c..cfbcd1aa48 100644 --- a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.h +++ b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.h @@ -18,48 +18,34 @@ ** ** ** ****************************************************************** */ -// $Revision: 1.3 $ -// $Date: 2009-05-11 21:01:10 $ -// $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/eigenSOE/FullGenEigenSolver.h,v $ - - -#ifndef FullGenEigenSolver_h -#define FullGenEigenSolver_h - -// Written: Andreas Schellenberg (andreas.schellenberg@gmx.net) -// Created: 11/07 -// Revision: A -// -// Description: This file contains the class definition for -// FullGenEigenSolver. It computes the generalized eigenvalues -// and eigenvectors of a pair of real nonsymmetric matrices using -// the LAPACK subroutine DGGEV. +#ifndef SymmGenEigenSolver_h +#define SymmGenEigenSolver_h #include -#include +#include -class FullGenEigenSolver : public EigenSolver +class SymmGeneralizedEigenSolver : public EigenSolver { public: - FullGenEigenSolver(); - virtual ~FullGenEigenSolver(); + SymmGeneralizedEigenSolver(); + virtual ~SymmGeneralizedEigenSolver(); virtual int solve(int numEigen, bool generalized, bool findSmallest = true); virtual int setSize(void); - virtual int setEigenSOE(FullGenEigenSOE &theSOE); + virtual int setEigenSOE(SymmGeneralizedEigenSOE &theSOE); virtual const Vector &getEigenvector(int mode); virtual double getEigenvalue(int mode); int sendSelf(int commitTag, Channel &theChannel); int recvSelf(int commitTag, Channel &theChannel, - FEM_ObjectBroker &theBroker); + FEM_ObjectBroker &theBroker); protected: private: void sort(int length, double *x, int *id); - FullGenEigenSOE *theSOE; + SymmGeneralizedEigenSOE *theSOE; int numEigen; double *eigenvalue; From 7e0811ea5b563b8b4b2c8f62d26321d2bd8e7fcb Mon Sep 17 00:00:00 2001 From: Michael Scott Date: Thu, 25 Sep 2025 14:44:02 -0700 Subject: [PATCH 250/261] Passing OpenSees K and M to dsygvx routine --- .../eigenSOE/SymmGeneralizedEigenSOE.cpp | 12 ++- .../eigenSOE/SymmGeneralizedEigenSolver.cpp | 74 +++++++++++++------ 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.cpp b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.cpp index afbff4f3a3..40290b673c 100644 --- a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.cpp +++ b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSOE.cpp @@ -140,7 +140,8 @@ int SymmGeneralizedEigenSOE::addA(const Matrix &m, const ID &id, double fact) double *startColiPtr = A + col*size; for (int j=0; j= 0) { + if (row = 0 && + row <= col) { // Only add upper double *APtr = startColiPtr + row; *APtr += m(j,i); } @@ -154,7 +155,8 @@ int SymmGeneralizedEigenSOE::addA(const Matrix &m, const ID &id, double fact) double *startColiPtr = A + col*size; for (int j=0; j= 0) { + if (row = 0 && + row <= col) { // Only add upper double *APtr = startColiPtr + row; *APtr += m(j,i)*fact; } @@ -187,7 +189,8 @@ int SymmGeneralizedEigenSOE::addM(const Matrix &m, const ID &id, double fact) double *startColiPtr = M + col*size; for (int j=0; j= 0) { + if (row = 0 && + row <= col) { // Only add upper double *MPtr = startColiPtr + row; *MPtr += m(j,i); } @@ -201,7 +204,8 @@ int SymmGeneralizedEigenSOE::addM(const Matrix &m, const ID &id, double fact) double *startColiPtr = M + col*size; for (int j=0; j= 0) { + if (row = 0 && + row <= col) { // Only add upper double *MPtr = startColiPtr + row; *MPtr += m(j,i)*fact; } diff --git a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp index a39c353dbb..20b7b63e92 100644 --- a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp +++ b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp @@ -94,7 +94,7 @@ int SymmGeneralizedEigenSolver::solve(int nEigen, bool generalized, bool findSma // get the number of equations int n = theSOE->size; - + // set the number of eigenvalues numEigen = nEigen; if (numEigen > n) @@ -118,7 +118,19 @@ int SymmGeneralizedEigenSolver::solve(int nEigen, bool generalized, bool findSma // stiffness matrix data double *Kptr = theSOE->A; - + /* + double *Kptr = new double[n*n]; + for (int i = 0; i < n*n; i++) Kptr[i] = 0.0; + Kptr[0] = 1220; + //Kptr[1] = -610; + Kptr[4] = -610; + Kptr[5] = 610; + Kptr[10] = 1220; + //Kptr[11] = -610; + Kptr[14] = -610; + Kptr[15] = 610; + */ + double *kCopy = new double[n*n]; for (int i = 0; i < n*n; i++) kCopy[i] = Kptr[i]; @@ -128,7 +140,15 @@ int SymmGeneralizedEigenSolver::solve(int nEigen, bool generalized, bool findSma // mass matrix data double *Mptr = theSOE->M; - + /* + double *Mptr = new double[n*n]; + for (int i = 0; i < n*n; i++) Mptr[i] = 0.0; + Mptr[0] = 1; + Mptr[5] = 1; + Mptr[10] = 1; + Mptr[15] = 1; + */ + double *mCopy = new double[n*n]; for (int i=0; i0 ifail has indices of eigenvectors that failed to converge) // info=out (0 if success, <0 arg error, >0 failed to converge) DSYGVX(&itype, jobz, range, uplo, &n, Kptr, &ldK, Mptr, &ldM, - vl, vu, &il, &iu, &abstol, + &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, work, &lwork, iwork, ifail, &info); #else dsygvx_(&itype, jobz, range, uplo, &n, Kptr, &ldK, Mptr, &ldM, - vl, vu, &il, &iu, &abstol, &m, w, z, &ldz, - work, &lwork, iwork, ifail, &info); + &vl, &vu, &il, &iu, &abstol, + &m, w, z, &ldz, work, &lwork, iwork, ifail, &info); #endif - + if (info < 0) { opserr << "SymmGeneralizedEigenSolver::solve() - invalid argument number " - << -info << " passed to LAPACK dggev routine\n"; + << -info << " passed to LAPACK dsygvx routine\n"; return info; } if (info > 0) { - opserr << "SymmGeneralizedEigenSolver::solve() - the LAPACK dggev routine " + opserr << "SymmGeneralizedEigenSolver::solve() - the LAPACK dsygvx routine " << "returned error code " << info << endln; return -info; } + /* + opserr << "m = " << m << endln; + for (int i = 0; i < m; i++) + opserr << w[i] << ' '; + opserr << endln; + + for (int j = 0; j < numEigen; j++) { + for (int i = 0; i < n; i++) + opserr << z[j*n + i] << ' '; + opserr << endln; + } + */ + theSOE->factored = true; for (int i=0; isort(n, eigenvalue, sortingID); + this->sort(numEigen, eigenvalue, sortingID); for (int i=0; i Date: Thu, 25 Sep 2025 16:50:20 -0700 Subject: [PATCH 251/261] Adding small mass if zero on diagonal of M --- .../eigenSOE/SymmGeneralizedEigenSolver.cpp | 45 +++++-------------- .../eigenSOE/SymmGeneralizedEigenSolver.h | 4 +- 2 files changed, 13 insertions(+), 36 deletions(-) diff --git a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp index 20b7b63e92..ae08ab2f75 100644 --- a/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp +++ b/SRC/system_of_eqn/eigenSOE/SymmGeneralizedEigenSolver.cpp @@ -51,10 +51,10 @@ extern "C" int dsygvx_(int *ITPYE, char *JOBZ, char *RANGE, char *UPLO, #endif -SymmGeneralizedEigenSolver::SymmGeneralizedEigenSolver() +SymmGeneralizedEigenSolver::SymmGeneralizedEigenSolver(double m) : EigenSolver(EigenSOLVER_TAGS_SymmGeneralizedEigenSolver), theSOE(0), numEigen(0), eigenvalue(0), - eigenvector(0), sortingID(0), eigenV(0) + eigenvector(0), sortingID(0), eigenV(0), msmall(m) { } @@ -118,18 +118,6 @@ int SymmGeneralizedEigenSolver::solve(int nEigen, bool generalized, bool findSma // stiffness matrix data double *Kptr = theSOE->A; - /* - double *Kptr = new double[n*n]; - for (int i = 0; i < n*n; i++) Kptr[i] = 0.0; - Kptr[0] = 1220; - //Kptr[1] = -610; - Kptr[4] = -610; - Kptr[5] = 610; - Kptr[10] = 1220; - //Kptr[11] = -610; - Kptr[14] = -610; - Kptr[15] = 610; - */ double *kCopy = new double[n*n]; for (int i = 0; i < n*n; i++) @@ -140,14 +128,14 @@ int SymmGeneralizedEigenSolver::solve(int nEigen, bool generalized, bool findSma // mass matrix data double *Mptr = theSOE->M; - /* - double *Mptr = new double[n*n]; - for (int i = 0; i < n*n; i++) Mptr[i] = 0.0; - Mptr[0] = 1; - Mptr[5] = 1; - Mptr[10] = 1; - Mptr[15] = 1; - */ + + // Check for zero mass on diagonal, add some small mass + int index = 0; + for (int i = 0; i < n; i++) { + if (Mptr[index] == 0.0) + Mptr[index] = Kptr[index]*msmall; + index += n+1; + } double *mCopy = new double[n*n]; for (int i=0; i Date: Thu, 25 Sep 2025 20:10:44 -0700 Subject: [PATCH 252/261] Updating CMake --- OTHER/LAPACK/CMakeLists.txt | 20 ++++++++++++++++++++ SRC/system_of_eqn/eigenSOE/CMakeLists.txt | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/OTHER/LAPACK/CMakeLists.txt b/OTHER/LAPACK/CMakeLists.txt index 9131a2c286..8490563a6d 100644 --- a/OTHER/LAPACK/CMakeLists.txt +++ b/OTHER/LAPACK/CMakeLists.txt @@ -143,6 +143,26 @@ target_sources(LAPACK PUBLIC dlatrs.f dla_rpvgrw.f dla_gerpvgrw.f + + dsygvx.f + dsygst.f + dsygs2.f + dsyevx.f + dormtr.f + dorgtr.f + dorgql.f + dorg2l.f + dormql.f + dorm2l.f + dlansy.f + dlarf1l.f + iladlr.f + iladlc.f + disnan.f + dlaisnan.f + dsytrd.f + dlatrd.f + dsytd2.f ) add_library(LAPACK_C) diff --git a/SRC/system_of_eqn/eigenSOE/CMakeLists.txt b/SRC/system_of_eqn/eigenSOE/CMakeLists.txt index 5f6de61057..cb61250c74 100644 --- a/SRC/system_of_eqn/eigenSOE/CMakeLists.txt +++ b/SRC/system_of_eqn/eigenSOE/CMakeLists.txt @@ -14,6 +14,8 @@ target_sources(OPS_SysOfEqn FullGenEigenSolver.cpp SymBandEigenSOE.cpp SymBandEigenSolver.cpp + SymmGeneralizedEigenSOE.cpp + SymmGeneralizedEigenSolver.cpp PUBLIC ArpackSOE.h ArpackSolver.h @@ -23,6 +25,8 @@ target_sources(OPS_SysOfEqn FullGenEigenSolver.h SymBandEigenSOE.h SymBandEigenSolver.h + SymmGeneralizedEigenSOE.h + SymmGeneralizedEigenSolver.h ) target_sources(OPS_SysOfEqn From e4a4bf8b232028ec3bce3c36656a88e35f3b4885 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Sat, 27 Sep 2025 13:25:36 -0700 Subject: [PATCH 253/261] Update PointsSpectrum.cpp --- SRC/reliability/domain/spectrum/PointsSpectrum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/reliability/domain/spectrum/PointsSpectrum.cpp b/SRC/reliability/domain/spectrum/PointsSpectrum.cpp index 474ba9db8a..bdde40b6b6 100644 --- a/SRC/reliability/domain/spectrum/PointsSpectrum.cpp +++ b/SRC/reliability/domain/spectrum/PointsSpectrum.cpp @@ -91,7 +91,7 @@ PointsSpectrum::getAmplitude(double frequency) else { double dy, dx, a, b; for (int i=1; i frequencies(i-1) && frequency < frequencies(i)) { + if (frequency > frequencies(i-1) && frequency <= frequencies(i)) { dy = amplitudes(i) - amplitudes(i-1); dx = frequencies(i) - frequencies(i-1); a = dy/dx; From f56befb7c0653d55fab324a97b666f135de48eb9 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 29 Sep 2025 15:51:26 -0700 Subject: [PATCH 254/261] Adding optional input for analysis end time --- SRC/analysis/analysis/SDFAnalysis.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/SRC/analysis/analysis/SDFAnalysis.cpp b/SRC/analysis/analysis/SDFAnalysis.cpp index e8d58e2601..3052e6e9a7 100644 --- a/SRC/analysis/analysis/SDFAnalysis.cpp +++ b/SRC/analysis/analysis/SDFAnalysis.cpp @@ -31,8 +31,20 @@ int OPS_sdfResponse() int numOptionalArgs = 0; int numArgs = OPS_GetNumRemainingInputArgs(); + double t_end = -1.0; while (OPS_GetNumRemainingInputArgs() > 0) { std::string type = OPS_GetString(); + if (type == "-tend") { + numOptionalArgs++; + if (OPS_GetNumRemainingInputArgs() > 0) { + numData = 1; + if (OPS_GetDoubleInput(&numData, &t_end) < 0) { + opserr << "ERROR sdfResponse - failed to read tend" << endln; + return 0; + } + numOptionalArgs++; + } + } if (type == "-uresid" || type == "-uresidual") { numOptionalArgs++; if (OPS_GetNumRemainingInputArgs() > 0) { @@ -64,8 +76,8 @@ int OPS_sdfResponse() if (numArgs < 7 || numArgs > 8) { opserr << "Incorrect number of arguments to sdfResponse --"; - opserr << "m, zeta, k, Fy, alpha, dtF, filename, dt, <-uresidual, uresid, -umaxprev, umaxp>" << endln; - opserr << "m, zeta, k, Fy, alpha, tsTag, dt, <-uresidual, uresid, -umaxprev, umaxp>" << endln; + opserr << "m, zeta, k, Fy, alpha, dtF, filename, dt, <-uresidual, uresid, -umaxprev, umaxp, -tend, tend>" << endln; + opserr << "m, zeta, k, Fy, alpha, tsTag, dt, <-uresidual, uresid, -umaxprev, umaxp, -tend, tend>" << endln; return -1; } @@ -171,7 +183,7 @@ int OPS_sdfResponse() int i = 0; double ft, u=0, du, v, a, fs, zs, ftrial, kT, kTeff, dg, phat, R, R0, accel; double time = accelSeries->getStartTime(); - double Tend = accelSeries->getDuration(); + double Tend = std::max(t_end,accelSeries->getDuration()); while (time < Tend) { ft = accelSeries->getFactor(time); From 0289dfbbe34be294412c26680b0a64c7ed09bc92 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 29 Sep 2025 16:10:53 -0700 Subject: [PATCH 255/261] Using user-specified end analysis time --- SRC/analysis/analysis/SDFAnalysis.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SRC/analysis/analysis/SDFAnalysis.cpp b/SRC/analysis/analysis/SDFAnalysis.cpp index 3052e6e9a7..7410d67d63 100644 --- a/SRC/analysis/analysis/SDFAnalysis.cpp +++ b/SRC/analysis/analysis/SDFAnalysis.cpp @@ -31,7 +31,7 @@ int OPS_sdfResponse() int numOptionalArgs = 0; int numArgs = OPS_GetNumRemainingInputArgs(); - double t_end = -1.0; + double t_end = 0.0; bool t_end_specified = false; while (OPS_GetNumRemainingInputArgs() > 0) { std::string type = OPS_GetString(); if (type == "-tend") { @@ -43,6 +43,7 @@ int OPS_sdfResponse() return 0; } numOptionalArgs++; + t_end_specified = true; } } if (type == "-uresid" || type == "-uresidual") { @@ -183,7 +184,7 @@ int OPS_sdfResponse() int i = 0; double ft, u=0, du, v, a, fs, zs, ftrial, kT, kTeff, dg, phat, R, R0, accel; double time = accelSeries->getStartTime(); - double Tend = std::max(t_end,accelSeries->getDuration()); + double Tend = t_end_specified ? t_end : accelSeries->getDuration(); while (time < Tend) { ft = accelSeries->getFactor(time); From 6f71a7db7c61901190c8806ef735f9e060c1db5c Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 10 Oct 2025 10:14:10 -0700 Subject: [PATCH 256/261] Update PressureIndependMultiYield.cpp --- SRC/material/nD/soil/PressureIndependMultiYield.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/SRC/material/nD/soil/PressureIndependMultiYield.cpp b/SRC/material/nD/soil/PressureIndependMultiYield.cpp index a8d6aaf59d..0d12a92882 100644 --- a/SRC/material/nD/soil/PressureIndependMultiYield.cpp +++ b/SRC/material/nD/soil/PressureIndependMultiYield.cpp @@ -73,9 +73,11 @@ void* OPS_PressureIndependMultiYield() param[5] = 0.0; param[6] = 100.; param[7] = 0.0; - numdata = 5; + numdata = 8; if (OPS_GetDoubleInput(&numdata, ¶m[0]) < 0) { - opserr << "WARNING invalid PressureIndependMultiYield double inputs" << "\n"; + opserr << "WARNING invalid PressureIndependMultiYield double inputs\n"; + opserr << "Be sure to input frictionAng, refPress, and pressDependCoe.\n"; + opserr << "These inputs are now required; recommended 0, 100 kPa, and 0, respectively" << endln; return 0; } @@ -1597,3 +1599,4 @@ int PressureIndependMultiYield:: isCrossingNextSurface(void) } + From 58164b5e4559d914f93b49a26944413914d1288a Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Thu, 16 Oct 2025 16:35:37 -0700 Subject: [PATCH 257/261] Update RigidDiaphragm.cpp --- SRC/domain/constraints/RigidDiaphragm.cpp | 57 ++++++++++------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/SRC/domain/constraints/RigidDiaphragm.cpp b/SRC/domain/constraints/RigidDiaphragm.cpp index 294fa383ce..778972b9c6 100644 --- a/SRC/domain/constraints/RigidDiaphragm.cpp +++ b/SRC/domain/constraints/RigidDiaphragm.cpp @@ -174,52 +174,45 @@ RigidDiaphragm::RigidDiaphragm(Domain &theDomain, int nR, ID &nC, // rigid diaphragm in xy plane if (perpPlaneConstrained == 2) { + + // dof corresponding to dX, dY and theta Z (0,1,5) + id(0) = 0; id(1) = 1; id(2) = 5; + // set up transformation matrix + mat(0,2) = - deltaY; + mat(1,2) = deltaX; + // check constrained node in xy plane with retained node - if (deltaZ == 0.0) { - - // dof corresponding to dX, dY and theta Z (0,1,5) - id(0) = 0; id(1) = 1; id(2) = 5; - - // set up transformation matrix - mat(0,2) = - deltaY; - mat(1,2) = deltaX; - - } else - opserr << "RigidDiaphragm::RigidDiaphragm - ignoring constrained Node " << ndC << ", not in xy plane\n"; + if (deltaZ != 0.0) + opserr << "RigidDiaphragm::RigidDiaphragm - proceeding with constrained Node " << ndC << " not in xy plane\n"; // rigid diaphragm in xz plane } else if (perpPlaneConstrained == 1) { - // check constrained node in xy plane with retained node - if (deltaY == 0.0) { - - // dof corresponding to dX, dZ and theta Y (0,2,4) - id(0) = 0; id(1) = 2; id(2) = 4; + // dof corresponding to dX, dZ and theta Y (0,2,4) + id(0) = 0; id(1) = 2; id(2) = 4; - // set up transformation matrix - mat(0,2) = deltaZ; - mat(1,2) = -deltaX; + // set up transformation matrix + mat(0,2) = deltaZ; + mat(1,2) = -deltaX; - } else - opserr << "RigidDiaphragm::RigidDiaphragm - ignoring constrained Node " << ndC << ", not in xz plane\n"; + // check constrained node in xy plane with retained node + if (deltaY != 0.0) + opserr << "RigidDiaphragm::RigidDiaphragm - proceeding with constrained Node " << ndC << " not in xz plane\n"; // rigid diaphragm in yz plane } else { - // check constrained node in xy plane with retained node - if (deltaX == 0.0) { - - // dof corresponding to dY, dZ and theta X (1,2,3) - id(0) = 1; id(1) = 2; id(2) = 3; + // dof corresponding to dY, dZ and theta X (1,2,3) + id(0) = 1; id(1) = 2; id(2) = 3; - // set up transformation matrix - mat(0,2) = -deltaZ; - mat(1,2) = deltaY; + // set up transformation matrix + mat(0,2) = -deltaZ; + mat(1,2) = deltaY; - } else - opserr << "RigidDiaphragm::RigidDiaphragm - ignoring constrained Node " << ndC << - ", not in xz plane\n"; + // check constrained node in xy plane with retained node + if (deltaX != 0.0) + opserr << "RigidDiaphragm::RigidDiaphragm - proceeding with constrained Node " << ndC << " not in yz plane\n"; } } else // node not in proper space From 69a34398d017c983b685f6c7c7b1cab8e5f04df0 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Tue, 21 Oct 2025 09:54:55 -0700 Subject: [PATCH 258/261] Adding gmsh recorder to Python interpreter --- SRC/interpreter/OpenSeesOutputCommands.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SRC/interpreter/OpenSeesOutputCommands.cpp b/SRC/interpreter/OpenSeesOutputCommands.cpp index ee36a2c319..b671f47520 100644 --- a/SRC/interpreter/OpenSeesOutputCommands.cpp +++ b/SRC/interpreter/OpenSeesOutputCommands.cpp @@ -88,6 +88,7 @@ void* OPS_RemoveRecorder(); void* OPS_MPCORecorder(); void* OPS_VTKHDF_Recorder(); #endif +void* OPS_GmshRecorder(); BackgroundMesh& OPS_getBgMesh(); void* OPS_DriftRecorder(); @@ -124,6 +125,7 @@ namespace { recordersMap.insert(std::make_pair("Collapse", &OPS_RemoveRecorder)); recordersMap.insert(std::make_pair("Drift", &OPS_DriftRecorder)); recordersMap.insert(std::make_pair("EnvelopeDrift", &OPS_EnvelopeDriftRecorder)); + recordersMap.insert(std::make_pair("gmsh", &OPS_GmshRecorder)); #ifdef _HDF5 recordersMap.insert(std::make_pair("mpco", &OPS_MPCORecorder)); recordersMap.insert(std::make_pair("VTKHDF", &OPS_VTKHDF_Recorder)); From 34b74e19f3db190ab4bf95b14513eceeaefdc5ff Mon Sep 17 00:00:00 2001 From: parduino Date: Mon, 27 Oct 2025 11:48:31 -0700 Subject: [PATCH 259/261] adding equivalent linear constitutive model --- DEVELOPER/core/classTags.h | 9 +++-- SRC/Makefile | 1 + .../FEM_ObjectBrokerAllClasses.cpp | 4 ++ SRC/classTags.h | 5 ++- .../OpenSeesNDMaterialCommands.cpp | 4 +- .../nD/TclModelBuilderNDMaterialCommand.cpp | 40 ++++++++++++------- SRC/material/nD/UWmaterials/CMakeLists.txt | 2 + SRC/material/nD/UWmaterials/Makefile | 3 +- .../commands/modeling/material/material.hpp | 2 + Win32/proj/material/material.vcxproj | 3 ++ Win32/proj/material/material.vcxproj.filters | 6 +++ Win64/proj/material/material.vcxproj | 2 + Win64/proj/material/material.vcxproj.filters | 6 +++ 13 files changed, 66 insertions(+), 21 deletions(-) diff --git a/DEVELOPER/core/classTags.h b/DEVELOPER/core/classTags.h index 65de56e9ce..325ad7bf9b 100644 --- a/DEVELOPER/core/classTags.h +++ b/DEVELOPER/core/classTags.h @@ -432,9 +432,12 @@ #define ND_TAG_PM4Sand 14021 // PM4Silt material - L.Chen #define ND_TAG_PM4Silt 14022 -// J2CyclicBoundingSurface material - D.Turello -#define ND_TAG_J2CyclicBoundingSurface 14023 - +// J2CyclicBoundingSurface material - P. Arduino, D.Turello +#define ND_TAG_J2CyclicBoundingSurface 14023 +#define ND_TAG_J2CyclicBoundingSurface3D 14024 +#define ND_TAG_J2CyclicBoundingSurfacePlaneStrain 14025 +// LinearElasticGGmax material - P. Arduino +#define ND_TAG_LinearElasticGGmax 14026 // MultiaxialCyclicPlasticity, add by Gang Wang #define ND_TAG_MultiaxialCyclicPlasticity 10031 #define ND_TAG_MultiaxialCyclicPlasticity3D 10032 diff --git a/SRC/Makefile b/SRC/Makefile index d0eb0b4a23..173931f25b 100644 --- a/SRC/Makefile +++ b/SRC/Makefile @@ -1008,6 +1008,7 @@ MATERIAL_LIBS = $(FE)/material/Material.o \ $(FE)/material/nD/UWmaterials/J2CyclicBoundingSurfacePlaneStrain.o \ $(FE)/material/nD/UWmaterials/PM4Sand.o \ $(FE)/material/nD/UWmaterials/PM4Silt.o \ + $(FE)/material/nD/UWmaterials/LinearElasticGGmax.o \ $(FE)/material/nD/UANDESmaterials/SAniSandMS.o \ $(FE)/material/nD/UANDESmaterials/SAniSandMS3D.o \ $(FE)/material/nD/UANDESmaterials/SAniSandMSPlaneStrain.o \ diff --git a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp index 8876d8e1c0..8ce18bc3af 100644 --- a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp +++ b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp @@ -297,6 +297,7 @@ #include "J2CyclicBoundingSurface.h" #include "J2CyclicBoundingSurface3D.h" #include "J2CyclicBoundingSurfacePlaneStrain.h" +#include "UWmaterials/LinearElasticGGmax.h" #include "UWmaterials/InitialStateAnalysisWrapper.h" #include "stressDensityModel/stressDensity.h" #include "InitStressNDMaterial.h" @@ -2375,6 +2376,9 @@ FEM_ObjectBrokerAllClasses::getNewNDMaterial(int classTag) case ND_TAG_J2CyclicBoundingSurfacePlaneStrain: return new J2CyclicBoundingSurfacePlaneStrain(); + case ND_TAG_LinearElasticGGmax: + return new LinearElasticGGmax(); + case ND_TAG_InitialStateAnalysisWrapper: return new InitialStateAnalysisWrapper(); case ND_TAG_stressDensity: diff --git a/SRC/classTags.h b/SRC/classTags.h index 943bd169e2..ea09a891d1 100644 --- a/SRC/classTags.h +++ b/SRC/classTags.h @@ -521,11 +521,12 @@ #define ND_TAG_PM4Sand 14021 // PM4Silt material - L.Chen #define ND_TAG_PM4Silt 14022 -// J2CyclicBoundingSurface material - P. Arduino, D.Turello +// J2CyclicBoundingSurface material - P. Arduino #define ND_TAG_J2CyclicBoundingSurface 14023 #define ND_TAG_J2CyclicBoundingSurface3D 14024 #define ND_TAG_J2CyclicBoundingSurfacePlaneStrain 14025 - +// LinearElasticGGmax material - P. Arduino +#define ND_TAG_LinearElasticGGmax 14026 // MultiaxialCyclicPlasticity, add by Gang Wang #define ND_TAG_MultiaxialCyclicPlasticity 10031 #define ND_TAG_MultiaxialCyclicPlasticity3D 10032 diff --git a/SRC/interpreter/OpenSeesNDMaterialCommands.cpp b/SRC/interpreter/OpenSeesNDMaterialCommands.cpp index 246a6c59ed..16074cf6cf 100644 --- a/SRC/interpreter/OpenSeesNDMaterialCommands.cpp +++ b/SRC/interpreter/OpenSeesNDMaterialCommands.cpp @@ -72,6 +72,7 @@ void* OPS_BeamFiberMaterial2d(); void* OPS_BeamFiberMaterial2dPS(); void* OPS_PM4SandMaterial(); void* OPS_PM4SiltMaterial(); +void* OPS_LinearElasticGGmaxMaterial(); void* OPS_UVCplanestress(); void* OPS_UVCmultiaxial(); void* OPS_PressureDependMultiYield03(); @@ -197,7 +198,8 @@ namespace { nDMaterialsMap.insert(std::make_pair("BeamFiber2d", &OPS_BeamFiberMaterial2d)); nDMaterialsMap.insert(std::make_pair("BeamFiber2dPS", &OPS_BeamFiberMaterial2dPS)); nDMaterialsMap.insert(std::make_pair("PM4Sand", &OPS_PM4SandMaterial)); - nDMaterialsMap.insert(std::make_pair("PM4Silt", &OPS_PM4SiltMaterial)); + nDMaterialsMap.insert(std::make_pair("PM4Silt", &OPS_PM4SiltMaterial)); + nDMaterialsMap.insert(std::make_pair("LinearElasticGGmax", &OPS_LinearElasticGGmaxMaterial)); nDMaterialsMap.insert(std::make_pair("UVCplanestress", &OPS_UVCplanestress)); nDMaterialsMap.insert(std::make_pair("UVCmultiaxial", &OPS_UVCmultiaxial)); nDMaterialsMap.insert(std::make_pair("PressureDependMultiYield03", &OPS_PressureDependMultiYield03)); diff --git a/SRC/material/nD/TclModelBuilderNDMaterialCommand.cpp b/SRC/material/nD/TclModelBuilderNDMaterialCommand.cpp index f7e2fc78e0..074185865f 100644 --- a/SRC/material/nD/TclModelBuilderNDMaterialCommand.cpp +++ b/SRC/material/nD/TclModelBuilderNDMaterialCommand.cpp @@ -20,6 +20,7 @@ ** Boris Jeremic (jeremic@ucdavis.edu) ** ** Zaohui Yang (zhyang@ucdavis.edu) ** ** Zhao Cheng (zcheng@ucdavis.edu) ** +** Pedro Arduino (parduino@uw.edu) ** ** ** ** ** ** ** @@ -83,6 +84,7 @@ extern void *OPS_ManzariDafaliasMaterial(void); extern void *OPS_ManzariDafaliasMaterialRO(void); extern void *OPS_PM4SandMaterial(void); extern void *OPS_PM4SiltMaterial(void); +extern void *OPS_LinearElasticGGmaxMaterial(void); extern void *OPS_J2CyclicBoundingSurfaceMaterial(void); extern void *OPS_CycLiqCPMaterial(void); extern void *OPS_CycLiqCPSPMaterial(void); @@ -494,23 +496,33 @@ TclModelBuilderNDMaterialCommand (ClientData clientData, Tcl_Interp *interp, int return TCL_ERROR; } - else if ((strcmp(argv[1], "J2CyclicBoundingSurface") == 0)) { + else if ((strcmp(argv[1], "J2CyclicBoundingSurface") == 0)) { - void *theMat = OPS_J2CyclicBoundingSurfaceMaterial(); - if (theMat != 0) - theMaterial = (NDMaterial *)theMat; - else - return TCL_ERROR; - } + void *theMat = OPS_J2CyclicBoundingSurfaceMaterial(); + if (theMat != 0) + theMaterial = (NDMaterial *)theMat; + else + return TCL_ERROR; + } - else if ((strcmp(argv[1], "PM4Silt") == 0)) { + else if ((strcmp(argv[1], "PM4Silt") == 0)) { + + void *theMat = OPS_PM4SiltMaterial(); + if (theMat != 0) + theMaterial = (NDMaterial *)theMat; + else + return TCL_ERROR; + } + + else if ((strcmp(argv[1], "LinearElasticGGmax") == 0)) { + + void *theMat = OPS_LinearElasticGGmaxMaterial(); + if (theMat != 0) + theMaterial = (NDMaterial *)theMat; + else + return TCL_ERROR; + } - void *theMat = OPS_PM4SiltMaterial(); - if (theMat != 0) - theMaterial = (NDMaterial *)theMat; - else - return TCL_ERROR; - } else if ((strcmp(argv[1],"ContactMaterial2D") == 0)){ diff --git a/SRC/material/nD/UWmaterials/CMakeLists.txt b/SRC/material/nD/UWmaterials/CMakeLists.txt index 00458f1a75..7ce5b26d4c 100644 --- a/SRC/material/nD/UWmaterials/CMakeLists.txt +++ b/SRC/material/nD/UWmaterials/CMakeLists.txt @@ -26,6 +26,7 @@ target_sources(OPS_Material ManzariDafaliasRO.cpp PM4Sand.cpp PM4Silt.cpp + LinearElasticGGmax.cpp PUBLIC BoundingCamClay.h BoundingCamClay3D.h @@ -47,6 +48,7 @@ target_sources(OPS_Material ManzariDafaliasRO.h PM4Sand.h PM4Silt.h + LinearElasticGGmax.h ) target_include_directories(OPS_Material PUBLIC ${CMAKE_CURRENT_LIST_DIR}) diff --git a/SRC/material/nD/UWmaterials/Makefile b/SRC/material/nD/UWmaterials/Makefile index 08464240d8..01c3184e28 100644 --- a/SRC/material/nD/UWmaterials/Makefile +++ b/SRC/material/nD/UWmaterials/Makefile @@ -19,7 +19,8 @@ OBJS = BoundingCamClay.o \ PM4Silt.o\ J2CyclicBoundingSurface.o\ J2CyclicBoundingSurface3D.o\ - J2CyclicBoundingSurfacePlaneStrain.o + J2CyclicBoundingSurfacePlaneStrain.o\ + LinearElasticGGmax.o all: $(OBJS) diff --git a/SRC/runtime/commands/modeling/material/material.hpp b/SRC/runtime/commands/modeling/material/material.hpp index ecaa3d0655..30b651465f 100644 --- a/SRC/runtime/commands/modeling/material/material.hpp +++ b/SRC/runtime/commands/modeling/material/material.hpp @@ -102,6 +102,7 @@ extern OPS_Routine OPS_ManzariDafaliasMaterial; extern OPS_Routine OPS_ManzariDafaliasMaterialRO; extern OPS_Routine OPS_PM4SandMaterial; extern OPS_Routine OPS_PM4SiltMaterial; +extern OPS_Routine OPS_LinearElasticGGmaxMaterial; extern OPS_Routine OPS_CycLiqCPMaterial; extern OPS_Routine OPS_CycLiqCPSPMaterial; extern OPS_Routine OPS_InitStressNDMaterial; @@ -276,6 +277,7 @@ static std::unordered_map OldMaterialCommands = { {"PM4Sand", OPS_PM4SandMaterial}, {"J2CyclicBoundingSurface", OPS_J2CyclicBoundingSurfaceMaterial}, {"PM4Silt", OPS_PM4SiltMaterial}, + {"LinearElasticGGmax", OPS_LinearElasticGGmaxMaterial}, {"ContactMaterial2D", OPS_ContactMaterial2DMaterial}, {"ContactMaterial3D", OPS_ContactMaterial3DMaterial}, {"InitialStateAnalysisWrapper", OPS_InitialStateAnalysisWrapperMaterial}, diff --git a/Win32/proj/material/material.vcxproj b/Win32/proj/material/material.vcxproj index 54b66fa258..83f712c921 100644 --- a/Win32/proj/material/material.vcxproj +++ b/Win32/proj/material/material.vcxproj @@ -134,6 +134,7 @@ + @@ -564,6 +565,8 @@ + + diff --git a/Win32/proj/material/material.vcxproj.filters b/Win32/proj/material/material.vcxproj.filters index 04b6542f81..e6a9760087 100644 --- a/Win32/proj/material/material.vcxproj.filters +++ b/Win32/proj/material/material.vcxproj.filters @@ -1352,6 +1352,9 @@ nD\UWmaterials + + nD\UWmaterials + nD @@ -2576,6 +2579,9 @@ nD\UWmaterials + + nD\UWmaterials + nD diff --git a/Win64/proj/material/material.vcxproj b/Win64/proj/material/material.vcxproj index c7e5859782..c532b2d600 100644 --- a/Win64/proj/material/material.vcxproj +++ b/Win64/proj/material/material.vcxproj @@ -239,6 +239,7 @@ + @@ -719,6 +720,7 @@ + diff --git a/Win64/proj/material/material.vcxproj.filters b/Win64/proj/material/material.vcxproj.filters index 6098b76e46..dd87d7fbb4 100644 --- a/Win64/proj/material/material.vcxproj.filters +++ b/Win64/proj/material/material.vcxproj.filters @@ -1352,6 +1352,9 @@ nD\UWmaterials + + nD\UWmaterials + nD @@ -2735,6 +2738,9 @@ nD\UWmaterials + + nD\UWmaterials + nD From 2869ac9edd6171e0c679c2dc941ad53dab803a81 Mon Sep 17 00:00:00 2001 From: parduino Date: Mon, 27 Oct 2025 17:15:38 -0700 Subject: [PATCH 260/261] Adding the missing cpp and h file --- .../nD/UWmaterials/LinearElasticGGmax.cpp | 472 ++++++++++++++++++ .../nD/UWmaterials/LinearElasticGGmax.h | 95 ++++ 2 files changed, 567 insertions(+) create mode 100644 SRC/material/nD/UWmaterials/LinearElasticGGmax.cpp create mode 100644 SRC/material/nD/UWmaterials/LinearElasticGGmax.h diff --git a/SRC/material/nD/UWmaterials/LinearElasticGGmax.cpp b/SRC/material/nD/UWmaterials/LinearElasticGGmax.cpp new file mode 100644 index 0000000000..f66ea5388a --- /dev/null +++ b/SRC/material/nD/UWmaterials/LinearElasticGGmax.cpp @@ -0,0 +1,472 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** LinearElasticGGmax: linear elastic nD with G/Gmax degradation ** +** ****************************************************************** */ + +#include "LinearElasticGGmax.h" +#include +#include +#include +#include +#include +#include +#include + +Vector LinearElasticGGmax::sigma(6); +Matrix LinearElasticGGmax::D(6,6); + +/* ----------------------- OPS Factory Function ---------------------- */ +void* OPS_LinearElasticGGmaxMaterial() +{ + int numdata = OPS_GetNumRemainingInputArgs(); + if (numdata < 5) { + opserr << "nDMaterial LinearElasticGGmax tag G K|nu rho curveType \n"; + return 0; + } + + int tag; int num = 1; + if (OPS_GetIntInput(&num, &tag) < 0) { + opserr << "LinearElasticGGmax: invalid tag\n"; + return 0; + } + + double props[3]; num = 3; + if (OPS_GetDoubleInput(&num, props) < 0) { + opserr << "LinearElasticGGmax: need G, K|nu, rho\n"; + return 0; + } + double G = props[0]; + double K_or_nu = props[1]; + double rho = props[2]; + + int curveType; num = 1; + if (OPS_GetIntInput(&num, &curveType) < 0) { + opserr << "LinearElasticGGmax: invalid curveType\n"; + return 0; + } + + if (curveType == 0) { + int npts; num = 1; + if (OPS_GetIntInput(&num, &npts) < 0 || npts < 2) { + opserr << "LinearElasticGGmax: user curve needs numPoints >= 2\n"; + return 0; + } + std::vector strains(npts), gg(npts); + num = npts; + if (OPS_GetDoubleInput(&num, strains.data()) < 0) { + opserr << "LinearElasticGGmax: bad strain list\n"; + return 0; + } + num = npts; + if (OPS_GetDoubleInput(&num, gg.data()) < 0) { + opserr << "LinearElasticGGmax: bad G/Gmax list\n"; + return 0; + } + return new LinearElasticGGmax(tag, G, K_or_nu, rho, strains, gg); + } else { + double params[3] = {0.,0.,0.}; + int rem = OPS_GetNumRemainingInputArgs(); + if (rem > 0) { + if (rem > 3) rem = 3; + num = rem; + if (OPS_GetDoubleInput(&num, params) < 0) { + opserr << "LinearElasticGGmax: invalid curve params\n"; + return 0; + } + } + return new LinearElasticGGmax(tag, G, K_or_nu, rho, curveType, params[0], params[1], params[2]); + } +} + +/* --------------------------- Constructors -------------------------- */ +LinearElasticGGmax::LinearElasticGGmax(int tag, double G_in, double K_or_nu_in, double r, + int cType, double p1, double p2, double p3) +: NDMaterial(tag, ND_TAG_LinearElasticGGmax), + G0(G_in), K0(0.0), nu(0.0), hasK(false), rho0(r), + mu_c(0.0), lambda_c(0.0), + curveType(cType), param1(p1), param2(p2), param3(p3), + epsilon(6), Cepsilon(6), nDim(3) +{ + // detect whether second is nu or K + if (K_or_nu_in > -0.999 && K_or_nu_in < 0.5) { nu = K_or_nu_in; hasK = false; } + else { K0 = K_or_nu_in; hasK = true; } + + epsilon.Zero(); Cepsilon.Zero(); + sigma.Zero(); D.Zero(); +} + +LinearElasticGGmax::LinearElasticGGmax(int tag, double G_in, double K_or_nu_in, double r, + const std::vector& strains, + const std::vector& ggmax) +: NDMaterial(tag, ND_TAG_LinearElasticGGmax), + G0(G_in), K0(0.0), nu(0.0), hasK(false), rho0(r), + mu_c(0.0), lambda_c(0.0), + curveType(0), param1(0.0), param2(0.0), param3(0.0), + userStrains(strains), userGGmax(ggmax), + epsilon(6), Cepsilon(6), nDim(3) +{ + if (K_or_nu_in > -0.999 && K_or_nu_in < 0.5) { nu = K_or_nu_in; hasK = false; } + else { K0 = K_or_nu_in; hasK = true; } + + epsilon.Zero(); Cepsilon.Zero(); + sigma.Zero(); D.Zero(); +} + +LinearElasticGGmax::LinearElasticGGmax() +: NDMaterial(0, ND_TAG_LinearElasticGGmax), + G0(0.0), K0(0.0), nu(0.0), hasK(true), rho0(0.0), + mu_c(0.0), lambda_c(0.0), + curveType(1), param1(0.0), param2(0.0), param3(0.0), + epsilon(6), Cepsilon(6), nDim(3) +{ + epsilon.Zero(); Cepsilon.Zero(); + sigma.Zero(); D.Zero(); +} + +LinearElasticGGmax::~LinearElasticGGmax() {} + +/* ------------------------ NDMaterial methods ----------------------- */ + +int LinearElasticGGmax::setTrialStrain(const Vector &strn) +{ + if (epsilon.Size() != strn.Size()) { + // detect dimensionality (3 for 2D plane strain/plane stress vectors) + if (strn.Size() == 3) { nDim = 2; epsilon.resize(3); Cepsilon.resize(3); } + else { nDim = 3; epsilon.resize(6); Cepsilon.resize(6); } + } + epsilon = strn; + + // compute G/Gmax from equivalent shear strain (uses normals too) + const double gamma_eq = computeShearStrain(epsilon); + const double gg = computeGGmax(gamma_eq); + computeTangent(gg); // sets mu_c, lambda_c and updates D + + // FAST path: sigma = 2*mu*eps + lambda*tr(eps)*I in Voigt form + if (nDim == 3) { + const double exx = epsilon(0), eyy = epsilon(1), ezz = epsilon(2); + const double gxy = epsilon(3), gyz = epsilon(4), gxz = epsilon(5); + const double tr = exx + eyy + ezz; + + sigma(0) = lambda_c*tr + 2.0*mu_c*exx; + sigma(1) = lambda_c*tr + 2.0*mu_c*eyy; + sigma(2) = lambda_c*tr + 2.0*mu_c*ezz; + sigma(3) = mu_c * gxy; // engineering shear + sigma(4) = mu_c * gyz; + sigma(5) = mu_c * gxz; + } else { + // plane strain: epsilon = [exx, eyy, gxy], with ezz = 0.0 + const double exx = epsilon(0), eyy = epsilon(1), gxy = epsilon(2); + const double tr = exx + eyy; + + sigma(0) = lambda_c*tr + 2.0*mu_c*exx; + sigma(1) = lambda_c*tr + 2.0*mu_c*eyy; + sigma(2) = mu_c * gxy; // tau_xy + } + + return 0; +} + +int LinearElasticGGmax::setTrialStrain(const Vector &strain, const Vector &rate) +{ return setTrialStrain(strain); } + +int LinearElasticGGmax::setTrialStrainIncr(const Vector &strain) +{ + Vector trial = Cepsilon; + trial.addVector(1.0, strain, 1.0); + return setTrialStrain(trial); +} + +int LinearElasticGGmax::setTrialStrainIncr(const Vector &strain, const Vector &rate) +{ return setTrialStrainIncr(strain); } + +const Vector &LinearElasticGGmax::getStrain(void) { return epsilon; } +const Vector &LinearElasticGGmax::getStress(void) { return sigma; } +const Matrix &LinearElasticGGmax::getTangent(void) { return D; } +const Matrix &LinearElasticGGmax::getInitialTangent(void) +{ + // initial tangent: use ggmax=1 + computeTangent(1.0); + return D; +} + +int LinearElasticGGmax::commitState(void) +{ + Cepsilon = epsilon; + return 0; +} + +int LinearElasticGGmax::revertToLastCommit(void) +{ + // Restore trial strain to last committed state + epsilon = Cepsilon; + + // Recompute tangent and stress consistent with restored strain + const double gamma_eq = computeShearStrain(epsilon); + const double gg = computeGGmax(gamma_eq); + computeTangent(gg); + + if (nDim == 3) { + const double exx = epsilon(0), eyy = epsilon(1), ezz = epsilon(2); + const double gxy = epsilon(3), gyz = epsilon(4), gxz = epsilon(5); + const double tr = exx + eyy + ezz; + + sigma(0) = lambda_c*tr + 2.0*mu_c*exx; + sigma(1) = lambda_c*tr + 2.0*mu_c*eyy; + sigma(2) = lambda_c*tr + 2.0*mu_c*ezz; + sigma(3) = mu_c * gxy; + sigma(4) = mu_c * gyz; + sigma(5) = mu_c * gxz; + } else { + const double exx = epsilon(0), eyy = epsilon(1), gxy = epsilon(2); + const double tr = exx + eyy; + + sigma(0) = lambda_c*tr + 2.0*mu_c*exx; + sigma(1) = lambda_c*tr + 2.0*mu_c*eyy; + sigma(2) = mu_c * gxy; + } + + return 0; +} + +int LinearElasticGGmax::revertToStart(void) +{ + epsilon.Zero(); Cepsilon.Zero(); sigma.Zero(); + computeTangent(1.0); + return 0; +} + +NDMaterial* LinearElasticGGmax::getCopy(void) +{ + double second = hasK ? K0 : nu; + LinearElasticGGmax *theCopy; + if (curveType == 0) { + theCopy = new LinearElasticGGmax(this->getTag(), G0, second, rho0, userStrains, userGGmax); + } else { + theCopy = new LinearElasticGGmax(this->getTag(), G0, second, rho0, curveType, param1, param2, param3); + } + theCopy->hasK = hasK; + theCopy->epsilon = epsilon; + theCopy->Cepsilon = Cepsilon; + theCopy->nDim = nDim; + return theCopy; +} + +NDMaterial* LinearElasticGGmax::getCopy(const char *type) +{ + return getCopy(); +} + +const char *LinearElasticGGmax::getType(void) const +{ + return (nDim==2) ? "PlaneStrain" : "ThreeDimensional"; +} + +int LinearElasticGGmax::getOrder(void) const +{ + return (nDim==2) ? 3 : 6; +} + +/* ------------------------- Channel I/O ------------------------------ */ + +int LinearElasticGGmax::sendSelf(int commitTag, Channel &theChannel) +{ + static Vector data(12); + data(0) = this->getTag(); + data(1) = G0; + data(2) = hasK ? K0 : nu; + data(3) = rho0; + data(4) = curveType; + data(5) = param1; + data(6) = param2; + data(7) = param3; + data(8) = nDim; + data(9) = (double)userStrains.size(); + data(10)= hasK ? 1.0 : 0.0; + data(11)= 0.0; + + int res = theChannel.sendVector(this->getDbTag(), commitTag, data); + if (res < 0) return res; + + if (curveType == 0 && !userStrains.empty()) { + Vector s(userStrains.size()), g(userGGmax.size()); + for (size_t i=0;igetDbTag(), commitTag, s)) < 0) return res; + if ((res = theChannel.sendVector(this->getDbTag(), commitTag, g)) < 0) return res; + } + return 0; +} + +int LinearElasticGGmax::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +{ + static Vector data(12); + int res = theChannel.recvVector(this->getDbTag(), commitTag, data); + if (res < 0) return res; + + this->setTag((int)data(0)); + G0 = data(1); + double second = data(2); + rho0 = data(3); + curveType = (int)data(4); + param1 = data(5); param2 = data(6); param3 = data(7); + nDim = (int)data(8); + int nPts = (int)data(9); + hasK = (data(10) > 0.5); + + if (hasK) { K0 = second; nu = 0.0; } + else { nu = second; K0 = 0.0; } + + if (curveType == 0 && nPts > 0) { + Vector s(nPts), g(nPts); + if ((res = theChannel.recvVector(this->getDbTag(), commitTag, s)) < 0) return res; + if ((res = theChannel.recvVector(this->getDbTag(), commitTag, g)) < 0) return res; + userStrains.resize(nPts); userGGmax.resize(nPts); + for (int i=0;igetTag() << endln; + s << " G0: " << G0 << endln; + if (hasK) s << " K0: " << K0 << endln; + else s << " nu: " << nu << endln; + s << " rho: " << rho0 << endln; + s << " curveType: " << curveType << endln; +} + +/* ------------------------ Private helpers -------------------------- */ + +double LinearElasticGGmax::computeShearStrain(const Vector& strain) const +{ + double gamma = 0.0; + + if (nDim == 3) { + // Voigt: [eps11, eps22, eps33, g12, g23, g31] with engineering shear + double eps11 = strain(0); + double eps22 = strain(1); + double eps33 = strain(2); + double eps12 = strain(3) * 0.5; // eng -> tensorial + double eps23 = strain(4) * 0.5; + double eps31 = strain(5) * 0.5; + + double epsm = (eps11 + eps22 + eps33) / 3.0; + double e11 = eps11 - epsm; + double e22 = eps22 - epsm; + double e33 = eps33 - epsm; + + double J2 = 0.5 * (e11*e11 + e22*e22 + e33*e33) + + (eps12*eps12 + eps23*eps23 + eps31*eps31); + + gamma = std::sqrt(2.0 * J2); + } else { + // 2D (plane strain/stress vector: [eps11, eps22, g12]) + double eps11 = strain(0); + double eps22 = strain(1); + double eps12 = strain(2) * 0.5; // eng -> tensorial + + // For pure 2D we use mean over in-plane normals + double epsm = (eps11 + eps22) / 2.0; + double e11 = eps11 - epsm; + double e22 = eps22 - epsm; + + double J2 = 0.5 * (e11*e11 + e22*e22) + eps12*eps12; + gamma = std::sqrt(2.0 * J2); + } + + return std::fabs(gamma); +} + +double LinearElasticGGmax::computeGGmax(double gamma) +{ + gamma = std::abs(gamma); + if (curveType == 0) return interpolateUserCurve(gamma); + if (curveType == 1) return hardinDrnevich(gamma); + if (curveType == 2) return vuceticDobry(gamma); + if (curveType == 3) return darendeli(gamma); + return 1.0; +} + +void LinearElasticGGmax::computeTangent(double gg) +{ + // Degraded shear modulus + double mu = std::max(0.0, G0 * gg); + double lambda; + if (hasK) { + double K = K0; // keep bulk modulus constant + lambda = K - (2.0/3.0)*mu; + } else { + lambda = (2.0*mu*nu) / (1.0 - 2.0*nu); + } + + // Cache values for fast stress computation + mu_c = mu; + lambda_c = lambda; + + // Fill D for getTangent/getInitialTangent + if (nDim == 3) { + D.Zero(); + double mup2 = lambda + 2.0*mu; + D(0,0)=D(1,1)=D(2,2)=mup2; + D(0,1)=D(1,0)=lambda; + D(0,2)=D(2,0)=lambda; + D(1,2)=D(2,1)=lambda; + D(3,3)=mu; D(4,4)=mu; D(5,5)=mu; + } else { + // plane strain: 3x3 [exx, eyy, gxy] + D.Zero(); + double mup2 = lambda + 2.0*mu; + D(0,0)=D(1,1)=mup2; + D(0,1)=D(1,0)=lambda; + D(2,2)=mu; + } +} + +/* -------------------------- Curve models --------------------------- */ + +double LinearElasticGGmax::hardinDrnevich(double gamma) const +{ + // gamma_ref in param1 + double gref = (param1>0.0? param1 : 1e-4); + return 1.0 / (1.0 + gamma / gref); +} + +double LinearElasticGGmax::vuceticDobry(double gamma) const +{ + // Simplified: PI in param1 -> adjust reference strain + double PI = std::max(0.0, param1); + double gref = 1e-4 * std::pow(10.0, -0.014*PI); // crude trend + return 1.0 / (1.0 + gamma / gref); +} + +double LinearElasticGGmax::darendeli(double gamma) const +{ + // Very simplified surrogate based on param1=PI, param2=p', param3=OCR + double PI = std::max(0.0, param1); + double p = (param2>0.0? param2:100.0); + double OCR = (param3>0.0? param3:1.0); + double gref = 1e-4 * std::pow(p/100.0, 0.3) * std::pow(OCR, 0.1) * std::pow(10.0, -0.01*PI); + return 1.0 / (1.0 + gamma / gref); +} + +double LinearElasticGGmax::interpolateUserCurve(double gamma) const +{ + if (userStrains.empty() || userGGmax.empty()) return 1.0; + // assume userStrains strictly increasing (positive gammas) + size_t n = userStrains.size(); + if (gamma <= userStrains.front()) return userGGmax.front(); + if (gamma >= userStrains.back()) return userGGmax.back(); + + // log-log linear interpolation + double lg = std::log10(gamma); + size_t i=1; + while (i userStrains[i]) ++i; + // interpolate between i-1 and i + double x1=std::log10(userStrains[i-1]), x2=std::log10(userStrains[i]); + double y1=std::log10(std::max(1e-12, userGGmax[i-1])), y2=std::log10(std::max(1e-12, userGGmax[i])); + double y = y1 + (y2-y1)*( (lg-x1)/(x2-x1) ); + return std::pow(10.0, y); +} diff --git a/SRC/material/nD/UWmaterials/LinearElasticGGmax.h b/SRC/material/nD/UWmaterials/LinearElasticGGmax.h new file mode 100644 index 0000000000..22c18b0dbc --- /dev/null +++ b/SRC/material/nD/UWmaterials/LinearElasticGGmax.h @@ -0,0 +1,95 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** LinearElasticGGmax: linear elastic nD material with G/Gmax curves ** +** Accepts (G,K) or (G,nu) and degrades only G by G/Gmax(gamma) ** +** ** +** ****************************************************************** */ +#ifndef LinearElasticGGmax_h +#define LinearElasticGGmax_h + +#include +#include +#include +#include + +class LinearElasticGGmax : public NDMaterial +{ +public: + // Factory hook (no friend declaration needed) + + // Predefined curves: curveType in {1=Hardin-Drnevich, 2=Vucetic-Dobry, 3=Darendeli} + LinearElasticGGmax(int tag, double G_in, double K_or_nu, double rho, + int curveType, double p1 = 0.0, double p2 = 0.0, double p3 = 0.0); + + // User curve (curveType==0) + LinearElasticGGmax(int tag, double G_in, double K_or_nu, double rho, + const std::vector& strains, const std::vector& ggmax); + + LinearElasticGGmax(); + ~LinearElasticGGmax(); + + const char *getClassType(void) const override { return "LinearElasticGGmax"; }; + + // Mandatory NDMaterial interface + int setTrialStrain(const Vector &strain) override; + int setTrialStrain(const Vector &strain, const Vector &rate) override; + int setTrialStrainIncr(const Vector &strain) override; + int setTrialStrainIncr(const Vector &strain, const Vector &rate) override; + + const Vector &getStrain(void) override; + const Vector &getStress(void) override; + const Matrix &getTangent(void) override; + const Matrix &getInitialTangent(void) override; + + int commitState(void) override; + int revertToLastCommit(void) override; + int revertToStart(void) override; + NDMaterial *getCopy(void) override; + NDMaterial *getCopy(const char *type) override; + + const char *getType(void) const override; + int getOrder(void) const override; + + int sendSelf(int commitTag, Channel &theChannel) override; + int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) override; + + void Print(OPS_Stream &s, int flag = 0) override; + +private: + // Material properties + double G0; // initial shear modulus + double K0; // bulk modulus (valid if hasK==true) + double nu; // Poisson's ratio (valid if hasK==false) + bool hasK; // true if user gave K; false if user gave nu + double rho0; // density (not used in constitutive law here) + double mu_c; // cached shear modulus for current trial state + double lambda_c; // cached first Lamé parameter for current trial state + + // G/Gmax curve definition + int curveType; // 0=user, 1=Hardin-Drnevich, 2=Vucetic-Dobry, 3=Darendeli + double param1, param2, param3; // model params (gamma_ref, PI, p', OCR, etc.) + std::vector userStrains; // engineering gamma values (>0) + std::vector userGGmax; // ratio values in [0,1] + + // State + Vector epsilon; // trial strain (6 for 3D Voigt, 3 for 2D) + Vector Cepsilon; // committed strain + static Vector sigma; // trial stress (resized by ctor) + static Matrix D; // tangent (resized by ctor) + int nDim; // 2 or 3 + + // Helpers + double computeGGmax(double gamma); + double computeShearStrain(const Vector& strain) const; // octahedral-equivalent + void computeTangent(double gg_ratio); + + // Curve models + double hardinDrnevich(double gamma) const; + double vuceticDobry(double gamma) const; + double darendeli(double gamma) const; + double interpolateUserCurve(double gamma) const; +}; + +#endif // LINEAR_ELASTIC_GGMAX_H From de54d7a06f2032b2c854ce6106bc17fb05a296bf Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Fri, 7 Nov 2025 12:52:10 -0800 Subject: [PATCH 261/261] Update OpenSeesCommands.cpp --- SRC/interpreter/OpenSeesCommands.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/SRC/interpreter/OpenSeesCommands.cpp b/SRC/interpreter/OpenSeesCommands.cpp index cff665352d..10eb2754b2 100644 --- a/SRC/interpreter/OpenSeesCommands.cpp +++ b/SRC/interpreter/OpenSeesCommands.cpp @@ -325,9 +325,13 @@ OpenSeesCommands::eigen(int typeSolver, double shift, } else if (typeSolver == EigenSOE_TAGS_SymmGeneralizedEigenSOE) { - SymmGeneralizedEigenSolver *theEigenSolver = new SymmGeneralizedEigenSolver(); +#ifdef _WIN32 + opserr << "SymmGeneralizedEigenSolver not currently compiled for Windows" << endln; +#else + SymmGeneralizedEigenSolver *theEigenSolver = new SymmGeneralizedEigenSolver(); theEigenSOE = new SymmGeneralizedEigenSOE(*theEigenSolver, *theAnalysisModel); - +#endif + } else { theEigenSOE = new ArpackSOE(shift);