/*----------------------------------------------------------------------------------*/ /* Parallel Sparse BLAS v2.2 */ /* (C) Copyright 2007 Salvatore Filippone University of Rome Tor Vergata */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* 1. Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* 2. Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions, and the following disclaimer in the */ /* documentation and/or other materials provided with the distribution. */ /* 3. The name of the PSBLAS group or the names of its contributors may */ /* not be used to endorse or promote products derived from this */ /* software without specific written permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED */ /* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ /* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS */ /* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR */ /* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ /* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ /* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN */ /* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) */ /* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ /* POSSIBILITY OF SUCH DAMAGE. */ /* */ /* */ /* File: ppdec.c */ /* */ /* Program: ppdec */ /* This sample program shows how to build and solve a sparse linear */ /* */ /* The program solves a linear system based on the partial differential */ /* equation */ /* */ /* */ /* */ /* The equation generated is */ /* */ /* b1 d d (u) b2 d d (u) a1 d (u)) a2 d (u))) */ /* - ------ - ------ + ----- + ------ + a3 u = 0 */ /* dx dx dy dy dx dy */ /* */ /* */ /* with Dirichlet boundary conditions on the unit cube */ /* */ /* 0<=x,y,z<=1 */ /* */ /* The equation is discretized with finite differences and uniform stepsize; */ /* the resulting discrete equation is */ /* */ /* ( u(x,y,z)(2b1+2b2+a1+a2)+u(x-1,y)(-b1-a1)+u(x,y-1)(-b2-a2)+ */ /* -u(x+1,y)b1-u(x,y+1)b2)*(1/h**2) */ /* */ /* Example adapted from: C.T.Kelley */ /* Iterative Methods for Linear and Nonlinear Equations */ /* SIAM 1995 */ /* */ /* */ /* In this sample program the index space of the discretized */ /* computational domain is first numbered sequentially in a standard way, */ /* then the corresponding vector is distributed according to an HPF BLOCK */ /* distribution directive. */ /* */ /* Boundary conditions are set in a very simple way, by adding */ /* equations of the form */ /* */ /* u(x,y) = rhs(x,y) */ /* */ /*----------------------------------------------------------------------------------*/ #include #include #include #include #include "psb_base_cbind.h" #include "psb_prec_cbind.h" #define LINEBUFSIZE 1024 #define NBMAX 20 double a1(double x, double y, double z) { return(1.0); } double a2(double x, double y, double z) { return(20.0*y); } double a3(double x, double y, double z) { return(1.0); } double a4(double x, double y, double z) { return(1.0); } double b1(double x, double y, double z) { return(1.0); } double b2(double x, double y, double z) { return(1.0); } double b3(double x, double y, double z) { return(1.0); } int matgen(int ictxt, int ng,int idim,int vg[],psb_c_dspmat *ah,psb_c_descriptor *cdh, psb_c_dvector *xh, psb_c_dvector *bh, psb_c_dvector *rh) { int iam, np; int x, y, z, el,glob_row,i,info,ret; double gx, gy, gz, deltah; double val[10*NBMAX], zt[NBMAX]; int irow[10*NBMAX], icol[10*NBMAX]; info = 0; psb_c_info(ictxt,&iam,&np); deltah = (double) 1.0/(idim-1); for (glob_row=1; glob_row<=ng; glob_row++) { /* Check if I have to do something about this entry */ if (vg[glob_row-1] == iam) { el=0; if ( (glob_row%(idim*idim)) == 0) { x = glob_row/(idim*idim); } else { x = glob_row/(idim*idim)+1; } if (((glob_row-(x-1)*idim*idim)%idim) == 0) { y = (glob_row-(x-1)*idim*idim)/idim; } else { y = (glob_row-(x-1)*idim*idim)/idim+1; } z = glob_row-(x-1)*idim*idim-(y-1)*idim; gx=x*deltah; gy=y*deltah; gz=z*deltah; zt[0] = 0.0; /* internal point: build discretization */ /* term depending on (x-1,y,z) */ if (x==1) { val[el] = -b1(gx,gy,gz)-a1(gx,gy,gz); val[el] /= deltah*deltah; zt[0] = exp(-gy*gy-gz*gz)*(-val[el]); } else { val[el]=-b1(gx,gy,gz) -a1(gx,gy,gz); val[el] = val[el]/(deltah*deltah); icol[el]=(x-2)*idim*idim+(y-1)*idim+(z); el=el+1; } /* term depending on (x,y-1,z) */ if (y==1) { val[el]=-b2(gx,gy,gz)-a2(gx,gy,gz); val[el] = val[el]/(deltah*deltah); zt[0] = exp(-gy*gy-gz*gz)*exp(-gx)*(-val[el]); } else { val[el]=-b2(gx,gy,gz)-a2(gx,gy,gz); val[el] = val[el]/(deltah*deltah); icol[el]=(x-1)*idim*idim+(y-2)*idim+(z); el=el+1; } /* term depending on (x,y,z-1)*/ if (z==1) { val[el]=-b3(gx,gy,gz)-a3(gx,gy,gz); val[el] = val[el]/(deltah*deltah); zt[0] = exp(-gy*gy-gz*gz)*exp(-gx)*(-val[el]); } else { val[el]=-b3(gx,gy,gz)-a3(gx,gy,gz); val[el] = val[el]/(deltah*deltah); icol[el]=(x-1)*idim*idim+(y-1)*idim+(z-1); el=el+1; } /* term depending on (x,y,z)*/ val[el]=2*b1(gx,gy,gz)+2*b2(gx,gy,gz)+2*b3(gx,gy,gz) +a1(gx,gy,gz)+a2(gx,gy,gz)+a3(gx,gy,gz); val[el] = val[el]/(deltah*deltah); icol[el]=(x-1)*idim*idim+(y-1)*idim+(z); el=el+1; /* term depending on (x,y,z+1) */ if (z==idim) { val[el]=-b1(gx,gy,gz); val[el] = val[el]/(deltah*deltah); zt[0] = exp(-gy*gy-gz*gz)*exp(-gx)*(-val[el]); } else { val[el]=-b1(gx,gy,gz); val[el] = val[el]/(deltah*deltah); icol[el]=(x-1)*idim*idim+(y-1)*idim+(z+1); el=el+1; } /* term depending on (x,y+1,z) */ if (y==idim) { val[el]=-b2(gx,gy,gz); val[el] = val[el]/(deltah*deltah); zt[0] = exp(-gy*gy-gz*gz)*exp(-gx)*(-val[el]); } else { val[el]=-b2(gx,gy,gz); val[el] = val[el]/(deltah*deltah); icol[el]=(x-1)*idim*idim+(y)*idim+(z); el=el+1; } /* term depending on (x+1,y,z) */ if (xdescriptor); /* Clean up object handles */ free(ph); free(xh); free(bh); free(ah); free(cdh); fprintf(stderr,"program completed successfully\n"); psb_c_barrier(ictxt); psb_c_exit(ictxt); }