Skip to content

Commit d526742

Browse files
First pass fixing bug with Trilinos multiple coupled Neumann (resistance) boundary conditions
1 parent 49a61d2 commit d526742

File tree

2 files changed

+66
-29
lines changed

2 files changed

+66
-29
lines changed

Code/Source/solver/trilinos_impl.cpp

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ Epetra_Vector *Trilinos::ghostX;
6363
/// Import ghostMap into blockMap to create ghost map
6464
Epetra_Import *Trilinos::Importer;
6565

66-
/// Contribution from coupled neumann boundary conditions
67-
Epetra_FEVector *Trilinos::bdryVec;
66+
/// Contribution from coupled neumann boundary conditions. One vector for each coupled Neumann boundary
67+
std::vector<Epetra_FEVector*> Trilinos::bdryVec_list;
6868

6969
Epetra_FECrsGraph *Trilinos::K_graph;
7070

@@ -116,16 +116,19 @@ int TrilinosMatVec::Apply(const Epetra_MultiVector &x,
116116
Trilinos::K->Apply(x, y); //K*x
117117
if (coupledBC)
118118
{
119-
//now need to add on bdry term v*(v'*x)
119+
//now need to add on bdry term v1*(v1'*x) + v2*(v2'*x) + ...
120120
double *dot = new double[1]; //only 1 multivector to store result in it
121121

122-
//compute dot product (v'*x)
123-
Trilinos::bdryVec->Dot(x,dot);
122+
for (auto bdryVec : Trilinos::bdryVec_list)
123+
{
124+
//compute dot product (v'*x)
125+
bdryVec->Dot(x, dot);
124126

125-
//Y = 1*Y + dot*v daxpy operation
126-
y.Update(*dot, //scalar for v
127-
*Trilinos::bdryVec, //FE_Vector
128-
1.0); ///scalar for Y
127+
//Y = 1*Y + dot*v daxpy operation
128+
y.Update(*dot, //scalar for v
129+
*bdryVec, //FE_Vector v
130+
1.0); ///scalar for Y
131+
}
129132

130133
delete[] dot;
131134
}
@@ -149,13 +152,15 @@ int TrilinosMatVec::Apply(const Epetra_MultiVector &x,
149152
* \param rowPtr CSR row ptr of size numLocalNodes + 1 to block rows
150153
* \param colInd CSR column indices ptr (size nnz points) to block rows
151154
* \param Dof size of each block element to give dim of each block
155+
*
156+
* \param numCoupledNeumannBC number of coupled Neumann BCs
152157
153158
*/
154159

155160
void trilinos_lhs_create_(int &numGlobalNodes, int &numLocalNodes,
156161
int &numGhostAndLocalNodes, int &nnz, const int *ltgSorted,
157162
const int *ltgUnsorted, const int *rowPtr, const int *colInd, int &Dof,
158-
int& cpp_index, int& proc_id)
163+
int& cpp_index, int& proc_id, int& numCoupledNeumannBC)
159164
{
160165

161166
#ifdef debug_trilinos_lhs_create
@@ -302,7 +307,12 @@ void trilinos_lhs_create_(int &numGlobalNodes, int &numLocalNodes,
302307
Trilinos::K = new Epetra_FEVbrMatrix(Copy, *Trilinos::K_graph);
303308
//construct RHS force vector F topology
304309
Trilinos::F = new Epetra_FEVector(*Trilinos::blockMap);
305-
Trilinos::bdryVec = new Epetra_FEVector(*Trilinos::blockMap);
310+
// Construct a boundary vector for each coupled Neumann boundary condition
311+
Trilinos::bdryVec_list.clear();
312+
for (int i = 0; i < numCoupledNeumannBC; ++i)
313+
{
314+
Trilinos::bdryVec_list.push_back(new Epetra_FEVector(*Trilinos::blockMap));
315+
}
306316

307317
// Initialize solution vector which is unique and does not include the ghost
308318
// indices using the unique map
@@ -670,7 +680,11 @@ void trilinos_solve_(double *x, const double *dirW, double &resNorm,
670680
//set to 0 for the next time iteration
671681
Trilinos::K->PutScalar(0.0);
672682
Trilinos::F->PutScalar(0.0);
673-
if (coupledBC) Trilinos::bdryVec->PutScalar(0.0);
683+
if (coupledBC) {
684+
for (auto bdryVec : Trilinos::bdryVec_list)
685+
bdryVec->PutScalar(0.0);
686+
687+
}
674688
//0 out initial guess for iteration
675689
Trilinos::X->PutScalar(0.0);
676690
// Free memory if MLPrec is invoked
@@ -920,16 +934,18 @@ void constructJacobiScaling(const double *dirW, Epetra_Vector &diagonal)
920934
Trilinos::K->RightScale(diagonal);
921935

922936
//Need to multiply v in vv' by diagonal
923-
if (coupledBC)
924-
Trilinos::bdryVec->Multiply(1.0, *Trilinos::bdryVec, diagonal, 0.0);
937+
if (coupledBC) {
938+
for (auto bdryVec : Trilinos::bdryVec_list)
939+
bdryVec->Multiply(1.0, *bdryVec, diagonal, 0.0);
940+
}
925941
} // void constructJacobiScaling()
926942

927943
// ----------------------------------------------------------------------------
928944
/**
929945
* \param v coupled boundary vector
930946
* \param isCoupledBC determines if coupled resistance BC is turned on
931947
*/
932-
void trilinos_bc_create_(const double *v, bool &isCoupledBC)
948+
void trilinos_bc_create_(const std::vector v_list, bool &isCoupledBC)
933949
{
934950
//store as global to determine which matvec multiply to use in solver
935951
coupledBC = isCoupledBC;
@@ -943,14 +959,23 @@ void trilinos_bc_create_(const double *v, bool &isCoupledBC)
943959
{
944960
//sum values into v fe case
945961
int num_global_rows = 1; //number of global block rows put in 1 at a time
946-
error = Trilinos::bdryVec->ReplaceGlobalValues (num_global_rows,
947-
&localToGlobalSorted[i], //global idx id-inputting sorted array
948-
&dof, //dof values per id pointer to dof
949-
&v[i*dof]); //values of size dof
950-
if (error != 0)
962+
963+
// Loop over all the coupled Neumann BCs
964+
for (int k = 0; k < v_list.size(); ++k)
951965
{
952-
std::cout << "ERROR: Setting boundary vector values!" << std::endl;
953-
exit(1);
966+
auto v = v_list[k];
967+
auto bdryVec = Trilinos::bdryVec_list[k];
968+
//set the coupled boundary vector
969+
error = bdryVec->ReplaceGlobalValues(
970+
num_global_rows,
971+
&localToGlobalSorted[i], //global idx id-inputting sorted array
972+
&dof, //dof values per id pointer to dof
973+
&v[i*dof]); //values of size dof
974+
if (error != 0)
975+
{
976+
std::cout << "ERROR: Setting boundary vector values!" << std::endl;
977+
exit(1);
978+
}
954979
}
955980
}
956981
}
@@ -991,9 +1016,11 @@ void trilinos_lhs_free_()
9911016
delete Trilinos::Importer;
9921017
Trilinos::Importer = NULL;
9931018
}
994-
if (Trilinos::bdryVec) {
995-
delete Trilinos::bdryVec;
996-
Trilinos::bdryVec = NULL;
1019+
if (Trilinos::bdryVec_list.size() > 0)
1020+
{
1021+
for (auto bdryVec : Trilinos::bdryVec_list)
1022+
delete bdryVec;
1023+
Trilinos::bdryVec_list.clear();
9971024
}
9981025
if (Trilinos::K_graph) {
9991026
delete Trilinos::K_graph;
@@ -1140,7 +1167,7 @@ void TrilinosLinearAlgebra::TrilinosImpl::alloc(ComMod& com_mod, eqType& lEq)
11401167
int task_id = com_mod.cm.idcm();
11411168

11421169
trilinos_lhs_create_(gtnNo, lhs.mynNo, tnNo, lhs.nnz, ltg_.data(), com_mod.ltg.data(), com_mod.rowPtr.data(),
1143-
com_mod.colPtr.data(), dof, cpp_index, task_id);
1170+
com_mod.colPtr.data(), dof, cpp_index, task_id, com_mod.lhs.nFaces);
11441171

11451172
}
11461173

@@ -1208,6 +1235,7 @@ void TrilinosLinearAlgebra::TrilinosImpl::init_dir_and_coup_neu(ComMod& com_mod,
12081235
}
12091236
}
12101237

1238+
12111239
Array<double> v(dof,tnNo);
12121240
bool isCoupledBC = false;
12131241

@@ -1224,9 +1252,10 @@ void TrilinosLinearAlgebra::TrilinosImpl::init_dir_and_coup_neu(ComMod& com_mod,
12241252
}
12251253
}
12261254
}
1255+
trilinos_bc_create_(v.data(), isCoupledBC);
12271256
}
12281257

