Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added cffd and variations #268

Merged
merged 24 commits into from
Nov 9, 2023
Merged

added cffd and variations #268

merged 24 commits into from
Nov 9, 2023

Conversation

guglielmopadula
Copy link
Member

Hi, these are the modifications of the library used in the preprint https://arxiv.org/abs/2308.03662.

Copy link
Collaborator

@mtezzele mtezzele left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution. Please add a link to the tutorial with a description in the readme you can find in the tutorials folder.
Please add the tests.

pygem/cffd.py Outdated
saved_parameters=self._save_parameters()
A,b=self._compute_linear_map(src_pts,saved_parameters.copy())
d=A@saved_parameters[self.indices]+b
deltax=np.linalg.inv(self.M)@A.T@np.linalg.inv((A@np.linalg.inv(self.M)@A.T))@(self.valconstraint-d)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a space between the operators

pygem/cffd.py Outdated
:rtype: numpy.ndarray
'''
tmp=np.zeros([*self.n_control_points,3])
tmp[:,:,:,0]=self.array_mu_x
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space after commas

:param np.ndarray saved_parameters
:return a tuple containing the coefficient and the intercept
:rtype tuple(np.ndarray,np.ndarray)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unnecessary empty lines in the doc

pygem/cffd.py Outdated
self._load_parameters(saved_parameters)
def_pts=super().__call__(src_pts)
outputs[0]=self.linconstraint(def_pts)
for i in range(1,n_indices+1):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add some inline comments please

pygem/vffd.py Outdated
"""
Utilities for performing Volume Free Form Deformation (BFFD).

:Theoretical Insight:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this will be rendered as intended in the online doc

class BFFD(CFFD):
'''
Class that handles the Barycenter Free Form Deformation on the mesh points.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arguments doc is missing

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi. For this class I did not add any argument doc because they are exactly the same as the mother class. The only difference is that in the child class a mother class member has a default value. I should add them anyway?
Thanks for your comments.

Copy link
Collaborator

@mtezzele mtezzele Sep 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please, so the online documentation will be self-contained.

pygem/cffd.py Outdated
Class that handles the Constrained Free Form Deformation on the mesh points.

:cvar callable linconstraint: it defines the F of the constraint F(x)=c.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove empty lines

pygem/cffd.py Outdated

def __call__(self, src_pts):
saved_parameters=self._save_parameters()
A,b=self._compute_linear_map(src_pts,saved_parameters.copy())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spaces

