SALSA Analysis Modules
|
00001 #include <stdlib.h> 00002 #include <string.h> 00003 #include "anamod.h" 00004 #include "petscmat.h" 00005 00006 #define CATEGORYCOOKIE 983429 00007 #define CHECKVALIDCATEGORY(x) ANAMODCHECKVALID(x,CATEGORYCOOKIE,"category") 00008 00009 struct categoryobject_ { 00010 int cookie; 00011 const char *name; 00012 int enabled; /* 1: enable, 0: never compute, -1: skip from loops */ 00013 int maxcomponents,ncomponents; 00014 PetscErrorCode (*optionfunction)(char*); 00015 componentobject *components; const char **componentnames; 00016 AnalysisDataType *types; 00017 } ; 00018 00019 extern int ncategories; 00020 int maxcategories; 00021 extern categoryobject *categoryobjects; 00022 const char **categorynames; /* pointers to the names in the actual objects */ 00023 00024 #undef __FUNCT__ 00025 #define __FUNCT__ "AllocCategoryObjects" 00026 PetscErrorCode AllocCategoryObjects() 00027 { 00028 PetscErrorCode ierr; 00029 PetscFunctionBegin; 00030 maxcategories = MXC; ncategories = 0; 00031 ierr = PetscMalloc 00032 (maxcategories*sizeof(categoryobject),&categoryobjects); CHKERRQ(ierr); 00033 ierr = PetscMalloc 00034 (maxcategories*sizeof(char*),&categorynames); CHKERRQ(ierr); 00035 PetscFunctionReturn(0); 00036 } 00037 00038 #undef __FUNCT__ 00039 #define __FUNCT__ "FreeCategoryObjects" 00040 PetscErrorCode FreeCategoryObjects() 00041 { 00042 int icat; PetscErrorCode ierr; 00043 PetscFunctionBegin; 00044 for (icat=0; icat<ncategories; icat++) { 00045 ierr = DestroyCategoryObject(categoryobjects[icat]); CHKERRQ(ierr); 00046 } 00047 ierr = PetscFree(categoryobjects); CHKERRQ(ierr); 00048 ierr = PetscFree(categorynames); CHKERRQ(ierr); 00049 PetscFunctionReturn(0); 00050 } 00051 00052 #undef __FUNCT__ 00053 #define __FUNCT__ "CreateCategoryObject" 00054 /*! Create a category object with a given name. 00055 See also DestroyCategoryObject(). 00056 */ 00057 PetscErrorCode CreateCategoryObject(const char *cat,categoryobject *obj) 00058 { 00059 categoryobject nnew; PetscErrorCode ierr; 00060 00061 PetscFunctionBegin; 00062 ierr = PetscMalloc(sizeof(struct categoryobject_),&nnew); CHKERRQ(ierr); 00063 ierr = PetscStrallocpy(cat,(char**)&(nnew->name)); CHKERRQ(ierr); 00064 nnew->cookie = CATEGORYCOOKIE; nnew->enabled = CATCMP_ENABLE; 00065 nnew->maxcomponents = MXC; nnew->ncomponents = 0; 00066 ierr = PetscMalloc 00067 (nnew->maxcomponents*sizeof(componentobject),&(nnew->components)); CHKERRQ(ierr); 00068 ierr = PetscMalloc 00069 (nnew->maxcomponents*sizeof(char*),&(nnew->componentnames)); CHKERRQ(ierr); 00070 ierr = PetscMalloc 00071 (nnew->maxcomponents*sizeof(AnalysisDataType),&(nnew->types)); CHKERRQ(ierr); 00072 *obj = nnew; 00073 PetscFunctionReturn(0); 00074 } 00075 00076 #undef __FUNCT__ 00077 #define __FUNCT__ "DestroyCategoryObject" 00078 /*! Deallocate a category object. See also CreateCategoryObject(). */ 00079 PetscErrorCode DestroyCategoryObject(categoryobject obj) 00080 { 00081 int icmp; PetscErrorCode ierr; 00082 PetscFunctionBegin; 00083 CHECKVALIDCATEGORY(obj); 00084 for (icmp=0; icmp<obj->ncomponents; icmp++) { 00085 ierr = DestroyComponentObject(obj->components[icmp]); CHKERRQ(ierr); 00086 } 00087 ierr = PetscFree(obj->components); CHKERRQ(ierr); 00088 ierr = PetscFree(obj->componentnames); CHKERRQ(ierr); 00089 ierr = PetscFree(obj->types); CHKERRQ(ierr); 00090 ierr = PetscFree(obj->name); CHKERRQ(ierr); 00091 ierr = PetscFree(obj); CHKERRQ(ierr); 00092 PetscFunctionReturn(0); 00093 } 00094 00095 #undef __FUNCT__ 00096 #define __FUNCT__ "GetCategoryIndex" 00097 /*! Test for existence of a category, and return its index 00098 if present. Both output parameters can be null. 00099 */ 00100 static PetscErrorCode GetCategoryIndex(const char* cat,int *icat,PetscTruth *flag) 00101 { 00102 int i; PetscTruth flg; PetscErrorCode ierr; 00103 PetscFunctionBegin; 00104 flg = PETSC_FALSE; 00105 for (i=0; i<ncategories; i++) { 00106 ierr = PetscStrcmp(cat,categoryobjects[i]->name,&flg); CHKERRQ(ierr); 00107 if (flg) {if (icat) *icat = i; goto found;} 00108 } 00109 found: 00110 if (flag) *flag = flg; 00111 if (!flag && !flg) 00112 SETERRQ(1,"Category not found but no flag provided to report this"); 00113 PetscFunctionReturn(0); 00114 } 00115 00116 #undef __FUNCT__ 00117 #define __FUNCT__ "GetOrCreateCategory" 00118 /*! Return a named category, creating it if necessary */ 00119 PetscErrorCode GetOrCreateCategory(const char *cat,categoryobject *catg) 00120 { 00121 int icat; PetscTruth flg; PetscErrorCode ierr; 00122 PetscFunctionBegin; 00123 ierr = GetCategoryIndex(cat,&icat,&flg); CHKERRQ(ierr); 00124 if (!flg) { 00125 icat = ncategories++; 00126 if (icat>=maxcategories) 00127 SETERRQ(1,"Category reallocation not implemented"); 00128 ierr = CreateCategoryObject(cat,&categoryobjects[icat]); CHKERRQ(ierr); 00129 categorynames[icat] = categoryobjects[icat]->name; 00130 } 00131 *catg = categoryobjects[icat]; 00132 PetscFunctionReturn(0); 00133 } 00134 00135 #undef __FUNCT__ 00136 #define __FUNCT__ "GetCategory" 00137 /*! Return a named category */ 00138 PetscErrorCode GetCategory(const char *cat,categoryobject *catg,PetscTruth *f) 00139 { 00140 int icat; PetscTruth flg; PetscErrorCode ierr; 00141 PetscFunctionBegin; 00142 ierr = GetCategoryIndex(cat,&icat,&flg); CHKERRQ(ierr); 00143 if (f) *f = flg; 00144 if (flg && catg) *catg = categoryobjects[icat]; 00145 PetscFunctionReturn(0); 00146 } 00147 00148 #undef __FUNCT__ 00149 #define __FUNCT__ "GetCategories" 00150 PetscErrorCode GetCategories(int *ncat,const char ***cats) 00151 { 00152 PetscFunctionBegin; 00153 if (ncat) *ncat = ncategories; 00154 if (cats) *cats = categorynames; 00155 PetscFunctionReturn(0); 00156 } 00157 00158 #undef __FUNCT__ 00159 #define __FUNCT__ "CategoryGetComponentIndex" 00160 /*! Test for presence of a component in a category, and return its index 00161 if present. The index parameter can be null. 00162 */ 00163 PetscErrorCode CategoryGetComponentIndex 00164 (categoryobject catg,const char *cmp,int *icmp,PetscTruth *flag) 00165 { 00166 int i; PetscTruth flg; PetscErrorCode ierr; 00167 PetscFunctionBegin; 00168 CHECKVALIDCATEGORY(catg); 00169 flg = PETSC_FALSE; 00170 for (i=0; i<catg->ncomponents; i++) { 00171 ierr = PetscStrcmp(cmp,catg->componentnames[i],&flg); CHKERRQ(ierr); 00172 if (flg) {if (icmp) *icmp = i; goto found;} 00173 } 00174 found: 00175 if (flag) *flag = flg; 00176 if (!flg && !flag) 00177 SETERRQ(1,"Component not found but no flag to return this info"); 00178 PetscFunctionReturn(0); 00179 } 00180 00181 #undef __FUNCT__ 00182 #define __FUNCT__ "CategoryGetOrCreateComponent" 00183 PetscErrorCode CategoryGetOrCreateComponent 00184 (categoryobject catg,const char *cmp,componentobject *cmpt) 00185 { 00186 int icmp; PetscTruth flg; PetscErrorCode ierr; 00187 PetscFunctionBegin; 00188 CHECKVALIDCATEGORY(catg); 00189 ierr = CategoryGetComponentIndex(catg,cmp,&icmp,&flg); CHKERRQ(ierr); 00190 if (!flg) { 00191 icmp = catg->ncomponents++; 00192 if (icmp>=catg->maxcomponents) 00193 SETERRQ(1,"Component reallocation not implemented"); 00194 ierr = CreateComponentObject(cmp,&(catg->components[icmp])); CHKERRQ(ierr); 00195 ierr = ComponentGetName 00196 (catg->components[icmp],&(catg->componentnames[icmp])); CHKERRQ(ierr); 00197 } 00198 *cmpt = catg->components[icmp]; 00199 PetscFunctionReturn(0); 00200 } 00201 00202 #undef __FUNCT__ 00203 #define __FUNCT__ "CategoryGetComponent" 00204 /*! Retrieve a component. 00205 00206 See also CategoryGetOrCreateComponent(), CategoryGetComponentIndex(). 00207 */ 00208 PetscErrorCode CategoryGetComponent 00209 (categoryobject catg,const char *cmp,componentobject *cmpt,PetscTruth *success) 00210 { 00211 int icmp; PetscTruth flg; PetscErrorCode ierr; 00212 PetscFunctionBegin; 00213 CHECKVALIDCATEGORY(catg); 00214 ierr = CategoryGetComponentIndex(catg,cmp,&icmp,&flg); CHKERRQ(ierr); 00215 if (success) *success = flg; 00216 if (flg) { 00217 if (cmpt) *cmpt = catg->components[icmp]; 00218 } else if (!success) 00219 SETERRQ(1,"Component not found but no flag given to report this"); 00220 PetscFunctionReturn(0); 00221 } 00222 00223 #undef __FUNCT__ 00224 #define __FUNCT__ "CategoryComponentSetModule" 00225 PetscErrorCode CategoryComponentSetModule 00226 (const char *cat,const char *cmp,AnalysisDataType type,int id, 00227 PetscErrorCode(*f)(AnaModNumericalProblem,AnalysisItem*,int*,PetscTruth*)) 00228 { 00229 categoryobject catg; componentobject cmpt; int icmp; PetscErrorCode ierr; 00230 PetscFunctionBegin; 00231 ierr = GetOrCreateCategory(cat,&catg); CHKERRQ(ierr); 00232 ierr = CategoryGetOrCreateComponent(catg,cmp,&cmpt); CHKERRQ(ierr); 00233 ierr = ComponentSetModule(cmpt,type,id,f); CHKERRQ(ierr); 00234 ierr = CategoryGetComponentIndex(catg,cmp,&icmp,PETSC_NULL); CHKERRQ(ierr); 00235 catg->types[icmp] = type; 00236 PetscFunctionReturn(0); 00237 } 00238 00239 #undef __FUNCT__ 00240 #define __FUNCT__ "CategoryGetModules" 00241 /*! Query the modules in a specified category. 00242 00243 The category name has to exist. The routine will call the Petsc error 00244 handler if the name is invalid. 00245 00246 Parameters: 00247 - \c cat : the category that is being queried 00248 - \c ms (optional) : the names of the modules in the category 00249 - \c t (optional) : the corresponding list of datatypes 00250 - \c id (optional) : the list of module IDs (see RetrieveQuantityByID()) 00251 - \c n (optional) : the number of modules in the category 00252 00253 See also GetCategories() and HasComputeCategory(). 00254 */ 00255 PetscErrorCode CategoryGetModules 00256 (const char *cat,const char ***ms,AnalysisDataType **t,int **id,int *n) 00257 { 00258 categoryobject catg; PetscTruth flg; PetscErrorCode ierr; 00259 PetscFunctionBegin; 00260 ierr = GetCategory(cat,&catg,&flg); CHKERRQ(ierr); 00261 if (!flg) SETERRQ1(1,"Unknown category <%s>",cat); 00262 if (ms) *ms = catg->componentnames; 00263 if (t) *t = catg->types; 00264 if (n) *n = catg->ncomponents; 00265 // if (id) *id = ids[i]; 00266 PetscFunctionReturn(0); 00267 } 00268 00269 /* 00270 * Stuff for category reporting 00271 */ 00272 static int categoryreadout=-1; 00273 00274 #undef __FUNCT__ 00275 #define __FUNCT__ "GetFirstCategory" 00276 PetscErrorCode GetFirstCategory(const char **rname,PetscTruth *rfound) 00277 { 00278 PetscTruth found = PETSC_FALSE; 00279 PetscFunctionBegin; 00280 categoryreadout = 0; 00281 while (categoryreadout<ncategories 00282 && categoryobjects[categoryreadout]->enabled!=CATCMP_ENABLE) 00283 categoryreadout++; 00284 if (categoryreadout<ncategories) { 00285 found = PETSC_TRUE; 00286 if (rname) *rname = categoryobjects[categoryreadout]->name; 00287 } 00288 *rfound = found; 00289 PetscFunctionReturn(0); 00290 } 00291 00292 #undef __FUNCT__ 00293 #define __FUNCT__ "GetNextCategory" 00294 PetscErrorCode GetNextCategory(const char **rname,PetscTruth *rfound) 00295 { 00296 PetscTruth found = PETSC_FALSE; 00297 PetscFunctionBegin; 00298 categoryreadout++; 00299 while (categoryreadout<ncategories 00300 && categoryobjects[categoryreadout]->enabled!=CATCMP_ENABLE) 00301 categoryreadout++; 00302 if (categoryreadout<ncategories) { 00303 found = PETSC_TRUE; 00304 if (rname) *rname = categoryobjects[categoryreadout]->name; 00305 } 00306 *rfound = found; 00307 PetscFunctionReturn(0); 00308 } 00309 00310 #undef __FUNCT__ 00311 #define __FUNCT__ "CategoryEnableByName" 00312 /*! Mark a category as enabled/disabled. Values (CatCmpEnableMode): 00313 - 0 : enable 00314 - 1 : skip from loops 00315 - 2 : skip altogether 00316 */ 00317 PetscErrorCode CategoryEnableByName(const char *cat,int mode) 00318 { 00319 int icat; 00320 PetscFunctionBegin; 00321 for (icat=0; icat<ncategories; icat++) { 00322 if (!strcmp(cat,categoryobjects[icat]->name)) { 00323 categoryobjects[icat]->enabled = mode; 00324 } 00325 } 00326 PetscFunctionReturn(0); 00327 } 00328 00329 #undef __FUNCT__ 00330 #define __FUNCT__ "DeclareCategoryOptionFunction" 00331 /*! This function allows the module developer to give the user 00332 commandline options for control of a module. 00333 00334 See DeclareCategoryOptionFunction(),GetCategoryOptionFunction(), 00335 AnaModOptionsHandling() and section \ref optionsfile. 00336 */ 00337 PetscErrorCode DeclareCategoryOptionFunction 00338 (const char *cat,PetscErrorCode(*f)(char*)) 00339 { 00340 PetscTruth flg; categoryobject catg; PetscErrorCode ierr; 00341 PetscFunctionBegin; 00342 ierr = GetCategory(cat,&catg,&flg); CHKERRQ(ierr); 00343 if (flg) { 00344 catg->optionfunction = f; 00345 } 00346 PetscFunctionReturn(0); 00347 } 00348 00349 #undef __FUNCT__ 00350 #define __FUNCT__ "CategoryGetOptionFunction" 00351 /*! This function is called in AnaModOptionsHandling(). 00352 There is probably no reason for the user ever to call it. 00353 00354 See DeclareCategoryOptionFunction(),GetCategoryOptionFunction(), 00355 AnaModOptionsHandling() and section \ref optionsfile. 00356 */ 00357 PetscErrorCode CategoryGetOptionFunction 00358 (const char *cat,PetscErrorCode(**f)(char*)) 00359 { 00360 PetscTruth flg; categoryobject catg; PetscErrorCode ierr; 00361 PetscFunctionBegin; 00362 ierr = GetCategory(cat,&catg,&flg); CHKERRQ(ierr); 00363 if (flg) { 00364 *f = catg->optionfunction; 00365 } else *f = NULL; 00366 PetscFunctionReturn(0); 00367 } 00368