1229-
trilinos_bc_create_(v.data(), isCoupledBC);
1258+
12301259
}
12311260

12321261
/// @brief Initialze an array used for something.
@@ -1325,3 +1354,11 @@ void TrilinosLinearAlgebra::TrilinosImpl::solve_assembled(ComMod& com_mod, eqTyp
13251354

13261355
}
13271356

1357+
1358+
v1 = [
1359+
0 0 0 0 0 0 0 0 .. r*a r*b r*c ... 0 0 0 0 0
1360+
]
1361+
1362+
v2 = [ 0 0 0 ... r2*a r2*b r2*c ... 0 0 0 0 0 ]
1363+
1364+

Code/Source/solver/trilinos_impl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ struct Trilinos
9999
static Epetra_Vector *X;
100100
static Epetra_Vector *ghostX;
101101
static Epetra_Import *Importer;
102-
static Epetra_FEVector *bdryVec;
102+
static std::vector<Epetra_FEVector*> bdryVec_list;
103103
static Epetra_MpiComm *comm;
104104
static Epetra_FECrsGraph *K_graph;
105105
};
@@ -189,7 +189,7 @@ class TrilinosMatVec: public virtual Epetra_Operator
189189
void trilinos_lhs_create_(int& numGlobalNodes, int& numLocalNodes,
190190
int& numGhostAndLocalNodes, int& nnz, const int *ltgSorted,
191191
const int *ltgUnsorted, const int *rowPtr, const int *colInd,
192-
int &dof, int& cpp_index, int& proc_id);
192+
int &dof, int& cpp_index, int& proc_id, int& numCoupledNeumannBC);
193193
/*
194194
void trilinos_lhs_create_(unsigned &numGlobalNodes, unsigned &numLocalNodes,
195195
unsigned &numGhostAndLocalNodes, unsigned &nnz, const int *ltgSorted,

0 commit comments

Comments
 (0)