xref: /petsc/src/dm/interface/dlregisdmdm.c (revision 0fdf79fb08699bf9be0aa4d8ba0185e387a216c8)
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(DMLabelRegisterAll());
174   PetscCall(PetscRegisterFinalize(DMLabelRegisterDestroy));
175   PetscCall(PetscRegisterFinalize(DMFinalizePackage));
176   PetscFunctionReturn(0);
177 }
178 #include <petscfe.h>
179 
180 static PetscBool PetscFEPackageInitialized = PETSC_FALSE;
181 /*@C
182   PetscFEFinalizePackage - This function finalizes everything in the PetscFE package. It is called
183   from PetscFinalize().
184 
185   Level: developer
186 
187 .seealso: `PetscInitialize()`
188 @*/
189 PetscErrorCode PetscFEFinalizePackage(void)
190 {
191   PetscFunctionBegin;
192   PetscCall(PetscFunctionListDestroy(&PetscSpaceList));
193   PetscCall(PetscFunctionListDestroy(&PetscDualSpaceList));
194   PetscCall(PetscFunctionListDestroy(&PetscFEList));
195   PetscFEPackageInitialized       = PETSC_FALSE;
196   PetscSpaceRegisterAllCalled     = PETSC_FALSE;
197   PetscDualSpaceRegisterAllCalled = PETSC_FALSE;
198   PetscFERegisterAllCalled        = PETSC_FALSE;
199   PetscFunctionReturn(0);
200 }
201 
202 /*@C
203   PetscFEInitializePackage - This function initializes everything in the FE package. It is called
204   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PetscSpaceCreate()
205   when using static libraries.
206 
207   Level: developer
208 
209 .seealso: `PetscInitialize()`
210 @*/
211 PetscErrorCode PetscFEInitializePackage(void)
212 {
213   char      logList[256];
214   PetscBool opt, pkg;
215 
216   PetscFunctionBegin;
217   if (PetscFEPackageInitialized) PetscFunctionReturn(0);
218   PetscFEPackageInitialized = PETSC_TRUE;
219 
220   /* Register Classes */
221   PetscCall(PetscClassIdRegister("Linear Space", &PETSCSPACE_CLASSID));
222   PetscCall(PetscClassIdRegister("Dual Space", &PETSCDUALSPACE_CLASSID));
223   PetscCall(PetscClassIdRegister("FE Space", &PETSCFE_CLASSID));
224   /* Register Constructors */
225   PetscCall(PetscSpaceRegisterAll());
226   PetscCall(PetscDualSpaceRegisterAll());
227   PetscCall(PetscFERegisterAll());
228   /* Register Events */
229   PetscCall(PetscLogEventRegister("DualSpaceSetUp", PETSCDUALSPACE_CLASSID, &PETSCDUALSPACE_SetUp));
230   PetscCall(PetscLogEventRegister("FESetUp", PETSCFE_CLASSID, &PETSCFE_SetUp));
231   /* Process Info */
232   {
233     PetscClassId classids[3];
234 
235     classids[0] = PETSCFE_CLASSID;
236     classids[1] = PETSCSPACE_CLASSID;
237     classids[2] = PETSCDUALSPACE_CLASSID;
238     PetscCall(PetscInfoProcessClass("fe", 1, classids));
239     PetscCall(PetscInfoProcessClass("space", 1, &classids[1]));
240     PetscCall(PetscInfoProcessClass("dualspace", 1, &classids[2]));
241   }
242   /* Process summary exclusions */
243   PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
244   if (opt) {
245     PetscCall(PetscStrInList("fe", logList, ',', &pkg));
246     if (pkg) PetscCall(PetscLogEventExcludeClass(PETSCFE_CLASSID));
247   }
248   /* Register package finalizer */
249   PetscCall(PetscRegisterFinalize(PetscFEFinalizePackage));
250   PetscFunctionReturn(0);
251 }
252 #include <petscfv.h>
253 
254 static PetscBool PetscFVPackageInitialized = PETSC_FALSE;
255 /*@C
256   PetscFVFinalizePackage - This function finalizes everything in the PetscFV package. It is called
257   from PetscFinalize().
258 
259   Level: developer
260 
261 .seealso: `PetscInitialize()`
262 @*/
263 PetscErrorCode PetscFVFinalizePackage(void)
264 {
265   PetscFunctionBegin;
266   PetscCall(PetscFunctionListDestroy(&PetscLimiterList));
267   PetscCall(PetscFunctionListDestroy(&PetscFVList));
268   PetscFVPackageInitialized     = PETSC_FALSE;
269   PetscFVRegisterAllCalled      = PETSC_FALSE;
270   PetscLimiterRegisterAllCalled = PETSC_FALSE;
271   PetscFunctionReturn(0);
272 }
273 
274 /*@C
275   PetscFVInitializePackage - This function initializes everything in the FV package. It is called
276   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PetscFVCreate()
277   when using static libraries.
278 
279   Level: developer
280 
281 .seealso: `PetscInitialize()`
282 @*/
283 PetscErrorCode PetscFVInitializePackage(void)
284 {
285   char      logList[256];
286   PetscBool opt, pkg;
287 
288   PetscFunctionBegin;
289   if (PetscFVPackageInitialized) PetscFunctionReturn(0);
290   PetscFVPackageInitialized = PETSC_TRUE;
291 
292   /* Register Classes */
293   PetscCall(PetscClassIdRegister("FV Space", &PETSCFV_CLASSID));
294   PetscCall(PetscClassIdRegister("Limiter", &PETSCLIMITER_CLASSID));
295   /* Register Constructors */
296   PetscCall(PetscFVRegisterAll());
297   /* Register Events */
298   /* Process Info */
299   {
300     PetscClassId classids[2];
301 
302     classids[0] = PETSCFV_CLASSID;
303     classids[1] = PETSCLIMITER_CLASSID;
304     PetscCall(PetscInfoProcessClass("fv", 1, classids));
305     PetscCall(PetscInfoProcessClass("limiter", 1, &classids[1]));
306   }
307   /* Process summary exclusions */
308   PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
309   if (opt) {
310     PetscCall(PetscStrInList("fv", logList, ',', &pkg));
311     if (pkg) PetscCall(PetscLogEventExcludeClass(PETSCFV_CLASSID));
312     PetscCall(PetscStrInList("limiter", logList, ',', &pkg));
313     if (pkg) PetscCall(PetscLogEventExcludeClass(PETSCLIMITER_CLASSID));
314   }
315   /* Register package finalizer */
316   PetscCall(PetscRegisterFinalize(PetscFVFinalizePackage));
317   PetscFunctionReturn(0);
318 }
319 #include <petscds.h>
320 
321 static PetscBool PetscDSPackageInitialized = PETSC_FALSE;
322 /*@C
323   PetscDSFinalizePackage - This function finalizes everything in the PetscDS package. It is called
324   from PetscFinalize().
325 
326   Level: developer
327 
328 .seealso: `PetscInitialize()`
329 @*/
330 PetscErrorCode PetscDSFinalizePackage(void)
331 {
332   PetscFunctionBegin;
333   PetscCall(PetscFunctionListDestroy(&PetscDSList));
334   PetscDSPackageInitialized = PETSC_FALSE;
335   PetscDSRegisterAllCalled  = PETSC_FALSE;
336   PetscFunctionReturn(0);
337 }
338 
339 /*@C
340   PetscDSInitializePackage - This function initializes everything in the DS package. It is called
341   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PetscDSCreate()
342   when using static libraries.
343 
344   Level: developer
345 
346 .seealso: `PetscInitialize()`
347 @*/
348 PetscErrorCode PetscDSInitializePackage(void)
349 {
350   char      logList[256];
351   PetscBool opt, pkg;
352 
353   PetscFunctionBegin;
354   if (PetscDSPackageInitialized) PetscFunctionReturn(0);
355   PetscDSPackageInitialized = PETSC_TRUE;
356 
357   /* Register Classes */
358   PetscCall(PetscClassIdRegister("Discrete System", &PETSCDS_CLASSID));
359   PetscCall(PetscClassIdRegister("Weak Form", &PETSCWEAKFORM_CLASSID));
360   /* Register Constructors */
361   PetscCall(PetscDSRegisterAll());
362   /* Register Events */
363   /* Process Info */
364   {
365     PetscClassId classids[1];
366 
367     classids[0] = PETSCDS_CLASSID;
368     PetscCall(PetscInfoProcessClass("ds", 1, classids));
369   }
370   /* Process summary exclusions */
371   PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
372   if (opt) {
373     PetscCall(PetscStrInList("ds", logList, ',', &pkg));
374     if (pkg) PetscCall(PetscLogEventExcludeClass(PETSCDS_CLASSID));
375   }
376   /* Register package finalizer */
377   PetscCall(PetscRegisterFinalize(PetscDSFinalizePackage));
378   PetscFunctionReturn(0);
379 }
380 
381 #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
382 /*
383   PetscDLLibraryRegister - This function is called when the dynamic library it is in is opened.
384 
385   This one registers all the mesh generators and partitioners that are in
386   the basic DM library.
387 
388 */
389 PETSC_EXTERN PetscErrorCode PetscDLLibraryRegister_petscdm(void)
390 {
391   PetscFunctionBegin;
392   PetscCall(AOInitializePackage());
393   PetscCall(PetscPartitionerInitializePackage());
394   PetscCall(DMInitializePackage());
395   PetscCall(PetscFEInitializePackage());
396   PetscCall(PetscFVInitializePackage());
397   PetscCall(DMFieldInitializePackage());
398   PetscFunctionReturn(0);
399 }
400 
401 #endif /* PETSC_HAVE_DYNAMIC_LIBRARIES */
402