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;
742 tmpstr =
getName()+
"_ip_Node"+Teuchos::Utils::toString(i+1);
749 tmpstr =
getName()+
"_ROM_Node"+Teuchos::Utils::toString(i+1);
831 for (
int j=0, Cidx=0; j<nnz && Cidx<Cnnz; j++)
852 for (
int j=0, Gidx=0; j<nnz && Gidx<Gnnz; j++)
874 #ifdef Xyce_DEBUG_DEVICE
877 Xyce::dout() << Xyce::section_divider << std::endl;
878 Xyce::dout() <<
"Instance::registerJacLIDs\n";
881 Xyce::dout() <<
" AEqu_up_NodeOffset: ";
884 Xyce::dout() << std::endl;
885 Xyce::dout() <<
" AEqu_ip_NodeOffset: ";
888 Xyce::dout() << std::endl;
889 Xyce::dout() <<
" AROMEqu_Lt_NodeOffset: ";
892 Xyce::dout() << std::endl;
893 Xyce::dout() <<
" AROMEqu_B_NodeOffset: " << std::endl;
898 Xyce::dout() << std::endl;
900 Xyce::dout() <<
" AROMEqu_GpC_NodeOffset: ";
903 Xyce::dout() << std::endl;
905 Xyce::dout() << Xyce::section_divider << std::endl;
922 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1018 i_ip[i] = solVec[intLIDVec[i]];
1020 double * xhat = &solVec[
li_ROM[0]];
1022 Teuchos::BLAS<int, double> blas;
1025 blas.GEMV( Teuchos::TRANS,
numROMVars, numExtVars, -1.0, &
Lhat[0],
numROMVars, xhat, 1, 1.0, &
Fhat[0], 1 );
1031 blas.GEMV( Teuchos::NO_TRANS,
numROMVars,
numROMVars, 1.0, &
Ghat[0],
numROMVars, xhat, 1, 0.0, &
Fhat[numExtVars], 1 );
1032 blas.GEMV( Teuchos::NO_TRANS,
numROMVars, numExtVars, -1.0, &
Bhat[0],
numROMVars, &v_up[0], 1, 1.0, &
Fhat[numExtVars], 1 );
1038 blas.GEMV( Teuchos::NO_TRANS,
numROMVars,
numROMVars, 1.0, &
Chat[0],
numROMVars, xhat, 1, 0.0, &
Qhat[0], 1 );
1040 #ifdef Xyce_DEBUG_DEVICE
1043 Xyce::dout() <<
" ----------------------------------" << std::endl;
1044 Xyce::dout() <<
"Instance::updatePrimaryState:" << std::endl;
1072 (*maskVectorPtr)[
li_ROM[i]] = 0.0;
1293 std::vector<Instance*>::iterator iter;
1297 for (iter=first; iter!=last; ++iter)
1299 (*iter)->processParams();
1318 :
DeviceModel(MB, configuration.getModelParameters(), factory_block)
1345 std::vector<Instance*>::iterator iter;
1349 for (iter=first; iter!=last; ++iter)
1367 std::vector<Instance*>::const_iterator iter;
1375 os <<
"Number of ROM instances: " << isize << std::endl;
1376 os <<
" name\t\tmodelName\tParameters" << std::endl;
1378 for (i = 0, iter = first; iter != last; ++iter, ++i)
1380 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
1406 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1423 #ifdef Xyce_DEBUG_DEVICE
1426 Xyce::dout() <<
" ----------------------------------" << std::endl;
1427 Xyce::dout() <<
" Master::updateState: " << std::endl;
1432 #pragma omp parallel for
1438 Teuchos::BLAS<int, double> blas;
1441 const char test =
'N';
1469 Xyce::dout() <<
"Bad 'USE_PORT_DESCRIPTION' flag" << std::endl;
1482 std::vector<double> lastStaVec, currStaVec, nextStaVec;
1483 lastStaVec.resize(M+N,0);
1484 currStaVec.resize(M+N,0);
1485 nextStaVec.resize(M+N,0);
1488 std::vector<double> lastPortVec, currPortVec, nextPortVec;
1489 lastPortVec.resize(N,0);
1490 currPortVec.resize(N,0);
1491 nextPortVec.resize(N,0);
1492 for(
int ix=0; ix<N; ++ix)
1496 nextPortVec[ix] = solVec[ci.
extLIDVec[ix]];
1506 Teuchos::LAPACK<int,double> lapack;
1507 std::vector<int> ipiv_A2last (M+N, 0);
1508 int info_A2, info_A2last, info2_A2, info2_A2last;
1515 int updateCurrStaVec=0;
1517 if (sameTimeStep==0) {updateCurrStaVec=1; }
1518 if (updateCurrStaVec==1) {
1519 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 );
1520 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 );
1521 blas.GEMV( Teuchos::NO_TRANS,N+M,N,-ci.
coefLast,&ci.
G2p[0],N+M,&currPortVec[0],1, 1.0,&currStaVec[0],1 );
1522 blas.GEMV( Teuchos::NO_TRANS,N+M,N,-(1-ci.
coefLast),&ci.
G2p[0],N+M,&lastPortVec[0],1,1.0,&currStaVec[0],1 );
1527 lapack.GETRS(test, M+N, 1, &ci.
A2[0], M+N, &ci.
ipiv_A2[0], &currStaVec[0], M+N, &info2_A2);
1530 lapack.GETRF( M+N, M+N, &ci.
A2last[0], M+N, &ipiv_A2last[0], &info_A2last);
1531 lapack.GETRS(test, M+N, 1, &ci.
A2last[0], M+N, &ipiv_A2last[0], &currStaVec[0], M+N, &info2_A2last);
1550 for(
int ix=0; ix<(M+N)*(M+N); ix++) { ci.
A2[ix]= (ci.
alph*ci.
C2[ix]) + (ci.
coef*ci.
G2[ix]); }
1551 lapack.GETRF( M+N, M+N, &ci.
A2[0], M+N, &ci.
ipiv_A2[0], &info_A2);
1552 for(
int ix=0; ix<(M+N)*N; ix++) { ci.
A2sol[ix] = ci.
coef * ci.
G2p[ix]; }
1553 lapack.GETRS(test, M+N, N, &ci.
A2[0], M+N, &ci.
ipiv_A2[0], &ci.
A2sol[0], M+N, &info2_A2);
1554 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);
1562 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 );
1563 blas.GEMV( Teuchos::NO_TRANS,N+M,N+M,ci.
alph,&ci.
C2[0],M+N,&currStaVec[0],1,1.0,&nextStaVec[0],1 );
1564 blas.GEMV( Teuchos::NO_TRANS,N+M,N,-ci.
coef,&ci.
G2p[0],N+M,&nextPortVec[0],1, 1.0,&nextStaVec[0],1 );
1565 blas.GEMV( Teuchos::NO_TRANS,N+M,N,-(1-ci.
coef),&ci.
G2p[0],N+M,&currPortVec[0],1,1.0,&nextStaVec[0],1 );
1566 lapack.GETRS(test, M+N, 1, &ci.
A2[0], M+N, &ci.
ipiv_A2[0], &nextStaVec[0], M+N, &info2_A2);
1575 blas.GEMV( Teuchos::NO_TRANS,N,N+M,1.0,&ci.
Gp2[0],N,&nextStaVec[0],1,0.0,&ci.
Fstamp[0],1 );
1587 std::vector<double> v_up(N);
1588 for (
int i=0; i<N; ++i)
1594 double * xhat = &solVec[ci.
li_ROM[0]];
1597 blas.GEMV( Teuchos::TRANS, ci.
numROMVars, ci.
numExtVars, -1.0, &ci.
Lhat[0], ci.
numROMVars, xhat, 1, 1.0, &ci.
Fhat[0], 1 );
1607 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 );
1608 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 );
1618 blas.GEMV( Teuchos::NO_TRANS, ci.
numROMVars, ci.
numROMVars, 1.0, &ci.
Chat[0], ci.
numROMVars, xhat, 1, 0.0, &ci.
Qhat[0], 1 );
1641 Xyce::dout() << std::endl << vname <<
": " << std::endl;
1642 for(
int ix=0; ix < Nrows; ix++)
1644 for(
int iy=0; iy < Ncols; iy++)
1646 Xyce::dout() << Matrix[iy*Nrows+ix] <<
" ";
1648 Xyce::dout() << std::endl;
1662 #ifdef Xyce_DEBUG_DEVICE
1665 Xyce::dout() <<
" ----------------------------------" << std::endl;
1666 Xyce::dout() <<
" Master::loadDAEVectors: " << std::endl;
1684 #pragma omp parallel for
1719 #ifdef Xyce_DEBUG_DEVICE
1722 Xyce::dout() <<
" ----------------------------------" << std::endl;
1723 Xyce::dout() <<
" Master::loadDAEMatrices: " << std::endl;
1734 #ifdef Xyce_DEBUG_DEVICE
1737 Xyce::dout() <<
" loads for ROM " << ci.
getName() << std::endl;
1741 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1753 #pragma omp parallel for
1759 #pragma omp parallel for
1770 #pragma omp parallel for
1775 #pragma omp parallel for
1788 #pragma omp parallel for
1791 for (
int i=0; i<nnz; ++i)
1797 #pragma omp parallel for
1803 #pragma omp parallel for
1818 #pragma omp parallel for
1821 for(
int i=0; i<nnz; i++)
1827 #pragma omp parallel for
1833 #pragma omp parallel for
1846 #pragma omp parallel for
1857 #pragma omp parallel for
1863 #pragma omp parallel for
1874 #pragma omp parallel for
1879 #pragma omp parallel for
1900 #pragma omp parallel for
1905 #pragma omp parallel for
1927 #pragma omp parallel for
1932 #pragma omp parallel for
1966 .registerDevice(
"rom", 1)
1967 .registerModelType(
"rom", 1);