stream::read_status underflow_try_buffer_(std::size_t len) { // TODO: This is quite crude, but it's not expected to be used a lot. // TODO: Exception safety std::size_t found_amount = first_left(); std::vector<bucket*> stack; stream::read_status s = stream::read_ok; while(found_amount < len) { stream::read_result r = read_bucket_and_return_(len - found_amount); if(r.s != stream::read_ok) { s = r.s; break; } found_amount += r.b->size(); stack.push_back(r.b); } // Put back in reverse order while(!stack.empty()) { source_->unread(stack.back()); stack.pop_back(); } return s; }
// Try to buffer //len// bytes. stream::read_status try_buffer(std::size_t len) { if(first_left() >= len) return stream::read_ok; // Already buffered else return underflow_try_buffer_(len); }
/// Apply changes to first bucket void correct_first_bucket_() { if(first_.get()) { std::size_t old_size = first_->size(); first_->cut_front(old_size - first_left()); } }
double CheMPS2::Excitation::matvec( const SyBookkeeper * book_up, const SyBookkeeper * book_down, const int orb1, const int orb2, const double alpha, const double beta, const double gamma, Sobject * S_up, Sobject * S_down, TensorO ** overlaps, TensorL ** regular, TensorL ** trans ){ const int indx = S_up->gIndex(); assert( orb1 < orb2 ); assert( indx == S_down->gIndex() ); assert( indx >= orb1 ); assert( indx < orb2 ); const int DIM = std::max( std::max( book_up->gMaxDimAtBound( indx ), book_up->gMaxDimAtBound( indx + 2 ) ), std::max( book_down->gMaxDimAtBound( indx ), book_down->gMaxDimAtBound( indx + 2 ) ) ); assert( book_up->gIrrep( orb1 ) == book_up->gIrrep( orb2 ) ); S_down->prog2symm(); double inproduct = 0.0; #pragma omp parallel reduction(+:inproduct) { if ( orb1 + 1 == orb2 ){ // The second quantized operators are neighbours #pragma omp for schedule(dynamic) for ( int dummy = 0; dummy < S_up->gNKappa(); dummy++ ){ const int ikappa = S_up->gReorder( dummy ); clear( ikappa, S_up ); inproduct += neighbours( ikappa, book_up, book_down, alpha, beta, gamma, S_up, S_down ); } } else { double * workmem1 = new double[ DIM * DIM ]; if ( orb1 == indx ){ // All the way at the left #pragma omp for schedule(dynamic) for ( int dummy = 0; dummy < S_up->gNKappa(); dummy++ ){ const int ikappa = S_up->gReorder( dummy ); clear( ikappa, S_up ); first_left( ikappa, book_up, book_down, alpha, S_up, S_down, trans[ indx + 1 ] ); second_left( ikappa, book_up, book_down, beta, S_up, S_down, regular[ indx + 1 ] ); inproduct += third_left( ikappa, book_up, book_down, gamma, S_up, S_down, overlaps[ indx + 1 ], workmem1 ); } } else { if ( orb2 == indx + 1 ){ // All the way at the right #pragma omp for schedule(dynamic) for ( int dummy = 0; dummy < S_up->gNKappa(); dummy++ ){ const int ikappa = S_up->gReorder( dummy ); clear( ikappa, S_up ); first_right( ikappa, book_up, book_down, alpha, S_up, S_down, trans[ indx - 1 ] ); second_right( ikappa, book_up, book_down, beta, S_up, S_down, regular[ indx - 1 ] ); inproduct += third_right( ikappa, book_up, book_down, gamma, S_up, S_down, overlaps[ indx - 1 ], workmem1 ); } } else { // Somewhere in the middle double * workmem2 = new double[ DIM * DIM ]; #pragma omp for schedule(dynamic) for ( int dummy = 0; dummy < S_up->gNKappa(); dummy++ ){ const int ikappa = S_up->gReorder( dummy ); clear( ikappa, S_up ); first_middle( ikappa, book_up, book_down, alpha, S_up, S_down, trans[ indx - 1 ], trans[ indx + 1 ], workmem1 ); second_middle( ikappa, book_up, book_down, beta, S_up, S_down, regular[ indx - 1 ], regular[ indx + 1 ], workmem1 ); inproduct += third_middle( ikappa, book_up, book_down, gamma, S_up, S_down, overlaps[ indx - 1 ], overlaps[ indx + 1 ], workmem1, workmem2 ); } delete [] workmem2; } } delete [] workmem1; } } S_up ->symm2prog(); // S_down->symm2prog(); S_down is not used anymore afterwards return inproduct; }