1*0436c2adSjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2*0436c2adSjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3*0436c2adSjeremylt // reserved. See files LICENSE and NOTICE for details. 4*0436c2adSjeremylt // 5*0436c2adSjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software 6*0436c2adSjeremylt // libraries and APIs for efficient high-order finite element and spectral 7*0436c2adSjeremylt // element discretizations for exascale applications. For more information and 8*0436c2adSjeremylt // source code availability see http://github.com/ceed. 9*0436c2adSjeremylt // 10*0436c2adSjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11*0436c2adSjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office 12*0436c2adSjeremylt // of Science and the National Nuclear Security Administration) responsible for 13*0436c2adSjeremylt // the planning and preparation of a capable exascale ecosystem, including 14*0436c2adSjeremylt // software, applications, hardware, advanced system engineering and early 15*0436c2adSjeremylt // testbed platforms, in support of the nation's exascale computing imperative. 16*0436c2adSjeremylt 17*0436c2adSjeremylt #include <ceed-impl.h> 18*0436c2adSjeremylt #include <ceed-backend.h> 19*0436c2adSjeremylt 20*0436c2adSjeremylt /// @cond DOXYGEN_SKIP 21*0436c2adSjeremylt static struct CeedVector_private ceed_vector_active; 22*0436c2adSjeremylt static struct CeedVector_private ceed_vector_none; 23*0436c2adSjeremylt /// @endcond 24*0436c2adSjeremylt 25*0436c2adSjeremylt /// @file 26*0436c2adSjeremylt /// Implementation of public CeedVector interfaces 27*0436c2adSjeremylt /// 28*0436c2adSjeremylt /// @addtogroup CeedVector 29*0436c2adSjeremylt /// @{ 30*0436c2adSjeremylt 31*0436c2adSjeremylt /** 32*0436c2adSjeremylt @brief Create a CeedVector of the specified length (does not allocate memory) 33*0436c2adSjeremylt 34*0436c2adSjeremylt @param ceed Ceed object where the CeedVector will be created 35*0436c2adSjeremylt @param length Length of vector 36*0436c2adSjeremylt @param[out] vec Address of the variable where the newly created 37*0436c2adSjeremylt CeedVector will be stored 38*0436c2adSjeremylt 39*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 40*0436c2adSjeremylt 41*0436c2adSjeremylt @ref Basic 42*0436c2adSjeremylt **/ 43*0436c2adSjeremylt int CeedVectorCreate(Ceed ceed, CeedInt length, CeedVector *vec) { 44*0436c2adSjeremylt int ierr; 45*0436c2adSjeremylt 46*0436c2adSjeremylt if (!ceed->VectorCreate) { 47*0436c2adSjeremylt Ceed delegate; 48*0436c2adSjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Vector"); CeedChk(ierr); 49*0436c2adSjeremylt 50*0436c2adSjeremylt if (!delegate) 51*0436c2adSjeremylt // LCOV_EXCL_START 52*0436c2adSjeremylt return CeedError(ceed, 1, "Backend does not support VectorCreate"); 53*0436c2adSjeremylt // LCOV_EXCL_STOP 54*0436c2adSjeremylt 55*0436c2adSjeremylt ierr = CeedVectorCreate(delegate, length, vec); CeedChk(ierr); 56*0436c2adSjeremylt return 0; 57*0436c2adSjeremylt } 58*0436c2adSjeremylt 59*0436c2adSjeremylt ierr = CeedCalloc(1,vec); CeedChk(ierr); 60*0436c2adSjeremylt (*vec)->ceed = ceed; 61*0436c2adSjeremylt ceed->refcount++; 62*0436c2adSjeremylt (*vec)->refcount = 1; 63*0436c2adSjeremylt (*vec)->length = length; 64*0436c2adSjeremylt (*vec)->state = 0; 65*0436c2adSjeremylt ierr = ceed->VectorCreate(length, *vec); CeedChk(ierr); 66*0436c2adSjeremylt return 0; 67*0436c2adSjeremylt } 68*0436c2adSjeremylt 69*0436c2adSjeremylt /** 70*0436c2adSjeremylt @brief Set the array used by a CeedVector, freeing any previously allocated 71*0436c2adSjeremylt array if applicable 72*0436c2adSjeremylt 73*0436c2adSjeremylt @param vec CeedVector 74*0436c2adSjeremylt @param mtype Memory type of the array being passed 75*0436c2adSjeremylt @param cmode Copy mode for the array 76*0436c2adSjeremylt @param array Array to be used, or NULL with CEED_COPY_VALUES to have the 77*0436c2adSjeremylt library allocate 78*0436c2adSjeremylt 79*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 80*0436c2adSjeremylt 81*0436c2adSjeremylt @ref Basic 82*0436c2adSjeremylt **/ 83*0436c2adSjeremylt int CeedVectorSetArray(CeedVector vec, CeedMemType mtype, CeedCopyMode cmode, 84*0436c2adSjeremylt CeedScalar *array) { 85*0436c2adSjeremylt int ierr; 86*0436c2adSjeremylt 87*0436c2adSjeremylt if (!vec->SetArray) 88*0436c2adSjeremylt // LCOV_EXCL_START 89*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Backend does not support VectorSetArray"); 90*0436c2adSjeremylt // LCOV_EXCL_STOP 91*0436c2adSjeremylt 92*0436c2adSjeremylt if (vec->state % 2 == 1) 93*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Cannot grant CeedVector array access, the " 94*0436c2adSjeremylt "access lock is already in use"); 95*0436c2adSjeremylt 96*0436c2adSjeremylt if (vec->numreaders > 0) 97*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Cannot grant CeedVector array access, a " 98*0436c2adSjeremylt "process has read access"); 99*0436c2adSjeremylt 100*0436c2adSjeremylt ierr = vec->SetArray(vec, mtype, cmode, array); CeedChk(ierr); 101*0436c2adSjeremylt vec->state += 2; 102*0436c2adSjeremylt 103*0436c2adSjeremylt return 0; 104*0436c2adSjeremylt } 105*0436c2adSjeremylt 106*0436c2adSjeremylt /** 107*0436c2adSjeremylt @brief Set the CeedVector to a constant value 108*0436c2adSjeremylt 109*0436c2adSjeremylt @param vec CeedVector 110*0436c2adSjeremylt @param[in] value Value to be used 111*0436c2adSjeremylt 112*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 113*0436c2adSjeremylt 114*0436c2adSjeremylt @ref Basic 115*0436c2adSjeremylt **/ 116*0436c2adSjeremylt int CeedVectorSetValue(CeedVector vec, CeedScalar value) { 117*0436c2adSjeremylt int ierr; 118*0436c2adSjeremylt 119*0436c2adSjeremylt if (vec->state % 2 == 1) 120*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Cannot grant CeedVector array access, the " 121*0436c2adSjeremylt "access lock is already in use"); 122*0436c2adSjeremylt 123*0436c2adSjeremylt if (vec->SetValue) { 124*0436c2adSjeremylt ierr = vec->SetValue(vec, value); CeedChk(ierr); 125*0436c2adSjeremylt } else { 126*0436c2adSjeremylt CeedScalar *array; 127*0436c2adSjeremylt ierr = CeedVectorGetArray(vec, CEED_MEM_HOST, &array); CeedChk(ierr); 128*0436c2adSjeremylt for (int i=0; i<vec->length; i++) array[i] = value; 129*0436c2adSjeremylt ierr = CeedVectorRestoreArray(vec, &array); CeedChk(ierr); 130*0436c2adSjeremylt } 131*0436c2adSjeremylt 132*0436c2adSjeremylt vec->state += 2; 133*0436c2adSjeremylt 134*0436c2adSjeremylt return 0; 135*0436c2adSjeremylt } 136*0436c2adSjeremylt 137*0436c2adSjeremylt /** 138*0436c2adSjeremylt @brief Sync the CeedVector to a specified memtype 139*0436c2adSjeremylt 140*0436c2adSjeremylt @param vec CeedVector 141*0436c2adSjeremylt @param mtype Memtype to be synced 142*0436c2adSjeremylt 143*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 144*0436c2adSjeremylt 145*0436c2adSjeremylt @ref Basic 146*0436c2adSjeremylt **/ 147*0436c2adSjeremylt int CeedVectorSyncArray(CeedVector vec, CeedMemType mtype) { 148*0436c2adSjeremylt int ierr; 149*0436c2adSjeremylt 150*0436c2adSjeremylt if (vec->state % 2 == 1) 151*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Cannot sync CeedVector, the access lock is " 152*0436c2adSjeremylt "already in use"); 153*0436c2adSjeremylt 154*0436c2adSjeremylt if (vec->SyncArray) { 155*0436c2adSjeremylt ierr = vec->SyncArray(vec, mtype); CeedChk(ierr); 156*0436c2adSjeremylt } else { 157*0436c2adSjeremylt const CeedScalar *array; 158*0436c2adSjeremylt ierr = CeedVectorGetArrayRead(vec, mtype, &array); CeedChk(ierr); 159*0436c2adSjeremylt ierr = CeedVectorRestoreArrayRead(vec, &array); CeedChk(ierr); 160*0436c2adSjeremylt } 161*0436c2adSjeremylt 162*0436c2adSjeremylt return 0; 163*0436c2adSjeremylt } 164*0436c2adSjeremylt 165*0436c2adSjeremylt /** 166*0436c2adSjeremylt @brief Get read/write access to a CeedVector via the specified memory type 167*0436c2adSjeremylt 168*0436c2adSjeremylt @param vec CeedVector to access 169*0436c2adSjeremylt @param mtype Memory type on which to access the array. If the backend 170*0436c2adSjeremylt uses a different memory type, this will perform a copy and 171*0436c2adSjeremylt CeedVectorRestoreArray() will copy back. 172*0436c2adSjeremylt @param[out] array Array on memory type mtype 173*0436c2adSjeremylt 174*0436c2adSjeremylt @note The CeedVectorGetArray* and CeedVectorRestoreArray* functions provide 175*0436c2adSjeremylt access to array pointers in the desired memory space. Pairing get/restore 176*0436c2adSjeremylt allows the Vector to track access, thus knowing if norms or other 177*0436c2adSjeremylt operations may need to be recomputed. 178*0436c2adSjeremylt 179*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 180*0436c2adSjeremylt 181*0436c2adSjeremylt @ref Basic 182*0436c2adSjeremylt **/ 183*0436c2adSjeremylt int CeedVectorGetArray(CeedVector vec, CeedMemType mtype, CeedScalar **array) { 184*0436c2adSjeremylt int ierr; 185*0436c2adSjeremylt 186*0436c2adSjeremylt if (!vec->GetArray) 187*0436c2adSjeremylt // LCOV_EXCL_START 188*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Backend does not support GetArray"); 189*0436c2adSjeremylt // LCOV_EXCL_STOP 190*0436c2adSjeremylt 191*0436c2adSjeremylt if (vec->state % 2 == 1) 192*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Cannot grant CeedVector array access, the " 193*0436c2adSjeremylt "access lock is already in use"); 194*0436c2adSjeremylt 195*0436c2adSjeremylt if (vec->numreaders > 0) 196*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Cannot grant CeedVector array access, a " 197*0436c2adSjeremylt "process has read access"); 198*0436c2adSjeremylt 199*0436c2adSjeremylt ierr = vec->GetArray(vec, mtype, array); CeedChk(ierr); 200*0436c2adSjeremylt vec->state += 1; 201*0436c2adSjeremylt 202*0436c2adSjeremylt return 0; 203*0436c2adSjeremylt } 204*0436c2adSjeremylt 205*0436c2adSjeremylt /** 206*0436c2adSjeremylt @brief Get read-only access to a CeedVector via the specified memory type 207*0436c2adSjeremylt 208*0436c2adSjeremylt @param vec CeedVector to access 209*0436c2adSjeremylt @param mtype Memory type on which to access the array. If the backend 210*0436c2adSjeremylt uses a different memory type, this will perform a copy 211*0436c2adSjeremylt (possibly cached). 212*0436c2adSjeremylt @param[out] array Array on memory type mtype 213*0436c2adSjeremylt 214*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 215*0436c2adSjeremylt 216*0436c2adSjeremylt @ref Basic 217*0436c2adSjeremylt **/ 218*0436c2adSjeremylt int CeedVectorGetArrayRead(CeedVector vec, CeedMemType mtype, 219*0436c2adSjeremylt const CeedScalar **array) { 220*0436c2adSjeremylt int ierr; 221*0436c2adSjeremylt 222*0436c2adSjeremylt if (!vec->GetArrayRead) 223*0436c2adSjeremylt // LCOV_EXCL_START 224*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Backend does not support GetArrayRead"); 225*0436c2adSjeremylt // LCOV_EXCL_STOP 226*0436c2adSjeremylt 227*0436c2adSjeremylt if (vec->state % 2 == 1) 228*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Cannot grant CeedVector read-only array " 229*0436c2adSjeremylt "access, the access lock is already in use"); 230*0436c2adSjeremylt 231*0436c2adSjeremylt ierr = vec->GetArrayRead(vec, mtype, array); CeedChk(ierr); 232*0436c2adSjeremylt vec->numreaders++; 233*0436c2adSjeremylt 234*0436c2adSjeremylt return 0; 235*0436c2adSjeremylt } 236*0436c2adSjeremylt 237*0436c2adSjeremylt /** 238*0436c2adSjeremylt @brief Restore an array obtained using CeedVectorGetArray() 239*0436c2adSjeremylt 240*0436c2adSjeremylt @param vec CeedVector to restore 241*0436c2adSjeremylt @param array Array of vector data 242*0436c2adSjeremylt 243*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 244*0436c2adSjeremylt 245*0436c2adSjeremylt @ref Basic 246*0436c2adSjeremylt **/ 247*0436c2adSjeremylt int CeedVectorRestoreArray(CeedVector vec, CeedScalar **array) { 248*0436c2adSjeremylt int ierr; 249*0436c2adSjeremylt 250*0436c2adSjeremylt if (!vec->RestoreArray) 251*0436c2adSjeremylt // LCOV_EXCL_START 252*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Backend does not support RestoreArray"); 253*0436c2adSjeremylt // LCOV_EXCL_STOP 254*0436c2adSjeremylt 255*0436c2adSjeremylt if (vec->state % 2 != 1) 256*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Cannot restore CeedVector array access, " 257*0436c2adSjeremylt "access was not granted"); 258*0436c2adSjeremylt 259*0436c2adSjeremylt ierr = vec->RestoreArray(vec); CeedChk(ierr); 260*0436c2adSjeremylt *array = NULL; 261*0436c2adSjeremylt vec->state += 1; 262*0436c2adSjeremylt 263*0436c2adSjeremylt return 0; 264*0436c2adSjeremylt } 265*0436c2adSjeremylt 266*0436c2adSjeremylt /** 267*0436c2adSjeremylt @brief Restore an array obtained using CeedVectorGetArrayRead() 268*0436c2adSjeremylt 269*0436c2adSjeremylt @param vec CeedVector to restore 270*0436c2adSjeremylt @param array Array of vector data 271*0436c2adSjeremylt 272*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 273*0436c2adSjeremylt 274*0436c2adSjeremylt @ref Basic 275*0436c2adSjeremylt **/ 276*0436c2adSjeremylt int CeedVectorRestoreArrayRead(CeedVector vec, const CeedScalar **array) { 277*0436c2adSjeremylt int ierr; 278*0436c2adSjeremylt 279*0436c2adSjeremylt if (!vec->RestoreArrayRead) 280*0436c2adSjeremylt // LCOV_EXCL_START 281*0436c2adSjeremylt return CeedError(vec->ceed, 1, "Backend does not support RestoreArrayRead"); 282*0436c2adSjeremylt // LCOV_EXCL_STOP 283*0436c2adSjeremylt 284*0436c2adSjeremylt ierr = vec->RestoreArrayRead(vec); CeedChk(ierr); 285*0436c2adSjeremylt *array = NULL; 286*0436c2adSjeremylt vec->numreaders--; 287*0436c2adSjeremylt 288*0436c2adSjeremylt return 0; 289*0436c2adSjeremylt } 290*0436c2adSjeremylt 291*0436c2adSjeremylt /** 292*0436c2adSjeremylt @brief View a CeedVector 293*0436c2adSjeremylt 294*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 295*0436c2adSjeremylt 296*0436c2adSjeremylt @ref Utility 297*0436c2adSjeremylt **/ 298*0436c2adSjeremylt int CeedVectorView(CeedVector vec, const char *fpfmt, FILE *stream) { 299*0436c2adSjeremylt const CeedScalar *x; 300*0436c2adSjeremylt 301*0436c2adSjeremylt int ierr = CeedVectorGetArrayRead(vec, CEED_MEM_HOST, &x); CeedChk(ierr); 302*0436c2adSjeremylt 303*0436c2adSjeremylt char fmt[1024]; 304*0436c2adSjeremylt fprintf(stream, "CeedVector length %ld\n", (long)vec->length); 305*0436c2adSjeremylt snprintf(fmt, sizeof fmt, " %s\n", fpfmt ? fpfmt : "%g"); 306*0436c2adSjeremylt for (CeedInt i=0; i<vec->length; i++) 307*0436c2adSjeremylt fprintf(stream, fmt, x[i]); 308*0436c2adSjeremylt 309*0436c2adSjeremylt ierr = CeedVectorRestoreArrayRead(vec, &x); CeedChk(ierr); 310*0436c2adSjeremylt 311*0436c2adSjeremylt return 0; 312*0436c2adSjeremylt } 313*0436c2adSjeremylt 314*0436c2adSjeremylt /** 315*0436c2adSjeremylt @brief Get the Ceed associated with a CeedVector 316*0436c2adSjeremylt 317*0436c2adSjeremylt @param vec CeedVector to retrieve state 318*0436c2adSjeremylt @param[out] ceed Variable to store ceed 319*0436c2adSjeremylt 320*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 321*0436c2adSjeremylt 322*0436c2adSjeremylt @ref Advanced 323*0436c2adSjeremylt **/ 324*0436c2adSjeremylt int CeedVectorGetCeed(CeedVector vec, Ceed *ceed) { 325*0436c2adSjeremylt *ceed = vec->ceed; 326*0436c2adSjeremylt return 0; 327*0436c2adSjeremylt } 328*0436c2adSjeremylt 329*0436c2adSjeremylt /** 330*0436c2adSjeremylt @brief Get the length of a CeedVector 331*0436c2adSjeremylt 332*0436c2adSjeremylt @param vec CeedVector to retrieve length 333*0436c2adSjeremylt @param[out] length Variable to store length 334*0436c2adSjeremylt 335*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 336*0436c2adSjeremylt 337*0436c2adSjeremylt @ref Advanced 338*0436c2adSjeremylt **/ 339*0436c2adSjeremylt int CeedVectorGetLength(CeedVector vec, CeedInt *length) { 340*0436c2adSjeremylt *length = vec->length; 341*0436c2adSjeremylt return 0; 342*0436c2adSjeremylt } 343*0436c2adSjeremylt 344*0436c2adSjeremylt /** 345*0436c2adSjeremylt @brief Get the state of a CeedVector 346*0436c2adSjeremylt 347*0436c2adSjeremylt @param vec CeedVector to retrieve state 348*0436c2adSjeremylt @param[out] state Variable to store state 349*0436c2adSjeremylt 350*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 351*0436c2adSjeremylt 352*0436c2adSjeremylt @ref Advanced 353*0436c2adSjeremylt **/ 354*0436c2adSjeremylt int CeedVectorGetState(CeedVector vec, uint64_t *state) { 355*0436c2adSjeremylt *state = vec->state; 356*0436c2adSjeremylt return 0; 357*0436c2adSjeremylt } 358*0436c2adSjeremylt 359*0436c2adSjeremylt /** 360*0436c2adSjeremylt @brief Get the backend data of a CeedVector 361*0436c2adSjeremylt 362*0436c2adSjeremylt @param vec CeedVector to retrieve state 363*0436c2adSjeremylt @param[out] data Variable to store data 364*0436c2adSjeremylt 365*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 366*0436c2adSjeremylt 367*0436c2adSjeremylt @ref Advanced 368*0436c2adSjeremylt **/ 369*0436c2adSjeremylt int CeedVectorGetData(CeedVector vec, void **data) { 370*0436c2adSjeremylt *data = vec->data; 371*0436c2adSjeremylt return 0; 372*0436c2adSjeremylt } 373*0436c2adSjeremylt 374*0436c2adSjeremylt /** 375*0436c2adSjeremylt @brief Set the backend data of a CeedVector 376*0436c2adSjeremylt 377*0436c2adSjeremylt @param[out] vec CeedVector to retrieve state 378*0436c2adSjeremylt @param data Data to set 379*0436c2adSjeremylt 380*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 381*0436c2adSjeremylt 382*0436c2adSjeremylt @ref Advanced 383*0436c2adSjeremylt **/ 384*0436c2adSjeremylt int CeedVectorSetData(CeedVector vec, void **data) { 385*0436c2adSjeremylt vec->data = *data; 386*0436c2adSjeremylt return 0; 387*0436c2adSjeremylt } 388*0436c2adSjeremylt 389*0436c2adSjeremylt /** 390*0436c2adSjeremylt @brief Add a refrence to a CeedVector 391*0436c2adSjeremylt 392*0436c2adSjeremylt @param[out] vec CeedVector to increment refrence counter 393*0436c2adSjeremylt 394*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 395*0436c2adSjeremylt 396*0436c2adSjeremylt @ref Advanced 397*0436c2adSjeremylt **/ 398*0436c2adSjeremylt int CeedVectorAddReference(CeedVector vec) { 399*0436c2adSjeremylt vec->refcount++; 400*0436c2adSjeremylt return 0; 401*0436c2adSjeremylt } 402*0436c2adSjeremylt 403*0436c2adSjeremylt /** 404*0436c2adSjeremylt @brief Destroy a CeedVector 405*0436c2adSjeremylt 406*0436c2adSjeremylt @param vec CeedVector to destroy 407*0436c2adSjeremylt 408*0436c2adSjeremylt @return An error code: 0 - success, otherwise - failure 409*0436c2adSjeremylt 410*0436c2adSjeremylt @ref Basic 411*0436c2adSjeremylt **/ 412*0436c2adSjeremylt int CeedVectorDestroy(CeedVector *vec) { 413*0436c2adSjeremylt int ierr; 414*0436c2adSjeremylt 415*0436c2adSjeremylt if (!*vec || --(*vec)->refcount > 0) 416*0436c2adSjeremylt return 0; 417*0436c2adSjeremylt 418*0436c2adSjeremylt if ((*vec) && ((*vec)->state % 2) == 1) 419*0436c2adSjeremylt return CeedError((*vec)->ceed, 1, "Cannot destroy CeedVector, the access " 420*0436c2adSjeremylt "lock is in use"); 421*0436c2adSjeremylt 422*0436c2adSjeremylt if ((*vec)->Destroy) { 423*0436c2adSjeremylt ierr = (*vec)->Destroy(*vec); CeedChk(ierr); 424*0436c2adSjeremylt } 425*0436c2adSjeremylt 426*0436c2adSjeremylt ierr = CeedDestroy(&(*vec)->ceed); CeedChk(ierr); 427*0436c2adSjeremylt ierr = CeedFree(vec); CeedChk(ierr); 428*0436c2adSjeremylt 429*0436c2adSjeremylt return 0; 430*0436c2adSjeremylt } 431*0436c2adSjeremylt 432*0436c2adSjeremylt /// @cond DOXYGEN_SKIP 433*0436c2adSjeremylt // Indicate that vector will be provided as an explicit argument to 434*0436c2adSjeremylt // CeedOperatorApply(). 435*0436c2adSjeremylt CeedVector CEED_VECTOR_ACTIVE = &ceed_vector_active; 436*0436c2adSjeremylt 437*0436c2adSjeremylt // Indicate that no vector is applicable (i.e., for CEED_EVAL_WEIGHTS). 438*0436c2adSjeremylt CeedVector CEED_VECTOR_NONE = &ceed_vector_none; 439*0436c2adSjeremylt /// @endcond 440*0436c2adSjeremylt /// @} 441