@@ -11,7 +11,7 @@ In this folder we collect several useful tutorials in order to understand the pr
| Tutorial4 [[.ipynb](/~https://github.com/mathLab/PyGeM/blob/master/tutorials/tutorial4/tutorial-4-idw.ipynb), [.py](/~https://github.com/mathLab/PyGeM/blob/master/tutorials/tutorial4/tutorial-4-idw.py), [.html](http://mathlab.github.io/PyGeM/tutorial-4-idw.html)] | inverse distance weighting to deform a cubic mesh | `pygem.IDW` | `numpy.ndarray` |
| Tutorial5 [[.ipynb](/~https://github.com/mathLab/PyGeM/blob/master/tutorials/tutorial5/tutorial-5-file.ipynb), [.py](/~https://github.com/mathLab/PyGeM/blob/master/tutorials/tutorial5/tutorial-5-file.py), [.html](http://mathlab.github.io/PyGeM/tutorial-5-file.html)] | free-form deformation to deform an object contained to file | `pygem.FFD` | `.vtp` file, `.stl` file |
| Tutorial6 [[.ipynb](/~https://github.com/fAndreuzzi/PyGeM/blob/master/tutorials/tutorial6/tutorial-6-ffd-rbf.ipynb), [.py](/~https://github.com/fAndreuzzi/PyGeM/blob/master/tutorials/tutorial6/tutorial-6-ffd-rbf.py), [.html](http://mathlab.github.io/PyGeM/tutorial-6-ffd-rbf.html)] | interpolation of an OpenFOAM mesh after a deformation | `pygem.FFD/RBF` | OpenFOAM |

| Tutorial8 [[.ipynb](/~https://github.com/guglielmopadula/PyGeM/blob/master/tutorials/tutorial8/tutorial-8-cffd.ipynb), [.py](/~https://github.com/guglielmopadula/PyGeM/blob/master/tutorials/tutorial8/tutorial-8-cffd.py), [.html](http://mathlab.github.io/PyGeM/tutorial-8-cffd.html)] | constrained free form deformation | `pygem.CFFD/BFFD/VFFD` | `.stl` file |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use the url of your fork. Use the mathlab one instead, please:/~https://github.com/mathLab/PyGeM/...
It should be tutorial7 and not 8.

May I ask you to fix also the path of tutorial 6 (I know it's not your fault but I spotted it only now...).

Thanks!

pygem/cffd.py Outdated
saved_parameters=self._save_parameters()
A, b = self._compute_linear_map(src_pts, saved_parameters.copy())
d = A @ saved_parameters[self.indices] + b
deltax = np.linalg.inv(self.M) @ A.T @ np.linalg.inv((A @ np.linalg.inv(self.M)@ A.T)) @ (self.valconstraint - d)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're computing the inverse of M twice in same line. Please, save intermediate result in a variable

@ndem0
Copy link
Member

ndem0 commented Sep 15, 2023

Dear @guglielmopadula, thanks for the additions! The contribution is very nice, but there are some gray point in the implementation. I started to left some comments, if you can please use also the code_formatter.sh before pushing in order to respect the code style (PEP8).

pygem/cffd.py Outdated
saved_parameters=self._save_parameters()
A, b = self._compute_linear_map(src_pts, saved_parameters.copy())
d = A @ saved_parameters[self.indices] + b
deltax = np.linalg.inv(self.M) @ A.T @ np.linalg.inv((A @ np.linalg.inv(self.M)@ A.T)) @ (self.valconstraint - d)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pygem/cffd.py Outdated
self._load_parameters(saved_parameters)
return self.ffd(src_pts)

def ffd(self,src_pts):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank space after comma

pygem/cffd.py Outdated
Comment on lines 127 to 144
saved_parameters_bak=saved_parameters.copy() #saving ffd parameters
n_indices=len(self.indices)
inputs=np.zeros([n_indices+1,n_indices+1])
outputs=np.zeros([n_indices+1,self.valconstraint.shape[0]])
np.random.seed(0)
for i in range(n_indices+1): ##now we generate the interpolation points
tmp=np.random.rand(1,n_indices)
tmp=tmp.reshape(1,-1)
inputs[i]=np.hstack([tmp, np.ones((tmp.shape[0], 1))]) #dependent variable
saved_parameters[self.indices]=tmp
self._load_parameters(saved_parameters) #loading the depent variable as a control point
def_pts=super().__call__(src_pts) #computing the deformation with the dependent variable
outputs[i]=self.linconstraint(def_pts) #computing the independent variable
sol=np.linalg.lstsq(inputs,outputs,rcond=None) #computation of the linear map
A=sol[0].T[:,:-1] #coefficient
b=sol[0].T[:,-1] #intercept
self._load_parameters(saved_parameters_bak) #restoring the original FFD parameters
return A,b
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change using PEP8 style

pygem/cffd.py Outdated


# I see that a similar function already exists in pygem.utils, but it does not work for inputs and outputs of different dimensions
def _compute_linear_map(self,src_pts,saved_parameters):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it do same of the function you're mentioning? Why do we should keep the older version?

pygem/vffd.py Outdated
Comment on lines 73 to 89
def __call__(self,src_pts):
self.vweight=np.abs(self.vweight)/np.sum(np.abs(self.vweight))
indices_bak=deepcopy(self.indices)
self.indices=np.array(self.indices)
indices_x=self.indices[self.indices%3==0].tolist()
indices_y=self.indices[self.indices%3==1].tolist()
indices_z=self.indices[self.indices%3==2].tolist()
indexes=[indices_x,indices_y,indices_z]
diffvolume=self.valconstraint-self.linconstraint(self.ffd(src_pts))
for i in range(3):
self.indices=indexes[i]
self.M=np.eye(len(self.indices))
self.valconstraint=self.linconstraint(self.ffd(src_pts))+self.vweight[i]*(diffvolume)
_=super().__call__(src_pts)
tmp=super().__call__(src_pts)
self.indices=indices_bak
return tmp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP8 style

pygem/vffd.py Outdated
self.indices=indexes[i]
self.M=np.eye(len(self.indices))
self.valconstraint=self.linconstraint(self.ffd(src_pts))+self.vweight[i]*(diffvolume)
_=super().__call__(src_pts)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the meaning of this line?

pygem/cffd.py Outdated
self._load_parameters(saved_parameters)
return self.ffd(src_pts)

def ffd(self,src_pts):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the meaning of this method?

pygem/vffd.py Outdated
self.vweight=np.abs(self.vweight)/np.sum(np.abs(self.vweight))
indices_bak=deepcopy(self.indices)
self.indices=np.array(self.indices)
indices_x=self.indices[self.indices%3==0].tolist()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very inefficient! What kind of reshaping are you trying to do?

pygem/bffd.py Outdated
Comment on lines 67 to 78
if __name__ == "__main__":
from pygem import BFFD
import numpy as np
bffd = BFFD()
bffd.read_parameters('tests/test_datasets/parameters_test_ffd_sphere.prm')
original_mesh_points = np.load('tests/test_datasets/meshpoints_sphere_orig.npy')
b=bffd.linconstraint(original_mesh_points)
bffd.valconstraint=b
bffd.indices=np.arange(np.prod(bffd.n_control_points)*3).tolist()
bffd.M=np.eye(len(bffd.indices))
new_mesh_points = bffd(original_mesh_points)
assert np.isclose(np.linalg.norm(bffd.linconstraint(new_mesh_points)-b),np.array([0.]))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove

pygem/cffd.py Outdated
>>> assert np.isclose(np.linalg.norm(fun(new_mesh_points)-b),np.array([0.]))
"""

def __init__(self, n_control_points=None):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(self, n_control_points=None, linear_constrain=None, val, indices=None, weight_matrix=None):

@ndem0
Copy link
Member

ndem0 commented Oct 16, 2023

Dear @guglielmopadula, I just quickly looked at the new code and it's exactly what I meant! Perfect, thank you! Only one change please: the class VFFD and BFFD are now in the same file (cffd.py). It is not an error but I would consider to keep them in a separate files (no matter their length) in order to be more accessible by new users

@ndem0
Copy link
Member

ndem0 commented Oct 30, 2023

Dear @guglielmopadula, now some of the tests are failing. Could you check? In your computer, is everything fine?

@guglielmopadula
Copy link
Member Author

Yes, I and I see that in the ubuntu 3.7 version they don't fail, so maybe there are some problems with the virtual machines?

@ndem0 ndem0 merged commit 3c11eb1 into mathLab:master Nov 9, 2023
1 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants