Git Product home page Git Product logo

cpgfunction's Introduction

Hello ๐Ÿ‘‹ Use the drop down arrows to learn more about the open-source work I've been apart of.
Controller Area Network bus
Ground heat exchangers
  • pygfunction served as the backbone for a first of kind ground heat exchanger design tool, ghedt.
  • cpgfunctionEP has been integrated into EnergyPlus as a third party application.
  • cpgfunction was used to compute g-functions on a high performance computing cluster (HPCC).

(Refer to my masters thesis for a more detailed discussion.)

cpgfunction's People

Contributors

j-c-cook avatar myoldmopar avatar

Watchers

 avatar  avatar  avatar

cpgfunction's Issues

Optimize linear interpolation of H matrices

https://people.sc.fsu.edu/~jburkardt/cpp_src/lagrange_interp_1d/lagrange_interp_1d.html

https://github.com/rncarpio/delaunay_linterp

Write you own:

Using BLAS/Linpack write your own linear interpolation of matrices. https://en.wikipedia.org/wiki/Linear_interpolation

https://scicomp.stackexchange.com/questions/20021/blas-lapack-or-atlas-for-matrix-multiplication-in-c

Matrix matrix multiplication: http://www.netlib.org/lapack/explore-html/d7/d2b/dgemm_8f.html

This does matrix multiplication on an upper or lower triangular matrix... Does that mean I could use my reduced matrix directly in matrix multiplication? : http://www.netlib.org/lapack/explore-html/d1/d54/group__double__blas__level3_gaf07edfbb2d2077687522652c9e283e1e.html#gaf07edfbb2d2077687522652c9e283e1e

This looks promising: https://github.com/parsiad/mlinterp. He claims to have a fast 1D interpolation in C++ of arbitrary dimensions.


The H matrix is "squashed" yes, but creating a H * R matrix multiplication where R is the reciprocity matrix would setup for performing matrix operations.

The matrix is psuedo symmetric by reciprosity.

Use Similarities False Possible Bug

There may be a bug when use_similarities is set to false.

More than likely, I did not change the h_ij matrix to the new indexing scheme for use_similarities = false.

Boolean for multithreading

Currently, each multi-threading call has a commented out non-multi-thread call below it. Rather than relying on commenting and de-commenting, provide a boolean option.

Add Testing Scripts that compare g-function output

  • Run a range of tests, store the g-function output in .json
  • Create testing scripts that run those exact g-functions
  • open .json and verify that the g-function at each place in time falls within 1.0E-06

Borefield interface

Implement a struct that provides quick access to L, Open, U, rectangles or custom borefields.

The coordinate generation functions should be separate from a borehole; perhaps a coordinates.cpp could be created.

Possible Performance Issue

Is this function being called a lot?

