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";
}
Beispiel #2
0
/** 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]);
  
}