Hi Thanks for that. I have since resolved my issue for purpose. I will however implement this suggestion by Jed as it seems more efficient and more consistent with the Petsc paradigm.
cheers Sanjay ________________________________________ From: Jed Brown [[email protected]] Sent: 09 February 2015 04:19 To: Sanjay Kharche; [email protected] Subject: Re: [petsc-users] passing information to TSIFunction Sanjay Kharche <[email protected]> writes: > Hi > > I need to pass a 2D array of ints to user defined functions, especially RHS. > Ideally, this 2D array is dynamically created at run time to make my > application general. Yesterday's discussion is below. > > I did this in the application context: > > /* User-defined data structures and routines */ > /* AppCtx: used by FormIFunction() */ > typedef struct { > DM da; // DM instance in which u, r are placed. > PetscInt geometry[usr_MY][usr_MX]; // This is static, so the whole thing > is visible to everybody who gets the context. This is my working solution as > of now. > Vec geom; // I duplicate u for this in calling function. > VecDuplicate( u , &user.geom). I cannot pass this to RHS function, I cannot > access values in geom in the called function. > PetscInt **geomet; // I calloc this in the calling function. I cannot > access the data in RHS function > int **anotherGeom; // just int. > } AppCtx; > > This static geometry 2D array can be seen in all functions that receive the > application context. This is a working solution to my problem, although not > ideal. The ideal solution would be if I can pass and receive something like > geom or geomet which are dynamically created after the 2D DA is created in > the calling function. Why not create a DMDA (serial and redundant if you prefer) for the geometry, store the geometry in a Vec, and use DMDAVecGetArray() to access it? I like to compose the geometry with the state DM and use DMCoarsenHooks if using rediscretized geometric multigrid (thus keeping the application context resolution-independent), but if you're putting resolution-dependent stuff in the context, you can just add the dmgeom and vector. > I am working through the manual and the examples, but some indication of how > to solve this specific issue will be great. > > cheers > Sanjay > > > > > ________________________________ > From: Matthew Knepley [[email protected]] > Sent: 04 February 2015 21:03 > To: Sanjay Kharche > Cc: [email protected] > Subject: Re: [petsc-users] passing information to TSIFunction > > On Wed, Feb 4, 2015 at 2:59 PM, Sanjay Kharche > <[email protected]<mailto:[email protected]>> > wrote: > > Hi > > I started with the ex15.c example from ts. Now I would like to pass a 2D int > array I call data2d to the FormIFunction which constructs the udot - RHS. > FormIFunction is used in Petsc's TSSetIFunction. My data2d is determined at > run time in the initialisation on each rank. data2d is the same size as the > solution array and the residual array. > > I tried adding a Vec to FormIFunction, but Petsc's TSIFunction ( > TSSetIFunction(ts,r,FormIFunction,&user); ) expects a set number & type of > arguments to FormIFunction. I tried passing data2d as a regular int pointer > as well as a Vec. As a Vec, I tried to access the data2d in a similar way as > the solution vector, which caused the serial and parallel execution to > produce errors. > > 1) This is auxiliary data which must come in through the context argument. > Many many example use a context > > 2) You should read the chapter on DAs in the manual. It describes the data > layout. In order for your code to > work in parallel I suggest you use a Vec and cast to int when you need > the value. > > Thanks, > > Matt > > Any ideas on how I can get an array of ints to FormIFunction? > > thanks > Sanjay > > > The function declaration: > // petsc functions. > extern PetscInt FormIFunction(TS,PetscReal,Vec,Vec,Vec,void*, Vec); // last > Vec is supposed to be my data2D, which is a duplicate of the u. > > I duplicate as follows: > DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, > DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,usr_MX,usr_MY,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&da); > user.da = da; > DMCreateGlobalVector(da,&u); > VecDuplicate(u,&r); > VecDuplicate(u,&Data2D); // so my assumption is that data2D is part of > da, but I cannot see/set its type anywhere > > The warnings/notes at build time: > >> make sk2d > /home/sanjay/petsc/linux-gnu-c-debug/bin/mpicc -o sk2d.o -c -fPIC -Wall > -Wwrite-strings -Wno-strict-aliasing -Wno-unknown-pragmas -g3 -O0 > -I/home/sanjay/petsc/include -I/home/sanjay/petsc/linux-gnu-c-debug/include > `pwd`/sk2d.c > /home/sanjay/petscProgs/Work/twod/sk2d.c: In function ‘main’: > /home/sanjay/petscProgs/Work/twod/sk2d.c:228:4: warning: passing argument 3 > of ‘TSSetIFunction’ from incompatible pointer type [enabled by default] > /home/sanjay/petsc/include/petscts.h:261:29: note: expected ‘TSIFunction’ but > argument is of type ‘PetscInt (*)(struct _p_TS *, PetscReal, struct _p_Vec > *, struct _p_Vec *, struct _p_Vec *, void *, struct _p_Vec *)’ > > > > > -- > What most experimenters take for granted before they begin their experiments > is infinitely more interesting than any results to which their experiments > lead. > -- Norbert Wiener
