<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Jun 22, 2010, at 7:59 AM, Mark Cheeseman wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr">Hi,<br><br>I am trying to write a PETSc program in FORTRAN90 where I need to update a single value in a global distributed array. I know the global coordinates of the position that needs to be updated in the global array but I cannot get the mapping from the local vector correct. In this case, I am working on a domain with global dimensions [arraysize(1),arraysize(2),arraysize(3)] and I want to alter a single point in the global distributed array, uGLOBAL, at the global position [arraysize(1)/2-1,arraysize(2)-1,3]. I cannot seem to be able to do this... what am I doing wrong?<br>
<br>...<br>DA da<br>Vec uGLOBAL, uLOCAL, tmp<br>PetscErrorCode ierr<br>PetscScalar, pointer :: xx<br>PetscInt rank, source_rank, i,j,k, row<br><br clear="all">....<br><br>call MPI_Comm_rank( PETSC_COMM_WORLD, rank, ierr )<br>
call DACreate3d( PETSC_COMM_WORLD, DA_NONPERIODIC, DA_STENCIL_BOX, &<br> arraysize(1), arraysize(2), arraysize(3), PETSC_DECIDE, &<br> PETSC_DECIDE, PETSC_DECIDE, 1, 5, PETSC_NULL_INTEGER, &<br>
PETSC_NULL_INTEGER, PETSC_NULL_INTEGER, da, ierr)<br>call DACreateGlobalVector( da, pNOW, ierr )<br>call DAGetCorners( da, xs, ys, zs, xl, yl, zl, ierr )<br><br> do i = xs,xs+xl-1<br> if ( i.eq.arraysize(1)/2-1 ) then<br>
src_loc(1) = i<br> do j = ys,ys+yl-1<br> if ( j.eq.arraysize(2)/2-1 ) then<br> src_loc(2) = j<br> do k = zs,zs+zl-1<br> if ( k.eq.3 ) then<br>
src_loc(2) = j<br> source_rank = rank<br> endif<br> enddo<br> endif<br> enddo<br> endif<br> enddo<br><br>call DAGetLocalVector( da, uLOCAL, ierr )<br>
call VecGetArrayF90( uLOCAL, xx, ierr )<br><br></div></blockquote> Use VecGetArrayF90() directly on the global vector and set the value in there. </div><div><br></div><div> Or instead of this you can determine the global location of the entry in the "natural ordering" and then use DAGetAO() followed by AOApplicationToPetsc() with the global location in the natural ordering to convert to the PETSc ordering and then call VecSetValues() with the global vector followed by VecAssemblyBegin() and VecAssemblyEnd().</div><div><br></div><div><br><blockquote type="cite"><div dir="ltr">if ( rank.eq.source_rank ) then<br> row = 15<br> xx(row) = pressure<br>endif<br><br>call VecRestoreArrayF90( uLOCAL, xx, ierr )<br>call DALocalToGlobal( da, uLOCAL, ADD_VALUES, uGLOBAL, ierr )<br>
call DARestoreLocalVector( da, uLOCAL, ierr )<br><br></div></blockquote><br><blockquote type="cite"><div dir="ltr"><br>Any help would be greatly appreciated. Is there a way to directly access the global distributed array (uGLOBAL) instead of working through the intermediate local array (uLOCAL)? I have tried the approach<br>
<br>call DAVecGetArray( da, uGLOBAL, xx, ierr )<br>xx = ....<br>call DAVecRestoreArray( da, uGLOBAL, xx, ierr )<br><br>Unfortunately, the compile always fails with the message that the DAVecRestoreArray function cannot be found.<br></div></blockquote><div><br></div> These are not supported in Fortran.</div><div><br></div><div> Barry</div><div><br></div><div><br><blockquote type="cite"><div dir="ltr">
<br>Thank you,<br>Mark<br><br>-- <br>Mark Patrick Cheeseman<br><br>Computational Scientist<br>KSL (KAUST Supercomputing Laboratory)<br>Building 1, Office #126<br>King Abdullah University of Science & Technology<br>Thuwal 23955-6900<br>
Kingdom of Saudi Arabia<br> <br>EMAIL : <a href="mailto:mark.cheeseman@kaust.edu.sa">mark.cheeseman@kaust.edu.sa</a><br>PHONE : +966 (2) 808 0221 (office)<br> +966 (54) 470 1082 (mobile)<br>SKYPE : mark.patrick.cheeseman<br>
</div>
</blockquote></div><br></body></html>