1 // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2 // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3 // reserved. See files LICENSE and NOTICE for details. 4 // 5 // This file is part of CEED, a collection of benchmarks, miniapps, software 6 // libraries and APIs for efficient high-order finite element and spectral 7 // element discretizations for exascale applications. For more information and 8 // source code availability see http://github.com/ceed. 9 // 10 // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11 // a collaborative effort of two U.S. Department of Energy organizations (Office 12 // of Science and the National Nuclear Security Administration) responsible for 13 // the planning and preparation of a capable exascale ecosystem, including 14 // software, applications, hardware, advanced system engineering and early 15 // testbed platforms, in support of the nation's exascale computing imperative. 16 17 #include <ceed-impl.h> 18 #include <string.h> 19 20 /// @file 21 /// Implementation of public CeedQFunction interfaces 22 /// 23 /// @addtogroup CeedQFunction 24 /// @{ 25 26 /** 27 @brief Create a CeedQFunction for evaluating interior (volumetric) terms. 28 29 @param ceed A Ceed object where the CeedQFunction will be created 30 @param vlength Vector length. Caller must ensure that number of quadrature 31 points is a multiple of vlength. 32 @param f Function pointer to evaluate action at quadrature points. 33 See below. 34 @param focca OCCA identifier "file.c:function_name" for definition of `f` 35 @param[out] qf Address of the variable where the newly created 36 CeedQFunction will be stored 37 38 @return An error code: 0 - success, otherwise - failure 39 40 The arguments of the call-back 'function' are: 41 42 1. [void *ctx][in/out] - user data, this is the 'ctx' pointer stored in 43 the CeedQFunction, set by calling CeedQFunctionSetContext 44 45 2. [CeedInt nq][in] - number of quadrature points to process 46 47 3. [const CeedScalar *const *u][in] - input fields data at quadrature pts, listed in the order given by the user 48 49 4. [CeedScalar *const *v][out] - output fields data at quadrature points, again listed in order given by the user 50 51 @ref Basic 52 **/ 53 int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vlength, 54 int (*f)(void*, CeedInt, const CeedScalar *const*, CeedScalar *const*), 55 const char *focca, CeedQFunction *qf) { 56 int ierr; 57 char *focca_copy; 58 59 if (!ceed->QFunctionCreate) { 60 Ceed delegate; 61 ierr = CeedGetDelegate(ceed, &delegate); CeedChk(ierr); 62 63 if (!delegate) 64 return CeedError(ceed, 1, "Backend does not support QFunctionCreate"); 65 66 ierr = CeedQFunctionCreateInterior(delegate, vlength, f, focca, qf); CeedChk(ierr); 67 return 0; 68 } 69 70 ierr = CeedCalloc(1,qf); CeedChk(ierr); 71 (*qf)->ceed = ceed; 72 ceed->refcount++; 73 (*qf)->refcount = 1; 74 (*qf)->vlength = vlength; 75 (*qf)->function = f; 76 ierr = CeedCalloc(strlen(focca)+1, &focca_copy); CeedChk(ierr); 77 strcpy(focca_copy, focca); 78 (*qf)->focca = focca_copy; 79 ierr = ceed->QFunctionCreate(*qf); CeedChk(ierr); 80 return 0; 81 } 82 83 /** 84 @brief Set a CeedQFunction field, used by CeedQFunctionAddInput/Output 85 86 @param f CeedQFunctionField 87 @param fieldname Name of QFunction field 88 @param ncomp Number of components per quadrature node 89 @param emode \ref CEED_EVAL_NONE to use values directly, 90 \ref CEED_EVAL_INTERP to use interpolated values, 91 \ref CEED_EVAL_GRAD to use gradients. 92 93 @return An error code: 0 - success, otherwise - failure 94 95 @ref Developer 96 **/ 97 static int CeedQFunctionFieldSet(struct CeedQFunctionField *f, 98 const char *fieldname, CeedInt ncomp, 99 CeedEvalMode emode) { 100 size_t len = strlen(fieldname); 101 char *tmp; 102 int ierr = CeedCalloc(len+1, &tmp); CeedChk(ierr); 103 memcpy(tmp, fieldname, len+1); 104 f->fieldname = tmp; 105 f->ncomp = ncomp; 106 f->emode = emode; 107 return 0; 108 } 109 110 /** 111 @brief Add a CeedQFunction input 112 113 @param qf CeedQFunction 114 @param fieldname Name of QFunction field 115 @param ncomp Number of components per quadrature node 116 @param emode \ref CEED_EVAL_NONE to use values directly, 117 \ref CEED_EVAL_INTERP to use interpolated values, 118 \ref CEED_EVAL_GRAD to use gradients. 119 120 @return An error code: 0 - success, otherwise - failure 121 122 @ref Basic 123 **/ 124 int CeedQFunctionAddInput(CeedQFunction qf, const char *fieldname, 125 CeedInt ncomp, CeedEvalMode emode) { 126 int ierr = CeedQFunctionFieldSet(&qf->inputfields[qf->numinputfields++], 127 fieldname, ncomp, emode); CeedChk(ierr); 128 return 0; 129 } 130 131 /** 132 @brief Add a CeedQFunction output 133 134 @param qf CeedQFunction 135 @param fieldname Name of QFunction field 136 @param ncomp Number of components per quadrature node 137 @param emode \ref CEED_EVAL_NONE to use values directly, 138 \ref CEED_EVAL_INTERP to use interpolated values, 139 \ref CEED_EVAL_GRAD to use gradients. 140 141 @return An error code: 0 - success, otherwise - failure 142 143 @ref Basic 144 **/ 145 int CeedQFunctionAddOutput(CeedQFunction qf, const char *fieldname, 146 CeedInt ncomp, CeedEvalMode emode) { 147 if (emode == CEED_EVAL_WEIGHT) 148 return CeedError(qf->ceed, 1, 149 "Cannot create qfunction output with CEED_EVAL_WEIGHT"); 150 int ierr = CeedQFunctionFieldSet(&qf->outputfields[qf->numoutputfields++], 151 fieldname, ncomp, emode); CeedChk(ierr); 152 return 0; 153 } 154 155 /** 156 @brief Get the Ceed associated with a CeedQFunction 157 158 @param qf CeedQFunction 159 @param[out] ceed Variable to store Ceed 160 161 @return An error code: 0 - success, otherwise - failure 162 163 @ref Utility 164 **/ 165 166 int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed) { 167 *ceed = qf->ceed; 168 return 0; 169 } 170 171 /** 172 @brief Get the vector length of a CeedQFunction 173 174 @param qf CeedQFunction 175 @param[out] veclength Variable to store vector length 176 177 @return An error code: 0 - success, otherwise - failure 178 179 @ref Utility 180 **/ 181 182 int CeedQFunctionGetVectorLength(CeedQFunction qf, CeedInt *vlength) { 183 *vlength = qf->vlength; 184 return 0; 185 } 186 187 /** 188 @brief Get the number of inputs and outputs to a CeedQFunction 189 190 @param qf CeedQFunction 191 @param[out] numinput Variable to store number of input fields 192 @param[out] numoutput Variable to store number of output fields 193 194 @return An error code: 0 - success, otherwise - failure 195 196 @ref Utility 197 **/ 198 199 int CeedQFunctionGetNumArgs(CeedQFunction qf, CeedInt *numinput, 200 CeedInt *numoutput) { 201 if (numinput) *numinput = qf->numinputfields; 202 if (numoutput) *numoutput = qf->numoutputfields; 203 return 0; 204 } 205 206 /** 207 @brief Get the FOCCA string for a CeedQFunction 208 209 @param qf CeedQFunction 210 @param[out] focca Variable to store focca string 211 212 @return An error code: 0 - success, otherwise - failure 213 214 @ref Utility 215 **/ 216 217 int CeedQFunctionGetFOCCA(CeedQFunction qf, char* *focca) { 218 *focca = (char*) qf->focca; 219 return 0; 220 } 221 222 /** 223 @brief Get global context size for a CeedQFunction 224 225 @param qf CeedQFunction 226 @param[out] ctxsize Variable to store size of context data values 227 228 @return An error code: 0 - success, otherwise - failure 229 230 @ref Utility 231 **/ 232 233 int CeedQFunctionGetContextSize(CeedQFunction qf, size_t *ctxsize) { 234 *ctxsize = qf->ctxsize; 235 return 0; 236 } 237 238 /** 239 @brief Get global context for a CeedQFunction 240 241 @param qf CeedQFunction 242 @param[out] ctx Variable to store context data values 243 244 @return An error code: 0 - success, otherwise - failure 245 246 @ref Utility 247 **/ 248 249 int CeedQFunctionGetContext(CeedQFunction qf, void* *ctx) { 250 *ctx = qf->ctx; 251 return 0; 252 } 253 254 /** 255 @brief Get backend data of a CeedQFunction 256 257 @param qf CeedQFunction 258 @param[out] data Variable to store data 259 260 @return An error code: 0 - success, otherwise - failure 261 262 @ref Utility 263 **/ 264 265 int CeedQFunctionGetData(CeedQFunction qf, void* *data) { 266 *data = qf->data; 267 return 0; 268 } 269 270 /** 271 @brief Set global context for a CeedQFunction 272 273 @param qf CeedQFunction 274 @param ctx Context data to set 275 @param ctxsize Size of context data values 276 277 @return An error code: 0 - success, otherwise - failure 278 279 @ref Basic 280 **/ 281 int CeedQFunctionSetContext(CeedQFunction qf, void *ctx, size_t ctxsize) { 282 qf->ctx = ctx; 283 qf->ctxsize = ctxsize; 284 return 0; 285 } 286 287 /** 288 @brief Apply the action of a CeedQFunction 289 290 @param qf CeedQFunction 291 @param Q Number of quadrature points 292 @param[in] u Array of input data arrays 293 @param[out] v Array of output data arrays 294 295 @return An error code: 0 - success, otherwise - failure 296 297 @ref Advanced 298 **/ 299 int CeedQFunctionApply(CeedQFunction qf, CeedInt Q, 300 const CeedScalar *const *u, 301 CeedScalar *const *v) { 302 int ierr; 303 if (!qf->Apply) 304 return CeedError(qf->ceed, 1, "Backend does not support QFunctionApply"); 305 if (Q % qf->vlength) 306 return CeedError(qf->ceed, 2, 307 "Number of quadrature points %d must be a multiple of %d", 308 Q, qf->vlength); 309 ierr = qf->Apply(qf, Q, u, v); CeedChk(ierr); 310 return 0; 311 } 312 313 /** 314 @brief Destroy a CeedQFunction 315 316 @param qf CeedQFunction to destroy 317 318 @return An error code: 0 - success, otherwise - failure 319 320 @ref Basic 321 **/ 322 int CeedQFunctionDestroy(CeedQFunction *qf) { 323 int ierr; 324 325 if (!*qf || --(*qf)->refcount > 0) return 0; 326 // Free field names 327 for (int i=0; i<(*qf)->numinputfields; i++) { 328 ierr = CeedFree(&(*qf)->inputfields[i].fieldname); CeedChk(ierr); 329 } 330 for (int i=0; i<(*qf)->numoutputfields; i++) { 331 ierr = CeedFree(&(*qf)->outputfields[i].fieldname); CeedChk(ierr); 332 } 333 if ((*qf)->Destroy) { 334 ierr = (*qf)->Destroy(*qf); CeedChk(ierr); 335 } 336 ierr = CeedFree(&(*qf)->focca); CeedChk(ierr); 337 ierr = CeedDestroy(&(*qf)->ceed); CeedChk(ierr); 338 ierr = CeedFree(qf); CeedChk(ierr); 339 return 0; 340 } 341 342 /// @} 343