<div dir="ltr">Hi everyone,<div><br></div><div>We are in the process of integrating nonlinear solution to our FE code through SNES. The first steps that I understood that need to be done is to be able to pass the assembled stiffness matrix K and force vector F to the "<b>formfunction</b>" to calculate the residual and "<b>formjacobian</b>" to calculate the tangent stiffness matrix. To do so, I have defined a struct:</div><div><br></div><div><b>extern PetscErrorCode FormJacobian(SNES,Vec,Mat,Mat,void*);<br>extern PetscErrorCode FormFunction(SNES,Vec,Vec,void*);</b><br><br>// define a struct type to pass K and f as "user context"<br><b>typedef struct<br> {<br> Mat K;<br> Vec f;<br> } K_and_f;</b><br></div><div><br></div><div>In the main program, the struct is declared</div><div><b>int main()</b></div><div><b>{</b></div><div><b>K_and_f main_K_and_f;</b> // declare the struct</div><div><br></div>// SNES - Populate K and f into the struct<br><b>main_K_and_f.K = K;</b> // K matrix<br><div><b>main_K_and_f.f = f; </b>// f vector <br></div><div>....</div><div>....</div><div><b>}</b></div><div>In form function</div><div><br></div><div><b>PetscErrorCode FormFunction(SNES snes, Vec x, Vec F, void* ctx) {<br> PetscErrorCode ierr;<br> PetscReal *ax,*c;<br> PetscReal *aF;<br> PetscScalar *Kc,v; <br> PetscInt nlocal,m,n,i,j,index[100000];<br><br> </b> // Create local Vec and Mat<br><b> Mat Kloc;</b><br><b> Vec Floc, Uloc, KUloc, resloc;</b><br><b> </b><br><b> K_and_f* ptr = (K_and_f*) ctx; </b>// cast the pointer to void into pointer to struct<br></div><div><b> </b>// Get local F array, FLOC</div><b> ierr = VecGhostGetLocalForm(ptr->f,&Floc);CHKERRQ(ierr);</b><div><br></div><div><br></div><div>I am able to get the f array from the main program using "
VecGhostGetLocalForm" and the vec is correct. However, I am having trouble with reading the K matrix in formfunction. </div><div><br></div><div>The following trial gives me incorrect K values in Kloc:</div><div><b>ierr = MatSeqAIJGetArray(ptr->K,&Kc);CHKERRQ(ierr); </b></div><div><b>ierr = MatGetLocalSize(ptr->K,&m,&n); CHKERRQ(ierr);<br></b></div><b>for(i=0;i<m;i++)<br> { <br> for(j=0;j<n;j++)<br> {<br> v = *(Kc + (i*n+j));<br> ierr = MatSetValues(Kloc,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr);<br> }<br></b><div><b> } </b><br><div> </div><div> When I compare K and Kloc, they are not identical </div><div><br></div><div><br></div><div>Please let me know if there is an equivalent function like <b>VecGhostGetLocalForm()</b> for Matrices. If not, is there a better way to do this.</div><div><br></div><div>Any guidance/help is greatly appreciated.</div><div><br></div><div>Thanks</div><div>Kaushik</div><div><br></div><div><br></div><div><br></div><div><br></div></div></div>