SAF_FieldTmpl *
saf_declare_field_tmpl(SAF_ParMode pmode, /* The parallel mode. */
SAF_Db *db, /* The database handle in which to create the template. */
const char *name, /* The name of the field template. */
SAF_Algebraic *atype, /* The algebraic type: SAF_ALGTYPE_SCALAR, SAF_ALGTYPE_VECTOR,
* SAF_ALGTYPE_TENSOR, SAF_ALGTYPE_SYMTENSOR, SAF_ALGTYPE_FIELD. If
* the algebraic type is SAF_ALGTYPE_FIELD, then all we know about the
* field is that it references other fields (i.e., an indirect field).
* Therefore, the next four arguments are not applicable. More
* generalized user defined type definitions will be available in later
* implementations. */
SAF_Basis *basis, /* The basis. Not implemented yet. Pass null */
SAF_Quantity *quantity, /* The quantity. See saf_declare_quantity() for quantity definitions and how
* to define new quantities. */
int num_comp, /* Number of components. Although this may often be inferred from ATYPE,
* SAF currently does no work to infer it. Pass SAF_NOT_APPLICABLE_INT if
* this template will be used in the declaration of an inhomogeneous field.
* Otherwise, pass the number of components. For a simple scalar field, the
* number of components is 1. See Fields for further discussion of
* inhomogeneous fields. */
SAF_FieldTmpl *ctmpl, /* This is an array of NUM_COMPS field template handles that comprise the
* composite field template or NULL if there are no component field
* templates. Pass NULL if this field template will be used in the
* declaration of an INhomogeneous field. */
SAF_FieldTmpl *ftmpl /* Returned field template handle for composite fields. If the algebraic
* type (ATYPE) is SAF_ALGTYPE_FIELD, then the returned field template
* may be used as a state template (see State Templates). */
)
{
SAF_ENTER(saf_declare_field_tmpl, NULL);
ss_scope_t scope=SS_SCOPE_NULL; /* The scope in which to declare the new field template. */
SAF_REQUIRE(_saf_valid_pmode(pmode), SAF_LOW_CHK_COST, NULL,
_saf_errmsg("PMODE must be valid"));
if (!_saf_is_participating_proc(pmode)) SAF_RETURN(NULL);
SAF_REQUIRE(ftmpl, SAF_LOW_CHK_COST, NULL,
_saf_errmsg("FTMPL must be non-null"));
SAF_REQUIRE(name, SAF_LOW_CHK_COST, NULL,
_saf_errmsg("NAME must be non-null"));
SAF_REQUIRE(num_comp==SAF_NOT_APPLICABLE_INT || num_comp>=1, SAF_LOW_CHK_COST, NULL,
_saf_errmsg("NUM_COMP >= 1"));
SAF_REQUIRE(num_comp==SAF_NOT_APPLICABLE_INT || (num_comp>1 && ctmpl) || num_comp==1, SAF_LOW_CHK_COST, NULL,
_saf_errmsg("CTMPL must be non-NULL if NUM_COMP > 1"));
SAF_REQUIRE(SS_ALGEBRAIC(atype), SAF_LOW_CHK_COST, NULL,
_saf_errmsg("ATYPE must be a valid algebraic type handle"));
SAF_REQUIRE(ctmpl || num_comp==SAF_NOT_APPLICABLE_INT || (!ctmpl && num_comp==1 && !SS_ALGEBRAIC(atype)->indirect),
SAF_LOW_CHK_COST, NULL,
_saf_errmsg("CTMPL may be NULL only if NUM_COMP == 1 and ATYPE must be direct"));
SAF_REQUIRE(!ctmpl || (ctmpl && num_comp!=SAF_NOT_APPLICABLE_INT), SAF_LOW_CHK_COST, NULL,
_saf_errmsg("CTMPL must be NULL if components are not appropriate"));
SAF_REQUIRE(!basis || SS_BASIS(basis), SAF_LOW_CHK_COST, NULL,
_saf_errmsg("BASIS must be a valid basis handle or NULL"));
SAF_REQUIRE(!quantity || SS_QUANTITY(quantity), SAF_LOW_CHK_COST, NULL,
_saf_errmsg("QUANTITY must be a valid quantity handle if supplied"));
/* The scope in which to declare the field template. */
ss_file_topscope(db, &scope);
/* Allocate and/or initialize the new field template object. */
ftmpl = (ss_fieldtmpl_t*)ss_pers_new(&scope, SS_MAGIC(ss_fieldtmpl_t), NULL, SAF_ALL==pmode?SS_ALLSAME:0U,
(ss_pers_t*)ftmpl, NULL);
if (SAF_EACH==pmode) SS_PERS_UNIQUE(ftmpl);
/* Save the component field templates */
if (ctmpl) {
if (ss_array_resize(SS_FIELDTMPL_P(ftmpl,ftmpls), (size_t)num_comp)<0 ||
ss_array_put(SS_FIELDTMPL_P(ftmpl,ftmpls), ss_pers_tm, (size_t)0, (size_t)num_comp, ctmpl)<0)
SAF_ERROR(NULL, _saf_errmsg("unable to link to component field templates"));
}
/* Initialize the other non-zero parts of the field template */
ss_string_set(SS_FIELDTMPL_P(ftmpl,name), name);
SS_FIELDTMPL(ftmpl)->algebraic = *atype;
if (basis) SS_FIELDTMPL(ftmpl)->basis = *basis;
if (quantity) SS_FIELDTMPL(ftmpl)->quantity = *quantity;
SS_FIELDTMPL(ftmpl)->num_comps = num_comp;
/* return stuff */
SAF_LEAVE(ftmpl);
}