double Borehole::distance(Borehole target) {

Because the Borehole argument is being passed by value, which is making a copy of the structure in each invocation of it. The argument most likely needs to be a const reference.

Create Segment Response I/O standard

The segment response matrix has been transformed from a triangular matrix to a vector.

void SegmentResponse::get_h_value(double &h, const int i, const int j, const int k) {

Currently, the object only gets the h value (get_h_value). A function for storing the h value needs to be made. The code currently exists at the following location:

} else if (SegRes.storage_mode==1) {

Hash table for h_ij

The four components of the hash will be:

  • time value
  • distance
  • difference of burial depth
  • difference in height

g-Function Interface

A g-function interface struct is going to be necessary for EnergyPlus to interact with this library.

  • borefield : struct
    • A borefield object needs constructed that provides easy interface to custom, L, U, Open and rectangular fields
    • Handles uniform height (in meters) H, uniform burial depth (in meters) D, uniform borehole radius (in meters) r_b
  • time : vector
    • There are different geometric time routines available. EnergyPlus could call the same routine based on an input duration (in months) and optional number of time steps nt
  • alpha : float, optional
    • The ground thermal diffusivity (m2/s)

The determination of the number of segments nSegments will be handled by the adaptive discretization scheme. If desired, the ability to turn off adaptive discretization and use a custom number of segments could be made possible.

Make q_reconstructed and SegmentResponse.h_ij 1 dimensional in temporal superposition

Allocation of multidimensional vectors is a hindrance on performance. For speed performance, it is vastly superior to define multi-dimensional matrices in a 1D format.

q_reconstructed and SegmentResponse.h_ij are used in _temporal_superposition. Now that #30 is taking place, to obtain a speed increase without allocating (significantly*) more memory, the vectors used in the function need to be 1D.

*Note on significantly more memory: With this technique, it appears that a vector of size nSources * nSources will need to be declared to hold intermediate results. There is a balance between memory and speed.

Add test of g-function with unequal segment lengths

The _borehole_segments function discretizes all the boreholes into segments of equal length. This occurs inside of the g-function calculation, so it is not feasible that a user calling the function from EnergyPlus could create a field of unequal segments. However, this solution does vary based on a grid. At some point a developer of this library could decide to adaptability vary the segment lengths based on proximity to the center of the field, so that the solution can be both converged and require less segments. At that point in time, it will be beneficial if that developer does find that the g-function calculation is accurate for unequal segment lengths in the field.

Commit fcc6ab5 brought this idea about, and is mentioned in #30 (comment).

Remove all references to standalone h_ij matrix

The library makes use of a reduced segment response matrix that is inside of a struct

struct SegmentResponse {
~SegmentResponse() {} // destructor
int nSources;
int nSum;
vector < vector < double > > h_ij;
vector<gt::boreholes::Borehole> boreSegments;
SegmentResponse(int nSources, int nSum, int nt) : nSources(nSources), boreSegments(nSources),
h_ij(nSum, vector<double>(nt, 0)), nSum(nSum)
{} // constructor
// storage_mode = 1 is the reduced segment response vector
int storage_mode = 1;
// void ReSizeContainers(int n, int nt);
void get_h_value(double &h, int i, int j, int k);
void get_index_value(int &index, int i, int j);

There used to be an h_ij vector that stood alone and was passed around. It needs removed.

Define fastest BLAS in CMake

This project is dependent on BLAS, which is used inside of LAPACK. Currently, the only BLAS routine used in cpgfunction is dgesv_ (though there will be more routines used in the future as specific sections of the code are transitioned from multi-threading to vector linear algebra). pygfunction makes use of the LAPACK routine _gesv.

At first, the Python matrix inversion in np.linalg.solve() was much faster than what I was making use of in C++. The root cause turned out to the use of Netlib BLAS library. Based on comparison of timing tests, it is possible the numpy package queries the chip-set to determine which routine is best optimized based on the structure of the chip. On my Intel i7, I was able to get matrix inversion speeds as fast as np.linalg.solve() by making use of the OpenBlas library.

I was reminded of this point when our UGRA Timothy West began computing g-functions on the cluster. He is building on the cluster using CMake, which currently makes use of the Netlib BLAS library. The submission scripts Timothy submitted were failing due to time limits. The reason why the jobs on the cluster can fail based on run-time are discussed in the following section.

This describes the creation of submission scripts for use on the cluster. The path to a directory of configurations is supplied. A wide range of timings have been previously recorded, and a function has been created that takes in the number of sources, and returns estimated amount of time to run. Then, based on those timings, the ideal subset-sums are found based on a given input number of days N. Typically, I will request each submission "bucket" to be one less day than what I am submitting to on the cluster, so that I know the jobs will not run out of time.

A possible outcome of this issue is an automatic selection of the fastest BLAS library, though that may not end up being the case. The following libraries will be tested, and the fastest will be requested in CMakeLists.txt:

  • Netlib BLAS
  • OpenBLAS
  • ATLAS

Create a set of tests for g-function calculation

The g-function calculation code currently computes g-functions using uniform borehole wall temperature (UBHWT) with accuracy. A set of test cases need to be computed and stored. The output of these test cases can be compared to the output of any code that has been modified on commit.

Make the segment response matrix 1 dimmensional

With the merging of #30, the code now has memory bloat. The following lines create a 1D segment response matrix, H_ij from the 2D SegmentResponse.h_ij. H_ij was constructed in this way to complete #30, however, the declaration of H_ij introduces nSources * (nSources + 1) / 2 * nt more memory than is required.

std::vector<double> H_ij(gauss_sum * nt, 0); // 1D nSources x nt
int idx;
for (int i=0; i<nt; i++) {
for (int j=0; j<gauss_sum; j++) {
idx = (i * gauss_sum) + j;
H_ij[idx] = SegRes.h_ij[j][i];
} // next j
} // next i

The response matrix SegmentResponse.h_ij has many dependencies throughout the code.

Typedef library for additional reduction in memory

Currently, the library makes use of double precision for every variable. It is feasible that single (float) precision will produce results with high enough accuracy; this could result in a 1/2 memory reduction.

A typedef declaration could be made which applies to the entire library. This would take slightly more effort than simply overloading functions. One thing to keep in mind is that sgesv would need to be called when functions for single precision were overloaded. The call to the external lapack dgesv (double gesv) "C" function occurs here.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.