System Preprocessors
|
00001 #include <stdlib.h> 00002 #include <stdio.h> 00003 #include <string.h> 00004 #include "petsc.h" 00005 #include "sysprotransform.h" 00006 #include "syspro_impl.h" 00007 00008 struct SalsaTransformObject_ { 00009 int cookie; 00010 const char *name,*explanation; 00011 SalsaTransform transform; 00012 int n_options,alloc_options,*options; const char *option,**optionexplanation; 00013 int *options_marked; int active_option; 00014 int alloc_annotate_c; const char **annotate_c; 00015 int alloc_annotate_i,*annotate_i; 00016 int marked; 00017 PetscErrorCode(*suitabilityfunction) 00018 (NumericalProblem,void*,SuitabilityValue*); 00019 void *suitabilityctx; 00020 }; 00021 00022 #define TFINC 20 00023 00024 /*! \page transform Preprocessor definition 00025 00026 \section preprocessorclass Class definition 00027 00028 A class of preprocessors (such as scaling, preconditioning) is defined 00029 using the function NewTransform(). 00030 00031 \section preprocessorindividual Individual preprocessor definition 00032 00033 The individual preprocessors (left scaling, preprocessing by ILU) 00034 are defined in a function that is passed as the \c specific_setup 00035 argument to DeclarePreprocessor(). This function makes calls to 00036 NewTransformObject(), TransformObjectIntAnnotate() et cetera. 00037 See for instance file \ref pc.c . 00038 */ 00039 00040 #undef __FUNCT__ 00041 #define __FUNCT__ "NewTransform" 00042 /*! Define a new class of preprocessors, for instance scaling 00043 or permutation. 00044 */ 00045 PetscErrorCode NewTransform(const char *name,SalsaTransform *tf) 00046 { 00047 SalsaTransform snew; PetscErrorCode ierr; 00048 PetscFunctionBegin; 00049 ierr = PetscNew(struct SalsaTransform_,&snew); CHKERRQ(ierr); 00050 ierr = PetscMemzero(snew,sizeof(struct SalsaTransform_)); CHKERRQ(ierr); 00051 snew->name = strdup(name); snew->cookie = TRANSFORMCOOKIE; 00052 00053 snew->alloc_objects = TFINC; snew->n_objects = 0; 00054 ierr = PetscMalloc(snew->alloc_objects*sizeof(SalsaTransformObject),&snew->transformobjects); CHKERRQ(ierr); 00055 ierr = PetscMemzero(snew->transformobjects,snew->alloc_objects*sizeof(SalsaTransformObject)); CHKERRQ(ierr); 00056 ierr = PetscMalloc(snew->alloc_objects*sizeof(int),&snew->aprioriselection); CHKERRQ(ierr); 00057 ierr = PetscMemzero(snew->aprioriselection,snew->alloc_objects*sizeof(int)); CHKERRQ(ierr); 00058 00059 *tf = snew; 00060 PetscFunctionReturn(0); 00061 } 00062 00063 PetscErrorCode DeregisterTransform(SalsaTransform tf) 00064 { 00065 int i; PetscErrorCode ierr; 00066 PetscFunctionBegin; 00067 CHECKVALIDTRANSFORM(tf); 00068 for (i=0; i<tf->n_objects; i++) { 00069 ierr = FreeTransformObject(tf->transformobjects[i]); CHKERRQ(ierr); 00070 } 00071 ierr = PetscFree(tf->transformobjects); CHKERRQ(ierr); 00072 ierr = PetscFree(tf->aprioriselection); CHKERRQ(ierr); 00073 if (tf->annotations_i) {ierr = PetscFree(tf->annotations_i); CHKERRQ(ierr);} 00074 if (tf->annotations_c) {ierr = PetscFree(tf->annotations_c); CHKERRQ(ierr);} 00075 ierr = PetscFree(tf); CHKERRQ(ierr); 00076 PetscFunctionReturn(0); 00077 } 00078 00079 #undef __FUNCT__ 00080 #define __FUNCT__ "TransformGetName" 00081 PetscErrorCode TransformGetName(SalsaTransform tf,const char **name) 00082 { 00083 PetscFunctionBegin; 00084 CHECKVALIDTRANSFORM(tf); 00085 *name = tf->name; 00086 PetscFunctionReturn(0); 00087 } 00088 00089 #undef __FUNCT__ 00090 #define __FUNCT__ "TransformGetObjects" 00091 PetscErrorCode TransformGetObjects 00092 (SalsaTransform tf,int *n,SalsaTransformObject **objs) 00093 { 00094 PetscFunctionBegin; 00095 CHECKVALIDTRANSFORM(tf); 00096 if (n) *n = tf->n_objects; 00097 if (objs) *objs = tf->transformobjects; 00098 PetscFunctionReturn(0); 00099 } 00100 00101 #undef __FUNCT__ 00102 #define __FUNCT__ "NewTransformObject" 00103 /*! Create a transform object specified by \c name 00104 for the preprocessor class \c transform. 00105 The \c to parameter can be NULL if no further specifications 00106 of the object are needed, in which case this only registers the name. 00107 */ 00108 PetscErrorCode NewTransformObject 00109 (const char *transform,const char *name,SalsaTransformObject *to) 00110 { 00111 SalsaTransform tf; SalsaTransformObject snew; PetscErrorCode ierr; 00112 PetscFunctionBegin; 00113 ierr = TransformGetByName(transform,&tf); CHKERRQ(ierr); 00114 ierr = PetscNew(struct SalsaTransformObject_,&snew); CHKERRQ(ierr); 00115 ierr = PetscMemzero(snew,sizeof(struct SalsaTransformObject_)); CHKERRQ(ierr); 00116 ierr = PetscStrallocpy(name,(char**)&(snew->name)); snew->transform = tf; 00117 snew->cookie = TRANSFORMOBJECTCOOKIE; 00118 if (tf->n_objects>=tf->alloc_objects) 00119 SETERRQ(1,"Can not realloc transform objects"); 00120 tf->transformobjects[tf->n_objects++] = snew; 00121 if (to) *to = snew; 00122 PetscFunctionReturn(0); 00123 } 00124 00125 #undef __FUNCT__ 00126 #define __FUNCT__ "FreeTransformObject" 00127 PetscErrorCode FreeTransformObject(SalsaTransformObject tf) 00128 { 00129 int iopt; PetscErrorCode ierr; 00130 CHECKVALIDTRANSFORMOBJECT(tf); 00131 PetscFunctionBegin; 00132 if (tf->options) { 00133 ierr = PetscFree(tf->options); CHKERRQ(ierr); 00134 ierr = PetscFree(tf->options_marked); CHKERRQ(ierr); 00135 for (iopt=0; iopt<tf->n_options; iopt++) 00136 free((char*)tf->optionexplanation[iopt]); 00137 ierr = PetscFree(tf->optionexplanation); CHKERRQ(ierr); 00138 } 00139 if (tf->annotate_i) {ierr = PetscFree(tf->annotate_i); CHKERRQ(ierr);} 00140 if (tf->annotate_c) {ierr = PetscFree(tf->annotate_c); CHKERRQ(ierr);} 00141 ierr = PetscFree(tf->name); CHKERRQ(ierr); //free(tf->name); 00142 ierr = PetscFree(tf); CHKERRQ(ierr); 00143 PetscFunctionReturn(0); 00144 } 00145 00146 #undef __FUNCT__ 00147 #define __FUNCT__ "TransformObjectGetName" 00148 PetscErrorCode TransformObjectGetName(SalsaTransformObject tf,const char **name) 00149 { 00150 PetscFunctionBegin; 00151 CHECKVALIDTRANSFORMOBJECT(tf); 00152 *name = tf->name; 00153 PetscFunctionReturn(0); 00154 } 00155 00156 #undef __FUNCT__ 00157 #define __FUNCT__ "TransformObjectSetExplanation" 00158 PetscErrorCode TransformObjectSetExplanation 00159 (SalsaTransformObject tf,const char *x) 00160 { 00161 PetscFunctionBegin; 00162 CHECKVALIDTRANSFORMOBJECT(tf); 00163 tf->explanation = x; 00164 PetscFunctionReturn(0); 00165 } 00166 00167 /*! \page suit Suitability functions 00168 00169 The general mechanism form choosing between algorithms is that of 00170 `suitability functions'. We associate with each specific preprocessor 00171 (for instance scaling/left) a function that returns either a fuzzy truth 00172 value (0--1) or `unknown' (-1). See TransformObjectSetSuitabilityFunction(), 00173 TransformObjectGetSuitabilityFunction(). See also \ref transform about 00174 specific preprocessor construction. 00175 00176 At the start of a preprocessor invocation, 00177 in PreprocessorSpecificSetup(), the suitability functions of all choices are 00178 evaluated, and the choices are marked as unsuitable (if the evaluate 00179 is zero), or ranked otherwise. 00180 00181 The only implemented suitability functions are for the linear problem; 00182 see \ref suitc. 00183 */ 00184 00185 #undef __FUNCT__ 00186 #define __FUNCT__ "TransformObjectSetSuitabilityFunction" 00187 /*! Set the suitability function; see \ref suit. 00188 00189 See also TransformObjectGetSuitabilityFunction(). 00190 */ 00191 PetscErrorCode TransformObjectSetSuitabilityFunction 00192 (SalsaTransformObject tf,void *sctx, 00193 PetscErrorCode(*f)(NumericalProblem,void*,SuitabilityValue*)) 00194 { 00195 PetscFunctionBegin; 00196 CHECKVALIDTRANSFORMOBJECT(tf); 00197 tf->suitabilityfunction = f; 00198 tf->suitabilityctx = sctx; 00199 PetscFunctionReturn(0); 00200 } 00201 00202 #undef __FUNCT__ 00203 #define __FUNCT__ "TransformObjectGetSuitabilityFunction" 00204 /*! Retrieve the suitability function and context; see \ref suit. Both 00205 arguments can be null. 00206 00207 See also TransformObjectSetSuitabilityFunction(). 00208 */ 00209 PetscErrorCode TransformObjectGetSuitabilityFunction 00210 (SalsaTransformObject tf,void **sctx, 00211 PetscErrorCode(**f)(NumericalProblem,void*,SuitabilityValue*)) 00212 { 00213 PetscFunctionBegin; 00214 CHECKVALIDTRANSFORMOBJECT(tf); 00215 if (sctx) *sctx = tf->suitabilityctx; 00216 if (f) *f = tf->suitabilityfunction; 00217 PetscFunctionReturn(0); 00218 } 00219 00220 #undef __FUNCT__ 00221 #define __FUNCT__ "TransformObjectGetTransformName" 00222 PetscErrorCode TransformObjectGetTransformName(SalsaTransformObject tf,char **name) 00223 { 00224 PetscFunctionBegin; 00225 CHECKVALIDTRANSFORMOBJECT(tf); 00226 *name = tf->transform->name; 00227 PetscFunctionReturn(0); 00228 } 00229 00230 #undef __FUNCT__ 00231 #define __FUNCT__ "TransformObjectGetByName" 00232 PetscErrorCode TransformObjectGetByName 00233 (const char *trans,const char *name,SalsaTransformObject *tf) 00234 { 00235 SalsaTransform tt; int i; PetscErrorCode ierr; 00236 PetscFunctionBegin; 00237 ierr = TransformGetByName(trans,&tt); CHKERRQ(ierr); 00238 for (i=0; i<tt->n_objects; i++) { 00239 if (!strcmp(name,tt->transformobjects[i]->name)) { 00240 *tf = tt->transformobjects[i]; 00241 CHECKVALIDTRANSFORMOBJECT(*tf); 00242 PetscFunctionReturn(0); 00243 } 00244 } 00245 SETERRQ2(1,"Could not find transform <%s:%s>",trans,name) 00246 PetscFunctionReturn(0); 00247 } 00248 00249 #undef __FUNCT__ 00250 #define __FUNCT__ "TransformObjectsGetNames" 00251 /*! 00252 Get the names of all declared transformobjects. An array is allocated 00253 for the names, which needs to be PetscFree()'d. 00254 */ 00255 PetscErrorCode TransformObjectsGetNames(SalsaTransform tf,const char ***names) 00256 { 00257 int i; const char **thenames; PetscErrorCode ierr; 00258 PetscFunctionBegin; 00259 CHECKVALIDTRANSFORM(tf); 00260 ierr = PetscMalloc(tf->n_objects*sizeof(char*),&thenames); CHKERRQ(ierr); 00261 for (i=0; i<tf->n_objects; i++) 00262 thenames[i] = tf->transformobjects[i]->name; 00263 *names = thenames; 00264 PetscFunctionReturn(0); 00265 } 00266 00267 /* 00268 * Annotations 00269 */ 00270 #undef __FUNCT__ 00271 #define __FUNCT__ "SysProDefineCharAnnotation" 00272 /*! Define a character string annotation for a transform. The index of this 00273 annotation can be retrieved with TransformCharAnnotationGetIndex(). 00274 The actual annotation can be found with TransformItemGetCharAnnotation(). 00275 */ 00276 PetscErrorCode SysProDefineCharAnnotation(const char *transform,const char *ann) 00277 { 00278 SalsaTransform tf; int loc; PetscErrorCode ierr; 00279 PetscFunctionBegin; 00280 00281 ierr = TransformGetByName(transform,&tf); CHKERRQ(ierr); 00282 00283 /* 00284 * Initial allocation of various arrays 00285 */ 00286 if (tf->n_annotate_c==0) { 00287 /* names */ 00288 ierr = PetscMalloc 00289 (TFINC*sizeof(char*),&(tf->annotations_c)); CHKERRQ(ierr); 00290 ierr = PetscMemzero 00291 (tf->annotations_c,TFINC*sizeof(char*)); CHKERRQ(ierr); 00292 loc = 0; 00293 } else if (tf->n_annotate_c==TFINC) { 00294 SETERRQ(1,"Can not realloc annotations yet"); 00295 } else { 00296 loc = tf->n_annotate_c; 00297 } 00298 00299 /* 00300 * now setup this annotation 00301 */ 00302 tf->annotations_c[loc] = strdup(ann); 00303 00304 tf->n_annotate_c++; 00305 PetscFunctionReturn(0); 00306 } 00307 00308 #undef __FUNCT__ 00309 #define __FUNCT__ "TransformCharAnnotationGetIndex" 00310 PetscErrorCode TransformCharAnnotationGetIndex 00311 (SalsaTransform tf,const char *ann,int *idx,PetscTruth *flg) 00312 { 00313 int i; PetscTruth f; PetscErrorCode ierr; 00314 PetscFunctionBegin; 00315 CHECKVALIDTRANSFORM(tf); 00316 *idx = -1; 00317 for (i=0; i<tf->n_annotate_c; i++) { 00318 ierr = PetscStrcmp(ann,tf->annotations_c[i],&f); CHKERRQ(ierr); 00319 if (f) { 00320 *idx = i; if (flg) *flg = f; break; 00321 } 00322 } 00323 PetscFunctionReturn(0); 00324 } 00325 00326 #undef __FUNCT__ 00327 #define __FUNCT__ "SysProDefineIntAnnotation" 00328 /*! Define a integer string annotation for a transform. The index of this 00329 annotation can be retrieved with TransformIntAnnotationGetIndex(). 00330 The actual annotation can be found with TransformItemGetIntAnnotation(). 00331 */ 00332 PetscErrorCode SysProDefineIntAnnotation(const char *transform,const char *ann) 00333 { 00334 SalsaTransform tf; int loc; PetscErrorCode ierr; 00335 PetscFunctionBegin; 00336 ierr = TransformGetByName(transform,&tf); CHKERRQ(ierr); 00337 /* 00338 * Initial allocation of various arrays 00339 */ 00340 if (tf->n_annotate_i==0) { 00341 /* names */ 00342 ierr = PetscMalloc 00343 (TFINC*sizeof(char*),&(tf->annotations_i)); CHKERRQ(ierr); 00344 ierr = PetscMemzero 00345 (tf->annotations_i,TFINC*sizeof(char*)); CHKERRQ(ierr); 00346 loc = 0; 00347 } else if (tf->n_annotate_i==TFINC) { 00348 SETERRQ(1,"Can not realloc annotations yet"); 00349 } else { 00350 loc = tf->n_annotate_i; 00351 } 00352 00353 /* 00354 * now setup this annotation 00355 */ 00356 tf->annotations_i[loc] = strdup(ann); 00357 00358 tf->n_annotate_i++; 00359 PetscFunctionReturn(0); 00360 } 00361 00362 #undef __FUNCT__ 00363 #define __FUNCT__ "TransformIntAnnotationGetIndex" 00364 PetscErrorCode TransformIntAnnotationGetIndex 00365 (SalsaTransform tf,const char *ann,int *idx,PetscTruth *flg) 00366 { 00367 int i; PetscTruth f; PetscErrorCode ierr; 00368 PetscFunctionBegin; 00369 CHECKVALIDTRANSFORM(tf); 00370 *idx = -1; 00371 for (i=0; i<tf->n_annotate_i; i++) { 00372 ierr = PetscStrcmp(ann,tf->annotations_i[i],&f); CHKERRQ(ierr); 00373 if (f) { 00374 *idx = i; if (flg) *flg = f; break; 00375 } 00376 } 00377 PetscFunctionReturn(0); 00378 } 00379 00380 #undef __FUNCT__ 00381 #define __FUNCT__ "TransformObjectMark" 00382 PetscErrorCode TransformObjectMark(SalsaTransformObject tf) 00383 { 00384 int j; 00385 PetscFunctionBegin; 00386 CHECKVALIDTRANSFORMOBJECT(tf); 00387 for (j=0; j<tf->n_options; j++) 00388 tf->options_marked[j] = 1; 00389 tf->marked = 1; 00390 PetscFunctionReturn(0); 00391 } 00392 00393 #undef __FUNCT__ 00394 #define __FUNCT__ "TransformObjectUnmark" 00395 PetscErrorCode TransformObjectUnmark(SalsaTransformObject tf) 00396 { 00397 int j; 00398 PetscFunctionBegin; 00399 CHECKVALIDTRANSFORMOBJECT(tf); 00400 for (j=0; j<tf->n_options; j++) 00401 tf->options_marked[j] = 0; 00402 tf->marked = 0; 00403 PetscFunctionReturn(0); 00404 } 00405 00406 #undef __FUNCT__ 00407 #define __FUNCT__ "TransformObjectsMarkAll" 00408 PetscErrorCode TransformObjectsMarkAll(SalsaTransform tf) 00409 { 00410 int i; PetscErrorCode ierr; 00411 PetscFunctionBegin; 00412 CHECKVALIDTRANSFORM(tf); 00413 for (i=0; i<tf->n_objects; i++) { 00414 SalsaTransformObject to = tf->transformobjects[i]; 00415 CHECKVALIDTRANSFORMOBJECT(to); 00416 ierr = TransformObjectMark(to); CHKERRQ(ierr); 00417 } 00418 PetscFunctionReturn(0); 00419 } 00420 00421 #undef __FUNCT__ 00422 #define __FUNCT__ "TransformObjectsUnmarkAll" 00423 PetscErrorCode TransformObjectsUnmarkAll(SalsaTransform tf) 00424 { 00425 int i; PetscErrorCode ierr; 00426 PetscFunctionBegin; 00427 CHECKVALIDTRANSFORM(tf); 00428 for (i=0; i<tf->n_objects; i++) { 00429 SalsaTransformObject to = tf->transformobjects[i]; 00430 CHECKVALIDTRANSFORMOBJECT(to); 00431 ierr = TransformObjectUnmark(to); CHKERRQ(ierr); 00432 } 00433 PetscFunctionReturn(0); 00434 } 00435 00436 #undef __FUNCT__ 00437 #define __FUNCT__ "TransformObjectGetMark" 00438 PetscErrorCode TransformObjectGetMark(SalsaTransformObject tf,int *m) 00439 { 00440 PetscFunctionBegin; 00441 CHECKVALIDTRANSFORMOBJECT(tf); 00442 *m = tf->marked; 00443 PetscFunctionReturn(0); 00444 } 00445 00446 #undef __FUNCT__ 00447 #define __FUNCT__ "TransformGetNUnmarked" 00448 PetscErrorCode TransformGetNUnmarked(SalsaTransform tf,int *n) 00449 { 00450 int i; 00451 PetscFunctionBegin; 00452 CHECKVALIDTRANSFORM(tf); 00453 *n = 0; 00454 for (i=0; i<tf->n_objects; i++) 00455 if (!tf->transformobjects[i]->marked) (*n)++; 00456 PetscFunctionReturn(0); 00457 } 00458 00459 #undef __FUNCT__ 00460 #define __FUNCT__ "PreprocessorSaveAprioriSelection" 00461 PetscErrorCode PreprocessorSaveAprioriSelection(SystemPreprocessor pp) 00462 { 00463 SalsaTransform tf = pp->transform; int ipp; 00464 PetscFunctionBegin; 00465 for (ipp=0; ipp<tf->n_objects; ipp++) { 00466 SalsaTransformObject to = tf->transformobjects[ipp]; 00467 CHECKVALIDTRANSFORMOBJECT(to); 00468 tf->aprioriselection[ipp] = to->marked; 00469 } 00470 PetscFunctionReturn(0); 00471 } 00472 00473 #undef __FUNCT__ 00474 #define __FUNCT__ "PreprocessorApplyAprioriSelection" 00475 PetscErrorCode PreprocessorApplyAprioriSelection(SystemPreprocessor pp) 00476 { 00477 SalsaTransform tf = pp->transform; int ipp; 00478 PetscFunctionBegin; 00479 for (ipp=0; ipp<tf->n_objects; ipp++) { 00480 tf->transformobjects[ipp]->marked = tf->aprioriselection[ipp]; 00481 } 00482 PetscFunctionReturn(0); 00483 } 00484 00485 #undef __FUNCT__ 00486 #define __FUNCT__ "TransformObjectsUseOnly" 00487 /*! Mark a list of names as to be used. 00488 00489 Cases: 00490 - \c "name1,name2,name3" : all other names are marked as not to be used 00491 - \c "not,name1,name2" : all names will be used, except for the 00492 ones listed 00493 */ 00494 PetscErrorCode TransformObjectsUseOnly(SalsaTransform tf,const char *list) 00495 { 00496 char *c; PetscErrorCode ierr; PetscTruth eliminate; 00497 PetscFunctionBegin; 00498 CHECKVALIDTRANSFORM(tf); 00499 c = strtok((char*)list,","); 00500 eliminate = (PetscTruth)(c && (PetscTruth)!strcmp(c,"not")); 00501 if (eliminate) { 00502 ierr = TransformObjectsUnmarkAll(tf); CHKERRQ(ierr); 00503 c = strtok(NULL,","); 00504 } else { 00505 ierr = TransformObjectsMarkAll(tf); CHKERRQ(ierr); 00506 } 00507 while (c) { 00508 SalsaTransformObject to; 00509 ierr = TransformObjectGetByName(tf->name,c,&to); CHKERRQ(ierr); 00510 if (eliminate) { 00511 ierr = TransformObjectMark(to); CHKERRQ(ierr); 00512 } else { 00513 ierr = TransformObjectUnmark(to); CHKERRQ(ierr); 00514 } 00515 c = strtok(NULL,","); 00516 } 00517 PetscFunctionReturn(0); 00518 } 00519 00520 #undef __FUNCT__ 00521 #define __FUNCT__ "TransformGetNextUnmarkedItem" 00522 /*! Find the next unmarked value; if \c old is NULL, the first 00523 first unmarked value is given, otherwise the first one after 00524 a match with \c old. 00525 */ 00526 PetscErrorCode TransformGetNextUnmarkedItem 00527 (SalsaTransform tf,const char *old,SalsaTransformObject *snew,PetscTruth *f) 00528 { 00529 int idx; PetscTruth foundtheoldone,found; 00530 PetscFunctionBegin; 00531 CHECKVALIDTRANSFORM(tf); 00532 found = PETSC_FALSE; 00533 foundtheoldone = TRUTH(old==NULL); 00534 for (idx=0; idx<tf->n_objects; idx++) { 00535 SalsaTransformObject to = tf->transformobjects[idx]; 00536 CHECKVALIDTRANSFORMOBJECT(to); 00537 if (!foundtheoldone) { 00538 /* skip iterations until we have a match with the old name; 00539 then we take the next iteration 00540 */ 00541 foundtheoldone = (PetscTruth)!strcmp(old,to->name); 00542 continue; 00543 } 00544 found = (PetscTruth)(!to->marked); 00545 if (found) { 00546 *snew = to; 00547 if (f) *f = PETSC_TRUE; 00548 PetscFunctionReturn(0); 00549 } 00550 } 00551 if (f) *f = found; 00552 else SETERRQ(1,"Could not find, but no flag given to report"); 00553 PetscFunctionReturn(0); 00554 } 00555 00556 #define STRDUP(a) ( (a) ? strdup(a) : NULL) 00557 00558 #undef __FUNCT__ 00559 #define __FUNCT__ "TransformObjectDefineOption" 00560 PetscErrorCode TransformObjectDefineOption 00561 (SalsaTransformObject tf,const char *opt) 00562 { 00563 PetscFunctionBegin; 00564 CHECKVALIDTRANSFORMOBJECT(tf); 00565 tf->option = strdup(opt); 00566 PetscFunctionReturn(0); 00567 } 00568 00569 #undef __FUNCT__ 00570 #define __FUNCT__ "TransformObjectAddOption" 00571 PetscErrorCode TransformObjectAddOption(SalsaTransformObject tf,int v) 00572 { 00573 PetscErrorCode ierr; 00574 PetscFunctionBegin; 00575 CHECKVALIDTRANSFORMOBJECT(tf); 00576 if (!tf->options) { 00577 ierr = PetscMalloc(TFINC*sizeof(int),&tf->options); CHKERRQ(ierr); 00578 ierr = PetscMemzero(tf->options,TFINC*sizeof(int)); CHKERRQ(ierr); 00579 ierr = PetscMalloc(TFINC*sizeof(int),&(tf->options_marked)); CHKERRQ(ierr); 00580 ierr = PetscMemzero(tf->options_marked,TFINC*sizeof(int)); CHKERRQ(ierr); 00581 ierr = PetscMalloc(TFINC*sizeof(char*),&(tf->optionexplanation)); CHKERRQ(ierr); 00582 ierr = PetscMemzero(tf->optionexplanation,TFINC*sizeof(char*)); CHKERRQ(ierr); 00583 tf->n_options = 0; tf->alloc_options = TFINC; 00584 } 00585 if (tf->n_options>=tf->alloc_options) 00586 SETERRQ1(1,"No space for further options in tranform %s",tf->name); 00587 tf->options[tf->n_options++] = v; 00588 PetscFunctionReturn(0); 00589 } 00590 00591 #undef __FUNCT__ 00592 #define __FUNCT__ "TransformObjectAddOptionExplanation" 00593 PetscErrorCode TransformObjectAddOptionExplanation 00594 (SalsaTransformObject tf,int opt,const char *ex) 00595 { 00596 int i; 00597 PetscFunctionBegin; 00598 CHECKVALIDTRANSFORMOBJECT(tf); 00599 for (i=0; i<tf->n_options; i++) { 00600 if (tf->options[i]==opt) { 00601 tf->optionexplanation[i] = strdup(ex); 00602 goto out; 00603 } 00604 } 00605 out: 00606 PetscFunctionReturn(0); 00607 } 00608 00609 #undef __FUNCT__ 00610 #define __FUNCT__ "TransformItemOptionsUseOnly" 00611 PetscErrorCode TransformItemOptionsUseOnly(SalsaTransformObject tf,const char *opt) 00612 { 00613 char *c; PetscErrorCode ierr; 00614 PetscFunctionBegin; 00615 CHECKVALIDTRANSFORMOBJECT(tf); 00616 c = strtok((char*)opt,","); 00617 tf->n_options = 0; 00618 while (c) { 00619 int cv; 00620 sscanf(c,"%d",&cv); 00621 ierr = TransformObjectAddOption(tf,cv); CHKERRQ(ierr); 00622 c = strtok(NULL,","); 00623 } 00624 PetscFunctionReturn(0); 00625 } 00626 00627 #undef __FUNCT__ 00628 #define __FUNCT__ "TransformItemGetFirstOption" 00629 PetscErrorCode TransformItemGetFirstOption 00630 (const char* tf,const char *it,int *v,PetscTruth *f) 00631 { 00632 SalsaTransformObject to; PetscTruth found,flg; 00633 int i; PetscErrorCode ierr; 00634 00635 PetscFunctionBegin; 00636 ierr = TransformObjectGetByName(tf,it,&to); CHKERRQ(ierr); 00637 found = PETSC_FALSE; flg = PETSC_FALSE; 00638 for (i=0; i<to->n_options; i++) { 00639 if (!to->options_marked[i]) { 00640 flg = PETSC_TRUE; 00641 *v = to->options[i]; 00642 goto out; 00643 } 00644 } 00645 00646 out: 00647 if (f) *f = flg; 00648 PetscFunctionReturn(0); 00649 } 00650 00651 #undef __FUNCT__ 00652 #define __FUNCT__ "TransformItemGetNextOption" 00653 PetscErrorCode TransformItemGetNextOption 00654 (const char* tf,const char *it,int *v,PetscTruth *f) 00655 { 00656 SalsaTransformObject to; PetscTruth found,flg; 00657 int i; PetscErrorCode ierr; 00658 00659 PetscFunctionBegin; 00660 ierr = TransformObjectGetByName(tf,it,&to); CHKERRQ(ierr); 00661 found = PETSC_FALSE; flg = PETSC_FALSE; 00662 for (i=0; i<to->n_options; i++) { 00663 if (found && !to->options_marked[i]) { 00664 flg = PETSC_TRUE; 00665 *v = to->options[i]; 00666 goto out; 00667 } 00668 if (to->options[i]==*v) found = PETSC_TRUE; 00669 } 00670 00671 out: 00672 if (f) *f = flg; 00673 PetscFunctionReturn(0); 00674 } 00675 00676 #undef __FUNCT__ 00677 #define __FUNCT__ "TransformItemOptionMark" 00678 PetscErrorCode TransformItemOptionMark(SalsaTransform tf,const char *it,int o) 00679 { 00680 SalsaTransformObject to; int i; PetscErrorCode ierr; 00681 PetscFunctionBegin; 00682 CHECKVALIDTRANSFORM(tf); 00683 ierr = TransformObjectGetByName(tf->name,it,&to); CHKERRQ(ierr); 00684 to->marked = 0; 00685 for (i=0; i<to->n_options; i++) 00686 if (to->options[i]==o) to->options_marked[i] = 1; 00687 00688 PetscFunctionReturn(0); 00689 } 00690 00691 #undef __FUNCT__ 00692 #define __FUNCT__ "TransformObjectCharAnnotate" 00693 PetscErrorCode TransformObjectCharAnnotate 00694 (SalsaTransformObject tf,const char *an,const char *v) 00695 { 00696 int idx; PetscTruth f; PetscErrorCode ierr; 00697 PetscFunctionBegin; 00698 CHECKVALIDTRANSFORMOBJECT(tf); 00699 if (!tf->annotate_c) { 00700 ierr = PetscMalloc(TFINC*sizeof(char*),&tf->annotate_c); CHKERRQ(ierr); 00701 ierr = PetscMemzero(tf->annotate_c,TFINC*sizeof(char*)); CHKERRQ(ierr); 00702 tf->alloc_annotate_c = TFINC; 00703 } 00704 ierr = TransformCharAnnotationGetIndex 00705 (tf->transform,an,&idx,&f); CHKERRQ(ierr); 00706 if (!f) SETERRQ1(1,"Could not find annotation %s",an); 00707 if (idx>=tf->alloc_annotate_c) 00708 SETERRQ1(1,"Char annotate index too large: %d.",idx); 00709 tf->annotate_c[idx] = v; 00710 PetscFunctionReturn(0); 00711 } 00712 00713 #undef __FUNCT__ 00714 #define __FUNCT__ "TransformObjectIntAnnotate" 00715 PetscErrorCode TransformObjectIntAnnotate 00716 (SalsaTransformObject tf,const char *an,int v) 00717 { 00718 int idx; PetscTruth f; PetscErrorCode ierr; 00719 PetscFunctionBegin; 00720 CHECKVALIDTRANSFORMOBJECT(tf); 00721 if (!tf->annotate_i) { 00722 ierr = PetscMalloc(TFINC*sizeof(int),&tf->annotate_i); CHKERRQ(ierr); 00723 ierr = PetscMemzero(tf->annotate_i,TFINC*sizeof(int)); CHKERRQ(ierr); 00724 tf->alloc_annotate_i = TFINC; 00725 } 00726 ierr = TransformIntAnnotationGetIndex 00727 (tf->transform,an,&idx,&f); CHKERRQ(ierr); 00728 if (!f) SETERRQ1(1,"Could not find annotation %s",an); 00729 if (idx>=tf->alloc_annotate_i) 00730 SETERRQ1(1,"Int annotate index too large: %d.",idx); 00731 tf->annotate_i[idx] = v; 00732 PetscFunctionReturn(0); 00733 } 00734 00735 #undef __FUNCT__ 00736 #define __FUNCT__ "TransformObjectGetIntAnnotation" 00737 PetscErrorCode TransformObjectGetIntAnnotation 00738 (SalsaTransformObject tf,const char *an,int *v,PetscTruth *f) 00739 { 00740 SalsaTransform tt = tf->transform; int ian; 00741 PetscFunctionBegin; 00742 CHECKVALIDTRANSFORMOBJECT(tf); 00743 *f = PETSC_FALSE; 00744 for (ian=0; ian<tt->n_annotate_i; ian++) { 00745 if (!strcmp(tt->annotations_i[ian],an)) { 00746 *f = TRUTH(tf->annotate_i!=NULL); 00747 if (*f) *v = tf->annotate_i[ian]; 00748 PetscFunctionReturn(0); 00749 } 00750 } 00751 PetscFunctionReturn(0); 00752 } 00753 00754 #undef __FUNCT__ 00755 #define __FUNCT__ "TransformReportTeXTable" 00756 PetscErrorCode TransformReportTeXTable(SalsaTransform tf,FILE *f) 00757 { 00758 int i,j; 00759 PetscFunctionBegin; 00760 00761 for (i=0; i<tf->n_objects; i++) { 00762 SalsaTransformObject to = tf->transformobjects[i]; 00763 fprintf(f,"%s&%s",to->name,to->explanation); 00764 if (to->n_options>0) { 00765 /* 00766 fprintf(f,"&%s&",to->optionexplanation); 00767 */ 00768 for (j=0; j<to->n_options; j++) { 00769 fprintf(f,"%d,",to->options[j]); 00770 } 00771 } else fprintf(f,"&&"); 00772 fprintf(f,"\\\\\n"); 00773 } 00774 PetscFunctionReturn(0); 00775 } 00776 00777 #undef __FUNCT__ 00778 #define __FUNCT__ "TransformReportEnabled" 00779 PetscErrorCode TransformReportEnabled(SalsaTransform tf,const char **rs) 00780 { 00781 const char *s,**names; int i; size_t l; PetscErrorCode ierr; 00782 PetscFunctionBegin; 00783 00784 ierr = PetscMalloc(1000*sizeof(char),&s); CHKERRQ(ierr); 00785 ierr = PetscMemzero((char*)s,1000*sizeof(char)); CHKERRQ(ierr); 00786 ierr = TransformObjectsGetNames(tf,&names); CHKERRQ(ierr); 00787 for (i=0; i<tf->n_objects; i++) { 00788 int mark; 00789 ierr = TransformObjectGetMark(tf->transformobjects[i],&mark); CHKERRQ(ierr); 00790 if (!mark) { 00791 ierr = PetscStrlen(s,&l); CHKERRQ(ierr); 00792 if (l) {sprintf((char*)s+l," "); l++;} sprintf((char*)s+l,"%s",names[i]); 00793 } 00794 } 00795 ierr = PetscFree(names); CHKERRQ(ierr); 00796 *rs = s; 00797 PetscFunctionReturn(0); 00798 } 00799 00800 #undef __FUNCT__ 00801 #define __FUNCT__ "TransformItemDescribeShort" 00802 PetscErrorCode TransformItemDescribeShort(SalsaTransform tf,char *it,int opt,char **s) 00803 { 00804 SalsaTransformObject to; char *ss; size_t l; PetscErrorCode ierr; 00805 PetscFunctionBegin; 00806 00807 ierr = TransformObjectGetByName(tf->name,it,&to); CHKERRQ(ierr); 00808 ierr = PetscMalloc(200*sizeof(char),&ss); CHKERRQ(ierr); 00809 sprintf(ss,"%s",to->name); CHKERRQ(ierr); 00810 ierr = PetscStrlen(ss,&l); CHKERRQ(ierr); 00811 if (to->n_options) { 00812 sprintf(ss+l,"(%d)",opt); 00813 ierr = PetscStrlen(ss,&l); CHKERRQ(ierr); 00814 } 00815 *s = ss; 00816 PetscFunctionReturn(0); 00817 } 00818 00819 #undef __FUNCT__ 00820 #define __FUNCT__ "TransformItemDescribeLong" 00821 PetscErrorCode TransformItemDescribeLong(SalsaTransform tf,char *it,int opt,char **s) 00822 { 00823 SalsaTransformObject to; 00824 char *ss; size_t l; PetscErrorCode ierr; 00825 00826 PetscFunctionBegin; 00827 CHECKVALIDTRANSFORM(tf); 00828 ierr = TransformObjectGetByName(tf->name,it,&to); CHKERRQ(ierr); 00829 ierr = PetscMalloc(200*sizeof(char),&ss); CHKERRQ(ierr); 00830 sprintf(ss,"%s",to->explanation); CHKERRQ(ierr); 00831 ierr = PetscStrlen(ss,&l); CHKERRQ(ierr); 00832 #if 0 00833 if (to->options[idx]) { 00834 sprintf(ss+l,"; %s",tf->options[idx]); 00835 ierr = PetscStrlen(ss,&l); CHKERRQ(ierr); 00836 } 00837 if (tf->noptions[idx]) { 00838 ierr = TransformItemGetOptionIndex(tf,idx,opt,&odx); CHKERRQ(ierr); 00839 if (odx>=0) 00840 sprintf(ss+l," %s",tf->options_texts[idx][odx]); 00841 else 00842 sprintf(ss+l,"(%d)",opt); 00843 ierr = PetscStrlen(ss,&l); CHKERRQ(ierr); 00844 } 00845 #endif 00846 *s = ss; 00847 PetscFunctionReturn(0); 00848 } 00849 00850 #undef __FUNCT__ 00851 #define __FUNCT__ "TransformSetUserChoices" 00852 /*! Declare that the user has ordained which choice(s) to take for a 00853 specific transform. The values of these choices are implicitly given 00854 by disabling some transforms. 00855 00856 See also TransformGetUserChoices(), TransformObjectsUseOnly(). 00857 */ 00858 PetscErrorCode TransformSetUserChoices(SalsaTransform tf,PetscTruth ch) 00859 { 00860 PetscFunctionBegin; 00861 CHECKVALIDTRANSFORM(tf); 00862 tf->userchoices = ch; 00863 PetscFunctionReturn(0); 00864 } 00865 00866 #undef __FUNCT__ 00867 #define __FUNCT__ "TransformGetUserChoices" 00868 /*! Query whether the user has ordained which choice(s) to take for a 00869 specific transform. The values of these choices are implicitly given 00870 by disabling some transforms. 00871 00872 See also TransformSetUserChoices(), TransformObjectsUseOnly(). 00873 */ 00874 PetscErrorCode TransformGetUserChoices(SalsaTransform tf,PetscTruth *ch) 00875 { 00876 PetscFunctionBegin; 00877 CHECKVALIDTRANSFORM(tf); 00878 *ch = tf->userchoices; 00879 PetscFunctionReturn(0); 00880 } 00881 00882 #undef __FUNCT__ 00883 #define __FUNCT__ "SetSuitabilityContextTester" 00884 PetscErrorCode SetSuitabilityContextTester(SalsaTransform tf,PetscErrorCode(*f)(void*)) 00885 { 00886 PetscFunctionBegin; 00887 CHECKVALIDTRANSFORM(tf); 00888 tf->suitabilityctxtester = f; 00889 PetscFunctionReturn(0); 00890 } 00891 00892 #undef __FUNCT__ 00893 #define __FUNCT__ "TestSuitabilityContext" 00894 PetscErrorCode TestSuitabilityContext(SalsaTransform tf,void *ctx) 00895 { 00896 PetscErrorCode ierr; 00897 PetscFunctionBegin; 00898 CHECKVALIDTRANSFORM0(tf); 00899 if (tf->suitabilityctxtester) { 00900 ierr = (tf->suitabilityctxtester)(ctx); CHKERRQ(ierr); 00901 } 00902 PetscFunctionReturn(0); 00903 } 00904 00905 #undef __FUNCT__ 00906 #define __FUNCT__ "SalsaTransformIntegrityTest" 00907 PetscErrorCode SalsaTransformIntegrityTest(SalsaTransform tf) 00908 { 00909 int i; PetscErrorCode ierr; 00910 PetscFunctionBegin; 00911 if (!tf || !tf->suitabilityctxtester) PetscFunctionReturn(0); 00912 for (i=0; i<tf->n_objects; i++) { 00913 SalsaTransformObject to = tf->transformobjects[i]; void *sctx; 00914 ierr = TransformObjectGetSuitabilityFunction 00915 (to,&sctx,PETSC_NULL); CHKERRQ(ierr); 00916 if (sctx) { 00917 ierr = TestSuitabilityContext(tf,sctx); CHKERRQ(ierr); 00918 } 00919 } 00920 PetscFunctionReturn(0); 00921 }