1 2 #include <petscao.h> 3 #include <petsc/private/dmlabelimpl.h> 4 #include <petsc/private/dmfieldimpl.h> 5 #include <petsc/private/dmpleximpl.h> 6 #include <petsc/private/dmplextransformimpl.h> 7 #include <petsc/private/petscdsimpl.h> 8 #include <petsc/private/petscfeimpl.h> 9 #include <petsc/private/petscfvimpl.h> 10 #include <petsc/private/dmswarmimpl.h> 11 #include <petsc/private/dmnetworkimpl.h> 12 13 static PetscBool DMPackageInitialized = PETSC_FALSE; 14 /*@C 15 DMFinalizePackage - This function finalizes everything in the DM package. It is called 16 from PetscFinalize(). 17 18 Level: developer 19 20 .seealso: `PetscInitialize()` 21 @*/ 22 PetscErrorCode DMFinalizePackage(void) 23 { 24 PetscFunctionBegin; 25 PetscCall(PetscFunctionListDestroy(&DMList)); 26 DMPackageInitialized = PETSC_FALSE; 27 DMRegisterAllCalled = PETSC_FALSE; 28 PetscFunctionReturn(0); 29 } 30 31 #if defined(PETSC_HAVE_HYPRE) 32 PETSC_EXTERN PetscErrorCode MatCreate_HYPREStruct(Mat); 33 PETSC_EXTERN PetscErrorCode MatCreate_HYPRESStruct(Mat); 34 #endif 35 36 /*@C 37 DMInitializePackage - This function initializes everything in the DM package. It is called 38 from PetscDLLibraryRegister_petscdm() when using dynamic libraries, and on the first call to AOCreate() 39 or DMDACreate() when using shared or static libraries. 40 41 Level: developer 42 43 .seealso: `PetscInitialize()` 44 @*/ 45 PetscErrorCode DMInitializePackage(void) 46 { 47 char logList[256]; 48 PetscBool opt,pkg; 49 50 PetscFunctionBegin; 51 if (DMPackageInitialized) PetscFunctionReturn(0); 52 DMPackageInitialized = PETSC_TRUE; 53 54 /* Register Classes */ 55 PetscCall(PetscClassIdRegister("Distributed Mesh",&DM_CLASSID)); 56 PetscCall(PetscClassIdRegister("DM Label",&DMLABEL_CLASSID)); 57 PetscCall(PetscClassIdRegister("Quadrature",&PETSCQUADRATURE_CLASSID)); 58 PetscCall(PetscClassIdRegister("Mesh Transform",&DMPLEXTRANSFORM_CLASSID)); 59 60 #if defined(PETSC_HAVE_HYPRE) 61 PetscCall(MatRegister(MATHYPRESTRUCT, MatCreate_HYPREStruct)); 62 PetscCall(MatRegister(MATHYPRESSTRUCT, MatCreate_HYPRESStruct)); 63 #endif 64 PetscCall(PetscSectionSymRegister(PETSCSECTIONSYMLABEL,PetscSectionSymCreate_Label)); 65 66 /* Register Constructors */ 67 PetscCall(DMRegisterAll()); 68 /* Register Events */ 69 PetscCall(PetscLogEventRegister("DMConvert", DM_CLASSID,&DM_Convert)); 70 PetscCall(PetscLogEventRegister("DMGlobalToLocal", DM_CLASSID,&DM_GlobalToLocal)); 71 PetscCall(PetscLogEventRegister("DMLocalToGlobal", DM_CLASSID,&DM_LocalToGlobal)); 72 PetscCall(PetscLogEventRegister("DMLocatePoints", DM_CLASSID,&DM_LocatePoints)); 73 PetscCall(PetscLogEventRegister("DMCoarsen", DM_CLASSID,&DM_Coarsen)); 74 PetscCall(PetscLogEventRegister("DMRefine", DM_CLASSID,&DM_Refine)); 75 PetscCall(PetscLogEventRegister("DMCreateInterp", DM_CLASSID,&DM_CreateInterpolation)); 76 PetscCall(PetscLogEventRegister("DMCreateRestrict", DM_CLASSID,&DM_CreateRestriction)); 77 PetscCall(PetscLogEventRegister("DMCreateInject", DM_CLASSID,&DM_CreateInjection)); 78 PetscCall(PetscLogEventRegister("DMCreateMat", DM_CLASSID,&DM_CreateMatrix)); 79 PetscCall(PetscLogEventRegister("DMCreateMassMat", DM_CLASSID,&DM_CreateMassMatrix)); 80 PetscCall(PetscLogEventRegister("DMLoad", DM_CLASSID,&DM_Load)); 81 PetscCall(PetscLogEventRegister("DMAdaptInterp", DM_CLASSID,&DM_AdaptInterpolator)); 82 83 PetscCall(PetscLogEventRegister("DMPlexBuFrCeLi", DM_CLASSID,&DMPLEX_BuildFromCellList)); 84 PetscCall(PetscLogEventRegister("DMPlexBuCoFrCeLi", DM_CLASSID,&DMPLEX_BuildCoordinatesFromCellList)); 85 PetscCall(PetscLogEventRegister("DMPlexCreateGmsh", DM_CLASSID,&DMPLEX_CreateGmsh)); 86 PetscCall(PetscLogEventRegister("DMPlexCrFromFile", DM_CLASSID,&DMPLEX_CreateFromFile)); 87 PetscCall(PetscLogEventRegister("Mesh Partition", DM_CLASSID,&DMPLEX_Partition)); 88 PetscCall(PetscLogEventRegister("Mesh Migration", DM_CLASSID,&DMPLEX_Migrate)); 89 PetscCall(PetscLogEventRegister("DMPlexPartSelf", DM_CLASSID,&DMPLEX_PartSelf)); 90 PetscCall(PetscLogEventRegister("DMPlexPartLblInv", DM_CLASSID,&DMPLEX_PartLabelInvert)); 91 PetscCall(PetscLogEventRegister("DMPlexPartLblSF", DM_CLASSID,&DMPLEX_PartLabelCreateSF)); 92 PetscCall(PetscLogEventRegister("DMPlexPartStrtSF", DM_CLASSID,&DMPLEX_PartStratSF)); 93 PetscCall(PetscLogEventRegister("DMPlexPointSF", DM_CLASSID,&DMPLEX_CreatePointSF)); 94 PetscCall(PetscLogEventRegister("DMPlexInterp", DM_CLASSID,&DMPLEX_Interpolate)); 95 PetscCall(PetscLogEventRegister("DMPlexDistribute", DM_CLASSID,&DMPLEX_Distribute)); 96 PetscCall(PetscLogEventRegister("DMPlexDistCones", DM_CLASSID,&DMPLEX_DistributeCones)); 97 PetscCall(PetscLogEventRegister("DMPlexDistLabels", DM_CLASSID,&DMPLEX_DistributeLabels)); 98 PetscCall(PetscLogEventRegister("DMPlexDistSF", DM_CLASSID,&DMPLEX_DistributeSF)); 99 PetscCall(PetscLogEventRegister("DMPlexDistOvrlp", DM_CLASSID,&DMPLEX_DistributeOverlap)); 100 PetscCall(PetscLogEventRegister("DMPlexDistField", DM_CLASSID,&DMPLEX_DistributeField)); 101 PetscCall(PetscLogEventRegister("DMPlexDistData", DM_CLASSID,&DMPLEX_DistributeData)); 102 PetscCall(PetscLogEventRegister("DMPlexInterpSF", DM_CLASSID,&DMPLEX_InterpolateSF)); 103 PetscCall(PetscLogEventRegister("DMPlexGToNBegin", DM_CLASSID,&DMPLEX_GlobalToNaturalBegin)); 104 PetscCall(PetscLogEventRegister("DMPlexGToNEnd", DM_CLASSID,&DMPLEX_GlobalToNaturalEnd)); 105 PetscCall(PetscLogEventRegister("DMPlexNToGBegin", DM_CLASSID,&DMPLEX_NaturalToGlobalBegin)); 106 PetscCall(PetscLogEventRegister("DMPlexNToGEnd", DM_CLASSID,&DMPLEX_NaturalToGlobalEnd)); 107 PetscCall(PetscLogEventRegister("DMPlexStratify", DM_CLASSID,&DMPLEX_Stratify)); 108 PetscCall(PetscLogEventRegister("DMPlexSymmetrize", DM_CLASSID,&DMPLEX_Symmetrize)); 109 PetscCall(PetscLogEventRegister("DMPlexPrealloc", DM_CLASSID,&DMPLEX_Preallocate)); 110 PetscCall(PetscLogEventRegister("DMPlexResidualFE", DM_CLASSID,&DMPLEX_ResidualFEM)); 111 PetscCall(PetscLogEventRegister("DMPlexJacobianFE", DM_CLASSID,&DMPLEX_JacobianFEM)); 112 PetscCall(PetscLogEventRegister("DMPlexInterpFE", DM_CLASSID,&DMPLEX_InterpolatorFEM)); 113 PetscCall(PetscLogEventRegister("DMPlexInjectorFE", DM_CLASSID,&DMPLEX_InjectorFEM)); 114 PetscCall(PetscLogEventRegister("DMPlexIntegralFEM", DM_CLASSID,&DMPLEX_IntegralFEM)); 115 PetscCall(PetscLogEventRegister("DMPlexRebalance", DM_CLASSID,&DMPLEX_RebalanceSharedPoints)); 116 PetscCall(PetscLogEventRegister("DMPlexLocatePoints", DM_CLASSID,&DMPLEX_LocatePoints)); 117 PetscCall(PetscLogEventRegister("DMPlexTopologyView", DM_CLASSID,&DMPLEX_TopologyView)); 118 PetscCall(PetscLogEventRegister("DMPlexLabelsView", DM_CLASSID,&DMPLEX_LabelsView)); 119 PetscCall(PetscLogEventRegister("DMPlexCoordinatesView", DM_CLASSID,&DMPLEX_CoordinatesView)); 120 PetscCall(PetscLogEventRegister("DMPlexSectionView", DM_CLASSID,&DMPLEX_SectionView)); 121 PetscCall(PetscLogEventRegister("DMPlexGlobalVectorView", DM_CLASSID,&DMPLEX_GlobalVectorView)); 122 PetscCall(PetscLogEventRegister("DMPlexLocalVectorView", DM_CLASSID,&DMPLEX_LocalVectorView)); 123 PetscCall(PetscLogEventRegister("DMPlexTopologyLoad", DM_CLASSID,&DMPLEX_TopologyLoad)); 124 PetscCall(PetscLogEventRegister("DMPlexLabelsLoad", DM_CLASSID,&DMPLEX_LabelsLoad)); 125 PetscCall(PetscLogEventRegister("DMPlexCoordinatesLoad", DM_CLASSID,&DMPLEX_CoordinatesLoad)); 126 PetscCall(PetscLogEventRegister("DMPlexSectionLoad", DM_CLASSID,&DMPLEX_SectionLoad)); 127 PetscCall(PetscLogEventRegister("DMPlexGlobalVectorLoad", DM_CLASSID,&DMPLEX_GlobalVectorLoad)); 128 PetscCall(PetscLogEventRegister("DMPlexLocalVectorLoad", DM_CLASSID,&DMPLEX_LocalVectorLoad)); 129 PetscCall(PetscLogEventRegister("DMPlexMetricEnforceSPD", DM_CLASSID,&DMPLEX_MetricEnforceSPD)); 130 PetscCall(PetscLogEventRegister("DMPlexMetricNormalize", DM_CLASSID,&DMPLEX_MetricNormalize)); 131 PetscCall(PetscLogEventRegister("DMPlexMetricAverage", DM_CLASSID,&DMPLEX_MetricAverage)); 132 PetscCall(PetscLogEventRegister("DMPlexMetricIntersect", DM_CLASSID,&DMPLEX_MetricIntersection)); 133 134 PetscCall(PetscLogEventRegister("RebalBuildGraph", DM_CLASSID,&DMPLEX_RebalBuildGraph)); 135 PetscCall(PetscLogEventRegister("RebalGatherGraph", DM_CLASSID,&DMPLEX_RebalGatherGraph)); 136 PetscCall(PetscLogEventRegister("RebalPartition", DM_CLASSID,&DMPLEX_RebalPartition)); 137 PetscCall(PetscLogEventRegister("RebalScatterPart", DM_CLASSID,&DMPLEX_RebalScatterPart)); 138 PetscCall(PetscLogEventRegister("RebalRewriteSF", DM_CLASSID,&DMPLEX_RebalRewriteSF)); 139 140 PetscCall(PetscLogEventRegister("DMSwarmMigrate", DM_CLASSID,&DMSWARM_Migrate)); 141 PetscCall(PetscLogEventRegister("DMSwarmDETSetup", DM_CLASSID,&DMSWARM_DataExchangerTopologySetup)); 142 PetscCall(PetscLogEventRegister("DMSwarmDExBegin", DM_CLASSID,&DMSWARM_DataExchangerBegin)); 143 PetscCall(PetscLogEventRegister("DMSwarmDExEnd", DM_CLASSID,&DMSWARM_DataExchangerEnd)); 144 PetscCall(PetscLogEventRegister("DMSwarmDESendCnt", DM_CLASSID,&DMSWARM_DataExchangerSendCount)); 145 PetscCall(PetscLogEventRegister("DMSwarmDEPack", DM_CLASSID,&DMSWARM_DataExchangerPack)); 146 PetscCall(PetscLogEventRegister("DMSwarmAddPnts", DM_CLASSID,&DMSWARM_AddPoints)); 147 PetscCall(PetscLogEventRegister("DMSwarmRmvPnts", DM_CLASSID,&DMSWARM_RemovePoints)); 148 PetscCall(PetscLogEventRegister("DMSwarmSort", DM_CLASSID,&DMSWARM_Sort)); 149 PetscCall(PetscLogEventRegister("DMSwarmSetSizes", DM_CLASSID,&DMSWARM_SetSizes)); 150 151 PetscCall(PetscLogEventRegister("DMNtLayoutSetUp", DM_CLASSID,&DMNetwork_LayoutSetUp)); 152 PetscCall(PetscLogEventRegister("DMNtSetUp", DM_CLASSID,&DMNetwork_SetUpNetwork)); 153 PetscCall(PetscLogEventRegister("DMNtDistribute", DM_CLASSID,&DMNetwork_Distribute)); 154 /* Process Info */ 155 { 156 PetscClassId classids[1]; 157 158 classids[0] = DM_CLASSID; 159 PetscCall(PetscInfoProcessClass("dm", 1, classids)); 160 } 161 162 /* Process summary exclusions */ 163 PetscCall(PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt)); 164 if (opt) { 165 PetscCall(PetscStrInList("dm",logList,',',&pkg)); 166 if (pkg) PetscCall(PetscLogEventExcludeClass(DM_CLASSID)); 167 } 168 169 PetscCall(DMGenerateRegisterAll()); 170 PetscCall(PetscRegisterFinalize(DMGenerateRegisterDestroy)); 171 PetscCall(DMPlexTransformRegisterAll()); 172 PetscCall(PetscRegisterFinalize(DMPlexTransformRegisterDestroy)); 173 PetscCall(PetscRegisterFinalize(DMFinalizePackage)); 174 PetscFunctionReturn(0); 175 } 176 #include <petscfe.h> 177 178 static PetscBool PetscFEPackageInitialized = PETSC_FALSE; 179 /*@C 180 PetscFEFinalizePackage - This function finalizes everything in the PetscFE package. It is called 181 from PetscFinalize(). 182 183 Level: developer 184 185 .seealso: `PetscInitialize()` 186 @*/ 187 PetscErrorCode PetscFEFinalizePackage(void) 188 { 189 PetscFunctionBegin; 190 PetscCall(PetscFunctionListDestroy(&PetscSpaceList)); 191 PetscCall(PetscFunctionListDestroy(&PetscDualSpaceList)); 192 PetscCall(PetscFunctionListDestroy(&PetscFEList)); 193 PetscFEPackageInitialized = PETSC_FALSE; 194 PetscSpaceRegisterAllCalled = PETSC_FALSE; 195 PetscDualSpaceRegisterAllCalled = PETSC_FALSE; 196 PetscFERegisterAllCalled = PETSC_FALSE; 197 PetscFunctionReturn(0); 198 } 199 200 /*@C 201 PetscFEInitializePackage - This function initializes everything in the FE package. It is called 202 from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PetscSpaceCreate() 203 when using static libraries. 204 205 Level: developer 206 207 .seealso: `PetscInitialize()` 208 @*/ 209 PetscErrorCode PetscFEInitializePackage(void) 210 { 211 char logList[256]; 212 PetscBool opt,pkg; 213 214 PetscFunctionBegin; 215 if (PetscFEPackageInitialized) PetscFunctionReturn(0); 216 PetscFEPackageInitialized = PETSC_TRUE; 217 218 /* Register Classes */ 219 PetscCall(PetscClassIdRegister("Linear Space", &PETSCSPACE_CLASSID)); 220 PetscCall(PetscClassIdRegister("Dual Space", &PETSCDUALSPACE_CLASSID)); 221 PetscCall(PetscClassIdRegister("FE Space", &PETSCFE_CLASSID)); 222 /* Register Constructors */ 223 PetscCall(PetscSpaceRegisterAll()); 224 PetscCall(PetscDualSpaceRegisterAll()); 225 PetscCall(PetscFERegisterAll()); 226 /* Register Events */ 227 PetscCall(PetscLogEventRegister("DualSpaceSetUp", PETSCDUALSPACE_CLASSID, &PETSCDUALSPACE_SetUp)); 228 PetscCall(PetscLogEventRegister("FESetUp", PETSCFE_CLASSID, &PETSCFE_SetUp)); 229 /* Process Info */ 230 { 231 PetscClassId classids[3]; 232 233 classids[0] = PETSCFE_CLASSID; 234 classids[1] = PETSCSPACE_CLASSID; 235 classids[2] = PETSCDUALSPACE_CLASSID; 236 PetscCall(PetscInfoProcessClass("fe", 1, classids)); 237 PetscCall(PetscInfoProcessClass("space", 1, &classids[1])); 238 PetscCall(PetscInfoProcessClass("dualspace", 1, &classids[2])); 239 } 240 /* Process summary exclusions */ 241 PetscCall(PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt)); 242 if (opt) { 243 PetscCall(PetscStrInList("fe",logList,',',&pkg)); 244 if (pkg) PetscCall(PetscLogEventExcludeClass(PETSCFE_CLASSID)); 245 } 246 /* Register package finalizer */ 247 PetscCall(PetscRegisterFinalize(PetscFEFinalizePackage)); 248 PetscFunctionReturn(0); 249 } 250 #include <petscfv.h> 251 252 static PetscBool PetscFVPackageInitialized = PETSC_FALSE; 253 /*@C 254 PetscFVFinalizePackage - This function finalizes everything in the PetscFV package. It is called 255 from PetscFinalize(). 256 257 Level: developer 258 259 .seealso: `PetscInitialize()` 260 @*/ 261 PetscErrorCode PetscFVFinalizePackage(void) 262 { 263 PetscFunctionBegin; 264 PetscCall(PetscFunctionListDestroy(&PetscLimiterList)); 265 PetscCall(PetscFunctionListDestroy(&PetscFVList)); 266 PetscFVPackageInitialized = PETSC_FALSE; 267 PetscFVRegisterAllCalled = PETSC_FALSE; 268 PetscLimiterRegisterAllCalled = PETSC_FALSE; 269 PetscFunctionReturn(0); 270 } 271 272 /*@C 273 PetscFVInitializePackage - This function initializes everything in the FV package. It is called 274 from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PetscFVCreate() 275 when using static libraries. 276 277 Level: developer 278 279 .seealso: `PetscInitialize()` 280 @*/ 281 PetscErrorCode PetscFVInitializePackage(void) 282 { 283 char logList[256]; 284 PetscBool opt,pkg; 285 286 PetscFunctionBegin; 287 if (PetscFVPackageInitialized) PetscFunctionReturn(0); 288 PetscFVPackageInitialized = PETSC_TRUE; 289 290 /* Register Classes */ 291 PetscCall(PetscClassIdRegister("FV Space", &PETSCFV_CLASSID)); 292 PetscCall(PetscClassIdRegister("Limiter", &PETSCLIMITER_CLASSID)); 293 /* Register Constructors */ 294 PetscCall(PetscFVRegisterAll()); 295 /* Register Events */ 296 /* Process Info */ 297 { 298 PetscClassId classids[2]; 299 300 classids[0] = PETSCFV_CLASSID; 301 classids[1] = PETSCLIMITER_CLASSID; 302 PetscCall(PetscInfoProcessClass("fv", 1, classids)); 303 PetscCall(PetscInfoProcessClass("limiter", 1, &classids[1])); 304 } 305 /* Process summary exclusions */ 306 PetscCall(PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt)); 307 if (opt) { 308 PetscCall(PetscStrInList("fv",logList,',',&pkg)); 309 if (pkg) PetscCall(PetscLogEventExcludeClass(PETSCFV_CLASSID)); 310 PetscCall(PetscStrInList("limiter",logList,',',&pkg)); 311 if (pkg) PetscCall(PetscLogEventExcludeClass(PETSCLIMITER_CLASSID)); 312 } 313 /* Register package finalizer */ 314 PetscCall(PetscRegisterFinalize(PetscFVFinalizePackage)); 315 PetscFunctionReturn(0); 316 } 317 #include <petscds.h> 318 319 static PetscBool PetscDSPackageInitialized = PETSC_FALSE; 320 /*@C 321 PetscDSFinalizePackage - This function finalizes everything in the PetscDS package. It is called 322 from PetscFinalize(). 323 324 Level: developer 325 326 .seealso: `PetscInitialize()` 327 @*/ 328 PetscErrorCode PetscDSFinalizePackage(void) 329 { 330 PetscFunctionBegin; 331 PetscCall(PetscFunctionListDestroy(&PetscDSList)); 332 PetscDSPackageInitialized = PETSC_FALSE; 333 PetscDSRegisterAllCalled = PETSC_FALSE; 334 PetscFunctionReturn(0); 335 } 336 337 /*@C 338 PetscDSInitializePackage - This function initializes everything in the DS package. It is called 339 from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PetscDSCreate() 340 when using static libraries. 341 342 Level: developer 343 344 .seealso: `PetscInitialize()` 345 @*/ 346 PetscErrorCode PetscDSInitializePackage(void) 347 { 348 char logList[256]; 349 PetscBool opt,pkg; 350 351 PetscFunctionBegin; 352 if (PetscDSPackageInitialized) PetscFunctionReturn(0); 353 PetscDSPackageInitialized = PETSC_TRUE; 354 355 /* Register Classes */ 356 PetscCall(PetscClassIdRegister("Discrete System", &PETSCDS_CLASSID)); 357 PetscCall(PetscClassIdRegister("Weak Form", &PETSCWEAKFORM_CLASSID)); 358 /* Register Constructors */ 359 PetscCall(PetscDSRegisterAll()); 360 /* Register Events */ 361 /* Process Info */ 362 { 363 PetscClassId classids[1]; 364 365 classids[0] = PETSCDS_CLASSID; 366 PetscCall(PetscInfoProcessClass("ds", 1, classids)); 367 } 368 /* Process summary exclusions */ 369 PetscCall(PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt)); 370 if (opt) { 371 PetscCall(PetscStrInList("ds",logList,',',&pkg)); 372 if (pkg) PetscCall(PetscLogEventExcludeClass(PETSCDS_CLASSID)); 373 } 374 /* Register package finalizer */ 375 PetscCall(PetscRegisterFinalize(PetscDSFinalizePackage)); 376 PetscFunctionReturn(0); 377 } 378 379 #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) 380 /* 381 PetscDLLibraryRegister - This function is called when the dynamic library it is in is opened. 382 383 This one registers all the mesh generators and partitioners that are in 384 the basic DM library. 385 386 */ 387 PETSC_EXTERN PetscErrorCode PetscDLLibraryRegister_petscdm(void) 388 { 389 PetscFunctionBegin; 390 PetscCall(AOInitializePackage()); 391 PetscCall(PetscPartitionerInitializePackage()); 392 PetscCall(DMInitializePackage()); 393 PetscCall(PetscFEInitializePackage()); 394 PetscCall(PetscFVInitializePackage()); 395 PetscCall(DMFieldInitializePackage()); 396 PetscFunctionReturn(0); 397 } 398 399 #endif /* PETSC_HAVE_DYNAMIC_LIBRARIES */ 400