[Paraview] Catalyst and adaptor: attaching new fields

Michel Rasquin michel.rasquin at colorado.edu
Mon Oct 26 12:28:19 EDT 2015


I found the issue. Never mind.
For the short story, NeedToCreateGrid() in CatalystCAdaptorAPI.cxx not only check if a grid already exists or not.
If a grid exists, it also clears the field data, which was my issue.
This function should therefore be called only once per data set.

Best, 

Michel



> On Oct 26, 2015, at 4:22 PM, Michel Rasquin <mira5007 at colorado.edu> wrote:
> 
> Hi everyone,
> 
> I am trying to add some fields to a vtkCPAdaptorAPI object for coprocessing with Catalyst.
> I rely for that purpose on the successful implementation of the Phasta adaptor provided along with ParaView.
> See ParaView-v4.4.0-source/CoProcessing/Adaptors/PhastaAdaptor/PhastaAdaptor.cxx.
> After the initialization of the coprocessing objects and the generation of the grid, the current implementation to add fields in the phasta adaptor relies on the following function: 
> 
> void addfields(… double* dofArray, double* vortArray, double * otherFieldOfInterest … )
> {
>  vtkCPInputDataDescription* idd = vtkCPAdaptorAPI::GetCoProcessorData()->GetInputDescriptionByName("input”);
>  vtkUnstructuredGrid* UnstructuredGrid = vtkUnstructuredGrid::SafeDownCast(idd->GetGrid());
>  if(!UnstructuredGrid) {
>    vtkGenericWarningMacro("No unstructured grid to attach field data to.");
>    return;
>  } 
> 
>  // now add numerical field data
>  //velocity
>  vtkIdType NumberOfNodes = UnstructuredGrid->GetNumberOfPoints();
>  if(idd->IsFieldNeeded("velocity"))
>  {
>    vtkDoubleArray* velocity = vtkDoubleArray::New();
>    velocity->SetName("velocity");
>    velocity->SetNumberOfComponents(3);
>    velocity->SetNumberOfTuples(NumberOfNodes);
>    for (vtkIdType idx=0; idx<NumberOfNodes; idx++) {
>      velocity->SetTuple3(idx, dofArray[idx],
>                          dofArray[idx+ *nshg],
>                          dofArray[idx+ *nshg*2]);
>    }
>    UnstructuredGrid->GetPointData()->AddArray(velocity);
>    velocity->Delete();
>  }
> 
>  if(idd->IsFieldNeeded(“vorticity"))
>  {
>    vtkDoubleArray* vorticity = vtkDoubleArray::New();
>    velocity->SetName(“vorticity");
>    velocity->SetNumberOfComponents(3);
>    velocity->SetNumberOfTuples(NumberOfNodes);
>    for (vtkIdType idx=0; idx<NumberOfNodes; idx++) {
>      velocity->SetTuple3(idx, vortArray[idx],
>                          vortArray[idx+ *nshg],
>                          vortArray[idx+ *nshg*2]);
>    }
>    UnstructuredGrid->GetPointData()->AddArray(vorticity);
>    vorticity->Delete();
>    }
> 
>  // etc for any the other fields of interest for Catalyst
> }
> 
> Currently, all the fields requested for coprocessing needs to be attached in this function at the same time, using the same pointer to vtkUnstructuredGrid resulting from the SafeDownCast mentioned above. However, I need a more flexible implementation so that I can call addfield (with no “s”) as many times as needed and attach a single field to the vtkCPAdaptorAPI object each time this function is called.
> 
> Concretely, my first implementation is simply the following:
> 
> void addfield(std::string fieldName, int* NumberOfComp, double* fieldArray)
> {
>  vtkCPInputDataDescription* idd = vtkCPAdaptorAPI::GetCoProcessorData()->GetInputDescriptionByName("input");
>  vtkUnstructuredGrid* UnstructuredGrid = vtkUnstructuredGrid::SafeDownCast(idd->GetGrid());
>  if(!UnstructuredGrid) {
>    vtkGenericWarningMacro("No unstructured grid to attach field data to.");
>    return;
>  }
> 
>  // Get number of nodes
>  vtkIdType NumberOfNodes = UnstructuredGrid->GetNumberOfPoints();
> 
>  // Add field
>  if(idd->IsFieldNeeded(fieldName.c_str())) {
>    vtkDoubleArray* dataArray = vtkDoubleArray::New();
>    dataArray->SetName(fieldName.c_str());
>    dataArray->SetNumberOfComponents(*NumberOfComp);
>    dataArray->SetNumberOfTuples(NumberOfNodes);
>    // fill in dataArray from fieldArray, NumberOfNodes and NumberOfComp
>>    UnstructuredGrid->GetPointData()->AddArray(dataArray);
>    dataArray->Delete();
>  }
> }
> 
> The problem is that only the last field passed to this new addfield() function can be actually used by Catalyst for coprocessing. 
> Indeed, it appears that all other fields previously passed to addfield() cannot be retrieved from the vtkCPAdaptorAPI object. 
> Consequently, any filter in the Catalyst pipeline that relies on the N-1 first fields (out of N in total) passed to addfields() will be ignored because relevant data is missing.
> 
> I suspect the issue is in one of the first two lines of the addfield() function, namely
> 
>  vtkCPInputDataDescription* idd = vtkCPAdaptorAPI::GetCoProcessorData()->GetInputDescriptionByName("input");
>  vtkUnstructuredGrid* UnstructuredGrid = vtkUnstructuredGrid::SafeDownCast(idd->GetGrid());
> 
> Could you please let me know if it is possible to pass one single field at a time to the Catalyst adaptor from different locations of the code, or if all the fields must be passed in one shot?
> 
> Thank you for your help.
> 
> Best regards,
> 
> Michel
> 
> 
> 



More information about the ParaView mailing list