<div dir="ltr"><div><div><div>Hello,<br></div>I have some problem when I try to set multiple values to a PETSc vector that I will use later on with SNES. I am using Fortran 90.<br></div>Here the problem and two fixes that however are not so good for performances reasons. The code is very simple.<br>
<br></div><b>Standard approach that does not work correctly: (I am probably doing something wrong)<br><br> </b>m = 1<br> ! Loop over all elements<br> do ielem = elem_low, elem_high<br> ! Loop over all nodes in the element<br>
do inode = 1, nodesperelem<br> !Loop over all equations<br> do ieq = 1, nequations<br> ! Add element to x_vec_local<br> x_vec_local(m) = ug(ieq,inode,ielem)<br>
! Add element to index list<br> ind(m) = (elem_low-1)*nodesperelem*nequations+m-1<br> ! Update m index<br> m = m+1<br> end do<br>
end do<br> end do<br><br><div> ! Set values in the portion of the vector owned by the process<br> call VecSetValues(x_vec_in,len_local,index_list,x_vec_local,INSERT_VALUES,& <br> & ierr_local)<br>
<br> ! Assemble initial guess<br> call VecAssemblyBegin(x_vec_in,ierr_local)<br> call VecAssemblyEnd(x_vec_in,ierr_local)<br><br></div><div>Then I print my expected values and the values contained in the PETSc vector to a file. See attachment. I am running in serial for the moment BUT strangely if you look at the file I have attached the first 79 DOFs values have a wrong ordering and the remaining 80 are zero.<br>
<br><br></div><div><b>1st approach: set just one value at the time inside the loop</b>.<br> m = 1<br> ! Loop over all elements<br> do ielem = elem_low, elem_high<br> ! Loop over all nodes in the element<br>
do inode = 1, nodesperelem<br> !Loop over all equations<br> do ieq = 1, nequations<br> ! Add element to x_vec_local<br> value = ug(ieq,inode,ielem)<br>
! Add element to index list<br> ind = (elem_low-1)*nodesperelem*nequations+m-1<br> call VecSetValues(x_vec_in,1,ind,value,INSERT_VALUES,& <br> & ierr_local)<br>
! Update m index<br> m = m+1<br> end do<br> end do<br> end do<br></div><div> <br><br></div><div><u>This works fine</u>. As you can see I am using the same expression used in the previous loop to compute the index of the element that I have to add in the x_vec_in, i.e.<br>
ind = (elem_low-1)*nodesperelem*nequations+m-1</div><div><br></div><div>Thus I cannot see which is the problem. <br></div><div><br><b>2nd approach: get the pointer to the local part of the global vector and use it to set the values in the global vector<br>
<br> </b>m = 1<br> ! Loop over all elements<br> do ielem = elem_low, elem_high<br> ! Loop over all nodes in the element<br> do inode = 1, nodesperelem<br> !Loop over all equations<br>
do ieq = 1, nequations<br> ! Add element to x_vec_local<br> tmp(m) = ug(ieq,inode,ielem)<br> ! Update m index<br> m = m+1<br> end do<br>
end do<br> end do<b><br></b><br><br></div><div><u>This works fine too</u>.<br><br><br></div><div>Jut to be complete. I use the following two approaches to view the vector:<br><br>call VecView(x_vec_in,PETSC_VIEWER_STDOUT_WORLD,ierr_local)<br>
<br><br></div><div>and <br><br>call VecGetArrayF90(x_vec_in,tmp,ierr_local)<br><br><br> m = 1<br> ! Loop over all elements<br> do ielem = elem_low, elem_high<br> ! Loop over all nodes in the element<br>
do inode = 1, nodesperelem<br> !Loop over all equations<br> do ieq = 1, nequations<br> write(*,*) m,index_list(m),x_vec_local(m),tmp(m) <br> ! Update m index<br>
m = m+1<br> end do<br> end do<br> end do<br><br><br></div><div>Thank you.<br></div><div><br clear="all"></div><div><div><div><div><div><br>-- <br><div dir="ltr">Matteo<br>
</div>
</div></div></div></div></div></div>