bool avtLCSFilter::RectilinearGridIterativeCalc( std::vector<avtIntegralCurve*> &ics ) { //algorithm sends index to global datastructure as well as end points. //Send List of index into global array to rank 0 //Send end positions into global array to rank 0 size_t nics = ics.size(); //loop over all the intelgral curves and add it back to the //original list of seeds. intVector indices(nics); doubleVector points(nics*3); doubleVector times(nics); for(size_t i=0, j=0; i<nics; ++i, j+=3) { avtStreamlineIC * ic = (avtStreamlineIC *) ics[i]; indices[i] = ic->id; avtVector point = ic->GetEndPoint(); points[j+0] = point[0]; points[j+1] = point[1]; points[j+2] = point[2]; if( doPathlines ) times[i] = ic->GetTime() - seedTime0; else times[i] = ic->GetTime(); } int* all_indices = 0; int* index_counts = 0; double* all_points = 0; int *point_counts = 0; double* all_times = 0; int *time_counts = 0; Barrier(); CollectIntArraysOnRootProc(all_indices, index_counts, &indices.front(), (int)indices.size()); CollectDoubleArraysOnRootProc(all_points, point_counts, &points.front(), (int)points.size()); CollectDoubleArraysOnRootProc(all_times, time_counts, ×.front(), (int)times.size()); Barrier(); //root should now have index into global structure and all //matching end positions. if(PAR_Rank() != 0) { return true; } else { //variable name. std::string var = outVarRoot + outVarName; //now global grid has been created. if( fsle_ds == 0 ) fsle_ds = CreateIterativeCalcDataSet(); // Get the stored data arrays vtkDoubleArray *exponents = (vtkDoubleArray *) fsle_ds->GetPointData()->GetArray(var.c_str()); vtkDoubleArray *component = (vtkDoubleArray *) fsle_ds->GetPointData()->GetArray("component"); vtkDoubleArray *times = (vtkDoubleArray *) fsle_ds->GetPointData()->GetArray("times"); size_t nTuples = exponents->GetNumberOfTuples(); // Storage for the points and times std::vector<avtVector> remapPoints(nTuples); std::vector<double> remapTimes(nTuples); //update remapPoints with new value bounds from integral curves. int par_size = PAR_Size(); size_t total = 0; for(int i = 0; i < par_size; ++i) { if(index_counts[i]*3 != point_counts[i] || index_counts[i] != time_counts[i]) { EXCEPTION1(VisItException, "Index count does not the result count." ); } total += index_counts[i]; } for(size_t j=0, k=0; j<total; ++j, k+=3) { size_t index = all_indices[j]; if(nTuples <= index) { EXCEPTION1(VisItException, "More integral curves were generatated than " "grid points." ); } remapPoints[index].set( all_points[k+0], all_points[k+1], all_points[k+2]); remapTimes[index] = all_times[j]; } // Store the times for the exponent. for(size_t l=0; l<nTuples; ++l) times->SetTuple1(l, remapTimes[l]); //use static function in avtGradientExpression to calculate //gradients. since this function only does scalar, break our //vectors into scalar components and calculate one at a time. vtkDataArray* jacobian[3]; for(int i = 0; i < 3; ++i) { // Store the point component by component for(size_t l=0; l<nTuples; ++l) component->SetTuple1(l, remapPoints[l][i]); jacobian[i] = avtGradientExpression::CalculateGradient(fsle_ds, "component"); } for (size_t i = 0; i < nTuples; i++) component->SetTuple1(i, std::numeric_limits<double>::epsilon()); //now have the jacobian - 3 arrays with 3 components. ComputeLyapunovExponent(jacobian, component); jacobian[0]->Delete(); jacobian[1]->Delete(); jacobian[2]->Delete(); // Compute the FSLE ComputeFSLE( component, times, exponents ); bool haveAllExponents = true; // For each integral curve check it's mask value to see it // additional integration is required. // ARS - FIX ME not parallelized!!!!!!!! for(size_t i=0; i<ics.size(); ++i) { avtStreamlineIC * ic = (avtStreamlineIC *) ics[i]; int ms = ic->GetMaxSteps(); if( ms < maxSteps ) { ic->SetMaxSteps(ms+1); ic->status.ClearTerminationMet(); } size_t l = ic->id; // The curve id is the index into the VTK data. // Check to see if all exponents have been found. if( exponents->GetTuple1(l) == std::numeric_limits<double>::min() && ms < maxSteps ) haveAllExponents = false; } //cleanup. if (all_indices) delete [] all_indices; if (index_counts) delete [] index_counts; if (all_points) delete [] all_points; if (point_counts) delete [] point_counts; if (all_times) delete [] all_times; if (time_counts) delete [] time_counts; return haveAllExponents; } }
void avtQueryOverTimeFilter::CreateFinalOutput() { if (ParallelizingOverTime()) { double *totalQRes; int *qResMsgs; CollectDoubleArraysOnRootProc(totalQRes, qResMsgs, &(qRes[0]), qRes.size()); double *totalTimes; int *timesMsgs; CollectDoubleArraysOnRootProc(totalTimes, timesMsgs, &(times[0]), times.size()); if (PAR_Rank() == 0) { int i; int nResults = 0; int maxIterations = 0; for (i = 0 ; i < PAR_Size() ; i++) { nResults += timesMsgs[i]; maxIterations = (timesMsgs[i] > maxIterations ? timesMsgs[i] : maxIterations); } std::vector<double> finalQRes(nResults, 0.); std::vector<double> finalTimes(nResults, 0.); int index = 0; for (int j = 0 ; j < maxIterations ; j++) { int loc = 0; for (i = 0 ; i < PAR_Size() ; i++) { if (timesMsgs[i] > j) { finalQRes[index] = totalQRes[loc+j]; finalTimes[index] = totalTimes[loc+j]; index++; } loc += timesMsgs[i]; } } qRes = finalQRes; times = finalTimes; delete [] totalQRes; delete [] qResMsgs; delete [] totalTimes; delete [] timesMsgs; } else { SetOutputDataTree(new avtDataTree()); finalOutputCreated = true; return; } } if (qRes.size() == 0) { debug4 << "Query failed at all timesteps" << endl; avtCallback::IssueWarning("Query failed at all timesteps"); avtDataTree_p dummy = new avtDataTree(); SetOutputDataTree(dummy); return; } if (useTimeForXAxis && qRes.size()/nResultsToStore != times.size()) { debug4 << "QueryOverTime ERROR, number of results (" << qRes.size() << ") does not equal number " << "of timesteps (" << times.size() << ")." << endl; avtCallback::IssueWarning( "\nQueryOverTime error, number of results does not equal " "number of timestates. Curve being created may be missing " "some values. Please contact a VisIt developer."); } else if (nResultsToStore > 1 && qRes.size() % nResultsToStore != 0) { debug4 << "QueryOverTime ERROR, number of results (" << qRes.size() << ") is not a multiple of " << nResultsToStore << "and therefore cannot generate x,y pairs." << endl; avtCallback::IssueWarning( "\nQueryOverTime error, number of results is incorrect. " "Curve being created may be missing some values. " "Please contact a VisIt developer."); } if (skippedTimes.size() != 0) { std::ostringstream osm; osm << "\nQueryOverTime (" << atts.GetQueryAtts().GetName().c_str() << ") experienced\n" << "problems with the following timesteps and \n" << "skipped them while generating the curve:\n "; for (int j = 0; j < skippedTimes.size(); j++) osm << skippedTimes[j] << " "; osm << "\nLast message received: " << errorMessage.c_str() << ends; debug4 << osm.str() << endl; avtCallback::IssueWarning(osm.str().c_str()); } stringVector vars = atts.GetQueryAtts().GetVariables(); bool multiCurve = false; if (atts.GetQueryAtts().GetQueryInputParams().HasNumericEntry("curve_plot_type")) { multiCurve = (atts.GetQueryAtts().GetQueryInputParams().GetEntry("curve_plot_type")->ToInt() == 1); } avtDataTree_p tree = CreateTree(times, qRes, vars, multiCurve); SetOutputDataTree(tree); finalOutputCreated = true; }