xref: /libCEED/interface/ceed-object.c (revision 860dc8215fde8015ce701d5081dc7f665abfde5f)
1 // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors.
2 // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3 //
4 // SPDX-License-Identifier: BSD-2-Clause
5 //
6 // This file is part of CEED:  http://github.com/ceed
7 
8 #include <ceed-impl.h>
9 #include <ceed.h>
10 #include <ceed/backend.h>
11 
12 /// @file
13 /// Implementation of CeedObject functionality
14 
15 /// ----------------------------------------------------------------------------
16 /// CeedObject Backend API
17 /// ----------------------------------------------------------------------------
18 /// @addtogroup CeedBackend
19 /// @{
20 
21 /**
22   @brief Create a `CeedObject`.
23 
24   Note: This interface takes a `CeedObject` and not a pointer to a `CeedObject` like other `Ceed*Create` interfaces.
25           This `CeedObject` will have already been allocated a the first part of the `Ceed*` struct.
26           This function is only intended to be called inside of `Ceed*Create` functions.
27 
28   @param[in]  ceed             `Ceed` object to reference
29   @param[in]  view_function    `Ceed*` function for viewing the `obj`
30   @param[in]  destroy_function `Ceed*` function for destroying the `obj`
31   @param[out] obj              Address of the variable where is `CeedObject` exists
32 
33   @return An error code: 0 - success, otherwise - failure
34 
35   @ref Backend
36 **/
37 int CeedObjectCreate(Ceed ceed, int (*view_function)(CeedObject, FILE *), int (*destroy_function)(CeedObject *), CeedObject obj) {
38   obj->ceed = NULL;
39   if (ceed) CeedCall(CeedReferenceCopy(ceed, &obj->ceed));
40   obj->View = view_function;
41   CeedCheck(destroy_function, CeedObjectReturnCeed(obj), CEED_ERROR_UNSUPPORTED, "Must provide destroy function to create CeedObject");
42   obj->Destroy   = destroy_function;
43   obj->ref_count = 1;
44   return CEED_ERROR_SUCCESS;
45 }
46 
47 /**
48   @brief Increment the reference counter for a `CeedObject`
49 
50   @param[in,out] obj `CeedObject` to increment the reference counter
51 
52   @return An error code: 0 - success, otherwise - failure
53 
54   @ref Backend
55 **/
56 int CeedObjectReference(CeedObject obj) {
57   obj->ref_count++;
58   return CEED_ERROR_SUCCESS;
59 }
60 
61 /**
62   @brief Decrement the reference counter for a `CeedObject`
63 
64   @param[in,out] obj `CeedObject` to decrement the reference counter
65 
66   @return The new reference count
67 
68   @ref Backend
69 **/
70 int CeedObjectDereference(CeedObject obj) {
71   return --obj->ref_count;  // prefix notation, to get new number of references
72 }
73 
74 /**
75   @brief Destroy a @ref CeedObject
76 
77   @param[in,out] obj `CeedObject` to destroy
78 
79   @return An error code: 0 - success, otherwise - failure
80 
81   @ref Backend
82 **/
83 int CeedObjectDestroy_Private(CeedObject obj) {
84   CeedCheck(obj->ref_count == 0, CeedObjectReturnCeed(obj), CEED_ERROR_UNSUPPORTED,
85             "Cannot destroy CeedObject, it is still referenced by another object");
86   if (obj->ceed) CeedCall(CeedDestroy(&obj->ceed));
87   return CEED_ERROR_SUCCESS;
88 }
89 
90 /// @}
91 
92 /// ----------------------------------------------------------------------------
93 /// CeedObject Public API
94 /// ----------------------------------------------------------------------------
95 /// @addtogroup CeedUser
96 /// @{
97 
98 /**
99   @brief View a `CeedObject`
100 
101   @param[in] obj    `CeedObject` to view
102   @param[in] stream Stream to view to, e.g., `stdout`
103 
104   @return An error code: 0 - success, otherwise - failure
105 
106   @ref User
107 **/
108 int CeedObjectView(CeedObject obj, FILE *stream) {
109   if (obj->View) CeedCall(obj->View(obj, stream));
110   return CEED_ERROR_SUCCESS;
111 }
112 
113 /**
114   @brief Set the number of tabs to indent for @ref CeedObjectView() output
115 
116   @param[in] obj      `CeedObject` to set the number of view tabs
117   @param[in] num_tabs Number of view tabs to set
118 
119   @return Error code: 0 - success, otherwise - failure
120 
121   @ref User
122 **/
123 int CeedObjectSetNumViewTabs(CeedObject obj, CeedInt num_tabs) {
124   CeedCheck(num_tabs >= 0, CeedObjectReturnCeed(obj), CEED_ERROR_MINOR, "Number of view tabs must be non-negative");
125   obj->num_view_tabs = num_tabs;
126   return CEED_ERROR_SUCCESS;
127 }
128 
129 /**
130   @brief Get the number of tabs to indent for @ref CeedObjectView() output
131 
132   @param[in]  obj      `CeedObject` to get the number of view tabs
133   @param[out] num_tabs Number of view tabs
134 
135   @return Error code: 0 - success, otherwise - failure
136 
137   @ref User
138 **/
139 int CeedObjectGetNumViewTabs(CeedObject obj, CeedInt *num_tabs) {
140   *num_tabs = obj->num_view_tabs;
141   return CEED_ERROR_SUCCESS;
142 }
143 
144 /**
145   @brief Get the `Ceed` associated with a `CeedObject`
146 
147   @param[in]  obj   `CeedObject`
148   @param[out] ceed  Variable to store `Ceed`
149 
150   @return An error code: 0 - success, otherwise - failure
151 
152   @ref Advanced
153 **/
154 int CeedObjectGetCeed(CeedObject obj, Ceed *ceed) {
155   *ceed = NULL;
156   CeedCall(CeedReferenceCopy(CeedObjectReturnCeed(obj), ceed));
157   return CEED_ERROR_SUCCESS;
158 }
159 
160 /**
161   @brief Return the `Ceed` associated with a `CeedObject`
162 
163   @param[in] obj `CeedObject`
164 
165   @return `Ceed` associated with the `basis`
166 
167   @ref Advanced
168 **/
169 Ceed CeedObjectReturnCeed(CeedObject obj) { return (obj->ceed) ? obj->ceed : (Ceed)obj; }
170 
171 /**
172   @brief Destroy a @ref CeedObject
173 
174   @param[in,out] obj Address of `CeedObject` to destroy
175 
176   @return An error code: 0 - success, otherwise - failure
177 
178   @ref Backend
179 **/
180 int CeedObjectDestroy(CeedObject *obj) {
181   CeedCall((*obj)->Destroy(obj));
182   return CEED_ERROR_SUCCESS;
183 }
184 
185 /// @}
186