1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
 SAF_StateGrp *
 saf_declare_state_group(SAF_ParMode   pmode,            /* The parallel mode. */
                         SAF_Db        *db,              /* The database in which to declare the new state group. */
                         const char    *name,            /* The name of this state group. */
                         SAF_Suite     *suite,           /* The suite that these states are associated with. */
                         SAF_Set       *mesh_space,      /* The set representing the computational mesh */
                         SAF_StateTmpl *stmpl,           /* A state template that defines the pattern (via a list of field
                                                          * templates) of fields that can be stored in each state. */
                         SAF_Quantity  *quantity,        /* The quantity associated with the axis of the parametric space.
                                                          * For example, SAF_TIME_QUANTITY. */
                         SAF_Unit      *unit,            /* The units associated with the axis of the parametric space. */
                         hid_t         coord_data_type,  /* The data type of the coordinates of the parametric space. */
                         SAF_StateGrp  *state_grp        /* The returned handle for a state group. */
                         )

 {
     SAF_ENTER(saf_declare_state_group,0);

     SAF_Cat stategrp_cat;
     int num_space_cats=0, num_param_cats=0, num_ftmpls=0;
     char tmp_name[1024];
     int index[1];
     SAF_FieldTmpl comp_ftmpl[2];
     SAF_Cat *space_cats = NULL;
     SAF_Cat *param_cats = NULL;
     SAF_FieldTmpl *coords_ftmpl;
     SAF_Field     *coord_fields;
     SAF_Field     *coords, *dep_var_fld;

     SAF_Field     mesh_defcoord_field;
     SAF_FieldTmpl mesh_defcoord_tmpl;

     SAF_FieldTmpl stategrp_comp_tmpls[2];
     SAF_FieldTmpl stategrp_tmpl;
     SAF_Field     *stategrp_contents;
     SAF_Db        suite_db=SS_FILE_NULL;

     int l_numFound = 0;
     SAF_Cat *l_catsFound = NULL;

     ss_pers_file((ss_pers_t*)suite, &suite_db);

     /* create a coordinate field for the suite, consisting of two components, a coordinate field of the parametric space, and
      * an indirect field containing IDs of the coordinate fields of the computational mesh; these component fields must also
      * be created */

     /* saf_find_categories (suite, "space_slice_cat", SAF_ANY_ROLE, SAF_ANY_TOPODIM, &num_space_cats, &space_cats); */
     saf_find_collections(pmode, suite, SAF_SPACE_SLICE, SAF_CELLTYPE_ANY, SAF_ANY_TOPODIM,
                          SAF_DECOMP_TORF, &num_space_cats, &space_cats);
     /* saf_find_categories (suite, "param_slice_cat", SAF_ANY_ROLE, SAF_ANY_TOPODIM, &num_param_cats, &param_cats); */
     saf_find_collections(pmode, suite, SAF_PARAM_SLICE, SAF_CELLTYPE_ANY, SAF_ANY_TOPODIM,
                          SAF_DECOMP_TORF, &num_param_cats, &param_cats);

     if( param_cats == NULL || space_cats == NULL ) {
         SAF_ERROR(NULL, _saf_errmsg("param_cats or space_cats collections returned NULL on suite"));
     }

     saf_find_collections(pmode, suite, SAF_TOPOLOGY,
                          SAF_CELLTYPE_ANY, SAF_ANY_TOPODIM,
                          SAF_DECOMP_TORF, &l_numFound, &l_catsFound);

     if( l_numFound <= 0 ) {
         saf_declare_category(SAF_ALL, db, "stategroups",
                              SAF_TOPOLOGY, 0, &stategrp_cat);
         saf_declare_collection(pmode, suite, &stategrp_cat,
                                SAF_CELLTYPE_POINT, 1, SAF_1DC(1),
                                SAF_DECOMP_FALSE);
     } else if( l_numFound >= 1 ) {
         stategrp_cat = l_catsFound[0];
         /* free(l_catsFound); */
     }

     coord_fields = (SAF_Field *)malloc( 2 * sizeof(SAF_Field));

     /* create the coordinate field associated with the parametric space; */
     sprintf (tmp_name, "%s_PARAM_COORDS_TMPL", name);
     saf_declare_field_tmpl (pmode, db, tmp_name, SAF_ALGTYPE_SCALAR, SAF_UNITY, quantity, 1, NULL, &(comp_ftmpl[0]));
     sprintf (tmp_name, "%s_PARAM_COORDS", name);
     saf_declare_field (pmode, db, comp_ftmpl+0, tmp_name, suite, unit, SAF_SELF(XXX), SAF_NODAL(param_cats+0, param_cats+0),
                        coord_data_type, NULL, SAF_INTERLEAVE_NONE, SAF_IDENTITY, NULL, &(coord_fields[0]));
     saf_declare_coords (pmode, coord_fields+0);

     /* create the indirect field that will contain the coord fields of each of the sets in the state group */
     saf_find_default_coords(pmode, mesh_space, &mesh_defcoord_field);
     if (SS_PERS_ISNULL(&mesh_defcoord_field))
         SAF_ERROR(NULL, _saf_errmsg("default coords are not defined on the mesh set"));

     saf_describe_field(pmode, &mesh_defcoord_field, &mesh_defcoord_tmpl,
                        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                        NULL, NULL, NULL, NULL, NULL);

     sprintf (tmp_name, "%s_SPACE_COORDS_TMPL", name);
     saf_declare_field_tmpl (pmode, db, tmp_name, SAF_ALGTYPE_FIELD, SAF_ANY_BASIS, SAF_NOT_APPLICABLE_QUANTITY, 1,
                             &mesh_defcoord_tmpl, &(comp_ftmpl[1]));
     sprintf (tmp_name, "%s_SPACE_COORDS", name);

     saf_declare_field (pmode, db, comp_ftmpl+1, tmp_name, suite, SAF_NOT_APPLICABLE_UNIT, SAF_SELF(XXX),
                        SAF_NODAL(space_cats+0, space_cats+0), SAF_HANDLE, NULL, SAF_INTERLEAVE_NONE, SAF_IDENTITY, NULL,
                        &(coord_fields[1]));

     saf_declare_coords (pmode, coord_fields+1);

     /* create the coord field made up of the param coord field and the space coord field */
     /* make this an indirect field until we can determine the status of composite fields containing components with different
      * algebraic types */
     coords = (SAF_Field *)malloc(sizeof(SAF_Field));
     sprintf( tmp_name, "%s_SUITE_COORDS_TMPL",name);

     coords_ftmpl = &(stategrp_comp_tmpls[0]);

     saf_declare_field_tmpl (pmode, db, tmp_name, SAF_ALGTYPE_FIELD, SAF_ANY_BASIS, SAF_NOT_APPLICABLE_QUANTITY, 2, comp_ftmpl,
                             coords_ftmpl);

     sprintf( tmp_name, "%s_SUITE_COORDS", name);

     saf_declare_field (pmode, db, coords_ftmpl, tmp_name, suite, SAF_NOT_APPLICABLE_UNIT, SAF_SELF(XXX),
                        SAF_NODAL(space_cats+0, space_cats+0), SAF_HANDLE, NULL, SAF_INTERLEAVE_VECTOR, SAF_IDENTITY, NULL, coords);

     index[0] = 0;

     saf_write_field (pmode, coords, 1, SAF_TUPLES, index, 1, SAF_HANDLE, (void **)&coord_fields, &suite_db);
     _saf_free(coord_fields);

     /* create the composite coord field made up of the param coord field and the space coord field */
 #if 0
     /* this is commented out in favor of using the indirect field above */
     sprintf (tmp_name, "%s_SUITE_COORDS_TMPL", name);
     saf_declare_field_tmpl(pmode, tmp_name, database, SAF_ALGTYPE_TUPLE, SAF_CARTESIAN, SAF_QLENGTH, 2,
                            comp_ftmpl, &coords_ftmpl);
     sprintf (tmp_name, "%s_SUITE_COORDS", name);
     saf_declare_field(pmode, coords_ftmpl, tmp_name, suite, SAF_NOT_APPLICABLE_UNIT, SAF_SELF(db),
                       SAF_NODAL(space_cats[0], space_cats[0]),
                       NULL, coord_fields, SAF_INTERLEAVE_VECTOR, SAF_IDENTITY, NULL, &coords);
 #endif

     /* create an indirect field to contain IDs of the fields for dependent variables; this is the current "state field"; use
      * the state template for this */

     /* find how many fields are in each state; this is the number of field templates in the state template */
     stategrp_comp_tmpls[1] = *stmpl;
     saf_describe_state_tmpl (pmode, stmpl, NULL,  &num_ftmpls, NULL);

     sprintf (tmp_name, "%s_DEP_VAR_FIELD", name);

     dep_var_fld = (SAF_Field *)malloc(sizeof(SAF_Field));
     if (num_ftmpls > 1) {   /* interleave isn't applicable if there's only 1 field per state */
         saf_declare_field (pmode, db, stmpl, tmp_name, suite, SAF_NOT_APPLICABLE_UNIT, SAF_SELF(XXX),
                            SAF_NODAL(space_cats+0, space_cats+0), SAF_HANDLE, NULL, SAF_INTERLEAVE_VECTOR, SAF_IDENTITY, NULL,
                            dep_var_fld);
     } else {
         saf_declare_field (pmode, db, stmpl, tmp_name, suite, SAF_NOT_APPLICABLE_UNIT, SAF_SELF(XXX),
                            SAF_NODAL(space_cats+0, space_cats+0), SAF_HANDLE, NULL, SAF_INTERLEAVE_NONE, SAF_IDENTITY, NULL,
                            dep_var_fld);
     }

     /* create the StateGrp indirect field that will contain the "composite" coords and dependent variable indirect fields */
     /* associate this stategrp field with the stategrp_cat category on suite */
     sprintf(tmp_name, "%s_TMPL", name);

     saf_declare_field_tmpl(pmode, db, tmp_name, SAF_ALGTYPE_FIELD, SAF_ANY_BASIS, SAF_NOT_APPLICABLE_QUANTITY,
                            2, stategrp_comp_tmpls, &stategrp_tmpl);
     saf_declare_field( pmode, db, &stategrp_tmpl, name, suite, SAF_NOT_APPLICABLE_UNIT, SAF_SELF(db),
                        SAF_NODAL(&stategrp_cat, &stategrp_cat), SAF_HANDLE, NULL, SAF_INTERLEAVE_VECTOR, SAF_IDENTITY, NULL,
                        state_grp);

     stategrp_contents = (SAF_Field *)malloc( 2 * sizeof(SAF_Field));
     stategrp_contents[0] = *coords;
     stategrp_contents[1] = *dep_var_fld;

     index[0] = 0;
     saf_write_field (pmode, state_grp, 1, SAF_TUPLES, index, 1, SAF_HANDLE, (void **)&stategrp_contents, &suite_db);

     _saf_free(coords);
     _saf_free(dep_var_fld);
     _saf_free(param_cats);
     _saf_free(space_cats);
     _saf_free(stategrp_contents);
     _saf_free(l_catsFound);
     SAF_LEAVE(SAF_SUCCESS);
 }