35#include <gridfields/type.h>
36#include <gridfields/gridfield.h>
37#include <gridfields/grid.h>
38#include <gridfields/implicit0cells.h>
39#include <gridfields/gridfieldoperator.h>
40#include <gridfields/restrict.h>
41#include <gridfields/refrestrict.h>
42#include <gridfields/array.h>
43#include <gridfields/GFError.h>
45#include <libdap/BaseType.h>
46#include <libdap/Int32.h>
47#include <libdap/Float64.h>
48#include <libdap/Array.h>
49#include <libdap/util.h>
51#include "ugrid_utils.h"
53#include "MeshDataVariable.h"
54#include "TwoDMeshTopology.h"
61#define BESDEBUG( x, y )
71TwoDMeshTopology::TwoDMeshTopology() :
72 d_meshVar(0), nodeCoordinateArrays(0), nodeCount(0), faceNodeConnectivityArray(0), faceCount(0), faceCoordinateArrays(
73 0), gridTopology(0), d_inputGridField(0), resultGridField(0), fncCellArray(0), _initialized(false)
75 rangeDataArrays =
new vector<MeshDataVariable *>();
76 sharedIntArrays =
new vector<int *>();
77 sharedFloatArrays =
new vector<float *>();
80TwoDMeshTopology::~TwoDMeshTopology()
82 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - BEGIN" << endl);
83 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - (" <<
this <<
")" << endl);
85 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting GF::GridField 'resultGridField'." << endl);
86 delete resultGridField;
88 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting GF::GridField 'inputGridField'." << endl);
89 delete d_inputGridField;
91 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting GF::Grid 'gridTopology'." << endl);
94 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting GF::Arrays..." << endl);
95 for (vector<GF::Array *>::iterator it = gfArrays.begin(); it != gfArrays.end(); ++it) {
97 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting GF:Array '" << gfa->getName() <<
"'" << endl);
100 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - GF::Arrays deleted." << endl);
102 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting sharedIntArrays..." << endl);
103 for (vector<int *>::iterator it = sharedIntArrays->begin(); it != sharedIntArrays->end(); ++it) {
105 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting integer array '" << i <<
"'" << endl);
108 delete sharedIntArrays;
110 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting sharedFloatArrays..." << endl);
111 for (vector<float *>::iterator it = sharedFloatArrays->begin(); it != sharedFloatArrays->end(); ++it) {
113 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting float array '" << f <<
"'" << endl);
116 delete sharedFloatArrays;
118 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting range data vector" << endl);
119 delete rangeDataArrays;
120 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Range data vector deleted." << endl);
122 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting vector of node coordinate arrays." << endl);
123 delete nodeCoordinateArrays;
125 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting vector of face coordinate arrays." << endl);
126 delete faceCoordinateArrays;
128 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - Deleting face node connectivity cell array (GF::Node's)." << endl);
129 delete[] fncCellArray;
131 BESDEBUG(
"ugrid",
"~TwoDMeshTopology() - END" << endl);
139 if (_initialized)
return;
141 d_meshVar = dds->var(meshVarName);
143 if (!d_meshVar)
throw Error(
"Unable to locate variable: " + meshVarName);
145 dimension = getAttributeValue(d_meshVar, UGRID_TOPOLOGY_DIMENSION);
146 if (dimension.empty()) dimension = getAttributeValue(d_meshVar, UGRID_DIMENSION);
148 if (dimension.empty()) {
149 string msg =
"ugr5(): The mesh topology variable '" + d_meshVar->name()
150 +
"' is missing the required attribute named '" + UGRID_TOPOLOGY_DIMENSION +
"'";
151 BESDEBUG(
"ugrid",
"TwoDMeshTopology::init() - " << msg);
156 ingestNodeCoordinateArrays(d_meshVar, dds);
161 ingestFaceCoordinateArrays(d_meshVar, dds);
164 ingestFaceNodeConnectivityArray(d_meshVar, dds);
180 throw Error(malformed_expr,
181 "ugr5(): While trying to read the UGrid mesh variable, an error occurred: " + e.get_error_message());
183 catch (std::exception &e) {
184 throw Error(malformed_expr,
185 string(
"ugr5(): While trying to read the UGrid mesh variable, an error occurred: ") + e.what());
193 BESDEBUG(
"ugrid",
"TwoDMeshTopology::setNodeCoordinateDimension() - BEGIN" << endl);
194 libdap::Array *dapArray = mdv->getDapArray();
195 libdap::Array::Dim_iter ait1;
197 for (ait1 = dapArray->dim_begin(); ait1 != dapArray->dim_end(); ++ait1) {
199 string dimName = dapArray->dimension_name(ait1);
201 if (dimName.compare(nodeDimensionName) == 0) {
203 "TwoDMeshTopology::setNodeCoordinateDimension() - Found dimension name matching nodeDimensionName '"<< nodeDimensionName <<
"'" << endl);
204 int size = dapArray->dimension_size(ait1,
true);
205 if (size == nodeCount) {
207 "TwoDMeshTopology::setNodeCoordinateDimension() - Dimension sizes match (" << libdap::long_to_string(nodeCount) <<
") - DONE" << endl);
209 mdv->setLocationCoordinateDimension(ait1);
216 "Unable to determine the node coordinate dimension of the range variable '" + mdv->getName()
217 +
"' The node dimension is named '" + nodeDimensionName +
"' with size "
218 + libdap::long_to_string(nodeCount));
225 libdap::Array *dapArray = mdv->getDapArray();
226 libdap::Array::Dim_iter ait1;
228 for (ait1 = dapArray->dim_begin(); ait1 != dapArray->dim_end(); ++ait1) {
229 string dimName = dapArray->dimension_name(ait1);
231 if (dimName.compare(faceDimensionName) == 0) {
232 int size = dapArray->dimension_size(ait1,
true);
233 if (size == faceCount) {
235 mdv->setLocationCoordinateDimension(ait1);
242 "Unable to determine the face coordinate dimension of the range variable '" + mdv->getName()
243 +
"' The face coordinate dimension is named '" + faceDimensionName +
"' with size "
244 + libdap::long_to_string(faceCount));
251 BESDEBUG(
"ugrid",
"TwoDMeshTopology::setLocationCoordinateDimension() - BEGIN" << endl);
256 switch (mdv->getGridLocation()) {
260 "TwoDMeshTopology::setLocationCoordinateDimension() - Checking Node variable '"<< mdv->getName() <<
"'" << endl);
262 setNodeCoordinateDimension(mdv);
269 "TwoDMeshTopology::setLocationCoordinateDimension() - Checking Face variable '"<< mdv->getName() <<
"'" << endl);
271 setFaceCoordinateDimension(mdv);
278 string msg =
"TwoDMeshTopology::setLocationCoordinateDimension() - Unknown/Unsupported location value '"
279 + libdap::long_to_string(mdv->getGridLocation()) +
"'";
280 BESDEBUG(
"ugrid", msg << endl);
286 "TwoDMeshTopology::setLocationCoordinateDimension() - MeshDataVariable '"<< mdv->getName() <<
"' is a "<< locstr <<
" variable," << endl);
288 "TwoDMeshTopology::setLocationCoordinateDimension() - MeshDataVariable '"<< mdv->getName() <<
"' location coordinate dimension is '" << mdv->getDapArray()->dimension_name(mdv->getLocationCoordinateDimension()) <<
"'" << endl);
290 BESDEBUG(
"ugrid",
"TwoDMeshTopology::setLocationCoordinateDimension() - DONE" << endl);
301void TwoDMeshTopology::ingestFaceNodeConnectivityArray(libdap::BaseType *meshTopology, libdap::DDS *dds)
304 BESDEBUG(
"ugrid",
"TwoDMeshTopology::ingestFaceNodeConnectivityArray() - Locating FNCA" << endl);
306 string face_node_connectivity_var_name;
307 AttrTable at = meshTopology->get_attr_table();
309 AttrTable::Attr_iter iter_fnc = at.simple_find(UGRID_FACE_NODE_CONNECTIVITY);
310 if (iter_fnc != at.attr_end()) {
311 face_node_connectivity_var_name = at.get_attr(iter_fnc, 0);
315 "Could not locate the " UGRID_FACE_NODE_CONNECTIVITY
" attribute in the " UGRID_MESH_TOPOLOGY
" variable! "
316 "The mesh_topology variable is named " + meshTopology->name());
319 "TwoDMeshTopology::ingestFaceNodeConnectivityArray() - Located the '" << UGRID_FACE_NODE_CONNECTIVITY <<
"' attribute." << endl);
323 BaseType *btp = dds->var(face_node_connectivity_var_name);
327 "Could not locate the " UGRID_FACE_NODE_CONNECTIVITY
" variable named '" + face_node_connectivity_var_name
328 +
"'! " +
"The mesh_topology variable is named " + meshTopology->name());
331 libdap::Array *fncArray =
dynamic_cast<libdap::Array*
>(btp);
333 throw Error(malformed_expr,
334 "Face Node Connectivity variable '" + face_node_connectivity_var_name
335 +
"' is not an Array type. It's an instance of " + btp->type_name());
339 "TwoDMeshTopology::ingestFaceNodeConnectivityArray() - Located FNC Array '" << fncArray->name() <<
"'." << endl);
342 int numDims = fncArray->dimensions(
true);
344 throw Error(malformed_expr,
345 "Face Node Connectivity variable '" + face_node_connectivity_var_name
346 +
"' Must have two (2) dimensions. It has " + libdap::long_to_string(numDims));
350 "TwoDMeshTopology::ingestFaceNodeConnectivityArray() - FNC Array '" << fncArray->name() <<
"' has two (2) dimensions." << endl);
353 libdap::Array::Dim_iter firstDim = fncArray->dim_begin();
354 libdap::Array::Dim_iter secondDim = fncArray->dim_begin();
357 if (faceDimensionName.empty()) {
360 int sizeFirst = fncArray->dimension_size(firstDim,
true);
361 int sizeSecond = fncArray->dimension_size(secondDim,
true);
363 "TwoDMeshTopology::ingestFaceNodeConnectivityArray() - sizeFirst: "<< libdap::long_to_string(sizeFirst) << endl);
365 "TwoDMeshTopology::ingestFaceNodeConnectivityArray() - sizeSecond: "<< libdap::long_to_string(sizeSecond) << endl);
367 if (sizeFirst < sizeSecond) {
369 "TwoDMeshTopology::ingestFaceNodeConnectivityArray() - FNC Array first dimension is smaller than second." << endl);
370 fncNodesDim = firstDim;
371 fncFacesDim = secondDim;
375 "TwoDMeshTopology::ingestFaceNodeConnectivityArray() - FNC Array second dimension is smaller than first." << endl);
376 fncNodesDim = secondDim;
377 fncFacesDim = firstDim;
381 "TwoDMeshTopology::ingestFaceNodeConnectivityArray() - fncFacesDim meshVarName: '" << fncArray->dimension_name(fncFacesDim) <<
"'" << endl);
383 "TwoDMeshTopology::ingestFaceNodeConnectivityArray() - fncFacesDim size: '" << fncArray->dimension_size(fncFacesDim,
true) <<
"'" << endl);
385 faceDimensionName = fncArray->dimension_name(fncFacesDim);
391 if (faceDimensionName.compare(fncArray->dimension_name(firstDim)) == 0) {
392 fncNodesDim = secondDim;
393 fncFacesDim = firstDim;
395 else if (faceDimensionName.compare(fncArray->dimension_name(secondDim)) == 0) {
396 fncNodesDim = firstDim;
397 fncFacesDim = secondDim;
400 string msg =
"The face coordinate dimension of the Face Node Connectivity variable '"
401 + face_node_connectivity_var_name +
"' Has dimension name.'" + fncArray->dimension_name(fncFacesDim)
402 +
"' which does not match the existing face coordinate dimension meshVarName '" + faceDimensionName
404 BESDEBUG(
"ugrid", msg << endl);
407 BESDEBUG(
"ugrid",
"TwoDMeshTopology::ingestFaceNodeConnectivityArray() - Face dimension names match." << endl);
412 "TwoDMeshTopology::ingestFaceNodeConnectivityArray() - Face dimension name: '" << faceDimensionName <<
"'" << endl);
415 if (faceCount == 0) {
416 faceCount = fncArray->dimension_size(fncFacesDim,
true);
418 "TwoDMeshTopology::ingestFaceNodeConnectivityArray() - Face count: "<< libdap::long_to_string(faceCount) << endl);
424 "TwoDMeshTopology::ingestFaceNodeConnectivityArray() - Face count: "<< libdap::long_to_string(faceCount) << endl);
425 if (faceCount != fncArray->dimension_size(fncFacesDim,
true)) {
426 string msg =
"The faces dimension of the Face Node Connectivity variable '"
427 + face_node_connectivity_var_name +
"' Has size "
428 + libdap::long_to_string(fncArray->dimension_size(fncFacesDim,
true))
429 +
" which does not match the existing face count of " + libdap::long_to_string(faceCount);
430 BESDEBUG(
"ugrid", msg << endl);
433 BESDEBUG(
"ugrid",
"TwoDMeshTopology::ingestFaceNodeConnectivityArray() - Face counts match!" << endl);
436 faceNodeConnectivityArray = fncArray;
438 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getFaceNodeConnectivityArray() - Got FCNA '"+fncArray->name()+
"'" << endl);
446void TwoDMeshTopology::ingestFaceCoordinateArrays(libdap::BaseType *meshTopology, libdap::DDS *dds)
449 "TwoDMeshTopology::ingestFaceCoordinateArrays() - BEGIN Gathering face coordinate arrays..." << endl);
451 if (faceCoordinateArrays == 0) faceCoordinateArrays =
new vector<libdap::Array *>();
453 faceCoordinateArrays->clear();
455 string face_coordinates;
456 AttrTable at = meshTopology->get_attr_table();
458 AttrTable::Attr_iter iter_nodeCoors = at.simple_find(UGRID_FACE_COORDINATES);
459 if (iter_nodeCoors != at.attr_end()) {
460 face_coordinates = at.get_attr(iter_nodeCoors, 0);
463 "TwoDMeshTopology::ingestFaceCoordinateArrays() - Located '"<< UGRID_FACE_COORDINATES <<
"' attribute." << endl);
466 vector<string> faceCoordinateNames = split(face_coordinates,
' ');
469 vector<string>::iterator coorName_it;
470 for (coorName_it = faceCoordinateNames.begin(); coorName_it != faceCoordinateNames.end(); ++coorName_it) {
471 string faceCoordinateName = *coorName_it;
474 "TwoDMeshTopology::ingestFaceCoordinateArrays() - Processing face coordinate '"<< faceCoordinateName <<
"'." << endl);
477 BaseType *btp = dds->var(faceCoordinateName);
480 "Could not locate the " UGRID_FACE_COORDINATES
" variable named '" + faceCoordinateName +
"'! "
481 +
"The mesh_topology variable is named " + meshTopology->name());
483 libdap::Array *newFaceCoordArray =
dynamic_cast<libdap::Array*
>(btp);
484 if (newFaceCoordArray == 0) {
485 throw Error(malformed_expr,
486 "Face coordinate variable '" + faceCoordinateName +
"' is not an Array type. It's an instance of "
491 "TwoDMeshTopology::ingestFaceCoordinateArrays() - Found face coordinate array '"<< faceCoordinateName <<
"'." << endl);
494 if (newFaceCoordArray->dimensions(
true) != 1) {
495 throw Error(malformed_expr,
496 "Face coordinate variable '" + faceCoordinateName
497 +
"' has more than one dimension. That's just not allowed. It has "
498 + long_to_string(newFaceCoordArray->dimensions(
true)) +
" dimensions.");
501 "TwoDMeshTopology::ingestFaceCoordinateArrays() - Face coordinate array '"<< faceCoordinateName <<
"' has a single dimension." << endl);
504 string dimName = newFaceCoordArray->dimension_name(newFaceCoordArray->dim_begin());
505 int dimSize = newFaceCoordArray->dimension_size(newFaceCoordArray->dim_begin(),
true);
508 "TwoDMeshTopology::ingestFaceCoordinateArrays() - dimName: '"<< dimName <<
"' dimSize: " << libdap::long_to_string(dimSize) << endl);
510 if (faceDimensionName.empty()) {
511 faceDimensionName = dimName;
514 "TwoDMeshTopology::ingestFaceCoordinateArrays() - faceDimensionName: '"<< faceDimensionName <<
"' " << endl);
516 if (faceDimensionName.compare(dimName) != 0) {
518 "The face coordinate array '" + faceCoordinateName +
"' has the named dimension '" + dimName
519 +
"' which differs from the expected dimension meshVarName '" + faceDimensionName
520 +
"'. The mesh_topology variable is named " + meshTopology->name());
522 BESDEBUG(
"ugrid",
"TwoDMeshTopology::ingestFaceCoordinateArrays() - Face dimension names match." << endl);
524 if (faceCount == 0) {
528 "TwoDMeshTopology::ingestFaceCoordinateArrays() - faceCount: "<< libdap::long_to_string(faceCount) << endl);
530 if (faceCount != dimSize) {
532 "The face coordinate array '" + faceCoordinateName +
"' has a dimension size of "
533 + libdap::long_to_string(dimSize) +
" which differs from the the expected size of "
534 + libdap::long_to_string(faceCount) +
" The mesh_topology variable is named "
535 + meshTopology->name());
537 BESDEBUG(
"ugrid",
"TwoDMeshTopology::ingestFaceCoordinateArrays() - Face counts match." << endl);
540 faceCoordinateArrays->push_back(newFaceCoordArray);
542 "TwoDMeshTopology::ingestFaceCoordinateArrays() - Face coordinate array '"<< faceCoordinateName <<
"' ingested." << endl);
545 "TwoDMeshTopology::ingestFaceCoordinateArrays() - Located "<< libdap::long_to_string(faceCoordinateArrays->size()) <<
" face coordinate arrays." << endl);
549 BESDEBUG(
"ugrid",
"TwoDMeshTopology::ingestFaceCoordinateArrays() - No Face Coordinates Found." << endl);
552 BESDEBUG(
"ugrid",
"TwoDMeshTopology::ingestFaceCoordinateArrays() - DONE" << endl);
561void TwoDMeshTopology::ingestNodeCoordinateArrays(libdap::BaseType *meshTopology, libdap::DDS *dds)
564 "TwoDMeshTopology::ingestNodeCoordinateArrays() - BEGIN Gathering node coordinate arrays..." << endl);
566 string node_coordinates;
567 AttrTable at = meshTopology->get_attr_table();
569 AttrTable::Attr_iter iter_nodeCoors = at.simple_find(UGRID_NODE_COORDINATES);
570 if (iter_nodeCoors != at.attr_end()) {
571 node_coordinates = at.get_attr(iter_nodeCoors, 0);
574 throw Error(
"Could not locate the " UGRID_NODE_COORDINATES
" attribute in the " UGRID_MESH_TOPOLOGY
575 " variable! The mesh_topology variable is named " + meshTopology->name());
578 "TwoDMeshTopology::ingestNodeCoordinateArrays() - Located '"<< UGRID_NODE_COORDINATES <<
"' attribute." << endl);
580 if (nodeCoordinateArrays == 0) nodeCoordinateArrays =
new vector<libdap::Array *>();
582 nodeCoordinateArrays->clear();
586 vector<string> nodeCoordinateNames = split(node_coordinates,
' ');
589 vector<string>::iterator coorName_it;
590 for (coorName_it = nodeCoordinateNames.begin(); coorName_it != nodeCoordinateNames.end(); ++coorName_it) {
591 string nodeCoordinateName = *coorName_it;
594 "TwoDMeshTopology::ingestNodeCoordinateArrays() - Processing node coordinate '"<< nodeCoordinateName <<
"'." << endl);
597 BaseType *btp = dds->var(nodeCoordinateName);
600 "Could not locate the " UGRID_NODE_COORDINATES
" variable named '" + nodeCoordinateName +
"'! "
601 +
"The mesh_topology variable is named " + meshTopology->name());
603 libdap::Array *newNodeCoordArray =
dynamic_cast<libdap::Array*
>(btp);
604 if (newNodeCoordArray == 0) {
605 throw Error(malformed_expr,
606 "Node coordinate variable '" + nodeCoordinateName +
"' is not an Array type. It's an instance of "
610 "TwoDMeshTopology::ingestNodeCoordinateArrays() - Found node coordinate array '"<< nodeCoordinateName <<
"'." << endl);
613 if (newNodeCoordArray->dimensions(
true) != 1) {
614 throw Error(malformed_expr,
615 "Node coordinate variable '" + nodeCoordinateName
616 +
"' has more than one dimension. That's just not allowed. It has "
617 + long_to_string(newNodeCoordArray->dimensions(
true)) +
" dimensions.");
620 "TwoDMeshTopology::ingestNodeCoordinateArrays() - Node coordinate array '"<< nodeCoordinateName <<
"' has a single dimension." << endl);
623 string dimName = newNodeCoordArray->dimension_name(newNodeCoordArray->dim_begin());
624 int dimSize = newNodeCoordArray->dimension_size(newNodeCoordArray->dim_begin(),
true);
627 "TwoDMeshTopology::ingestNodeCoordinateArrays() - dimName: '"<< dimName <<
"' dimSize: " << libdap::long_to_string(dimSize) << endl);
629 if (nodeDimensionName.empty()) {
630 nodeDimensionName = dimName;
633 "TwoDMeshTopology::ingestNodeCoordinateArrays() - nodeDimensionName: '"<< nodeDimensionName <<
"' " << endl);
634 if (nodeDimensionName.compare(dimName) != 0) {
636 "The node coordinate array '" + nodeCoordinateName +
"' has the named dimension '" + dimName
637 +
"' which differs from the expected dimension meshVarName '" + nodeDimensionName
638 +
"'. The mesh_topology variable is named " + meshTopology->name());
640 BESDEBUG(
"ugrid",
"TwoDMeshTopology::ingestNodeCoordinateArrays() - Node dimension names match." << endl);
642 if (nodeCount == 0) {
646 "TwoDMeshTopology::ingestNodeCoordinateArrays() - nodeCount: "<< libdap::long_to_string(nodeCount) << endl);
648 if (nodeCount != dimSize) {
650 "The node coordinate array '" + nodeCoordinateName +
"' has a dimension size of "
651 + libdap::long_to_string(dimSize) +
" which differs from the the expected size of "
652 + libdap::long_to_string(nodeCount) +
" The mesh_topology variable is named "
653 + meshTopology->name());
655 BESDEBUG(
"ugrid",
"TwoDMeshTopology::ingestNodeCoordinateArrays() - Node counts match." << endl);
658 nodeCoordinateArrays->push_back(newNodeCoordArray);
660 "TwoDMeshTopology::ingestNodeCoordinateArrays() - Coordinate array '"<< nodeCoordinateName <<
"' ingested." << endl);
664 BESDEBUG(
"ugrid",
"TwoDMeshTopology::ingestNodeCoordinateArrays() - DONE" << endl);
668void TwoDMeshTopology::buildBasicGfTopology()
672 "TwoDMeshTopology::buildBasicGfTopology() - Building GridFields objects for mesh_topology variable "<< getMeshVariable()->name() << endl);
675 "TwoDMeshTopology::buildGridFieldsTopology() - Constructing new GF::Grid for "<< meshVarName() << endl);
676 gridTopology =
new GF::Grid(meshVarName());
680 "TwoDMeshTopology::buildGridFieldsTopology() - Building and adding implicit range Nodes to the GF::Grid" << endl);
681 GF::AbstractCellArray *nodes =
new GF::Implicit0Cells(nodeCount);
683 gridTopology->setKCells(nodes, node);
692 "TwoDMeshTopology::buildGridFieldsTopology() - Building face node connectivity Cell array from the DAP version" << endl);
693 GF::CellArray *faceNodeConnectivityCells = getFaceNodeConnectivityCells();
697 BESDEBUG(
"ugrid",
"TwoDMeshTopology::buildGridFieldsTopology() - Attaching Cell array to GF::Grid" << endl);
698 gridTopology->setKCells(faceNodeConnectivityCells, face);
702 "TwoDMeshTopology::buildGridFieldsTopology() - Construct new GF::GridField from GF::Grid" << endl);
703 d_inputGridField =
new GF::GridField(gridTopology);
708 vector<libdap::Array *>::iterator ncit;
709 for (ncit = nodeCoordinateArrays->begin(); ncit != nodeCoordinateArrays->end(); ++ncit) {
710 libdap::Array *nca = *ncit;
712 "TwoDMeshTopology::buildGridFieldsTopology() - Adding node coordinate "<< nca->name() <<
" to GF::GridField at rank 0" << endl);
713 GF::Array *gfa = extractGridFieldArray(nca, sharedIntArrays, sharedFloatArrays);
714 gfArrays.push_back(gfa);
715 d_inputGridField->AddAttribute(node, gfa);
720 for (ncit = faceCoordinateArrays->begin(); ncit != faceCoordinateArrays->end(); ++ncit) {
721 libdap::Array *fca = *ncit;
723 "TwoDMeshTopology::buildGridFieldsTopology() - Adding face coordinate "<< fca->name() <<
" to GF::GridField at rank " << face << endl);
724 GF::Array *gfa = extractGridFieldArray(fca, sharedIntArrays, sharedFloatArrays);
725 gfArrays.push_back(gfa);
726 d_inputGridField->AddAttribute(face, gfa);
730int TwoDMeshTopology::getResultGridSize(locationType dim)
732 return resultGridField->Size(dim);
745GF::Node *TwoDMeshTopology::getFncArrayAsGFCells(libdap::Array *fncVar)
747 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getFncArrayAsGFCells() - BEGIN" << endl);
749 int nodesPerFace = fncVar->dimension_size(fncNodesDim,
true);
750 int faceCount = fncVar->dimension_size(fncFacesDim,
true);
754 if (fncVar->dim_begin() == fncNodesDim) {
757 BESDEBUG(
"ugrid",
"Reorganizing the data from the DAP FNC Array for GF." << endl);
759 cells =
new GF::Node[faceCount * nodesPerFace];
760 GF::Node *temp_nodes = 0;
762 if (fncVar->type() == dods_int32_c || fncVar->type() == dods_uint32_c) {
763 temp_nodes =
new GF::Node[faceCount * nodesPerFace];
764 fncVar->value(temp_nodes);
768 temp_nodes = ugrid::extractArray<GF::Node>(fncVar);
771 for (
int fIndex = 0; fIndex < faceCount; fIndex++) {
772 for (
int nIndex = 0; nIndex < nodesPerFace; nIndex++) {
773 cells[nodesPerFace * fIndex + nIndex] = *(temp_nodes + (fIndex + (faceCount * nIndex)));
784 if (fncVar->type() == dods_int32_c || fncVar->type() == dods_uint32_c) {
785 cells =
new GF::Node[faceCount * nodesPerFace];
786 fncVar->value(cells);
790 cells = ugrid::extractArray<GF::Node>(fncVar);
794 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getFncArrayAsGFCells() - DONE" << endl);
802int TwoDMeshTopology::getStartIndex(libdap::Array *array)
804 AttrTable &at = array->get_attr_table();
805 AttrTable::Attr_iter start_index_iter = at.simple_find(UGRID_START_INDEX);
806 if (start_index_iter != at.attr_end()) {
807 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getStartIndex() - Found the "<< UGRID_START_INDEX <<
" attribute." << endl);
808 AttrTable::entry *start_index_entry = *start_index_iter;
809 if (start_index_entry->attr->size() == 1) {
810 string val = (*start_index_entry->attr)[0];
811 BESDEBUG(
"TwoDMeshTopology::getStartIndex",
"value: " << val << endl);
812 stringstream buffer(val);
815 buffer >> start_index;
819 throw Error(malformed_expr,
820 "Index origin attribute exists, but either no value supplied, or more than one value supplied.");
831GF::CellArray *TwoDMeshTopology::getFaceNodeConnectivityCells()
834 "TwoDMeshTopology::getFaceNodeConnectivityCells() - Building face node connectivity Cell array from the Array '" << faceNodeConnectivityArray->name() <<
"'" << endl);
836 int nodesPerFace = faceNodeConnectivityArray->dimension_size(fncNodesDim);
837 int total_size = nodesPerFace * faceCount;
840 "TwoDMeshTopology::getFaceNodeConnectivityCells() - Converting FNCArray to GF::Node array." << endl);
841 fncCellArray = getFncArrayAsGFCells(faceNodeConnectivityArray);
844 int startIndex = getStartIndex(faceNodeConnectivityArray);
845 if (startIndex != 0) {
847 "TwoDMeshTopology::getFaceNodeConnectivityCells() - Applying startIndex to GF::Node array." << endl);
848 for (
int j = 0; j < total_size; j++) {
849 fncCellArray[j] -= startIndex;
853 GF::CellArray *rankTwoCells =
new GF::CellArray(fncCellArray, faceCount, nodesPerFace);
855 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getFaceNodeConnectivityCells() - DONE" << endl);
860void TwoDMeshTopology::applyRestrictOperator(locationType loc,
string filterExpression)
863 BESDEBUG(
"ugrid",
"TwoDMeshTopology::applyRestrictOperator() - BEGIN" << endl);
870 "TwoDMeshTopology::applyRestrictOperator() - Constructing new GF::RestrictOp using user "<<
"supplied 'dimension' value and filter expression combined with the GF:GridField " << endl);
871 GF::RestrictOp op = GF::RestrictOp(filterExpression, loc, d_inputGridField);
874 BESDEBUG(
"ugrid",
"TwoDMeshTopology::applyRestrictOperator() - Applying GridField operator." << endl);
875 GF::GridField *resultGF = op.getResult();
877 resultGridField = resultGF;
879 "TwoDMeshTopology::applyRestrictOperator() - GridField operator applied and result obtained." << endl);
881 BESDEBUG(
"ugrid",
"TwoDMeshTopology::applyRestrictOperator() - END" << endl);
884void TwoDMeshTopology::convertResultGridFieldStructureToDapObjects(vector<BaseType *> *results)
886 BESDEBUG(
"ugrid",
"TwoDMeshTopology::convertResultGridFieldStructureToDapObjects() - BEGIN" << endl);
888 BESDEBUG(
"ugrid",
"TwoDMeshTopology::convertResultGridFieldStructureToDapObjects() - Normalizing Grid." << endl);
889 resultGridField->GetGrid()->normalize();
892 "TwoDMeshTopology::convertResultGridFieldStructureToDapObjects() - resultGridField->MaxRank(): "<< resultGridField->MaxRank() << endl);
894 if (resultGridField->MaxRank() < 0) {
895 throw BESError(
"Oops! The ugrid constraint expression resulted in an empty response.", BES_SYNTAX_USER_ERROR,
901 "TwoDMeshTopology::convertResultGridFieldStructureToDapObjects() - Converting the node coordinate arrays to DAP arrays." << endl);
902 vector<libdap::Array *>::iterator it;
903 for (it = nodeCoordinateArrays->begin(); it != nodeCoordinateArrays->end(); ++it) {
904 libdap::Array *sourceCoordinateArray = *it;
905 libdap::Array *resultCoordinateArray = getGFAttributeAsDapArray(sourceCoordinateArray, node, resultGridField);
906 results->push_back(resultCoordinateArray);
912 "TwoDMeshTopology::convertResultGridFieldStructureToDapObjects() - Converting the face coordinate arrays to DAP arrays." << endl);
913 for (it = faceCoordinateArrays->begin(); it != faceCoordinateArrays->end(); ++it) {
914 libdap::Array *sourceCoordinateArray = *it;
915 libdap::Array *resultCoordinateArray = getGFAttributeAsDapArray(sourceCoordinateArray, face, resultGridField);
916 results->push_back(resultCoordinateArray);
922 "TwoDMeshTopology::convertResultGridFieldStructureToDapObjects() - Adding the new face node connectivity array to the response." << endl);
923 libdap::Array *resultFaceNodeConnectivityDapArray = getGridFieldCellArrayAsDapArray(resultGridField,
924 faceNodeConnectivityArray);
925 results->push_back(resultFaceNodeConnectivityDapArray);
927 results->push_back(getMeshVariable()->ptr_duplicate());
929 BESDEBUG(
"ugrid",
"TwoDMeshTopology::convertResultGridFieldStructureToDapObjects() - END" << endl);
937libdap::Array *TwoDMeshTopology::getGridFieldCellArrayAsDapArray(GF::GridField *resultGridField,
938 libdap::Array *sourceFcnArray)
940 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getGridFieldCellArrayAsDapArray() - BEGIN" << endl);
943 GF::CellArray* gfCellArray = (GF::CellArray*) (resultGridField->GetGrid()->getKCells(2));
946 vector<vector<int> > nodes2 = gfCellArray->makeArrayInts();
948 libdap::Array *resultFncDapArray =
new libdap::Array(sourceFcnArray->name(),
new Int32(sourceFcnArray->name()));
954 bool follows_ugrid_09_spec =
true;
955 libdap::Array::Dim_iter di = sourceFcnArray->dim_begin();
957 follows_ugrid_09_spec =
false;
959 resultFncDapArray->append_dim(3, di->name);
961 resultFncDapArray->append_dim(nodes2.size(), di->name);
964 resultFncDapArray->append_dim(nodes2.size(), di->name);
966 resultFncDapArray->append_dim(3, di->name);
970 resultFncDapArray->set_attr_table(sourceFcnArray->get_attr_table());
971 resultFncDapArray->reserve_value_capacity(3 * nodes2.size());
974 int startIndex = getStartIndex(sourceFcnArray);
979 if (!follows_ugrid_09_spec) {
981 vector<dods_int32> node_data(3 * nodes2.size());
982 vector<dods_int32>::iterator ndi = node_data.begin();
984 if (startIndex == 0) {
985 for (
unsigned int i = 0; i < 3; ++i) {
986 for (
unsigned int n = 0; n < nodes2.size(); ++n) {
987 *ndi++ = nodes2[n][i];
992 for (
unsigned int i = 0; i < 3; ++i) {
993 for (
unsigned int n = 0; n < nodes2.size(); ++n) {
994 *ndi++ = nodes2[n][i] + startIndex;
999 resultFncDapArray->set_value(node_data, node_data.size());
1003 vector<dods_int32> node_data(nodes2.size() * 3);
1004 vector<dods_int32>::iterator ndi = node_data.begin();
1006 if (startIndex == 0) {
1007 for (
unsigned int n = 0; n < nodes2.size(); ++n) {
1008 for (
unsigned int i = 0; i < 3; ++i) {
1009 *ndi++ = nodes2[n][i];
1014 for (
unsigned int n = 0; n < nodes2.size(); ++n) {
1015 for (
unsigned int i = 0; i < 3; ++i) {
1016 *ndi++ = nodes2[n][i] + startIndex;
1021 resultFncDapArray->set_value(node_data, node_data.size());
1024 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getGridFieldCellArrayAsDapArray() - DONE" << endl);
1026 return resultFncDapArray;
1039static string copySizeOneDimensions(libdap::Array *sourceArray, libdap::Array *dapArray)
1041 for (libdap::Array::Dim_iter srcArrIt = sourceArray->dim_begin(); srcArrIt != sourceArray->dim_end(); ++srcArrIt) {
1043 int dimSize = sourceArray->dimension_size(srcArrIt,
true);
1044 string dimName = sourceArray->dimension_name(srcArrIt);
1048 dapArray->append_dim(dimSize, dimName);
1059static libdap::Array::Dim_iter copySizeOneDimensions(libdap::Array *sourceArray, libdap::Array *dapArray)
1061 libdap::Array::Dim_iter dataDimension;
1062 for (libdap::Array::Dim_iter srcArrIt = sourceArray->dim_begin(); srcArrIt != sourceArray->dim_end(); ++srcArrIt) {
1065 int dimSize = sourceArray->dimension_size(srcArrIt,
true);
1066 string dimName = sourceArray->dimension_name(srcArrIt);
1070 BESDEBUG(
"ugrid",
"TwoDMeshTopology::copySizeOneDimensions() - Adding size one dimension '"<< dimName <<
"' from source array into result." << endl);
1071 dapArray->append_dim(dimSize, dimName);
1074 BESDEBUG(
"ugrid",
"TwoDMeshTopology::copySizeOneDimensions() - Located data dimension '"<< dimName <<
"' in source array." << endl);
1075 dataDimension = srcArrIt;
1079 BESDEBUG(
"ugrid",
"TwoDMeshTopology::copySizeOneDimensions() - Returning dimension iterator pointing to '"<< sourceArray->dimension_name(dataDimension) <<
"'." << endl);
1080 return dataDimension;
1088libdap::Array *TwoDMeshTopology::getGFAttributeAsDapArray(libdap::Array *templateArray, locationType rank,
1089 GF::GridField *resultGridField)
1091 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getGFAttributeAsDapArray() - BEGIN" << endl);
1096 "TwoDMeshTopology::getGFAttributeAsDapArray() - Retrieving rank "<< rank <<
" GF::GridField Attribute '" << templateArray->name() <<
"'" << endl);
1098 gfa = resultGridField->GetAttribute(rank, templateArray->name());
1100 libdap::Array *dapArray;
1101 BaseType *templateVar = templateArray->var();
1104 switch (templateVar->type()) {
1109 case dods_int32_c: {
1111 vector<dods_int32> GF_ints = gfa->makeArray();
1114 dapArray =
new libdap::Array(templateArray->name(),
new libdap::Int32(templateVar->name()) );
1117 dimName = copySizeOneDimensions(templateArray, dapArray);
1120 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getGFAttributeAsDapArray() - Adding dimension " << dimName << endl);
1122 dapArray->append_dim(GF_ints.size(), dimName);
1125 dapArray->set_value(GF_ints, GF_ints.size());
1128 case dods_float32_c:
1129 case dods_float64_c: {
1131 vector<dods_float64> GF_floats = gfa->makeArrayf();
1134 dapArray =
new libdap::Array(templateArray->name(),
new libdap::Float64(templateVar->name()) );
1137 dimName = copySizeOneDimensions(templateArray, dapArray);
1140 dapArray->append_dim(GF_floats.size(), dimName);
1143 dapArray->set_value(GF_floats, GF_floats.size());
1147 throw InternalErr(__FILE__, __LINE__,
"Unknown DAP type encountered when converting to gridfields array");
1152 "TwoDMeshTopology::getGFAttributeAsDapArray() - Copying libdap::Attribute's from template array " << templateArray->name() << endl);
1153 dapArray->set_attr_table(templateArray->get_attr_table());
1155 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getGFAttributeAsDapArray() - DONE" << endl);
1167 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getResultGFAttributeValues() - BEGIN" << endl);
1172 "TwoDMeshTopology::getResultGFAttributeValues() - Retrieving GF::GridField Attribute '" << attrName <<
"'" << endl);
1175 if (resultGridField->IsAttribute(rank, attrName)) {
1176 gfa = resultGridField->GetAttribute(rank, attrName);
1179 string msg =
"Oddly, the requested attribute '" + attrName +
"' associated with rank "
1180 + libdap::long_to_string(rank) +
" does not appear in the resultGridField object! \n"
1181 +
"resultGridField->MaxRank(): " + libdap::long_to_string(resultGridField->MaxRank());
1183 throw InternalErr(__FILE__, __LINE__,
"ERROR - Unable to locate requested GridField attribute. " + msg);
1191 case dods_int32_c: {
1194 "TwoDMeshTopology::getResultGFAttributeValues() - Retrieving GF::Array as libdap::Array of libdap::Int32." << endl);
1195 vector<dods_int32> GF_ints = gfa->makeArray();
1201 for(
unsigned int i=0; i<GF_ints.size(); i++) {
1202 s <<
"GF_ints[" << i <<
"]: " << GF_ints[i] << endl;
1204 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getResultGFAttributeValues() - Retrieved GF_ints: "<< endl << s.str());
1208 "TwoDMeshTopology::getResultGFAttributeValues() - Copying GF result to target memory" << endl);
1209 memcpy(target, GF_ints.data(), GF_ints.size() *
sizeof(dods_int32));
1212 case dods_float32_c:
1213 case dods_float64_c: {
1216 "TwoDMeshTopology::getResultGFAttributeValues() - Retrieving GF::Array as libdap::Array of libdap::Float64." << endl);
1217 vector<dods_float64> GF_floats = gfa->makeArrayf();
1220 for(
unsigned int i=0; i<GF_floats.size(); i++) {
1221 s <<
"GF_ints[" << i <<
"]: " << GF_floats[i] << endl;
1223 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getResultGFAttributeValues() - Retrieved GF_floats: "<< endl << s.str());
1226 "TwoDMeshTopology::getResultGFAttributeValues() - Copying GF result to target memory" << endl);
1227 memcpy(target, GF_floats.data(), GF_floats.size() *
sizeof(dods_float64));
1232 throw InternalErr(__FILE__, __LINE__,
1233 "Unknown DAP type encountered when converting to gridfields result values");
1236 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getResultGFAttributeValues() - END" << endl);
1239static string getIndexVariableName(locationType location)
1244 return "node_index";
1247 return "face_index";
1254 string msg =
"ugr5(): Unknown/Unsupported location value '" + libdap::long_to_string(location) +
"'";
1255 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getIndexVariableName() - " << msg << endl);
1256 throw Error(malformed_expr, msg);
1259int TwoDMeshTopology::getInputGridSize(locationType location)
1273 string msg =
"ugr5(): Unknown/Unsupported location value '" + libdap::long_to_string(location) +
"'";
1274 BESDEBUG(
"ugrid",
"TwoDMeshTopology::getInputGridSize() - " << msg << endl);
1275 throw Error(malformed_expr, msg);
1283 int size = getInputGridSize(location);
1284 string name = getIndexVariableName(location);
1287 "TwoDMeshTopology::addIndexVariable() - Adding index variable '" << name <<
"' size: " << libdap::long_to_string(size) <<
" at rank " << libdap::long_to_string(location) << endl);
1289 GF::Array *indexArray = newGFIndexArray(name, size, sharedIntArrays);
1290 d_inputGridField->AddAttribute(location, indexArray);
1291 gfArrays.push_back(indexArray);
1297void TwoDMeshTopology::getResultIndex(locationType location,
void *target)
1299 string name = getIndexVariableName(location);
void init(string meshVarName, libdap::DDS *dds)
void getResultGFAttributeValues(string attrName, libdap::Type type, locationType rank, void *target)
void addIndexVariable(locationType location)
Adds an index variable at the gridfields rank as indicated by the passed locationType.