@@ -63,8 +63,8 @@ Epetra_Vector *Trilinos::ghostX;
6363// / Import ghostMap into blockMap to create ghost map
6464Epetra_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
6969Epetra_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
155160void 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+
0 commit comments