Hi Barry,

thanks for your response. I guess my code excerpt wasn't very good, nor 
was my description. My apologies.

The evaluation in more details goes like this:
Depending on the coordinates x and y (and only on them) I calculate 4 
vectors S1,...,S4.
I have a constant matrix C in the appctx. The three quantities I am 
interested in are then:

1) u1 = (x+y)*VecTDot(S1, MatMult(C, S2))
2) u2 = u1/(x+y) + (x+y)*VecTDot(S3, MatMult(C, S2))
3) u3 = u1/(x+y) + (x+y)*VecTDot(S1, MatMult(C, S4))

With this (hopefully better) description let me answer to your points 
below individually.
On 02/08/2011 05:29 PM, Barry Smith wrote:
> On Feb 8, 2011, at 10:16 AM, Klaus Zimmermann wrote:
>
>> Dear all,
>>
>> I want to evaluate a function on a grid. Right now I have some custom code 
>> (see the end of this message).
>> I am now thinking of rewriting this using more PETSC facilities because in 
>> the future we want to extend the
>> program to higher dimensions and also unstructured grids.
>     There is little similarity and little chance of code reuse between using 
> a structured grid and an unstructured grid at the level of your function 
> evaluations. So if you truly want to have a structured grid version and 
> unstructured you should just have different FormFunctions for them.
This is why I hoped to reuse code for the unstructured version: As long 
as I can call a method with coordinates and context I am fine.
I don't really need any solving. Do I still need different FormFunctions?

>> As I understand it now there are several
>> candidates in PETSC for doing this:
>>
>> 1) PF
>> 2) DALocalFunction
>     Using the "local" function approach with DMMGSetSNESLocal() is just a way 
> of hiding the DAVecGetArray() calls from the function code and is good when 
> you have simple FormFunctions that do no rely on other vectors beside the 
> usual input and output vectors. In your example below I do not understand why 
> you have the input and output vectors inside the appctx, usually they are the 
> input and output arguments to the formfunction set with SNESSetFunction() or 
> DMMGSetSNES()
I agree. This is mostly because I didn't understand the concepts so well 
at the time I wrote this code and one of the reasons why I would like to 
refactor.
In my case there should in principle be three output vectors. All the 
facilities I have seen in petsc only deal with a single output vector. 
Is this correct?
Of course there is an obvious mapping, but I would prefer to keep the 
vectors apart because that way it is easier to deal with the parallel 
layout.

>> 3) FIAT (?)
>>
>> Could you please advise on what should be used?
>> An additional problem is that several distinct functions should be evaluated 
>> at the same time due to the
>> due to the reuse of intermediate results.
>
>     Are these functions associated with different SNES solvers or is the 
> composition of these "several distinct functions" that defines the equations 
> you are solving with PETSc? If the later then you just need to write either a 
> single function that computes everything or have some smart use of inline to 
> get good performance even with different functions.
I am not really using any solving at the moment. Please let me know if 
you need more detail.

Thanks again,
Klaus

>     Barry
>
>> Any help is appreciated!
>> Thanks in advance,
>> Klaus
>>
>> ------------------8<------------------8<------------------8<------------------8<------------------8<--------------
>>
>> PetscErrorCode EvaluatePsiAndGradPsi(AppCtx *user) {
>>   PetscErrorCode ierr;
>>   PetscInt i, j, cxs, cxm, cys, cym;
>>   PetscScalar **lpsi;
>>   PetscScalar **lGradPsi_x, **lGradPsi_y;
>>   Vec gc;
>>   DACoor2d **coors;
>>   DA cda;
>>   ierr = DAGetCoordinateDA(user->zGrid,&cda);CHKERRQ(ierr);
>>   ierr = DAGetCoordinates(user->zGrid,&gc);CHKERRQ(ierr);
>>   ierr = DAVecGetArray(cda, gc,&coors);CHKERRQ(ierr);
>>   ierr = DAGetCorners(cda,&cxs,&cys, PETSC_NULL,&cxm,&cym, 
>> PETSC_NULL);CHKERRQ(ierr);
>>
>>   ierr = DAVecGetArray(user->zGrid, user->psi,&lpsi);CHKERRQ(ierr);
>>   ierr = DAVecGetArray(user->zGrid, 
>> user->gradPsi_x,&lGradPsi_x);CHKERRQ(ierr);
>>   ierr = DAVecGetArray(user->zGrid, 
>> user->gradPsi_y,&lGradPsi_y);CHKERRQ(ierr);
>>   for(i=cys; i<cys+cym; i++) {
>>     for(j=cxs; j<cxs+cxm; j++) {
>>       PetscReal x = PetscRealPart(coors[i][j].x-coors[i][j].y),
>>     y = PetscRealPart(coors[i][j].y);
>>       if(x>=0) {
>>     ierr = EvaluatePsiAndGradPsi(user, x, y,
>> &(lpsi[i][j]),
>> &(lGradPsi_x[i][j]),
>> &(lGradPsi_y[i][j]));CHKERRQ(ierr);
>>       }
>>     }
>>   }
>>   ierr = DAVecRestoreArray(user->zGrid, 
>> user->gradPsi_x,&lGradPsi_x);CHKERRQ(ierr);
>>   ierr = DAVecRestoreArray(user->zGrid, 
>> user->gradPsi_y,&lGradPsi_y);CHKERRQ(ierr);
>>   ierr = DAVecRestoreArray(user->zGrid, user->psi,&lpsi);CHKERRQ(ierr);
>>   ierr = DAVecRestoreArray(cda, gc,&coors);CHKERRQ(ierr);
>>   ierr = VecDestroy(gc);CHKERRQ(ierr);
>>   ierr = DADestroy(cda);CHKERRQ(ierr);
>>   return 0;
>> }

Reply via email to