<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.&nbsp; 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.&nbsp; 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].&nbsp; 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,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arraysize(1), arraysize(2), arraysize(3), PETSC_DECIDE, &amp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PETSC_DECIDE, PETSC_DECIDE, 1, 5, PETSC_NULL_INTEGER,&nbsp;&nbsp; &amp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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>&nbsp;&nbsp;&nbsp; do i = xs,xs+xl-1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( i.eq.arraysize(1)/2-1 ) then<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src_loc(1) = i<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do j = ys,ys+yl-1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( j.eq.arraysize(2)/2-1 ) then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src_loc(2) = j<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do k = zs,zs+zl-1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( k.eq.3 ) then<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; src_loc(2) = j<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; source_rank = rank<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; endif<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enddo<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; endif<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enddo<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; endif<br>&nbsp;&nbsp;&nbsp;&nbsp; enddo<br><br>call DAGetLocalVector( da, uLOCAL, ierr )<br>
call VecGetArrayF90( uLOCAL, xx, ierr )<br><br></div></blockquote>&nbsp;&nbsp; Use VecGetArrayF90() directly on the global vector and set the value in there. &nbsp;</div><div><br></div><div>&nbsp;&nbsp; Or instead of this you can determine the global location of the entry in the "natural ordering" and then use DAGetAO() followed by AOApplicationToPetsc() &nbsp;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&nbsp; ( rank.eq.source_rank )&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp; row = 15<br>&nbsp; &nbsp;&nbsp; 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.&nbsp; Is there a way to directly access the global distributed array (uGLOBAL) instead of working through the intermediate local array (uLOCAL)?&nbsp; 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>&nbsp;&nbsp; &nbsp;These are not supported in Fortran.</div><div><br></div><div>&nbsp;&nbsp;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 &amp; Technology<br>Thuwal 23955-6900<br>
Kingdom of Saudi Arabia<br> &nbsp; &nbsp; &nbsp; &nbsp; <br>EMAIL &nbsp; : <a href="mailto:mark.cheeseman@kaust.edu.sa">mark.cheeseman@kaust.edu.sa</a><br>PHONE : +966 &nbsp; (2) 808 0221 (office)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +966 (54) 470 1082 (mobile)<br>SKYPE : mark.patrick.cheeseman<br>

</div>
</blockquote></div><br></body></html>