160 RCP<const Import> Importer = A->getCrsGraph()->getImporter();
161 Xpetra::UnderlyingLib lib = ownedCoarseMap->lib();
166 LO LO_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
172 TEUCHOS_TEST_FOR_EXCEPTION(A->GetFixedBlockSize() != 1,
Exceptions::RuntimeError,
"ClassicalPFactory: Multiple PDEs per node not supported yet");
175 TEUCHOS_TEST_FOR_EXCEPTION(!A->getRowMap()->isSameAs(*A->getDomainMap()),
Exceptions::RuntimeError,
"ClassicalPFactory: MPI Ranks > 1 not supported yet");
178 std::string scheme = pL.get<std::string>(
"aggregation: classical scheme");
179 bool need_ghost_rows =
false;
180 if(scheme ==
"ext+i")
181 need_ghost_rows=
true;
182 else if(scheme ==
"direct")
183 need_ghost_rows=
false;
184 else if(scheme ==
"classical modified")
185 need_ghost_rows=
true;
193 RCP<const LocalOrdinalVector> fc_splitting;
194 ArrayRCP<const LO> myPointType;
195 if(Importer.is_null()) {
196 fc_splitting = owned_fc_splitting;
199 RCP<LocalOrdinalVector> fc_splitting_nonconst = LocalOrdinalVectorFactory::Build(A->getCrsGraph()->getColMap());
200 fc_splitting_nonconst->doImport(*owned_fc_splitting,*Importer,Xpetra::INSERT);
201 fc_splitting = fc_splitting_nonconst;
203 myPointType = fc_splitting->getData(0);
207 RCP<const Matrix> Aghost;
208 RCP<const LocalOrdinalVector> fc_splitting_ghost;
209 ArrayRCP<const LO> myPointType_ghost;
210 RCP<const Import> remoteOnlyImporter;
211 if(need_ghost_rows && !Importer.is_null()){
212 ArrayView<const LO> remoteLIDs = Importer->getRemoteLIDs();
213 size_t numRemote = Importer->getNumRemoteIDs();
214 Array<GO> remoteRows(numRemote);
215 for (
size_t i = 0; i < numRemote; i++)
216 remoteRows[i] = Importer->getTargetMap()->getGlobalElement(remoteLIDs[i]);
218 RCP<const Map> remoteRowMap = MapFactory::Build(lib,Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), remoteRows(),
219 A->getDomainMap()->getIndexBase(), A->getDomainMap()->getComm());
221 remoteOnlyImporter = Importer->createRemoteOnlyImport(remoteRowMap);
222 RCP<const CrsMatrix> Acrs = rcp_dynamic_cast<const CrsMatrixWrap>(A)->getCrsMatrix();
223 RCP<CrsMatrix> Aghost_crs = CrsMatrixFactory::Build(Acrs,*remoteOnlyImporter,A->getDomainMap(),remoteOnlyImporter->getTargetMap());
224 Aghost = rcp(
new CrsMatrixWrap(Aghost_crs));
237 RCP<const Map> coarseMap;
238 if(Importer.is_null())
239 coarseMap = ownedCoarseMap;
242 GhostCoarseMap(*A,*Importer,myPointType,ownedCoarseMap,coarseMap);
246 RCP<LocalOrdinalVector> BlockNumber;
247 std::string drop_algo = pL.get<std::string>(
"aggregation: drop scheme");
248 if (drop_algo.find(
"block diagonal") != std::string::npos || drop_algo ==
"signed classical") {
249 RCP<LocalOrdinalVector> OwnedBlockNumber;
251 if(Importer.is_null())
252 BlockNumber = OwnedBlockNumber;
254 BlockNumber = LocalOrdinalVectorFactory::Build(A->getColMap());
255 BlockNumber->doImport(*OwnedBlockNumber,*Importer,Xpetra::INSERT);
259#if defined(CMS_DEBUG) || defined(CMS_DUMP)
261 RCP<const CrsMatrix> Acrs = rcp_dynamic_cast<const CrsMatrixWrap>(A)->getCrsMatrix();
262 int rank = A->getRowMap()->getComm()->getRank();
263 printf(
"[%d] A local size = %dx%d\n",rank,(
int)Acrs->getRowMap()->getLocalNumElements(),(
int)Acrs->getColMap()->getLocalNumElements());
265 printf(
"[%d] graph local size = %dx%d\n",rank,(
int)graph->GetDomainMap()->getLocalNumElements(),(
int)graph->GetImportMap()->getLocalNumElements());
267 std::ofstream ofs(std::string(
"dropped_graph_") + std::to_string(fineLevel.
GetLevelID())+std::string(
"_") + std::to_string(rank) + std::string(
".dat"),std::ofstream::out);
268 RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(ofs));
269 graph->print(*fancy,
Debug);
270 std::string out_fc = std::string(
"fc_splitting_") + std::to_string(fineLevel.
GetLevelID()) +std::string(
"_") + std::to_string(rank)+ std::string(
".dat");
271 std::string out_block = std::string(
"block_number_") + std::to_string(fineLevel.
GetLevelID()) +std::string(
"_") + std::to_string(rank)+ std::string(
".dat");
274 using real_type =
typename Teuchos::ScalarTraits<SC>::magnitudeType;
275 using RealValuedMultiVector =
typename Xpetra::MultiVector<real_type,LO,GO,NO>;
276 typedef Xpetra::MultiVectorFactory<real_type,LO,GO,NO> RealValuedMultiVectorFactory;
278 RCP<RealValuedMultiVector> mv = RealValuedMultiVectorFactory::Build(fc_splitting->getMap(),1);
279 ArrayRCP<real_type> mv_data= mv->getDataNonConst(0);
282 ArrayRCP<const LO> fc_data= fc_splitting->getData(0);
283 for(LO i=0; i<(LO)fc_data.size(); i++)
284 mv_data[i] = Teuchos::as<real_type>(fc_data[i]);
285 Xpetra::IO<real_type,LO,GO,NO>::Write(out_fc,*mv);
288 if(!BlockNumber.is_null()) {
289 RCP<RealValuedMultiVector> mv2 = RealValuedMultiVectorFactory::Build(BlockNumber->getMap(),1);
290 ArrayRCP<real_type> mv_data2= mv2->getDataNonConst(0);
291 ArrayRCP<const LO> b_data= BlockNumber->getData(0);
292 for(LO i=0; i<(LO)b_data.size(); i++) {
293 mv_data2[i] = Teuchos::as<real_type>(b_data[i]);
295 Xpetra::IO<real_type,LO,GO,NO>::Write(out_block,*mv2);
309 Array<LO> cpoint2pcol(myPointType.size(),LO_INVALID);
310 Array<LO> pcol2cpoint(coarseMap->getLocalNumElements(),LO_INVALID);
313 for(LO i=0; i<(LO) myPointType.size(); i++) {
314 if(myPointType[i] == C_PT) {
315 cpoint2pcol[i] = num_c_points;
318 else if (myPointType[i] == F_PT)
321 for(LO i=0; i<(LO)cpoint2pcol.size(); i++) {
322 if(cpoint2pcol[i] != LO_INVALID)
323 pcol2cpoint[cpoint2pcol[i]] =i;
328 Teuchos::Array<size_t> eis_rowptr;
329 Teuchos::Array<bool> edgeIsStrong;
336 RCP<const Map> coarseColMap = coarseMap;
337 RCP<const Map> coarseDomainMap = ownedCoarseMap;
338 if(scheme ==
"ext+i") {
340 Coarsen_Ext_Plus_I(*A,Aghost,*graph,coarseColMap,coarseDomainMap,num_c_points,num_f_points,myPointType(),myPointType_ghost(),cpoint2pcol,pcol2cpoint,eis_rowptr,edgeIsStrong,BlockNumber,P);
342 else if(scheme ==
"direct") {
344 Coarsen_Direct(*A,Aghost,*graph,coarseColMap,coarseDomainMap,num_c_points,num_f_points,myPointType(),myPointType_ghost(),cpoint2pcol,pcol2cpoint,eis_rowptr,edgeIsStrong,BlockNumber,P);
346 else if(scheme ==
"classical modified") {
348 Coarsen_ClassicalModified(*A,Aghost,*graph,coarseColMap,coarseDomainMap,num_c_points,num_f_points,myPointType(),myPointType_ghost(),cpoint2pcol,pcol2cpoint,eis_rowptr,edgeIsStrong,BlockNumber,remoteOnlyImporter,P);
353 Xpetra::IO<SC,LO,GO,NO>::Write(
"classical_p.mat."+std::to_string(coarseLevel.
GetLevelID()), *P);
358 Set(coarseLevel,
"P",P);
359 RCP<const CrsGraph> pg = P->getCrsGraph();
360 Set(coarseLevel,
"P Graph",pg);
367 RCP<ParameterList> params = rcp(
new ParameterList());
368 params->set(
"printLoadBalancingInfo",
true);
375Coarsen_ClassicalModified(
const Matrix & A,
const RCP<const Matrix> & Aghost,
const GraphBase & graph, RCP<const Map> & coarseColMap, RCP<const Map> & coarseDomainMap, LO num_c_points, LO num_f_points,
const Teuchos::ArrayView<const LO> & myPointType,
const Teuchos::ArrayView<const LO> & myPointType_ghost,
const Teuchos::Array<LO> & cpoint2pcol,
const Teuchos::Array<LO> & pcol2cpoint, Teuchos::Array<size_t> & eis_rowptr, Teuchos::Array<bool> & edgeIsStrong, RCP<LocalOrdinalVector> & BlockNumber, RCP<const Import> remoteOnlyImporter,RCP<Matrix> & P)
const {
415 using STS =
typename Teuchos::ScalarTraits<SC>;
416 LO LO_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
418 SC SC_ZERO = STS::zero();
420 int rank = A.getRowMap()->getComm()->getRank();
424 ArrayRCP<const LO> block_id;
425 if(!BlockNumber.is_null())
426 block_id = BlockNumber->getData(0);
431 size_t Nrows = A.getLocalNumRows();
432 double c_point_density = (double)num_c_points / (num_c_points+num_f_points);
435 double nnz_per_row_est = c_point_density*mean_strong_neighbors_per_row;
437 size_t nnz_est = std::max(Nrows,std::min((
size_t)A.getLocalNumEntries(),(
size_t)(nnz_per_row_est*Nrows)));
438 Array<size_t> tmp_rowptr(Nrows+1);
439 Array<LO> tmp_colind(nnz_est);
445 for(LO row=0; row < (LO) Nrows; row++) {
446 size_t row_start = eis_rowptr[row];
447 ArrayView<const LO> indices;
448 ArrayView<const SC> vals;
450 if(myPointType[row] == DIRICHLET_PT) {
453 else if(myPointType[row] == C_PT) {
455 C_hat.insert(cpoint2pcol[row]);
461 A.getLocalRowView(row, indices, vals);
462 for(LO j=0; j<indices.size(); j++)
463 if(myPointType[indices[j]] == C_PT && edgeIsStrong[row_start + j])
464 C_hat.insert(cpoint2pcol[indices[j]]);
468 if(ct + (
size_t)C_hat.size() > (
size_t)tmp_colind.size()) {
469 tmp_colind.resize(std::max(ct+(
size_t)C_hat.size(),(
size_t)2*tmp_colind.size()));
473 std::copy(C_hat.begin(), C_hat.end(),tmp_colind.begin()+ct);
475 tmp_rowptr[row+1] = tmp_rowptr[row] + C_hat.size();
478 tmp_colind.resize(tmp_rowptr[Nrows]);
480 RCP<CrsMatrix> Pcrs = CrsMatrixFactory::Build(A.getRowMap(),coarseColMap,0);
481 ArrayRCP<size_t> P_rowptr;
482 ArrayRCP<LO> P_colind;
483 ArrayRCP<SC> P_values;
485 if (A.getRowMap()->lib() == Xpetra::UseTpetra) {
486 P_rowptr = Teuchos::arcpFromArray(tmp_rowptr);
487 P_colind = Teuchos::arcpFromArray(tmp_colind);
488 P_values.resize(P_rowptr[Nrows]);
493 Pcrs->allocateAllValues(tmp_rowptr[Nrows],P_rowptr,P_colind,P_values);
494 std::copy(tmp_rowptr.begin(),tmp_rowptr.end(), P_rowptr.begin());
495 std::copy(tmp_colind.begin(),tmp_colind.end(), P_colind.begin());
496 Pcrs->setAllValues(P_rowptr,P_colind,P_values);
497 Pcrs->expertStaticFillComplete(coarseDomainMap, A.getDomainMap());
501 RCP<const CrsGraph> Pgraph;
502 RCP<const CrsGraph> Pghost;
505 ArrayRCP<const size_t> Pghost_rowptr;
506 ArrayRCP<const LO> Pghost_colind;
507 if(!remoteOnlyImporter.is_null()) {
508 if (A.getRowMap()->lib() == Xpetra::UseTpetra) {
509 RCP<CrsGraph> tempPgraph = CrsGraphFactory::Build(A.getRowMap(),coarseColMap,P_rowptr,P_colind);
510 tempPgraph->fillComplete(coarseDomainMap,A.getDomainMap());
514 Pgraph = Pcrs->getCrsGraph();
516 TEUCHOS_ASSERT(!Pgraph.is_null());
517 Pghost = CrsGraphFactory::Build(Pgraph,*remoteOnlyImporter,Pgraph->getDomainMap(),remoteOnlyImporter->getTargetMap());
518 Pghost->getAllIndices(Pghost_rowptr,Pghost_colind);
522 ArrayRCP<LO> Acol_to_Pcol(A.getColMap()->getLocalNumElements(),LO_INVALID);
525 ArrayRCP<LO> Pghostcol_to_Pcol;
526 if(!Pghost.is_null()) {
527 Pghostcol_to_Pcol.resize(Pghost->getColMap()->getLocalNumElements(),LO_INVALID);
528 for(LO i=0; i<(LO) Pghost->getColMap()->getLocalNumElements(); i++)
529 Pghostcol_to_Pcol[i] = Pgraph->getColMap()->getLocalElement(Pghost->getColMap()->getGlobalElement(i));
533 ArrayRCP<LO> Aghostcol_to_Acol;
534 if(!Aghost.is_null()) {
535 Aghostcol_to_Acol.resize(Aghost->getColMap()->getLocalNumElements(),LO_INVALID);
536 for(LO i=0; i<(LO)Aghost->getColMap()->getLocalNumElements(); i++)
537 Aghostcol_to_Acol[i] = A.getColMap()->getLocalElement(Aghost->getColMap()->getGlobalElement(i));
542 for(LO i=0; i < (LO)Nrows; i++) {
543 if(myPointType[i] == DIRICHLET_PT) {
547 printf(
"[%d] ** A(%d,:) is a Dirichlet-Point.\n",rank,i);
550 else if (myPointType[i] == C_PT) {
552 P_values[P_rowptr[i]] = Teuchos::ScalarTraits<SC>::one();
555 printf(
"[%d] ** A(%d,:) is a C-Point.\n",rank,i);
562 printf(
"[%d] ** A(%d,:) is a F-Point.\n",rank,i);
566 ArrayView<const LO> A_indices_i, A_indices_k;
567 ArrayView<const SC> A_vals_i, A_vals_k;
568 A.getLocalRowView(i, A_indices_i, A_vals_i);
569 size_t row_start = eis_rowptr[i];
571 ArrayView<const LO> P_indices_i = P_colind.view(P_rowptr[i],P_rowptr[i+1] - P_rowptr[i]);
572 ArrayView<SC> P_vals_i = P_values.view(P_rowptr[i],P_rowptr[i+1] - P_rowptr[i]);
575 for(LO j=0; j<(LO)P_vals_i.size(); j++)
576 P_vals_i[j] = SC_ZERO;
580 for(LO j=0; j<(LO)P_indices_i.size(); j++) {
581 Acol_to_Pcol[pcol2cpoint[P_indices_i[j]]] = P_rowptr[i] + j;
585 SC first_denominator = SC_ZERO;
589 for(LO k0=0; k0<(LO)A_indices_i.size(); k0++) {
590 LO k = A_indices_i[k0];
591 SC a_ik = A_vals_i[k0];
592 LO pcol_k = Acol_to_Pcol[k];
597 first_denominator += a_ik;
600 printf(
"- A(%d,%d) is the diagonal\n",i,k);
604 else if(myPointType[k] == DIRICHLET_PT) {
607 printf(
"- A(%d,%d) is a Dirichlet point\n",i,k);
611 else if(pcol_k != LO_INVALID && pcol_k >= (LO)P_rowptr[i]) {
613 P_values[pcol_k] += a_ik;
615 printf(
"- A(%d,%d) is a strong C-Point\n",i,k);
618 else if (!edgeIsStrong[row_start + k0]) {
620 if(block_id.size() == 0 || block_id[i] == block_id[k]) {
621 first_denominator += a_ik;
623 printf(
"- A(%d,%d) is weak adding to diagonal(%d,%d) (%6.4e)\n",i,k,block_id[i],block_id[k],a_ik);
626 printf(
"- A(%d,%d) is weak but does not match blocks (%d,%d), discarding\n",i,k,block_id[i],block_id[k]);
635 printf(
"- A(%d,%d) is a strong F-Point\n",i,k);
639 SC second_denominator = SC_ZERO;
644 A.getLocalRowView(k, A_indices_k, A_vals_k);
645 for(LO m0=0; m0<(LO)A_indices_k.size(); m0++){
646 LO m = A_indices_k[m0];
654 sign_akk = Sign(a_kk);
655 for(LO m0=0; m0<(LO)A_indices_k.size(); m0++){
656 LO m = A_indices_k[m0];
657 if(m != k && Acol_to_Pcol[A_indices_k[m0]] >= (LO)P_rowptr[i]) {
658 SC a_km = A_vals_k[m0];
659 second_denominator+= (Sign(a_km) == sign_akk ? SC_ZERO : a_km);
665 if(second_denominator != SC_ZERO) {
666 for(LO j0=0; j0<(LO)A_indices_k.size(); j0++) {
667 LO j = A_indices_k[j0];
670 if(Acol_to_Pcol[j] >= (LO)P_rowptr[i]) {
671 SC a_kj = A_vals_k[j0];
672 SC sign_akj_val = sign_akk == Sign(a_kj) ? SC_ZERO : a_kj;
673 P_values[Acol_to_Pcol[j]] += a_ik * sign_akj_val / second_denominator;
675 printf(
"- - Unscaled P(%d,A-%d) += %6.4e = %5.4e\n",i,j,a_ik * sign_akj_val / second_denominator,P_values[Acol_to_Pcol[j]]);
682 printf(
"- - A(%d,%d) second denominator is zero\n",i,k);
684 if(block_id.size() == 0 || block_id[i] == block_id[k])
685 first_denominator += a_ik;
694 Aghost->getLocalRowView(kless, A_indices_k, A_vals_k);
695 GO k_g = Aghost->getRowMap()->getGlobalElement(kless);
696 for(LO m0=0; m0<(LO)A_indices_k.size(); m0++){
697 GO m_g = Aghost->getColMap()->getGlobalElement(A_indices_k[m0]);
705 sign_akk = Sign(a_kk);
706 for(LO m0=0; m0<(LO)A_indices_k.size(); m0++){
707 GO m_g = Aghost->getColMap()->getGlobalElement(A_indices_k[m0]);
708 LO mghost = A_indices_k[m0];
709 LO m = Aghostcol_to_Acol[mghost];
710 if(m_g != k_g && m != LO_INVALID && Acol_to_Pcol[m] >= (LO)P_rowptr[i]) {
711 SC a_km = A_vals_k[m0];
712 second_denominator+= (Sign(a_km) == sign_akk ? SC_ZERO : a_km);
719 if(second_denominator != SC_ZERO) {
720 for(LO j0=0; j0<(LO)A_indices_k.size(); j0++){
721 LO jghost = A_indices_k[j0];
722 LO j = Aghostcol_to_Acol[jghost];
724 if((j != LO_INVALID) && (Acol_to_Pcol[j] >= (LO)P_rowptr[i])) {
725 SC a_kj = A_vals_k[j0];
726 SC sign_akj_val = sign_akk == Sign(a_kj) ? SC_ZERO : a_kj;
727 P_values[Acol_to_Pcol[j]] += a_ik * sign_akj_val / second_denominator;
729 printf(
"- - Unscaled P(%d,A-%d) += %6.4e\n",i,j,a_ik * sign_akj_val / second_denominator);
737 printf(
"- - A(%d,%d) second denominator is zero\n",i,k);
739 if(block_id.size() == 0 || block_id[i] == block_id[k])
740 first_denominator += a_ik;
748 if(first_denominator != SC_ZERO) {
749 for(LO j0=0; j0<(LO)P_indices_i.size(); j0++) {
751 SC old_pij = P_vals_i[j0];
752 P_vals_i[j0] /= -first_denominator;
753 printf(
"P(%d,%d) = %6.4e = %6.4e / (%6.4e + %6.4e)\n",i,P_indices_i[j0],P_vals_i[j0],old_pij,a_ii,first_denominator - a_ii);
755 P_vals_i[j0] /= -first_denominator;
765 Pcrs->setAllValues(P_rowptr,P_colind,P_values);
766 Pcrs->expertStaticFillComplete(coarseDomainMap, A.getDomainMap());
768 P = rcp(
new CrsMatrixWrap(Pcrs));
776Coarsen_Direct(
const Matrix & A,
const RCP<const Matrix> & Aghost,
const GraphBase & graph, RCP<const Map> & coarseColMap, RCP<const Map> & coarseDomainMap, LO num_c_points, LO num_f_points,
const Teuchos::ArrayView<const LO> & myPointType,
const Teuchos::ArrayView<const LO> & myPointType_ghost,
const Teuchos::Array<LO> & cpoint2pcol,
const Teuchos::Array<LO> & pcol2cpoint, Teuchos::Array<size_t> & eis_rowptr, Teuchos::Array<bool> & edgeIsStrong, RCP<LocalOrdinalVector> & BlockNumber, RCP<Matrix> & P)
const {
822 using STS =
typename Teuchos::ScalarTraits<SC>;
823 using MT =
typename STS::magnitudeType;
824 using MTS =
typename Teuchos::ScalarTraits<MT>;
825 size_t Nrows = A.getLocalNumRows();
826 double c_point_density = (double)num_c_points / (num_c_points+num_f_points);
829 double nnz_per_row_est = c_point_density*mean_strong_neighbors_per_row;
831 size_t nnz_est = std::max(Nrows,std::min((
size_t)A.getLocalNumEntries(),(
size_t)(nnz_per_row_est*Nrows)));
832 SC SC_ZERO = STS::zero();
833 MT MT_ZERO = MTS::zero();
834 Array<size_t> tmp_rowptr(Nrows+1);
835 Array<LO> tmp_colind(nnz_est);
841 for(LO row=0; row < (LO) Nrows; row++) {
842 size_t row_start = eis_rowptr[row];
843 ArrayView<const LO> indices;
844 ArrayView<const SC> vals;
846 if(myPointType[row] == DIRICHLET_PT) {
849 else if(myPointType[row] == C_PT) {
851 C_hat.insert(cpoint2pcol[row]);
857 A.getLocalRowView(row, indices, vals);
858 for(LO j=0; j<indices.size(); j++)
859 if(myPointType[indices[j]] == C_PT && edgeIsStrong[row_start + j])
860 C_hat.insert(cpoint2pcol[indices[j]]);
864 if(ct + (
size_t)C_hat.size() > (
size_t)tmp_colind.size()) {
865 tmp_colind.resize(std::max(ct+(
size_t)C_hat.size(),(
size_t)2*tmp_colind.size()));
869 std::copy(C_hat.begin(), C_hat.end(),tmp_colind.begin()+ct);
871 tmp_rowptr[row+1] = tmp_rowptr[row] + C_hat.size();
874 tmp_colind.resize(tmp_rowptr[Nrows]);
877 P = rcp(
new CrsMatrixWrap(A.getRowMap(), coarseColMap, 0));
878 RCP<CrsMatrix> PCrs = rcp_dynamic_cast<CrsMatrixWrap>(P)->getCrsMatrix();
879 ArrayRCP<size_t> P_rowptr;
880 ArrayRCP<LO> P_colind;
881 ArrayRCP<SC> P_values;
884printf(
"CMS: Allocating P w/ %d nonzeros\n",(
int)tmp_rowptr[Nrows]);
886 PCrs->allocateAllValues(tmp_rowptr[Nrows], P_rowptr, P_colind, P_values);
887 TEUCHOS_TEST_FOR_EXCEPTION(tmp_rowptr.size() !=P_rowptr.size(),
Exceptions::RuntimeError,
"ClassicalPFactory: Allocation size error (rowptr)");
888 TEUCHOS_TEST_FOR_EXCEPTION(tmp_colind.size() !=P_colind.size(),
Exceptions::RuntimeError,
"ClassicalPFactory: Allocation size error (colind)");
890 for(LO i=0; i<(LO)Nrows+1; i++)
891 P_rowptr[i] = tmp_rowptr[i];
892 for(LO i=0; i<(LO)tmp_rowptr[Nrows]; i++)
893 P_colind[i] = tmp_colind[i];
897 for(LO i=0; i < (LO)Nrows; i++) {
898 if(myPointType[i] == DIRICHLET_PT) {
902 printf(
"** A(%d,:) is a Dirichlet-Point.\n",i);
905 else if (myPointType[i] == C_PT) {
907 P_values[P_rowptr[i]] = Teuchos::ScalarTraits<SC>::one();
910 printf(
"** A(%d,:) is a C-Point.\n",i);
919 ArrayView<const LO> A_indices_i, A_incides_k;
920 ArrayView<const SC> A_vals_i, A_indices_k;
921 A.getLocalRowView(i, A_indices_i, A_vals_i);
922 size_t row_start = eis_rowptr[i];
924 ArrayView<LO> P_indices_i = P_colind.view(P_rowptr[i],P_rowptr[i+1] - P_rowptr[i]);
925 ArrayView<SC> P_vals_i = P_values.view(P_rowptr[i],P_rowptr[i+1] - P_rowptr[i]);
930 char mylabel[5]=
"FUCD";
932 printf(
"** A(%d,:) = ",i);
933 for(LO j=0; j<(LO)A_indices_i.size(); j++){
934 printf(
"%6.4e(%d-%c%c) ",A_vals_i[j],A_indices_i[j],mylabel[1+myPointType[A_indices_i[j]]],sw[(
int)edgeIsStrong[row_start+j]]);
941 SC pos_numerator = SC_ZERO, neg_numerator = SC_ZERO;
942 SC pos_denominator = SC_ZERO, neg_denominator = SC_ZERO;
944 for(LO j=0; j<(LO)A_indices_i.size(); j++) {
945 SC a_ik = A_vals_i[j];
946 LO k = A_indices_i[j];
953 if(myPointType[k] == C_PT && edgeIsStrong[row_start + j]) {
954 if(STS::real(a_ik) > MT_ZERO) pos_denominator += a_ik;
955 else neg_denominator += a_ik;
961 if(STS::real(a_ik) > MT_ZERO) pos_numerator += a_ik;
962 else neg_numerator += a_ik;
965 SC alpha = (neg_denominator == MT_ZERO) ? SC_ZERO : (neg_numerator / neg_denominator);
966 SC beta = (pos_denominator == MT_ZERO) ? SC_ZERO : (pos_numerator / pos_denominator);
971 for(LO p_j=0; p_j<(LO)P_indices_i.size(); p_j++){
972 LO P_col = pcol2cpoint[P_indices_i[p_j]];
977 for(LO a_j =0; a_j<(LO)A_indices_i.size(); a_j++) {
978 if(A_indices_i[a_j] == P_col) {
979 a_ij = A_vals_i[a_j];
983 SC w_ij = (STS::real(a_ij) < 0 ) ? (alpha * a_ij) : (beta * a_ij);
985 SC alpha_or_beta = (STS::real(a_ij) < 0 ) ? alpha : beta;
986 printf(
"P(%d,%d/%d) = - %6.4e * %6.4e = %6.4e\n",i,P_indices_i[p_j],pcol2cpoint[P_indices_i[p_j]],alpha_or_beta,a_ij,w_ij);
988 P_vals_i[p_j] = w_ij;
994 PCrs->setAllValues(P_rowptr, P_colind, P_values);
995 PCrs->expertStaticFillComplete(coarseDomainMap, A.getDomainMap());