10 const unsigned numDofsSub,
14 : numDofs_( static_cast<int>( numDofs ) ),
15 numDofsSub_( static_cast<int>( numDofsSub ) ),
16 matrixType_( matrixType ),
18 numSubLoc_ ( numSubLoc )
99 meshDim_ =
static_cast<int>( meshDim );
110 int numElemSubInt =
static_cast<int>(
numElemSub_ );
115 for (
unsigned i = 1; i < static_cast<unsigned>(
nProc_ ); i++ )
116 procElemStarts[i] = procElemStarts[i-1] + procElemStarts[i];
118 for (
unsigned i =
nProc_; i > 0; i-- )
119 procElemStarts[i] = procElemStarts[i-1];
121 procElemStarts[0] = 0;
127 OLD_ASSERT( std::accumulate( nnet.begin(), nnet.end(), 0 ) == (
int)(inet.size()),
128 "array inet size mismatch \n " );
130 "array nndf content mismatch: %d %d \n ", std::accumulate( nndf.begin(), nndf.end(), 0 ),
numDofsSub_ );
132 "array isvgvn size mismatch \n " );
134 "array nnet size mismatch \n " );
136 "array nndf size mismatch \n " );
138 "array xyz size mismatch: %d %d \n ", static_cast<int>(xyz.size()),
numNodesSub_ * nDim_ );
141 inet_.resize( inet.size() );
142 std::copy( inet.begin(), inet.end(),
inet_.begin() );
143 nnet_.resize( nnet.size() );
144 std::copy( nnet.begin(), nnet.end(),
nnet_.begin() );
145 nndf_.resize( nndf.size() );
146 std::copy( nndf.begin(), nndf.end(),
nndf_.begin() );
147 isegn_.resize( isegn.size() );
148 std::copy( isegn.begin(), isegn.end(),
isegn_.begin() );
149 isngn_.resize( isngn.size() );
150 std::copy( isngn.begin(), isngn.end(),
isngn_.begin() );
151 isvgvn_.resize( isvgvn.size() );
152 std::copy( isvgvn.begin(), isvgvn.end(),
isvgvn_.begin() );
153 xyz_.resize( xyz.size() );
154 std::copy( xyz.begin(), xyz.end(),
xyz_.begin() );
156 std::copy( element_data.begin(), element_data.end(),
element_data_.begin() );
159 for (
unsigned ind = 0; ind <
isvgvn_.size(); ++ind ) {
174 unsigned length = numElements * elMatSize;
187 for (
unsigned i = 0; i < rowIndices.size(); i++) {
188 for (
unsigned j = 0; j < colIndices.size(); j++) {
191 if (subMat(i,j) != 0.0)
192 coo_.
insert( rowIndices[i], colIndices[j], subMat(i,j) );
224 for (
unsigned i = 0; i < dofIndices.size( ); i ++ ) {
234 DebugOut().every_proc() <<
"RHS, Missing map to local for idx: " << dofIndices[i];
236 const unsigned indLoc = pos -> second;
238 rhsVec_[ indLoc ] += subVec[i];
249 const double factor,
FMT_UNUSED const double scalar )
252 ConstraintVec_::const_iterator cIter = constraints.begin( );
253 ConstraintVec_::const_iterator cEnd = constraints.end( );
255 for ( ; cIter != cEnd; ++cIter ) {
256 unsigned globalDof = cIter -> first;
257 double value = (cIter -> second );
263 unsigned indLoc = pos -> second;
278 thisConstraint.push_back( std::make_pair( index, 0. ) );
280 thisConstraint.clear();
288 const double &
value )
320 int verboseLevel,
int maxIt,
int ndecrMax,
bool use_adaptive )
325 "Subdomain mesh was not loaded, perhaps missing call to loadMesh() member function. \n " );
334 if ( numSubAtLevels != NULL ) {
337 OLD_ASSERT( numLevels == static_cast<int>((*numSubAtLevels).size()),
338 "Inconsistent size of numbers of subdomains at levels: %d %d \n",
339 numLevels, static_cast<int>((*numSubAtLevels).size()) );
341 "Inconsistent number of subdomains at first level: %d %d \n",
342 (*numSubAtLevels)[0], numSub );
344 std::copy( (*numSubAtLevels).begin(), (*numSubAtLevels).end(),
350 if ( numLevels == 2 ) {
351 numSubLev[0] = numSub;
354 else if ( numLevels > 2 ) {
355 double coarsening = pow( numSub, 1. /
double(numLevels - 1) );
357 numSubLev[0] = numSub;
358 for (
int i = 1; i <= numLevels-2; i++) {
359 int ir = numLevels - i - 1;
360 numSubLev[i] = (int) pow( coarsening, ir );
361 if ( numSubLev[i]%2 != 0 ) {
362 numSubLev[i] = numSubLev[i] + 1;
365 numSubLev[numLevels-1] = 1;
368 OLD_ASSERT(
false,
"Missing numbers of subdomains at levels. \n" );
375 int lnumSubLev = numSubLev.size();
378 int justDirectSolve = 0;
380 bddcml_init_c( &numLevels, &(numSubLev[0]), &lnumSubLev, &
numSubLoc_, &commInt, &verboseLevel, &numBase, &justDirectSolve );
387 int linet =
inet_.size();
388 int lnnet =
nnet_.size();
389 int lnndf =
nndf_.size();
390 int lisngn =
isngn_.size();
392 int lisegn =
isegn_.size();
397 int lifix =
ifix_.size();
398 int lfixv =
fixv_.size();
401 int isRhsCompleteInt = 0;
409 bool onlyUpperTriangle;
411 onlyUpperTriangle =
false;
414 onlyUpperTriangle =
true;
427 for (
unsigned inz = 0; inz < a_sparse.size(); inz++ ) {
428 if ( i_sparse[inz] != indRow ) {
429 indRow = i_sparse[inz];
430 Global2LocalMap_::iterator pos =
global2LocalDofMap_.find( static_cast<unsigned> ( indRow ) );
432 "Cannot remap index %d to local indices. \n ", indRow );
433 indRowLoc =
static_cast<int> ( pos -> second );
435 if ( j_sparse[inz] != indCol ) {
436 indCol = j_sparse[inz];
437 Global2LocalMap_::iterator pos =
global2LocalDofMap_.find( static_cast<unsigned> ( indCol ) );
439 "Cannot remap index %d to local indices. \n ", indCol );
440 indColLoc =
static_cast<int> ( pos -> second );
443 i_sparse[ inz ] = indRowLoc;
444 j_sparse[ inz ] = indColLoc;
449 int isMatAssembledInt = 0;
451 int la = a_sparse.size();
455 "It appears that diagonal weights for BDDC are not loaded. This is currently mandatory. \n " );
469 for (
unsigned inz = 0; inz < diag_sparse.size(); inz++ ) {
470 indRow = i_diag_sparse[inz];
471 Global2LocalMap_::iterator pos =
global2LocalDofMap_.find( static_cast<unsigned> ( indRow ) );
473 "Cannot remap index %d to local indices. \n ", indRow );
474 indRowLoc =
static_cast<int> ( pos -> second );
476 i_diag_sparse[ inz ] = indRowLoc;
480 OLD_ASSERT( lsub_diagonal == static_cast<int>(diag_sparse.size()),
481 "Array length mismatch: %d %d . \n ", lsub_diagonal, static_cast<int>(diag_sparse.size()) );
485 for (
int i = 0; i < lsub_diagonal; i++ ){
486 indRowLoc = i_diag_sparse[i];
487 double value = diag_sparse[i];
488 sub_diagonal[indRowLoc] =
value;
490 OLD_ASSERT( std::find(sub_diagonal.begin(), sub_diagonal.end(), -1. ) == sub_diagonal.end(),
491 "There are missing entries in the diagonal of weights. \n " );
494 int numDofsInt =
static_cast<int> (
numDofs_ );
495 int numDofsSubInt =
static_cast<int> (
numDofsSub_ );
502 else {
OLD_ASSERT(
false,
"Illegal matrixType \n " );}
505 int lsol =
sol_.size();
509 int lUserConstraints1 = 0;
510 int lUserConstraints2 = 0;
512 int lelement_data1 = 1;
518 int find_components_int = 1;
525 &(
xyz_[0]),&lxyz1,&lxyz2,
527 &(
rhsVec_[0]),&lrhsVec, &isRhsCompleteInt,
529 &matrixTypeInt, &(i_sparse[0]), &(j_sparse[0]), &(a_sparse[0]), &la, &isMatAssembledInt,
530 &(userConstraints[0]),&lUserConstraints1,&lUserConstraints2,
532 &(sub_diagonal[0]), &lsub_diagonal,
533 &find_components_int);
541 int use_defaults_int = 0;
542 int parallel_division_int = 0;
543 int use_arithmetic_int = 1;
544 int use_adaptive_int;
545 if ( use_adaptive ) {
546 use_adaptive_int = 1;
549 use_adaptive_int = 0;
551 int use_user_constraints_int = 0;
552 int weights_type = 3;
555 int use_corner_constraints_int = 1;
559 bddcml_setup_preconditioner_c( & matrixTypeInt, & use_defaults_int,
560 & parallel_division_int, & use_arithmetic_int,
561 & use_corner_constraints_int,
562 & use_adaptive_int, & use_user_constraints_int,
567 double normSquaredLoc = 0.;
569 bddcml_dotprod_subdomain_c( &iSub, &(
rhsVec_[0]), &lrhsVec, &(
rhsVec_[0]), &lrhsVec, &normSquaredLoc );
571 for (
double elem:
rhsVec_ ) normSquaredLoc += elem*elem;
575 double normSquared = 0.;
577 normRhs_ = std::sqrt( normSquared );
588 int recycling_int = 0;
589 int max_number_of_stored_vectors = 100;
593 bddcml_solve_c( & commInt, & method, & tol, & maxIt, & ndecrMax,
594 & recycling_int, & max_number_of_stored_vectors,
604 bddcml_download_local_solution_c( &iSub, &(
sol_[0]), &lsol );
609 bddcml_dotprod_subdomain_c( &iSub, &(
sol_[0]), &lsol, &(
sol_[0]), &lsol, &normSquaredLoc );
611 for (
double elem:
sol_ ) normSquaredLoc += elem*elem;
617 normSol_ = std::sqrt( normSquared );
void applyConstraints(ConstraintVec_ &constraints, const double factor, const double scalar)
void prepareAssembly(const IndexType length)
std::vector< double > fixv_
values of fixed boundary conditions at places of ifix_ - values outside fixed dofs are ignored ...
void finishAssembly()
Finalize matrix assembly - build the assembled input and truncate matrix.
BddcmlWrapper(const unsigned numDofs, const unsigned numDofsSub, const MatrixType matrixType=GENERAL, const MPI_Comm comm=MPI_COMM_WORLD, int numSubLoc=1)
int numIter_
required number of iterations
int nProc_
number of processors in communicator
void finishMatAssembly()
Finalize assembly of matrix.
void prepareMatAssembly(unsigned numElements, unsigned elMatSize)
Prepare assembly of matrix - reserve space in underlying coordinate matrix object.
int rank_
ID of processors in communicator.
std::vector< int > inet_
safety state variable to warn if solver is called without loading subdomain mesh
~BddcmlWrapper()
Destructor frees the BDDCML structures.
std::vector< double > xyz_
int numNodes_
total number of nodes
Global2LocalMap_ global2LocalDofMap_
type for storage of global to local map
enum matrixTypeEnum MatrixType
IndexType nnz() const
Return number of non-zeros.
la::MatrixCoo< int, double > coo_
matrix in coordinate format (COO)
void insertToMatrix(const SubMat_ &eStiff, const VecUint_ &rowIndices, const VecUint_ &colIndices)
insert submatrix to system matrix - into coordinate matrix object
double normSol_
norm of the global solution
const MatrixType matrixType_
type of matrix
static constexpr bool value
int numElem_
total number of elements
int numSubLoc_
number of subdomains on process
std::vector< double > sol_
distributed solution vector
std::vector< int > isvgvn_
Indices of Subdomain Variables in Global Variable Numbering ( i.e. dof mapping )
std::vector< int > isegn_
Indices of Subdomain Elements in Global Numbering.
int numElemSub_
number of elements in subdomain
#define START_TIMER(tag)
Starts a timer with specified tag.
#define MPI_Allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm)
#define MPI_Comm_c2f(comm)
std::vector< double > rhsVec_
vector with RHS values restricted to subdomain, i.e. values are repeated at shared nodes ...
bool isMatAssembled_
true if matrix is assembled
void insert(const IndexType i, const IndexType j, const ValueType value)
Insert a value to unassembled vector.
void insertToDiagonalWeights(const int &index, const double &value)
std::vector< int > ifix_
indices of fixed boundary conditions - ( 0 for free variable, 1 for constrained dof ) ...
#define MPI_Allreduce(sendbuf, recvbuf, count, datatype, op, comm)
symmetric positive definite,
general symmetric ( e.g. saddle point ),
bool isDiagAssembled_
true if diagonal is assembled
void loadRawMesh(const int nDim, const int numNodes, const std::vector< int > &inet, const std::vector< int > &nnet, const std::vector< int > &nndf, const std::vector< int > &isegn, const std::vector< int > &isngn, const std::vector< int > &isvgvn, const std::vector< double > &xyz, const std::vector< double > &element_data, const int meshDim=0)
Load raw data about mesh.
void fixDOF(const unsigned index, const double scalar=1.)
void extractArrays(std::vector< IndexType > &rowIndices, std::vector< IndexType > &colIndices, std::vector< ValueType > &values, bool onlyUpperTriangle=false)
Fill independent arrays with column indices, row pointers and values.
std::vector< int > isngn_
Indices of Subdomain Nodes in Global Numbering.
int meshDim_
mesh dimension, may differ from space dimension - e.g. 2 for shells in 3D
void solveSystem(double tol=1.e-7, int numLevels=2, std::vector< int > *numSubAtLevels=NULL, int verboseLevel=0, int maxIt=1000, int ndecrMax=30, bool use_adaptive=false)
Solve the system.
int numNodesSub_
number of nodes in subdomain
void finishDiagAssembly()
Finalize assembly of diagonal.
#define END_TIMER(tag)
Ends a timer with specified tag.
const MPI_Comm comm_
communicator
ublas::vector< double > SubVec_
std::vector< double > element_data_
array with data on elements, here used for permeability for each element
la::MatrixCoo< int, double > diagWeightsCoo_
diagonal of subdomain matrix in sparse format and global numbers
const int numDofsSub_
number of subdomain dofs
const int numDofs_
number of total dofs
ublas::matrix< double > SubMat_
void clear()
destroy all contents
#define DebugOut()
Macro defining 'debug' record of log.
double normRhs_
norm of the global right-hand side
void insertToRhs(const SubVec_ &eForce, const VecUint_ &dofIndices)
insert subvector to system rhs vector