adc-connect / adcc

adcc: Seamlessly connect your program to ADC
https://adc-connect.org
GNU General Public License v3.0
32 stars 21 forks source link

Higher dimensional Tensors #147

Open jonasleitner opened 2 years ago

jonasleitner commented 2 years ago

I want to determine the full iterative second order MP wave function. Actually, I only need the second order singles Amplitudes. However, since I want to perform calculations with non-canonical orbitals, I determine the MP wave function iteratively, according to the Hylleraas functional. The problem is that the equations of the residual couple the singles to the doubles, the doubles to the triples etc. Therefore, in order to obtain the iterative Singles I also need the Triples and Quadruples. The iterations require contractions of the form (also including outer products):

# contracted indices dim Tensor A dim Tensor B
2 2 6
1 2 6
2 2 8
1 2 8
0 4 2
0 2 6
0 4 4

I just started having a look at it. Beside the additional contractions, it would only require to create new symmetry objects for the 6 and 8D tensors, correct? You think it is possible to implement it without putting too much effort into it?

mfherbst commented 2 years ago

It's mostly template instantiations, which you need to extend beyond the current limits, but to be frank this is scattered all over the code in libadc.Grep for INSTANTIATE to find the spots. There is also a python script to generate valid dimensions for contractions (TensorImpl/instantiate_valid.py).

It's doable, but will probably require a bit of fiddeling and especially to support tensors of dimension 8 this could increase code size a lot, so it's best to do this selectively. Have a look and if you have questions we can talk.

If you only want to do this once for testing, the effort is not worth it in my opinion. If you want to support this generally in adcc, it might pay off.

mfherbst commented 2 years ago

Happy to discuss this further, if you are interested by the way.

jonasleitner commented 2 years ago

Me too. I just didn't had time to continue working on it yet. So far I did only write a function to set up a symmetry object for a 6D tensor.

If you only want to do this once for testing, the effort is not worth it in my opinion. If you want to support this generally in adcc, it might pay off.

I didn't had a look on the template instantiations yet, but overall it seems doable to mee. But probably I am missing something. I hope I only need it to justify some approximations, but I guess its also not bad to think about adding the higher tensors in general to adcc. I hope that I will find time to continue next week. Will keep you updated :)

jonasleitner commented 2 years ago

Ok, now I know what you mean about the code size. The IF_DIMENSIONS_MATCH_EXECUTE_CONTRACT instantiations are exhausting, which makes the code quite unreadable - though its not hard to implement due to the python script.

I'm currently trying to get a minimal example running, i.e. I only add the few contractions I actually need atm. However, when I try to import the newly build libadcc (with INSTANTIATE up to 8 and the additional contractions) I get an ImportError: undefined symbol: _ZN9libtensor8btod_addILm7EE7performERNS_18gen_block_stream_iILm7ENS_21block_tensor_i_traitsIdEEEE

So I guess that also libtensor needs to be rebuild and some flags set or whatever to enable the higher dims. I don't know how much work this is and what needs to be done there.

Alternatively, @maxscheurer pointed out that it is also possible to just use numpy for testing and then only implement the higher tensors later if they are really needed. This would also be a solution for now, since I only need the singles amplitudes.

mfherbst commented 2 years ago

However, when I try to import the newly build libadcc (with INSTANTIATE up to 8 and the additional contractions) I get an ImportError:

It might well be that we do not instantiate these things on the libtensor side either.

just use numpy for testing and then only implement the higher tensors later if they are really needed.

Certainly the simpler solution for now. If you stick to the einsum syntax, then it should be relatively easy to reuse the code later.

jonasleitner commented 2 years ago

Certainly the simpler solution for now. If you stick to the einsum syntax, then it should be relatively easy to reuse the code later.

Yes, so I think we just postpone this until I'm sure that I need it. But thanks for the help and discussion so far :)