PetscErrorCode FEMAssembleTotal2DLaplace(MPI_Comm comm, Mesh *mesh, Mat &A, Vec &b, PetscReal(*f)(Point), PetscReal(*K)(Point)) { PetscErrorCode ierr; PetscInt rank; MPI_Comm_rank(PETSC_COMM_WORLD, &rank); PetscInt size = mesh->vetrices.size(); ierr = MatCreateMPIAIJ(comm, size, size, PETSC_DECIDE, PETSC_DECIDE, 7, PETSC_NULL, 0, PETSC_NULL, &A); CHKERRQ(ierr); ierr = VecCreateMPI(comm, size, PETSC_DECIDE, &b); CHKERRQ(ierr); for (std::map<PetscInt, Element*>::iterator e = mesh->elements.begin(); e != mesh->elements.end(); e++) { PetscScalar bl[3]; PetscScalar Al[9]; PetscReal R[4]; PetscInt elSize = e->second->numVetrices; Point *vetrices = new Point[elSize]; PetscInt ixs[elSize]; for (int j = 0; j < elSize; j++) { ixs[j] = e->second->vetrices[j]; vetrices[j] = *(mesh->vetrices[ixs[j]]); } R[0] = vetrices[1].x - vetrices[0].x; R[2] = vetrices[1].y - vetrices[0].y; R[1] = vetrices[2].x - vetrices[0].x; R[3] = vetrices[2].y - vetrices[0].y; Point center = getCenterOfSet(vetrices, elSize); bLoc(R, bl, f(center)); ALoc(R, Al, K(center)); ierr = VecSetValues(b, elSize, ixs, bl, ADD_VALUES); CHKERRQ(ierr); ierr = MatSetValues(A, elSize, ixs, elSize, ixs, Al, ADD_VALUES); CHKERRQ(ierr); } ierr = VecAssemblyBegin(b); CHKERRQ(ierr); ierr = VecAssemblyEnd(b); CHKERRQ(ierr); ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); return ierr; }
void RLS ( const DistSparseMatrix<Real>& A, const DistMultiVec<Real>& b, Real rho, DistMultiVec<Real>& x, const socp::affine::Ctrl<Real>& ctrl ) { DEBUG_CSE const Int m = A.Height(); const Int n = A.Width(); mpi::Comm comm = A.Comm(); DistMultiVec<Int> orders(comm), firstInds(comm); Zeros( orders, m+n+3, 1 ); Zeros( firstInds, m+n+3, 1 ); { const Int localHeight = orders.LocalHeight(); for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = orders.GlobalRow(iLoc); if( i < m+1 ) { orders.SetLocal( iLoc, 0, m+1 ); firstInds.SetLocal( iLoc, 0, 0 ); } else { orders.SetLocal( iLoc, 0, n+2 ); firstInds.SetLocal( iLoc, 0, m+1 ); } } } // G := | -1 0 0 | // | 0 0 A | // | 0 -1 0 | // | 0 0 -I | // | 0 0 0 | DistSparseMatrix<Real> G(comm); { Zeros( G, m+n+3, n+2 ); // Count the number of entries of G to reserve // ------------------------------------------- Int numLocalUpdates = 0; const Int localHeight = G.LocalHeight(); for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = G.GlobalRow(iLoc); if( i == 0 || i == m+1 || (i>m+1 && i<m+n+2) ) ++numLocalUpdates; } const Int numEntriesA = A.NumLocalEntries(); G.Reserve( numLocalUpdates+numEntriesA, numEntriesA ); // Queue the local updates // ----------------------- for( Int iLoc=0; iLoc<localHeight; ++iLoc ) { const Int i = G.GlobalRow(iLoc); if( i == 0 ) G.QueueLocalUpdate( iLoc, 0, -1 ); else if( i == m+1 ) G.QueueLocalUpdate( iLoc, 1, -1 ); else if( i > m+1 && i < m+n+2 ) G.QueueLocalUpdate( iLoc, i-m, -1 ); } // Queue the remote updates // ------------------------ for( Int e=0; e<numEntriesA; ++e ) G.QueueUpdate( A.Row(e)+1, A.Col(e)+2, A.Value(e) ); G.ProcessQueues(); } // h := | 0 | // | b | // | 0 | // | 0 | // | 1 | DistMultiVec<Real> h(comm); Zeros( h, m+n+3, 1 ); auto& bLoc = b.LockedMatrix(); { const Int bLocalHeight = b.LocalHeight(); h.Reserve( bLocalHeight ); for( Int iLoc=0; iLoc<bLocalHeight; ++iLoc ) h.QueueUpdate( b.GlobalRow(iLoc)+1, 0, bLoc(iLoc) ); h.ProcessQueues(); } h.Set( END, 0, 1 ); // c := [1; rho; 0] DistMultiVec<Real> c(comm); Zeros( c, n+2, 1 ); c.Set( 0, 0, 1 ); c.Set( 1, 0, rho ); DistSparseMatrix<Real> AHat(comm); Zeros( AHat, 0, n+2 ); DistMultiVec<Real> bHat(comm); Zeros( bHat, 0, 1 ); DistMultiVec<Real> xHat(comm), y(comm), z(comm), s(comm); SOCP( AHat, G, bHat, c, h, orders, firstInds, xHat, y, z, s, ctrl ); x = xHat( IR(2,END), ALL ); }
PetscErrorCode FEMAssemble2DLaplace(MPI_Comm comm, Mesh *mesh, Mat &A, Vec &b, PetscReal(*f)(Point), PetscReal(*K)(Point)) { PetscErrorCode ierr; PetscInt rank; MPI_Comm_rank(PETSC_COMM_WORLD, &rank); PetscInt size = mesh->vetrices.size(); ierr = MatCreateMPIAIJ(comm, size, size, PETSC_DECIDE, PETSC_DECIDE, 7, PETSC_NULL, 0, PETSC_NULL, &A); CHKERRQ(ierr); ierr = VecCreateMPI(comm, size, PETSC_DECIDE, &b); CHKERRQ(ierr); std::set<PetscInt> indDirchlet; for (std::set<PetscInt>::iterator i = mesh->borderEdges.begin(); i != mesh->borderEdges.end(); i++) { for (int j = 0; j < 2; j++) { indDirchlet.insert(mesh->edges[*i]->vetrices[j]); } } for (std::map<PetscInt, Element*>::iterator e = mesh->elements.begin(); e != mesh->elements.end(); e++) { PetscScalar bl[3]; PetscScalar Al[9]; PetscReal R[4]; PetscInt elSize = e->second->numVetrices; Point *vetrices = new Point[elSize]; PetscInt ixs[elSize]; for (int j = 0; j < elSize; j++) { ixs[j] = e->second->vetrices[j]; vetrices[j] = *(mesh->vetrices[ixs[j]]); } R[0] = vetrices[1].x - vetrices[0].x; R[2] = vetrices[1].y - vetrices[0].y; R[1] = vetrices[2].x - vetrices[0].x; R[3] = vetrices[2].y - vetrices[0].y; Point center = getCenterOfSet(vetrices, elSize); bLoc(R, bl, f(center)); ALoc(R, Al, K(center)); //Enforce Dirchlet condition for (int j = 0; j < 3; j++) { if (indDirchlet.count(ixs[j]) > 0) { for (int k = 0; k < 3; k++) { Al[j * 3 + k] = 0; Al[k * 3 + j] = 0; } Al[j * 3 + j] = 1; bl[j] = 0; } } ierr = VecSetValues(b, elSize, ixs, bl, ADD_VALUES); CHKERRQ(ierr); ierr = MatSetValues(A, elSize, ixs, elSize, ixs, Al, ADD_VALUES); CHKERRQ(ierr); } ierr = VecAssemblyBegin(b); CHKERRQ(ierr); ierr = VecAssemblyEnd(b); CHKERRQ(ierr); ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); return ierr; }