void NairnFEA::FEAAnalysis() { char nline[200]; int result; int i; NodalDispBC *nextBC; double times[5]; #pragma mark --- TASK 0: INITIALIZE // start timer times[0]=CPUTime(); // get problem size and other initialization nsize=nnodes*nfree + numConstraints; nband=GetBandWidth(); if(np==AXI_SYM) { xax='r'; yax='z'; zax='t'; } // Stiffness matrix info PrintSection("TOTAL STIFFNESS MATRIX"); sprintf(nline,"Initial number of equations:%6d Initial bandwidth:%6d",nsize,nband); cout << nline << endl << endl; #pragma mark --- TASK 1: ALLOCATE R VECTOR // Allocate reaction vector and load with nodal loads and edge loads rm=(double *)malloc(sizeof(double)*(nsize+1)); if(rm==NULL) throw CommonException("Memory error allocating reaction vector (rm)","NairnFEA::FEAAnalysis"); for(i=1;i<=nsize;i++) rm[i]=0.; // add nodal loads to rm[] vector NodalLoad *nextLoad=firstLoadBC; while(nextLoad!=NULL) nextLoad=nextLoad->Reaction(rm,np,nfree); // add stresses on element edges to rm[] vector ForcesOnEdges(); #pragma mark --- TASK 2: GET STIFFNESS MATRIX // allocate and fill global stiffness matrix, st[][], and reaction vector, rm[] times[1]=CPUTime(); BuildStiffnessMatrix(); #pragma mark --- TASK 3: DISPLACEMENT BCs // Impose displacement boundary conditions and rotate // nodes for skew boundary conditions nextBC=firstDispBC; while(nextBC!=NULL) nextBC=nextBC->FixOrRotate(st,rm,nsize,nband,nfree); #pragma mark --- TASK 4: INVERT STIFFNESS MATRIX // Solve linear system for nodal displacements times[2]=CPUTime(); double *work=(double *)malloc(sizeof(double)*(nsize+1)); if(work==NULL) throw CommonException("Memory error allocating work vector for linear solver", "NairnFEA::FEAAnalysis"); result=gelbnd(st,nsize,nband,rm,work,0); if(result==1) { throw CommonException("Linear solver error: matrix is singular. Check boundary conditions.\n (Hint: turn on resequencing to check for mesh connectivity problem)", "NairnFEA::FEAAnalysis"); } else if(result==-1) { cout << "Linear solver warning: solution process was close to singular. Results might be invalid." << endl; } free(work); free(st); free(stiffnessMemory); #pragma mark --- TASK 5a: UNSKEW ROTATED NODES nextBC=firstDispBC; while(nextBC!=NULL) nextBC=nextBC->Unrotate(rm,nfree); #pragma mark --- TASK 6: OUTPUT RESULTS // time to here for performance evaluation double execTime=ElapsedTime(); // elpased time in secs times[3]=CPUTime(); // Print Displacements DisplacementResults(); // Calculate forces, stresses, and energy // print element forces and stresses ForceStressEnergyResults(); // Average nodal stresses AvgNodalStresses(); // reactivities at fixed nodes ReactionResults(); // strain energies EnergyResults(); // execution times times[4]=CPUTime(); PrintSection("EXECUTION TIMES AND MEMORY"); cout << "1. Allocate Memory: " << (times[1]-times[0]) << " secs" << endl; cout << "2. Build Stiffness Matrix: " << (times[2]-times[1]) << " secs" << endl; cout << "3. Solve Linear System: " << (times[3]-times[2]) << " secs" << endl; cout << "4. Write Results: " << (times[4]-times[3]) << " secs" << endl; cout << "5. Total Execution CPU Time: " << times[3] << " secs" << endl; cout << "6. Total Execution Elapsed Time: " << execTime << " secs" << endl; cout << "7. Scaling: " << times[3]/execTime << endl; //--------------------------------------------------- // Trailer cout << "\n***** NAIRNFEA RUN COMPLETED\n"; }
/** usage: GetPeaks(in_data, peaks); * output in peaks correspond to the sorted positions of peaks of a density * will be fit using bandwith bw to input vector in_data. * nans removed from in_data * values in peaks are ordered low to high */ void Clonality::GetPeaks(vector<float> const& in_data, vector<double>& peaks){ if (datasize == 0) datasize = in_data.size(); size_t nn = (datasize < in_data.size()) ? datasize : in_data.size(); size_t rate=SamplingRate(nn, in_data.size()); vector<double> data(nn, 0); size_t cnt = 0; size_t ix = 0;; for (size_t i=0; i < nn; i++) { ix += rate; int iix = ix % in_data.size(); if ( ! isnan (in_data[iix]) ) data[cnt++] = in_data[iix]; } if (cnt > 2) { // this flow has to have beads with usable values to be used data.resize(cnt); double bw = GetBandWidth(data); scprint( this,"bw=%f;\n", bw); if (bw > 0) { vector<double> weights(data.size(), 1.0f); getpeaksInternal(data, cutoff, bw, npoints, weights, peaks); return; } } // no usable bandwidth or count too low, return a single peak scprint( this,"bw=0; cnt=%d;\n", (int)cnt); peaks.resize(1); peaks[0] = 0; size_t n = 0; for (size_t i=0; i<cnt; i++) { #if __cplusplus >= 201103L if ( ! std::isinf(data[i]) ) { #else if ( ! isinf(data[i]) ) { #endif n++; peaks[0] += data[i]; } } assert ( n == cnt ); // no infinities supposed to happen if (n>0) peaks[0] = peaks[0]/n; scprint( this,"npeak=1; "); scprint( this,"f(%f)=Inf\n", peaks[0]); } void Clonality::getpeaksInternal(vector<double>& data, double const _cutoff, double const bw, int const _npoints, vector<double>& weights, vector<double>& peaks) { int m=data.size(); // number of rows assert ( m > 2 ); assert ( (0 <= _cutoff) && (_cutoff < 1) ); assert (_npoints > 0); // normalize weight vector to sum to 1 double wsum = 0; for (unsigned int k=0; k<weights.size(); ++k){ wsum += weights[k]; } assert (wsum > 0); for (unsigned int k=0; k<weights.size(); ++k){ weights[k] = weights[k]/wsum; } // find density functions vector<double> density(_npoints); vector<double> xi(_npoints); // find limits for range of X vector<double> xlimits(2,0); // FitDensity::XLimits(data, bw, xlimits, range_limit, bw_increment); XLimits(data, bw, xlimits, range_limit_low, range_limit_high, bw_increment); scprint( this,"ksdensity, from = %f, to = %f\n", xlimits[0], xlimits[1]); // call density and return density in xi, density FitDensity::kdensity(data, density, xi, weights, bw, xlimits[0], xlimits[1]); // compute overall signal double overallSignal = FitDensity::SquaredIntegral(xi, density); // find the peaks in (xi, density) and return in peaks vector<size_t> peakIndex; vector<size_t> valleyIndex; int npeak1 = FitDensity::findpeaks(valleyIndex, peakIndex, density, 0.046*overallSignal, xi); assert( npeak1 > 0 ); scprint( this,"before trim, npeak=%d; ", npeak1); for (size_t i=0; i<peakIndex.size(); i++) { scprint( this,"f(%f)=%f ", xi[peakIndex[i]],density[peakIndex[i]]); } scprint( this,"\n"); // trim off any peaks in extremes of data, // these are meaningless wiggles in the density estimation int npeak = TrimExtremalPeaks(data, xi, _cutoff, valleyIndex, peakIndex); scprint( this,"after trim, npeak=%d; ", npeak); if (npeak > 0) { for (size_t i=0; i<peakIndex.size(); i++) { scprint( this,"f(%f)=%f ", xi[peakIndex[i]],density[peakIndex[i]]); } scprint( this,"\n"); // apply ad hoc rules here npeak = ApplyAdHocPeakRemoval( xi, density, valleyIndex, peakIndex ); } // debug_density.assign(density.begin(), density.end()); // debug_xi.assign(xi.begin(), xi.end()); { scprint( this,"xi=[ "); for (size_t i=0; i<density.size(); i++) scprint( this,"%.3f ", xi[i]); scprint( this,"];\n"); scprint( this,"yi=[ "); for (size_t i=0; i<density.size(); i++) scprint( this,"%.4f ", density[i]*(xi[1]-xi[0])); scprint( this,"];\n"); } peaks.resize(npeak); for(size_t i = 0; i < peakIndex.size(); ++i) peaks[i] = *(xi.begin() + peakIndex[i]); }