46 #include <Xyce_config.h>
50 #include <N_UTL_Misc.h>
64 #include <N_ERH_ErrorMgr.h>
66 #include <N_LAS_Vector.h>
67 #include <N_LAS_Matrix.h>
68 #include <N_LAS_Util.h>
70 #include <N_UTL_Expression.h>
71 #include <N_IO_mmio.h>
73 #include <Teuchos_BLAS.hpp>
74 #include <Teuchos_Utils.hpp>
75 #include <Teuchos_LAPACK.hpp>
81 #undef HAVE_INTTYPES_H
84 #include <Trilinos_Util.h>
144 :
DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
159 lastTimeStepNumber(0)
171 if (
given(
"BASE_FILENAME"))
173 FILE *c_file, *g_file, *b_file, *l_file;
174 Xyce::IO::MMIO::MM_typecode mat_code;
180 c_file = fopen(cfile.c_str(),
"r");
181 g_file = fopen(gfile.c_str(),
"r");
182 b_file = fopen(bfile.c_str(),
"r");
183 l_file = fopen(lfile.c_str(),
"r");
184 if (c_file == NULL || g_file == NULL || b_file == NULL || l_file == NULL)
186 UserFatal0(*
this) <<
"Cannot open one of the ROM files: " << cfile <<
"," << gfile <<
"," << bfile <<
"," << lfile;
190 Xyce::IO::MMIO::mm_read_banner( b_file, &mat_code );
191 Xyce::IO::MMIO::mm_read_mtx_array_size( b_file, &M, &N );
217 Xyce::IO::MMIO::mm_read_banner( l_file, &mat_code );
218 Xyce::IO::MMIO::mm_read_mtx_array_size( l_file, &tmpM, &tmpN );
221 for (
int i=0; i<M*N; i++)
223 fscanf(b_file,
"%lg\n", &
Bhat[i]);
224 fscanf(l_file,
"%lg\n", &
Lhat[i]);
229 Xyce::IO::MMIO::mm_read_banner( c_file, &mat_code );
236 Xyce::IO::MMIO::mm_read_mtx_array_size( c_file, &tmpM, &tmpN );
240 if (mm_is_general(mat_code))
243 for (
int i=0; i<M*M; i++)
245 fscanf(c_file,
"%lg\n", &
Chat[i]);
248 else if (mm_is_symmetric(mat_code) || mm_is_skew(mat_code))
250 int arraySize = M*(M+1)/2;
251 std::vector<double> Chat_tmp( arraySize );
253 for (
int i=0; i<arraySize; i++)
255 fscanf(c_file,
"%lg\n", &Chat_tmp[i]);
258 for (
int j=0; j<M; j++)
260 for (
int i=j; i<M; i++)
262 double val = Chat_tmp[j*M - j*(j-1)/2 + i - j];
266 if (mm_is_symmetric(mat_code))
276 UserFatal0(*
this) <<
"Do not recognize the Matrix Market format for Chat (matrix is not general or symmetric)";
282 Xyce::IO::MMIO::mm_read_mtx_crd_size( c_file, &tmpM, &tmpN, &nnz );
285 UserFatal0(*
this) <<
"Chat has zero entries according to the Matrix Market file " << cfile;
289 std::vector<double> Chat_tmp( nnz );
290 std::vector<int> rowIdx( nnz ), colIdx( nnz );
293 Xyce::IO::MMIO::mm_read_mtx_crd_data( c_file, tmpM, tmpN, nnz, &rowIdx[0], &colIdx[0], &Chat_tmp[0], mat_code );
296 for (
int i=0; i<nnz; ++i)
302 if (mm_is_symmetric(mat_code) || mm_is_skew(mat_code))
304 if (rowIdx[i]!=colIdx[i])
306 if (mm_is_symmetric(mat_code))
308 rowIdx.push_back(colIdx[i]);
309 colIdx.push_back(rowIdx[i]);
310 Chat_tmp.push_back(Chat_tmp[i]);
314 rowIdx.push_back(colIdx[i]);
315 colIdx.push_back(rowIdx[i]);
316 Chat_tmp.push_back(-Chat_tmp[i]);
323 int nnz2 = rowIdx.size();
337 Xyce::IO::MMIO::mm_read_banner( g_file, &mat_code );
344 Xyce::IO::MMIO::mm_read_mtx_array_size( g_file, &tmpM, &tmpN );
348 if (mm_is_general(mat_code))
351 for (
int i=0; i<M*M; i++)
353 fscanf(g_file,
"%lg\n", &
Ghat[i]);
356 else if (mm_is_symmetric(mat_code) || mm_is_skew(mat_code))
358 int arraySize = M*(M+1)/2;
359 std::vector<double> Ghat_tmp( arraySize );
361 for (
int i=0; i<arraySize; i++)
363 fscanf(g_file,
"%lg\n", &Ghat_tmp[i]);
366 for (
int j=0; j<M; j++)
368 for (
int i=j; i<M; i++)
370 double val = Ghat_tmp[j*M - j*(j-1)/2 + i - j];
374 if (mm_is_symmetric(mat_code))
384 UserFatal0(*
this) <<
"Do not recognize the Matrix Market format for Ghat (matrix is not general or symmetric)";
390 Xyce::IO::MMIO::mm_read_mtx_crd_size( g_file, &tmpM, &tmpN, &nnz );
393 UserFatal0(*
this) <<
"Ghat has zero entries according to the Matrix Market file " << gfile;
397 std::vector<double> Ghat_tmp( nnz );
398 std::vector<int> rowIdx( nnz ), colIdx( nnz );
401 Xyce::IO::MMIO::mm_read_mtx_crd_data( g_file, tmpM, tmpN, nnz, &rowIdx[0], &colIdx[0], &Ghat_tmp[0], mat_code );
404 for (
int i=0; i<nnz; ++i)
410 if (mm_is_symmetric(mat_code) || mm_is_skew(mat_code))
412 if (rowIdx[i]!=colIdx[i])
414 if (mm_is_symmetric(mat_code))
416 rowIdx.push_back(colIdx[i]);
417 colIdx.push_back(rowIdx[i]);
418 Ghat_tmp.push_back(Ghat_tmp[i]);
422 rowIdx.push_back(colIdx[i]);
423 colIdx.push_back(rowIdx[i]);
424 Ghat_tmp.push_back(-Ghat_tmp[i]);
431 int nnz2 = rowIdx.size();
449 std::vector<int>::iterator it;
450 std::vector<int>::iterator itCG =
CG_colIdx.begin();
451 std::vector<int>::iterator itChat =
Chat_colIdx.begin();
452 std::vector<int>::iterator itGhat =
Ghat_colIdx.begin();
454 for (
int i=0; i<M; ++i)
460 it = set_union( itChat, itChat + numEntriesChat, itGhat, itGhat + numEntriesGhat, itCG );
466 itChat += numEntriesChat;
467 itGhat += numEntriesGhat;
480 G2.resize((M+N)*(M+N));
481 C2.resize((M+N)*(M+N));
482 A2.resize((M+N)*(M+N));
483 A2last.resize((M+N)*(M+N));
486 A2sol.resize((M+N)*N);
502 for(
int iy=0; iy<M; iy++)
504 for(
int ix=0; ix<M; ix++)
505 G2[((N+M+1)*N)+ix+(M+N)*iy] =
Ghat[ix+iy*M];
510 for (
int ix=0; ix<M; ix++)
517 for(
int ix=0; ix<N; ix++)
519 for(
int ix=0; ix<M; ix++)
521 for(
int iy=0; iy<N; iy++)
522 G2[((M+N)*N)+iy+(M+N)*ix] = -
Lhat[ix+iy*M];
527 for(
int iy=0; iy<M; iy++)
529 for(
int ix=0; ix<M; ix++)
530 C2[((N+M+1)*N)+ix+(M+N)*iy] =
Chat[ix+iy*M];
535 for (
int ix=0; ix<M; ix++)
543 for(
int iy=0; iy<N; iy++)
545 for(
int ix=0; ix<M; ix++)
546 G2p[N+ix+(M+N)*iy] = -
Bhat[ix+iy*M];
550 for(
int iy=0; iy<N; iy++)
613 for (
int j=numExtVars; j<numEntries; j++)
618 for (
int j=numExtVars; j<numEntries; j++)
658 const std::vector<int> & extLIDVecRef)
678 #ifdef Xyce_DEBUG_DEVICE
681 Xyce::dout() << section_divider << std::endl;
683 Xyce::dout() <<
"::registerLIDs:\n";
684 Xyce::dout() <<
" name = " <<
getName() << std::endl;
686 Xyce::dout() <<
"\nsolution indices:\n";
688 Xyce::dout() <<
" li_up[" << i <<
"] = " <<
extLIDVec[i] << std::endl;
692 Xyce::dout() <<
" li_ip[" << i <<
"] = " << intLIDVec[i] << std::endl;
695 Xyce::dout() <<
" li_ROM[" << i <<
"] = " <<
li_ROM[i] << std::endl;
697 Xyce::dout() << section_divider << std::endl;
826 for (
int j=0, Cidx=0; j<nnz && Cidx<Cnnz; j++)
847 for (
int j=0, Gidx=0; j<nnz && Gidx<Gnnz; j++)
869 #ifdef Xyce_DEBUG_DEVICE
872 Xyce::dout() << Xyce::section_divider << std::endl;
873 Xyce::dout() <<
"Instance::registerJacLIDs\n";
876 Xyce::dout() <<
" AEqu_up_NodeOffset: ";
879 Xyce::dout() << std::endl;
880 Xyce::dout() <<
" AEqu_ip_NodeOffset: ";
883 Xyce::dout() << std::endl;
884 Xyce::dout() <<
" AROMEqu_Lt_NodeOffset: ";
887 Xyce::dout() << std::endl;
888 Xyce::dout() <<
" AROMEqu_B_NodeOffset: " << std::endl;
893 Xyce::dout() << std::endl;
895 Xyce::dout() <<
" AROMEqu_GpC_NodeOffset: ";
898 Xyce::dout() << std::endl;
900 Xyce::dout() << Xyce::section_divider << std::endl;
917 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1013 i_ip[i] = solVec[intLIDVec[i]];
1015 double * xhat = &solVec[
li_ROM[0]];
1017 Teuchos::BLAS<int, double> blas;
1020 blas.GEMV( Teuchos::TRANS,
numROMVars, numExtVars, -1.0, &
Lhat[0],
numROMVars, xhat, 1, 1.0, &
Fhat[0], 1 );
1026 blas.GEMV( Teuchos::NO_TRANS,
numROMVars,
numROMVars, 1.0, &
Ghat[0],
numROMVars, xhat, 1, 0.0, &
Fhat[numExtVars], 1 );
1027 blas.GEMV( Teuchos::NO_TRANS,
numROMVars, numExtVars, -1.0, &
Bhat[0],
numROMVars, &v_up[0], 1, 1.0, &
Fhat[numExtVars], 1 );
1033 blas.GEMV( Teuchos::NO_TRANS,
numROMVars,
numROMVars, 1.0, &
Chat[0],
numROMVars, xhat, 1, 0.0, &
Qhat[0], 1 );
1035 #ifdef Xyce_DEBUG_DEVICE
1038 Xyce::dout() <<
" ----------------------------------" << std::endl;
1039 Xyce::dout() <<
"Instance::updatePrimaryState:" << std::endl;
1067 (*maskVectorPtr)[
li_ROM[i]] = 0.0;
1288 std::vector<Instance*>::iterator iter;
1292 for (iter=first; iter!=last; ++iter)
1294 (*iter)->processParams();
1313 :
DeviceModel(MB, configuration.getModelParameters(), factory_block)
1340 std::vector<Instance*>::iterator iter;
1344 for (iter=first; iter!=last; ++iter)
1362 std::vector<Instance*>::const_iterator iter;
1370 os <<
"Number of ROM instances: " << isize << std::endl;
1371 os <<
" name\t\tmodelName\tParameters" << std::endl;
1373 for (i = 0, iter = first; iter != last; ++iter, ++i)
1375 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
1401 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1418 #ifdef Xyce_DEBUG_DEVICE
1421 Xyce::dout() <<
" ----------------------------------" << std::endl;
1422 Xyce::dout() <<
" Master::updateState: " << std::endl;
1427 #pragma omp parallel for
1433 Teuchos::BLAS<int, double> blas;
1436 const char test =
'N';
1464 Xyce::dout() <<
"Bad 'USE_PORT_DESCRIPTION' flag" << std::endl;
1477 std::vector<double> lastStaVec, currStaVec, nextStaVec;
1478 lastStaVec.resize(M+N,0);
1479 currStaVec.resize(M+N,0);
1480 nextStaVec.resize(M+N,0);
1483 std::vector<double> lastPortVec, currPortVec, nextPortVec;
1484 lastPortVec.resize(N,0);
1485 currPortVec.resize(N,0);
1486 nextPortVec.resize(N,0);
1487 for(
int ix=0; ix<N; ++ix)
1491 nextPortVec[ix] = solVec[ci.
extLIDVec[ix]];
1501 Teuchos::LAPACK<int,double> lapack;
1502 std::vector<int> ipiv_A2last (M+N, 0);
1503 int info_A2, info_A2last, info2_A2, info2_A2last;
1510 int updateCurrStaVec=0;
1512 if (sameTimeStep==0) {updateCurrStaVec=1; }
1513 if (updateCurrStaVec==1) {
1514 blas.GEMV( Teuchos::NO_TRANS,N+M,N+M,-(1-ci.
coefLast),&ci.
G2[0],M+N,&lastStaVec[0],1,0.0,&currStaVec[0],1 );
1515 blas.GEMV( Teuchos::NO_TRANS,N+M,N+M,ci.
alph_last,&ci.
C2[0],M+N,&lastStaVec[0],1,1.0,&currStaVec[0],1 );
1516 blas.GEMV( Teuchos::NO_TRANS,N+M,N,-ci.
coefLast,&ci.
G2p[0],N+M,&currPortVec[0],1, 1.0,&currStaVec[0],1 );
1517 blas.GEMV( Teuchos::NO_TRANS,N+M,N,-(1-ci.
coefLast),&ci.
G2p[0],N+M,&lastPortVec[0],1,1.0,&currStaVec[0],1 );
1522 lapack.GETRS(test, M+N, 1, &ci.
A2[0], M+N, &ci.
ipiv_A2[0], &currStaVec[0], M+N, &info2_A2);
1525 lapack.GETRF( M+N, M+N, &ci.
A2last[0], M+N, &ipiv_A2last[0], &info_A2last);
1526 lapack.GETRS(test, M+N, 1, &ci.
A2last[0], M+N, &ipiv_A2last[0], &currStaVec[0], M+N, &info2_A2last);
1545 for(
int ix=0; ix<(M+N)*(M+N); ix++) { ci.
A2[ix]= (ci.
alph*ci.
C2[ix]) + (ci.
coef*ci.
G2[ix]); }
1546 lapack.GETRF( M+N, M+N, &ci.
A2[0], M+N, &ci.
ipiv_A2[0], &info_A2);
1547 for(
int ix=0; ix<(M+N)*N; ix++) { ci.
A2sol[ix] = ci.
coef * ci.
G2p[ix]; }
1548 lapack.GETRS(test, M+N, N, &ci.
A2[0], M+N, &ci.
ipiv_A2[0], &ci.
A2sol[0], M+N, &info2_A2);
1549 blas.GEMM(Teuchos::NO_TRANS, Teuchos::NO_TRANS, N, N, M+N, -1.0,&ci.
Gp2[0],N,&ci.
A2sol[0],M+N,0.0,&ci.
Jstamp[0], N);
1557 blas.GEMV( Teuchos::NO_TRANS,N+M,N+M,-(1-ci.
coef),&ci.
G2[0],M+N,&currStaVec[0],1,0.0,&nextStaVec[0],1 );
1558 blas.GEMV( Teuchos::NO_TRANS,N+M,N+M,ci.
alph,&ci.
C2[0],M+N,&currStaVec[0],1,1.0,&nextStaVec[0],1 );
1559 blas.GEMV( Teuchos::NO_TRANS,N+M,N,-ci.
coef,&ci.
G2p[0],N+M,&nextPortVec[0],1, 1.0,&nextStaVec[0],1 );
1560 blas.GEMV( Teuchos::NO_TRANS,N+M,N,-(1-ci.
coef),&ci.
G2p[0],N+M,&currPortVec[0],1,1.0,&nextStaVec[0],1 );
1561 lapack.GETRS(test, M+N, 1, &ci.
A2[0], M+N, &ci.
ipiv_A2[0], &nextStaVec[0], M+N, &info2_A2);
1570 blas.GEMV( Teuchos::NO_TRANS,N,N+M,1.0,&ci.
Gp2[0],N,&nextStaVec[0],1,0.0,&ci.
Fstamp[0],1 );
1582 std::vector<double> v_up(N);
1583 for (
int i=0; i<N; ++i)
1589 double * xhat = &solVec[ci.
li_ROM[0]];
1592 blas.GEMV( Teuchos::TRANS, ci.
numROMVars, ci.
numExtVars, -1.0, &ci.
Lhat[0], ci.
numROMVars, xhat, 1, 1.0, &ci.
Fhat[0], 1 );
1602 blas.GEMV( Teuchos::NO_TRANS, ci.
numROMVars, ci.
numROMVars, 1.0, &ci.
Ghat[0], ci.
numROMVars, xhat, 1, 0.0, &ci.
Fhat[ci.
numExtVars], 1 );
1603 blas.GEMV( Teuchos::NO_TRANS, ci.
numROMVars, ci.
numExtVars, -1.0, &ci.
Bhat[0], ci.
numROMVars, &v_up[0], 1, 1.0, &ci.
Fhat[ci.
numExtVars], 1 );
1613 blas.GEMV( Teuchos::NO_TRANS, ci.
numROMVars, ci.
numROMVars, 1.0, &ci.
Chat[0], ci.
numROMVars, xhat, 1, 0.0, &ci.
Qhat[0], 1 );
1636 Xyce::dout() << std::endl << vname <<
": " << std::endl;
1637 for(
int ix=0; ix < Nrows; ix++)
1639 for(
int iy=0; iy < Ncols; iy++)
1641 Xyce::dout() << Matrix[iy*Nrows+ix] <<
" ";
1643 Xyce::dout() << std::endl;
1655 bool Master::loadDAEVectors (
double * solVec,
double * fVec,
double *qVec,
double * bVec,
double * storeLeadF,
double * storeLeadQ)
1657 #ifdef Xyce_DEBUG_DEVICE
1660 Xyce::dout() <<
" ----------------------------------" << std::endl;
1661 Xyce::dout() <<
" Master::loadDAEVectors: " << std::endl;
1679 #pragma omp parallel for
1714 #ifdef Xyce_DEBUG_DEVICE
1717 Xyce::dout() <<
" ----------------------------------" << std::endl;
1718 Xyce::dout() <<
" Master::loadDAEMatrices: " << std::endl;
1729 #ifdef Xyce_DEBUG_DEVICE
1732 Xyce::dout() <<
" loads for ROM " << ci.
getName() << std::endl;
1736 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1748 #pragma omp parallel for
1754 #pragma omp parallel for
1765 #pragma omp parallel for
1770 #pragma omp parallel for
1783 #pragma omp parallel for
1786 for (
int i=0; i<nnz; ++i)
1792 #pragma omp parallel for
1798 #pragma omp parallel for
1813 #pragma omp parallel for
1816 for(
int i=0; i<nnz; i++)
1822 #pragma omp parallel for
1828 #pragma omp parallel for
1841 #pragma omp parallel for
1852 #pragma omp parallel for
1858 #pragma omp parallel for
1869 #pragma omp parallel for
1874 #pragma omp parallel for
1895 #pragma omp parallel for
1900 #pragma omp parallel for
1922 #pragma omp parallel for
1927 #pragma omp parallel for
1961 .registerDevice(
"rom", 1)
1962 .registerModelType(
"rom", 1);