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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
 int
 saf_write_state(SAF_ParMode  pmode,             /* The parallel mode. */
                 SAF_StateGrp *state_grp,        /* The state group into which this state will be inserted. */
                 int          state_index,       /* The index within the state group at which this state will be written.
                                                  * This index is 0-based. */
                 SAF_Set      *mesh_space,       /* The ID of the mesh associated with this state. */
                 hid_t        coord_data_type,   /* The data type of COORD */
                 void         *coord_data,       /* The coordinate of STATE_INDEX within the state group.  For instance, this
                                                  * is typically the time value of the state. */
                 SAF_Field    *fields            /* The fields (the dependent variables) to be written to this state. */
                 )
 {
   SAF_ENTER(saf_write_state, SAF_PRECONDITION_ERROR);

   SAF_Db db=SS_FILE_NULL;
   SAF_Cat *param_cats = NULL, *space_cats = NULL, *stategrp_cats = NULL, *mesh_space_cats = NULL;
   int num_param_cats = 0, num_space_cats = 0, /*num_stategrp_cats = 0,*/ num_mesh_space_cats = 0;
   int coll_count = 0, param_count = 0;
   int i, add_count;
   int rel_buf[1];
   int index[1];
   SAF_Set suite; /* the suite "associated" with this stategroup */
   SAF_FieldTmpl stategrp_tmpl;

   SAF_Rel /* *space_rels = NULL,*/ *suite_space_rels = NULL;

   SAF_Field *stategrp_state = NULL;
   hid_t group_type;
   size_t group_size;
   SAF_Field *stategrp_contents = NULL;
   SAF_Field *coords = NULL;
   SAF_Field *coord = NULL;
   SAF_Field *mesh_coord = NULL, *param_coord = NULL;
   SAF_Field *mesh_default_coord = NULL;


   /* find the suite associated with this stategroup */
   saf_describe_field(pmode, state_grp, &stategrp_tmpl, NULL, &suite,
                      NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                      NULL, NULL, NULL, NULL);

   saf_get_count_and_type_for_field(pmode, state_grp, NULL, &group_size, &group_type );


   /* get and set the database and db handles */
   ss_pers_file((ss_pers_t*)&suite, &db);


   {
     /* If necessary, extend the SAF_SPACE_SLICE collection with which the states are associated */

     /* Find the SAF_SPACE_SLICE category defined on this set (suite) */
     space_cats = NULL;
     /* saf_find_categories (suite, "space_slice_cat" , SAF_ANY_ROLE, SAF_ANY_TOPODIM, &num_space_cats, (SAF_Cat **)&space_cats); */
     saf_find_collections(pmode, &suite, SAF_SPACE_SLICE, SAF_CELLTYPE_ANY, SAF_ANY_TOPODIM,
                          SAF_DECOMP_TORF, &num_space_cats, &space_cats);
     param_cats = NULL;
     /* saf_find_categories( suite, "param_slice_cat", SAF_ANY_ROLE, SAF_ANY_TOPODIM, &num_param_cats, (SAF_Cat **)&param_cats); */
     saf_find_collections(pmode, &suite, SAF_PARAM_SLICE, SAF_CELLTYPE_ANY, SAF_ANY_TOPODIM,
                          SAF_DECOMP_TORF, &num_param_cats, &param_cats);


     saf_find_collections(pmode, mesh_space, SAF_SPACE_SLICE, SAF_CELLTYPE_ANY, SAF_ANY_TOPODIM, SAF_DECOMP_TORF, \
                          &num_mesh_space_cats, NULL);



     if( num_mesh_space_cats < 1 ) {
       saf_declare_collection(pmode, mesh_space, space_cats+0, SAF_CELLTYPE_POINT, 1, SAF_1DC(1), SAF_DECOMP_FALSE);
     }
     mesh_space_cats = NULL;
     saf_find_collections(pmode, mesh_space, SAF_SPACE_SLICE, SAF_CELLTYPE_ANY, SAF_ANY_TOPODIM, SAF_DECOMP_TORF, \
                          &num_mesh_space_cats, &mesh_space_cats);



     /* stategrp_role = saf_find_one_role( database, "stategroup_role"); */
 /*
     stategrp_cats = NULL;
     saf_find_categories( suite, "stategroups", SAF_ANY_ROLE, SAF_ANY_TOPODIM, &num_stategrp_cats, (SAF_Cat **)&stategrp_cats);
 */


     saf_describe_collection (pmode, &suite, space_cats+0, NULL, &coll_count, NULL, NULL, NULL);
     saf_describe_collection (pmode, &suite, param_cats+0, NULL, &param_count, NULL, NULL, NULL);

     add_count = 0;
     if (coll_count < state_index+1) {  /* assume just 1-d suite for this first implementation */
       add_count = state_index - coll_count + 1;
       saf_extend_collection (pmode, &suite, space_cats+0, add_count, SAF_1DC(add_count));

       if ( add_count > 1 )
         printf("WARNING: saf_write_state: extending space collection by more than 1\n");

     }

 /*
     space_rels = NULL;
     saf_find_subset_relations(pmode, suite,  mesh_space, SAF_COMMON(space_cats[0]), &num_space_rels, &space_rels);
 */


 /*
     if( state_index > num_space_rels ) {
       printf("state_index is greater than number of subset relations: %i,%i",state_index, num_space_rels);
     }
 */


     if( add_count > 0 ){
       suite_space_rels = (SAF_Rel *)malloc( add_count * sizeof(SAF_Rel));
       for( i = 0 ; i < add_count ; i++ ) {

           saf_declare_subset_relation(pmode, &db, &suite, mesh_space, SAF_COMMON(space_cats+0), SAF_TUPLES, SAF_INT, NULL,
                                       H5I_INVALID_HID, NULL, &(suite_space_rels[i]));

         rel_buf[0] = coll_count + i; /* write the state_index to the subset relation */
         saf_write_subset_relation(pmode, suite_space_rels+i, H5T_NATIVE_INT, rel_buf, H5I_INVALID_HID, NULL, &db);
       }
     }


   }

   {

     /* the stategrp blob should contain two field handles:
          the first is the indirect coord field containing the mesh_coords, and param_coord
          the second is the state field containing the fields stored at this suite_index
     */
     index[0] = 0;
     stategrp_contents = NULL;
     saf_read_field (pmode, state_grp, NULL, 1, SAF_TUPLES, index, (void **)(&stategrp_contents));
     coord = &(stategrp_contents[0]);
     stategrp_state = &(stategrp_contents[1]);

     /* now read the coord field and get the mesh coord and the param coord (dump times) */
     coords = NULL;
     saf_read_field (pmode, coord, NULL, 1, SAF_TUPLES, index, (void **)(&coords));
     mesh_coord = &(coords[1]);
     param_coord = &(coords[0]);

     /* write the handle from the mesh_space default coord field to the mesh_coord indirect field */
     mesh_default_coord = (SAF_Field *)malloc(sizeof(SAF_Field));
     saf_find_default_coords(pmode, mesh_space, mesh_default_coord);
     if (SS_PERS_ISNULL(mesh_default_coord))
         SAF_ERROR(-1,_saf_errmsg("default coords are not defined on the mesh set"));
     index[0] = state_index;
     saf_write_field( pmode, mesh_coord, 1, SAF_TUPLES, index, 1, SAF_HANDLE, (void **)(&mesh_default_coord), &db);
     _saf_free(mesh_default_coord);

     /* write the param coord value (typically a dump time) to the param_coord field */
     /*
       coord contains the value of type coord_data_type.  coord and coord_data_type are supplied by the user
        in this functions parameters
     */
     while( param_count < (state_index+1) ) {
       add_count = (state_index+1) - param_count;
       saf_extend_collection (pmode, &suite, param_cats+0, add_count, SAF_1DC(add_count));
       saf_describe_collection (pmode, &suite, param_cats+0, NULL, &param_count, NULL, NULL, NULL);
     }
     index[0] = state_index;
     saf_write_field( pmode, param_coord, 1, SAF_TUPLES, index, 1, coord_data_type, (void **)&coord_data, &db);

     /* write the field IDs for the dependent variables to the state */
     saf_write_field( pmode, stategrp_state, 1, SAF_TUPLES, index, 1, SAF_HANDLE, (void **)&fields, &db);

     /*
       that should be it, no need to write anything to the stategrp field itself since it simply contains
        the ids of the fields we're writing to.
     */
   }


         if( param_cats != NULL )
                 free(param_cats);

         if( space_cats != NULL )
                 free(space_cats);

         if( mesh_space_cats != NULL )
                 free(mesh_space_cats);

         if( stategrp_cats != NULL )
                 free(stategrp_cats);

         if( suite_space_rels != NULL )
                 free( suite_space_rels );

         if( stategrp_contents != NULL )
                 free( stategrp_contents);

         if( coords != NULL )
                 free(coords);

         SAF_LEAVE(0);
 }