diff --git a/Energy.py b/Energy.py new file mode 100644 index 0000000000000000000000000000000000000000..a645ef42bb0639043bb6ac83b2253ad86360a0c6 --- /dev/null +++ b/Energy.py @@ -0,0 +1,59 @@ +#coding=utf8 + +################################################################################ +### ### +### Created by Martin Genet, 2016-2018 ### +### ### +### École Polytechnique, Palaiseau, France ### +### ### +################################################################################ + +import dolfin + +import myPythonLibrary as mypy +import myVTKPythonLibrary as myvtk + +import dolfin_dic as ddic + +################################################################################ + +class Energy(): + + + + def reinit(self, + *args, + **kwargs): + + pass + + + + def call_before_solve(self, + *args, + **kwargs): + + pass + + + + def call_after_solve(self, + *args, + **kwargs): + + pass + + + + def get_qoi_names(self): + + return [self.name+"_ener"] + + + + def get_qoi_values(self): + + self.ener = (dolfin.assemble(self.ener_form)/self.problem.mesh_V0)**(1./2) + self.printer.print_sci(self.name+"_ener",self.ener) + + return [self.ener] diff --git a/Energy_Regularization.py b/Energy_Regularization.py new file mode 100644 index 0000000000000000000000000000000000000000..651d89d813210528acfebed45ec15370954f6b26 --- /dev/null +++ b/Energy_Regularization.py @@ -0,0 +1,142 @@ +#coding=utf8 + +################################################################################ +### ### +### Created by Martin Genet, 2016-2018 ### +### ### +### École Polytechnique, Palaiseau, France ### +### ### +################################################################################ + +import dolfin + +import myPythonLibrary as mypy +import myVTKPythonLibrary as myvtk + +import dolfin_cm as dcm + +import dolfin_dic as ddic +from Energy import Energy + +################################################################################ + +class RegularizationEnergy(Energy): + + + + def __init__(self, + problem, + name="reg", + w=1., + type="equilibrated", + model="neohookean", + young=1., + poisson=0., + quadrature_degree=None): + + self.problem = problem + self.printer = problem.printer + self.name = name + self.w = w + self.type = type + self.model = model + self.young = young + self.poisson = poisson + self.quadrature_degree = quadrature_degree + + self.printer.print_str("Defining regularization energy…") + self.printer.inc() + + self.printer.print_str("Defining measures…") + + self.form_compiler_parameters = { + "representation":"uflacs", # MG20180327: Is that needed? + "quadrature_degree":self.quadrature_degree} + self.dV = dolfin.Measure( + "dx", + domain=self.problem.mesh, + metadata=self.form_compiler_parameters) + self.dF = dolfin.Measure( + "dS", + domain=self.problem.mesh, + metadata=self.form_compiler_parameters) + self.dS = dolfin.Measure( + "ds", + domain=self.problem.mesh, + metadata=self.form_compiler_parameters) + + self.printer.print_str("Defining mechanical model…") + + self.E = dolfin.Constant(self.young) + self.nu = dolfin.Constant(self.poisson) + self.material_parameters = { + "E":self.E, + "nu":self.nu} + + if (self.model == "linear"): # <- super bad + self.e = dolfin.sym(dolfin.grad(self.problem.U)) + self.material = dcm.HookeElasticMaterial( + parameters=self.material_parameters) + self.Psi_m, self.S_m = self.material.get_free_energy( + epsilon=self.e) + self.P_m = self.S_m + elif (self.model in ("kirchhoff", "neohookean")): + self.dim = self.problem.U.ufl_shape[0] + self.I = dolfin.Identity(self.dim) + self.F = self.I + dolfin.grad(self.problem.U) + self.C = self.F.T * self.F + if (self.model == "kirchhoff"): # <- pretty bad too + self.E = (self.C - self.I)/2 + self.material = dcm.KirchhoffElasticMaterial( + parameters=self.material_parameters) + self.Psi_m, self.S_m = self.material.get_free_energy( + E=self.E) + elif (self.model == "neohookean"): + self.material = dcm.CiarletGeymonatNeoHookeanElasticMaterial( + parameters=self.material_parameters) + self.Psi_m, self.S_m = self.material.get_free_energy( + C=self.C) + self.P_m = self.F * self.S_m + else: + assert (0), "\"model\" ("+str(self.model)+") must be \"linear\", \"kirchhoff\" or \"neohookean\". Aborting." + + self.printer.print_str("Defining regularization energy…") + + if (self.type == "hyperelastic"): + self.Psi_m_V = self.Psi_m + self.Psi_m_F = dolfin.Constant(0) + self.Psi_m_S = dolfin.Constant(0) + elif (self.type == "equilibrated"): + self.Div_P = dolfin.div(self.P_m) + self.Psi_m_V = dolfin.inner(self.Div_P, + self.Div_P) + self.N = dolfin.FacetNormal(self.problem.mesh) + self.Jump_P_N = dolfin.jump(self.P_m, + self.N) + self.cell_h = dolfin.Constant(self.problem.mesh.hmin()) + self.Psi_m_F = dolfin.inner(self.Jump_P_N, + self.Jump_P_N)/self.cell_h + # self.P_N = self.P_m * self.N + # self.P_N_N = dolfin.dot(self.N, + # self.P_N) + # self.P_N_T = self.P_N - self.P_N_N * self.N + # self.Psi_m_S = dolfin.inner(self.P_N_T, + # self.P_N_T)/self.cell_h + # self.Psi_m_S = dolfin.inner(self.P_N, + # self.P_N)/self.cell_h + self.Psi_m_S = dolfin.Constant(0) + else: + assert (0), "\"type\" ("+str(self.type)+") must be \"hyperelastic\" or \"equilibrated\". Aborting." + + self.DPsi_m_V = dolfin.derivative( self.Psi_m_V, self.problem.U, self.problem.dU_test ) + self.DPsi_m_F = dolfin.derivative( self.Psi_m_F, self.problem.U, self.problem.dU_test ) + self.DPsi_m_S = dolfin.derivative( self.Psi_m_S, self.problem.U, self.problem.dU_test ) + self.DDPsi_m_V = dolfin.derivative(self.DPsi_m_V, self.problem.U, self.problem.dU_trial) + self.DDPsi_m_F = dolfin.derivative(self.DPsi_m_F, self.problem.U, self.problem.dU_trial) + self.DDPsi_m_S = dolfin.derivative(self.DPsi_m_S, self.problem.U, self.problem.dU_trial) + + self.ener_form = self.Psi_m_V * self.dV + self.Psi_m_F * self.dF + self.Psi_m_S * self.dS + self.res_form = self.DPsi_m_V * self.dV + self.DPsi_m_F * self.dF + self.DPsi_m_S * self.dS + self.jac_form = self.DDPsi_m_V * self.dV + self.DDPsi_m_F * self.dF + self.DDPsi_m_S * self.dS + + self.printer.dec() diff --git a/Energy_WarpedImage.py b/Energy_WarpedImage.py new file mode 100644 index 0000000000000000000000000000000000000000..454865a43e676fe073247e1a9de1c554daeead63 --- /dev/null +++ b/Energy_WarpedImage.py @@ -0,0 +1,283 @@ +#coding=utf8 + +################################################################################ +### ### +### Created by Martin Genet, 2016-2018 ### +### ### +### École Polytechnique, Palaiseau, France ### +### ### +################################################################################ + +import dolfin +import numpy + +import myPythonLibrary as mypy +import myVTKPythonLibrary as myvtk + +import dolfin_dic as ddic +from Energy import Energy + +################################################################################ + +class WarpedImageEnergy(Energy): + + + + def __init__(self, + problem, + image_series, + quadrature_degree, + name="im", + w=1., + ref_frame=0, + dynamic_scaling=False): + + self.problem = problem + self.printer = self.problem.printer + self.image_series = image_series + self.quadrature_degree = quadrature_degree + self.name = name + self.w = w + self.ref_frame = ref_frame + self.dynamic_scaling = dynamic_scaling + + self.printer.print_str("Defining warped image correlation energy…") + self.printer.inc() + + self.printer.print_str("Defining quadrature finite elements…") + + # fe + self.fe = dolfin.FiniteElement( + family="Quadrature", + cell=self.problem.mesh.ufl_cell(), + degree=self.quadrature_degree, + quad_scheme="default") + self.fe._quad_scheme = "default" # should not be needed + for sub_element in self.fe.sub_elements(): # should not be needed + sub_element._quad_scheme = "default" # should not be needed + + # ve + self.ve = dolfin.VectorElement( + family="Quadrature", + cell=self.problem.mesh.ufl_cell(), + degree=self.quadrature_degree, + quad_scheme="default") + self.ve._quad_scheme = "default" # should not be needed + for sub_element in self.ve.sub_elements(): # should not be needed + sub_element._quad_scheme = "default" # should not be needed + + # te + self.te = dolfin.TensorElement( + family="Quadrature", + cell=self.problem.mesh.ufl_cell(), + degree=self.quadrature_degree, + quad_scheme="default") + self.te._quad_scheme = "default" # should not be needed + for sub_element in self.te.sub_elements(): # should not be needed + sub_element._quad_scheme = "default" # should not be needed + + self.printer.print_str("Defining measure…") + + self.form_compiler_parameters = { + "quadrature_degree":self.quadrature_degree, + "quadrature_scheme":"default"} + self.dV = dolfin.Measure( + "dx", + domain=self.problem.mesh, + metadata=self.form_compiler_parameters) + + self.printer.print_str("Loading reference image…") + self.printer.inc() + + # ref_frame + assert (abs(self.ref_frame) < self.image_series.n_frames),\ + "abs(ref_frame) = "+str(abs(self.ref_frame))+" >= "+str(self.image_series.n_frames)+" = image_series.n_frames. Aborting." + self.ref_frame = self.ref_frame%self.image_series.n_frames + self.printer.print_var("ref_frame",self.ref_frame) + + # Iref + self.Iref = dolfin.Expression( + cppcode=ddic.get_ExprIm_cpp( + im_dim=self.image_series.dimension, + im_type="im", + im_is_def=0), + element=self.fe) + self.ref_image_filename = self.image_series.get_image_filename(self.ref_frame) + self.Iref.init_image(self.ref_image_filename) + + self.Iref_int = dolfin.assemble(self.Iref * self.dV)/self.problem.mesh_V0 + self.printer.print_var("Iref_int",self.Iref_int) + + self.Iref_norm = (dolfin.assemble(self.Iref**2 * self.dV)/self.problem.mesh_V0)**(1./2) + assert (self.Iref_norm > 0.),\ + "Iref_norm = "+str(self.Iref_norm)+" <= 0. Aborting." + self.printer.print_var("Iref_norm",self.Iref_norm) + + # DIref + self.DIref = dolfin.Expression( + cppcode=ddic.get_ExprIm_cpp( + im_dim=self.image_series.dimension, + im_type="grad" if (self.image_series.grad_basename is None) else "grad_no_deriv", + im_is_def=0), + element=self.ve) + self.ref_image_grad_filename = self.image_series.get_image_grad_filename(self.ref_frame) + self.DIref.init_image(self.ref_image_grad_filename) + + self.printer.dec() + self.printer.print_str("Defining deformed image…") + + self.scaling = numpy.array([1.,0.]) + if (self.dynamic_scaling): + self.p = numpy.empty((2,2)) + self.q = numpy.empty(2) + + # Idef + self.Idef = dolfin.Expression( + cppcode=ddic.get_ExprIm_cpp( + im_dim=self.image_series.dimension, + im_type="im", + im_is_def=1), + element=self.fe) + self.Idef.init_image(self.ref_image_filename) + self.Idef.init_disp(self.problem.U) + self.Idef.init_dynamic_scaling(self.scaling) + + # DIdef + self.DIdef = dolfin.Expression( + cppcode=ddic.get_ExprIm_cpp( + im_dim=self.image_series.dimension, + im_type="grad" if (self.image_series.grad_basename is None) else "grad_no_deriv", + im_is_def=1), + element=self.ve) + self.DIdef.init_image(self.ref_image_filename) + self.DIdef.init_disp(self.problem.U) + self.DIdef.init_dynamic_scaling(self.scaling) + + self.printer.print_str("Defining previous image…") + + # Iold + self.Iold = dolfin.Expression( + cppcode=ddic.get_ExprIm_cpp( + im_dim=self.image_series.dimension, + im_type="im", + im_is_def=1), + element=self.fe) + self.Iold.init_image(self.ref_image_filename) + self.Iold.init_disp(self.problem.Uold) + self.Iold.init_dynamic_scaling(self.scaling) # 2016/07/25: ok, same scaling must apply to Idef & Iold… + + # DIold + self.DIold = dolfin.Expression( + cppcode=ddic.get_ExprIm_cpp( + im_dim=self.image_series.dimension, + im_type="grad" if (self.image_series.grad_basename is None) else "grad_no_deriv", + im_is_def=1), + element=self.ve) + self.DIold.init_image(self.ref_image_filename) + self.DIold.init_disp(self.problem.Uold) + self.DIold.init_dynamic_scaling(self.scaling) # 2016/07/25: ok, same scaling must apply to Idef & Iold… + + self.printer.print_str("Defining correlation energy…") + + # Phi_ref + self.Phi_Iref = dolfin.Expression( + cppcode=ddic.get_ExprCharFuncIm_cpp( + im_dim=self.image_series.dimension), + element=self.fe) + self.Phi_Iref.init_image(self.ref_image_filename) + + # Psi_c + self.Psi_c = self.Phi_Iref * (self.Idef - self.Iref)**2/2 + self.DPsi_c = self.Phi_Iref * (self.Idef - self.Iref) * dolfin.dot(self.DIdef, self.problem.dU_test) + + self.DDPsi_c = self.Phi_Iref * dolfin.dot(self.DIdef, self.problem.dU_trial) * dolfin.dot(self.DIdef, self.problem.dU_test) + self.DDPsi_c_old = self.Phi_Iref * dolfin.dot(self.DIold, self.problem.dU_trial) * dolfin.dot(self.DIold, self.problem.dU_test) + self.DDPsi_c_ref = self.Phi_Iref * dolfin.dot(self.DIref, self.problem.dU_trial) * dolfin.dot(self.DIref, self.problem.dU_test) + + self.Psi_c_old = self.Phi_Iref * (self.Idef - self.Iold)**2/2 + self.DPsi_c_old = self.Phi_Iref * (self.Idef - self.Iold) * dolfin.dot(self.DIdef, self.problem.dU_test) + + # forms + self.ener_form = self.Psi_c * self.dV + self.res_form = self.DPsi_c * self.dV + self.jac_form = self.DDPsi_c * self.dV + + self.printer.dec() + + + + def reinit(self): + + self.scaling[:] = [1.,0.] + + + + def call_before_solve(self, + k_frame, + k_frame_old): + + self.printer.print_str("Loading deformed image for correlation energy…") + + # Idef + self.def_image_filename = self.image_series.get_image_filename(k_frame) + self.Idef.init_image(self.def_image_filename) + + # DIdef + self.def_grad_image_filename = self.image_series.get_image_grad_filename(k_frame) + self.DIdef.init_image(self.def_grad_image_filename) + + self.printer.print_str("Loading previous image for correlation energy…") + + # Iold + self.old_image_filename = self.image_series.get_image_filename(k_frame_old) + self.Iold.init_image(self.old_image_filename) + + # DIold + self.old_grad_image_filename = self.image_series.get_image_grad_filename(k_frame_old) + self.DIold.init_image(self.old_grad_image_filename) + + + + def call_after_solve(self): + + if (self.dynamic_scaling): + self.printer.print_str("Updating dynamic scaling…") + self.printer.inc() + + self.get_qoi_values() + + self.p[0,0] = dolfin.assemble(self.Idef**2 * self.dV) + self.p[0,1] = dolfin.assemble(self.Idef * self.dV) + self.p[1,0] = self.p[0,1] + self.p[1,1] = 1. + self.q[0] = dolfin.assemble(self.Idef*self.Iref * self.dV) + self.q[1] = dolfin.assemble(self.Iref * self.dV) + self.scaling[:] = numpy.linalg.solve(self.p, self.q) + self.printer.print_var("scaling",self.scaling) + + self.Idef.update_dynamic_scaling(self.scaling) # should not be needed + self.DIdef.update_dynamic_scaling(self.scaling) # should not be needed + + self.Iold.update_dynamic_scaling(self.scaling) # should not be needed + self.DIold.update_dynamic_scaling(self.scaling) # should not be needed + + self.get_qoi_values() + + self.printer.dec() + + + + def get_qoi_names(self): + + return [self.name+"_ener", self.name+"_err"] + + + + def get_qoi_values(self): + + self.ener = (dolfin.assemble(self.ener_form)/self.problem.mesh_V0)**(1./2) + self.printer.print_sci(self.name+"_ener",self.ener) + self.err = self.ener/self.Iref_norm + self.printer.print_sci(self.name+"_err",self.err) + + return [self.ener, self.err] diff --git a/ImageIterator.py b/ImageIterator.py new file mode 100644 index 0000000000000000000000000000000000000000..08dd004efe5cf9bd61341f3ed2eeb04d4c4193c2 --- /dev/null +++ b/ImageIterator.py @@ -0,0 +1,155 @@ +#coding=utf8 + +################################################################################ +### ### +### Created by Martin Genet, 2016-2018 ### +### ### +### École Polytechnique, Palaiseau, France ### +### ### +################################################################################ + +import glob +import os +import time + +import myPythonLibrary as mypy +import myVTKPythonLibrary as myvtk + +import dolfin_dic as ddic + +################################################################################ + +class ImageIterator(): + + + + def __init__(self, + problem, + solver, + parameters={}): + + self.problem = problem + self.printer = self.problem.printer + self.solver = solver + + self.working_folder = parameters["working_folder"] if ("working_folder" in parameters) else "." + self.working_basename = parameters["working_basename"] if ("working_basename" in parameters) else "sol" + self.initialize_DU_with_DUold = parameters["initialize_DU_with_DUold"] if ("initialize_DU_with_DUold" in parameters) else False + + + + def iterate(self): + + self.printer.print_str("Writing initial solution…") + self.printer.inc() + + if not os.path.exists(self.working_folder): + os.mkdir(self.working_folder) + pvd_basename = self.working_folder+"/"+self.working_basename + for vtu_filename in glob.glob(pvd_basename+"_[0-9]*.vtu"): + os.remove(vtu_filename) + ddic.write_VTU_file( + filebasename=pvd_basename, + function=self.problem.U, + time=self.problem.images_ref_frame) + + self.printer.dec() + self.printer.print_str("Initializing QOI file…") + self.printer.inc() + + qoi_names = ["k_frame"]+self.problem.get_qoi_names() + qoi_filebasename = self.working_folder+"/"+self.working_basename+"-qoi" + qoi_printer = mypy.DataPrinter( + names=qoi_names, + filename=qoi_filebasename+".dat") + qoi_values = [self.problem.images_ref_frame]+self.problem.get_qoi_values() + qoi_printer.write_line( + values=qoi_values) + + self.printer.dec() + self.printer.print_str("Looping over frames…") + + n_iter_tot = 0 + global_success = True + for forward_or_backward in ["forward","backward"]: + self.printer.print_var("forward_or_backward",forward_or_backward) + + if (forward_or_backward == "forward"): + k_frames = range(self.problem.images_ref_frame+1, self.problem.images_n_frames, +1) + elif (forward_or_backward == "backward"): + k_frames = range(self.problem.images_ref_frame-1, -1, -1) + #self.printer.print_var("k_frames",k_frames) + + if (forward_or_backward == "backward"): + self.problem.reinit() + + self.printer.inc() + success = True + for k_frame in k_frames: + self.printer.print_var("k_frame",k_frame,-1) + + if (forward_or_backward == "forward"): + k_frame_old = k_frame-1 + elif (forward_or_backward == "backward"): + k_frame_old = k_frame+1 + #self.printer.print_var("k_frame_old",k_frame_old,-1) + + if (self.initialize_DU_with_DUold): + self.problem.U.vector().axpy(1., self.problem.DUold.vector()) + + self.problem.call_before_solve( + k_frame=k_frame, + k_frame_old=k_frame_old) + + self.printer.print_str("Running registration…") + + success, n_iter = self.solver.solve( + k_frame=k_frame) + n_iter_tot += n_iter + + if not (success): + global_success = False + break + + self.problem.call_after_solve() + + self.printer.print_str("Writing solution…") + self.printer.inc() + + ddic.write_VTU_file( + filebasename=pvd_basename, + function=self.problem.U, + time=k_frame) + + self.printer.dec() + self.printer.print_str("Writing QOI file…") + self.printer.inc() + + qoi_printer.write_line( + [k_frame]+self.problem.get_qoi_values()) + + self.printer.dec() + + self.printer.dec() + + if not (global_success): + break + + self.printer.print_str("Image iterator finished…") + self.printer.inc() + + self.printer.print_var("n_iter_tot",n_iter_tot) + + self.printer.dec() + self.printer.print_str("Plotting QOI…") + + qoi_printer.close() + commandline = "gnuplot -e \"set terminal pdf;" + commandline += " set output '"+qoi_filebasename+".pdf';" + commandline += " set grid;" + for k_qoi in xrange(1,len(qoi_names)): + commandline += " plot '"+qoi_filebasename+".dat' u 1:"+str(1+k_qoi)+" lw 3 title '"+qoi_names[k_qoi]+"';" + commandline += "\"" + os.system(commandline) + + return global_success diff --git a/ImageSeries.py b/ImageSeries.py new file mode 100644 index 0000000000000000000000000000000000000000..89eea3b992c6fd2b86b054d77f3fe6051043f2ef --- /dev/null +++ b/ImageSeries.py @@ -0,0 +1,93 @@ +#coding=utf8 + +################################################################################ +### ### +### Created by Martin Genet, 2016-2018 ### +### ### +### École Polytechnique, Palaiseau, France ### +### ### +################################################################################ + +import glob + +import myPythonLibrary as mypy +import myVTKPythonLibrary as myvtk + +import dolfin_dic as ddic + +################################################################################ + + + +class ImageSeries(): + + + + def __init__(self, + problem, + folder, + basename, + grad_folder=None, + grad_basename=None, + n_frames=None, + ext="vti"): + + self.problem = problem + self.printer = self.problem.printer + self.folder = folder + self.basename = basename + self.grad_folder = grad_folder + self.grad_basename = grad_basename + self.n_frames = n_frames + self.ext = ext + + self.printer.print_str("Reading image series…") + self.printer.inc() + + self.filenames = glob.glob(self.folder+"/"+self.basename+"_[0-9]*"+"."+self.ext) + assert (len(self.filenames) >= 2),\ + "Not enough images ("+self.folder+"/"+self.basename+"_[0-9]*"+"."+self.ext+"). Aborting." + + if (self.n_frames is None): + self.n_frames = len(self.filenames) + else: + assert (self.n_frames <= len(self.filenames)) + assert (self.n_frames >= 2),\ + "n_frames = "+str(self.n_frames)+" < 2. Aborting." + self.printer.print_var("n_frames",self.n_frames) + + self.zfill = len(self.filenames[0].rsplit("_",1)[-1].split(".",1)[0]) + + if (self.grad_basename is not None): + if (self.grad_folder is None): + self.grad_folder = self.folder + self.grad_filenames = glob.glob(self.grad_folder+"/"+self.grad_basename+"_[0-9]*"+"."+self.ext) + assert (len(self.grad_filenames) >= self.n_frames) + + image = myvtk.readImage( + filename=self.get_image_filename( + k_frame=0), + verbose=0) + self.dimension = myvtk.getImageDimensionality( + image=image, + verbose=0) + self.printer.print_var("dimension",self.dimension) + + self.printer.dec() + + + + def get_image_filename(self, + k_frame): + + return self.folder+"/"+self.basename+"_"+str(k_frame).zfill(self.zfill)+"."+self.ext + + + + def get_image_grad_filename(self, + k_frame): + + if (self.grad_basename is None): + return self.get_image_filename(k_frame) + else: + return self.grad_folder+"/"+self.grad_basename+"_"+str(k_frame).zfill(self.zfill)+"."+self.ext diff --git a/NonlinearSolver.py b/NonlinearSolver.py new file mode 100644 index 0000000000000000000000000000000000000000..7bba64cf5312416c168934068df05ea97f256378 --- /dev/null +++ b/NonlinearSolver.py @@ -0,0 +1,358 @@ +#coding=utf8 + +################################################################################ +### ### +### Created by Martin Genet, 2016-2018 ### +### ### +### École Polytechnique, Palaiseau, France ### +### ### +################################################################################ + +import dolfin +import glob +import math +import numpy +import os +import time + +import myPythonLibrary as mypy +import myVTKPythonLibrary as myvtk + +import dolfin_dic as ddic + +################################################################################ + +class NonlinearSolver(): + + + + def __init__(self, + problem, + parameters={}): + + self.problem = problem + self.printer = self.problem.printer + + # linear solver + self.linear_solver_name = parameters["linear_solver_name"] if ("linear_solver_name" in parameters) else "mumps" + + self.res_vec = dolfin.Vector() + self.jac_mat = dolfin.Matrix() + + self.linear_solver = dolfin.LUSolver( + self.jac_mat, + self.linear_solver_name) + self.linear_solver.parameters['report'] = bool(0) + self.linear_solver.parameters['reuse_factorization'] = bool(0) + self.linear_solver.parameters['same_nonzero_pattern'] = bool(1) + self.linear_solver.parameters['symmetric'] = bool(1) + self.linear_solver.parameters['verbose'] = bool(0) + + # relaxation + self.relax_type = parameters["relax_type"] if ("relax_type" in parameters) else "gss" + + if (self.relax_type == "aitken"): + self.compute_relax = self.compute_relax_aitken + elif (self.relax_type == "constant"): + self.compute_relax = self.compute_relax_constant + self.relax_val = parameters["relax"] if ("relax" in parameters) else 1. + elif (self.relax_type == "gss"): + self.compute_relax = self.compute_relax_gss + self.relax_tol = parameters["relax_tol"] if ("relax_tol" in parameters) else 0 + self.relax_n_iter_max = parameters["relax_n_iter_max"] if ("relax_n_iter_max" in parameters) else 5 + + # iterations control + self.tol_dU = parameters["tol_dU"] if ("tol_dU" in parameters) else None + self.tol_res_rel = parameters["tol_res_rel"] if ("tol_res_rel" in parameters) else None + self.n_iter_max = parameters["n_iter_max"] if ("n_iter_max" in parameters) else 32 + + # write iterations + self.write_iterations = parameters["write_iterations"] if ("write_iterations" in parameters) else False + + if (self.write_iterations): + self.working_folder = parameters["working_folder"] + self.working_basename = parameters["working_basename"] + + for filename in glob.glob(self.working_folder+"/"+self.working_basename+"-frame=[0-9]*.*"): + os.remove(filename) + + + + def solve(self, + k_frame=None): + + if (self.write_iterations): + self.frame_filebasename = self.working_folder+"/"+self.working_basename+"-frame="+str(k_frame).zfill(len(str(self.problem.images_n_frames))) + + self.frame_printer = mypy.DataPrinter( + names=["k_iter", "res_norm", "res_err_rel", "relax", "dU_norm", "U_norm", "dU_err"], + filename=self.frame_filebasename+".dat") + + ddic.write_VTU_file( + filebasename=self.frame_filebasename, + function=self.problem.U, + time=0) + + self.k_iter = 0 + self.success = False + self.printer.inc() + while (True): + self.k_iter += 1 + self.printer.print_var("k_iter",self.k_iter,-1) + + # linear problem + self.linear_success = self.linear_solve() + if not (self.linear_success): + break + + # relaxation + self.compute_relax() + + # solution update + self.problem.U.vector().axpy(self.relax, self.problem.dU.vector()) + self.problem.U_norm = self.problem.U.vector().norm("l2") + #self.printer.print_sci("U_norm",self.problem.U_norm) + + if (self.write_iterations): + ddic.write_VTU_file( + filebasename=self.frame_filebasename, + function=self.problem.U, + time=self.k_iter) + + # displacement error + self.problem.dU_norm *= abs(self.relax) + #self.printer.print_sci("dU_norm",self.problem.dU_norm) + if (self.problem.dU_norm == 0.) and (self.problem.Uold_norm == 0.) and (self.problem.U_norm == 0.): + self.problem.dU_err = 0. + elif (self.problem.Uold_norm == 0.): + self.problem.dU_err = self.problem.dU_norm/self.problem.U_norm + else: + self.problem.dU_err = self.problem.dU_norm/self.problem.Uold_norm + self.printer.print_sci("dU_err",self.problem.dU_err) + + if (self.write_iterations): + self.frame_printer.write_line([self.k_iter, self.res_norm, self.res_err_rel, self.relax, self.problem.dU_norm, self.problem.U_norm, self.problem.dU_err]) + + # exit test + self.success = True + if (self.tol_res_rel is not None) and (self.res_err_rel > self.tol_res_rel): + self.success = False + if (self.tol_dU is not None) and (self.problem.dU_err > self.tol_dU ): + self.success = False + + # exit + if (self.success): + self.printer.print_str("Nonlinear solver converged…") + break + + if (self.k_iter == self.n_iter_max): + self.printer.print_str("Warning! Nonlinear solver failed to converge… (k_frame = "+str(k_frame)+")") + break + + self.printer.dec() + + if (self.write_iterations): + self.frame_printer.close() + commandline = "gnuplot -e \"set terminal pdf noenhanced;" + commandline += " set output '"+self.frame_filebasename+".pdf';" + commandline += " set key box textcolor variable;" + commandline += " set grid;" + commandline += " set logscale y;" + commandline += " set yrange [1e-3:1e0];" + commandline += " plot '"+self.frame_filebasename+".dat' u 1:7 pt 1 lw 3 title 'dU_err', "+str(self.tol_dU)+" lt -1 notitle;" + commandline += " unset logscale y;" + commandline += " set yrange [*:*];" + commandline += " plot '' u 1:4 pt 1 lw 3 title 'relax'\"" + os.system(commandline) + + return self.success, self.k_iter + + + + def linear_solve(self): + + # res_old + if (self.k_iter > 1): + if (hasattr(self, "res_old_vec")): + self.res_old_vec[:] = self.res_vec[:] + else: + self.res_old_vec = self.res_vec.copy() + self.res_old_norm = self.res_norm + + # linear system: residual assembly + self.printer.print_str("Residual assembly…",newline=False) + timer = time.time() + self.problem.assemble_res( + res_vec=self.res_vec) + timer = time.time() - timer + self.printer.print_str(" "+str(timer)+" s",tab=False) + + self.printer.inc() + + # res_norm + self.res_norm = self.res_vec.norm("l2") + #self.printer.print_sci("res_norm",self.res_norm) + + # dres + if (self.k_iter > 1): + if (hasattr(self, "dres_vec")): + self.dres_vec[:] = self.res_vec[:] - self.res_old_vec[:] + else: + self.dres_vec = self.res_vec - self.res_old_vec + self.dres_norm = self.dres_vec.norm("l2") + self.printer.print_sci("dres_norm",self.dres_norm) + + # res_err_rel + if (self.k_iter == 1): + self.res_err_rel = 1. + else: + self.res_err_rel = self.dres_norm / self.res_old_norm + self.printer.print_sci("res_err_rel",self.res_err_rel) + + self.printer.dec() + + # linear system: matrix assembly + self.printer.print_str("Jacobian assembly…",newline=False) + timer = time.time() + self.problem.assemble_jac( + jac_mat=self.jac_mat) + timer = time.time() - timer + self.printer.print_str(" "+str(timer)+" s",tab=False) + + # linear system: solve + try: + self.printer.print_str("Solve…",newline=False) + timer = time.time() + self.linear_solver.solve( + self.problem.dU.vector(), + self.res_vec) + timer = time.time() - timer + self.printer.print_str(" "+str(timer)+" s",tab=False) + except: + self.printer.print_str("Warning! Linear solver failed!",tab=False) + return False + #self.printer.print_var("dU",dU.vector().array()) + + self.printer.inc() + + # dU_norm + self.problem.dU_norm = self.problem.dU.vector().norm("l2") + #self.printer.print_sci("dU_norm",self.problem.dU_norm) + if not (numpy.isfinite(self.problem.dU_norm)): + self.printer.print_str("Warning! Solution increment is NaN! Setting it to 0.",tab=False) + self.problem.dU.vector().zero() + + self.printer.dec() + + return True + + + + def compute_relax_aitken(self): + + if (self.k_iter == 1): + self.relax = 1. + else: + self.relax *= (-1.) * self.res_old_vec.inner(self.dres_vec) / self.dres_norm**2 + self.printer.print_sci("relax",self.relax) + + + + def compute_relax_constant(self): + + self.relax = self.relax_val + self.printer.print_sci("relax",self.relax) + + + + def compute_relax_gss(self): + + phi = (1 + math.sqrt(5)) / 2 + relax_a = (1-phi)/(2-phi) + relax_b = 1/(2-phi) + need_update_c = True + need_update_d = True + relax_cur = 0. + relax_list = [] + ener_list = [] + self.printer.inc() + relax_k = 1 + while (True): + self.printer.print_var("relax_k",relax_k,-1) + # self.printer.print_sci("relax_a",relax_a) + # self.printer.print_sci("relax_b",relax_b) + if (need_update_c): + relax_c = relax_b - (relax_b - relax_a) / phi + relax_list.append(relax_c) + self.printer.print_sci("relax_c",relax_c) + self.problem.U.vector().axpy(relax_c-relax_cur, self.problem.dU.vector()) + relax_cur = relax_c + relax_fc = self.problem.assemble_ener() + #self.printer.print_sci("relax_fc",relax_fc) + if (numpy.isnan(relax_fc)): + relax_fc = float('+inf') + #self.printer.print_sci("relax_fc",relax_fc) + self.printer.print_sci("relax_fc",relax_fc) + ener_list.append(relax_fc) + if (need_update_d): + relax_d = relax_a + (relax_b - relax_a) / phi + relax_list.append(relax_d) + self.printer.print_sci("relax_d",relax_d) + self.problem.U.vector().axpy(relax_d-relax_cur, self.problem.dU.vector()) + relax_cur = relax_d + relax_fd = self.problem.assemble_ener() + if (numpy.isnan(relax_fd)): + relax_fd = float('+inf') + #self.printer.print_sci("relax_fd",relax_fd) + self.printer.print_sci("relax_fd",relax_fd) + ener_list.append(relax_fd) + # self.printer.print_var("relax_list",relax_list) + # self.printer.print_var("ener_list",ener_list) + if (relax_k > 1): + ener_min_old = ener_min + relax_min = relax_list[numpy.argmin(ener_list)] + # self.printer.print_var("relax_min",relax_min) + ener_min = min(ener_list) + # self.printer.print_var("ener_min",ener_min) + if (relax_k > 1): + dener_min = ener_min-ener_min_old + self.printer.print_var("dener_min",dener_min) + relax_err = dener_min/ener_list[0] + self.printer.print_var("relax_err",relax_err) + if (relax_min != 0.) and (relax_err < self.relax_tol): + break + if (relax_k == self.relax_n_iter_max): + break + if (relax_fc < relax_fd): + relax_b = relax_d + relax_d = relax_c + relax_fd = relax_fc + need_update_c = True + need_update_d = False + elif (relax_fc >= relax_fd): + relax_a = relax_c + relax_c = relax_d + relax_fc = relax_fd + need_update_c = False + need_update_d = True + else: assert(0) + relax_k += 1 + self.printer.dec() + self.problem.U.vector().axpy(-relax_cur, self.problem.dU.vector()) + #self.printer.print_var("ener_list",ener_list) + + if (self.write_iterations): + self.iter_filebasename = self.frame_filebasename+"-iter="+str(self.k_iter).zfill(3) + file_dat_iter = open(self.iter_filebasename+".dat","w") + file_dat_iter.write("\n".join([" ".join([str(val) for val in [relax_list[relax_k], ener_list[relax_k]]]) for relax_k in xrange(len(relax_list))])) + file_dat_iter.close() + commandline = "gnuplot -e \"set terminal pdf;" + commandline += " set output '"+self.iter_filebasename+".pdf';" + commandline += " plot '"+self.iter_filebasename+".dat' using 1:2 with points title 'psi_int';" + commandline += " plot '"+self.iter_filebasename+".dat' u 1:2 with points title 'psi_int', '"+self.iter_filebasename+".dat' using (\$2=='inf'?\$1:1/0):(GPVAL_Y_MIN+(0.8)*(GPVAL_Y_MAX-GPVAL_Y_MIN)):(0):((0.2)*(GPVAL_Y_MAX-GPVAL_Y_MIN)) with vectors notitle\"" + os.system(commandline) + + self.relax = relax_list[numpy.argmin(ener_list)] + self.printer.print_sci("relax",self.relax) + if (self.relax == 0.): + self.printer.print_str("Warning! Optimal relaxation is null…") diff --git a/Problem.py b/Problem.py new file mode 100644 index 0000000000000000000000000000000000000000..cdbba9bc1076127ebeb4b5fd8467c4274c38d03a --- /dev/null +++ b/Problem.py @@ -0,0 +1,20 @@ +#coding=utf8 + +################################################################################ +### ### +### Created by Martin Genet, 2016-2018 ### +### ### +### École Polytechnique, Palaiseau, France ### +### ### +################################################################################ + +import myPythonLibrary as mypy +import myVTKPythonLibrary as myvtk + +import dolfin_dic as ddic + +################################################################################ + +class Problem(): + + pass diff --git a/Problem_ImageRegistration.py b/Problem_ImageRegistration.py new file mode 100644 index 0000000000000000000000000000000000000000..fdf6396a8dc1e490f6abd6d46089f2d902bfd691 --- /dev/null +++ b/Problem_ImageRegistration.py @@ -0,0 +1,277 @@ +#coding=utf8 + +################################################################################ +### ### +### Created by Martin Genet, 2016-2018 ### +### ### +### École Polytechnique, Palaiseau, France ### +### ### +################################################################################ + +import dolfin +import os + +import myPythonLibrary as mypy +import myVTKPythonLibrary as myvtk + +import dolfin_dic as ddic +from Problem import Problem + +################################################################################ + +class ImageRegistrationProblem(Problem): + + + + def __init__(self, + mesh=None, + mesh_folder=None, + mesh_basename=None, + U_family="Lagrange", + U_degree=1): + + self.printer = mypy.Printer() + + self.set_mesh( + mesh=mesh, + mesh_folder=mesh_folder, + mesh_basename=mesh_basename) + + self.set_displacement( + U_family=U_family, + U_degree=U_degree) + + self.energies = [] + + + + def __del__(self): + + self.printer.close() + + + + def set_mesh(self, + mesh=None, + mesh_folder=None, + mesh_basename=None): + + self.printer.print_str("Loading mesh…") + self.printer.inc() + + assert ((mesh is not None) or ((mesh_folder is not None) and (mesh_basename is not None))),\ + "Must provide a mesh (mesh = "+str(mesh)+") or a mesh file (mesh_folder = "+str(mesh_folder)+", mesh_basename = "+str(mesh_basename)+"). Aborting." + + if (mesh is None): + self.mesh_folder = mesh_folder + self.mesh_basename = mesh_basename + self.mesh_filebasename = self.mesh_folder+"/"+self.mesh_basename + self.mesh_filename = self.mesh_filebasename+"."+"xml" + assert (os.path.exists(self.mesh_filename)),\ + "No mesh in "+mesh_filename+". Aborting." + self.mesh = dolfin.Mesh(self.mesh_filename) + else: + self.mesh = mesh + + self.mesh_dimension = self.mesh.ufl_domain().geometric_dimension() + assert (self.mesh_dimension in (2,3)),\ + "mesh_dimension ("+str(self.mesh_dimension)+") must be 2 or 3. Aborting." + self.printer.print_var("mesh_dimension",self.mesh_dimension) + + self.printer.print_var("mesh_n_vertices",self.mesh.num_vertices()) + self.printer.print_var("mesh_n_cells",self.mesh.num_cells()) + + self.dV = dolfin.Measure( + "dx", + domain=self.mesh) + self.dS = dolfin.Measure( + "ds", + domain=self.mesh) + self.dF = dolfin.Measure( + "dS", + domain=self.mesh) + + self.mesh_V0 = dolfin.assemble(dolfin.Constant(1) * self.dV) + self.printer.print_sci("mesh_V0",self.mesh_V0) + self.mesh_S0 = dolfin.assemble(dolfin.Constant(1) * self.dS) + self.printer.print_sci("mesh_S0",self.mesh_S0) + self.mesh_h0 = self.mesh_V0**(1./self.mesh_dimension) + self.printer.print_sci("mesh_h0",self.mesh_h0) + self.mesh_h0 = dolfin.Constant(self.mesh_h0) + + self.printer.dec() + + + + def set_displacement(self, + U_family="Lagrange", + U_degree=1): + + self.printer.print_str("Defining functions…") + + self.U_family = U_family + self.U_degree = U_degree + self.U_fe = dolfin.VectorElement( + family=self.U_family, + cell=self.mesh.ufl_cell(), + degree=self.U_degree) + self.U_fs = dolfin.FunctionSpace( + self.mesh, + self.U_fe) + self.U = dolfin.Function( + self.U_fs, + name="displacement") + self.U.vector().zero() + self.U_norm = 0. + self.Uold = dolfin.Function( + self.U_fs, + name="previous displacement") + self.Uold.vector().zero() + self.Uold_norm = 0. + self.DUold = dolfin.Function( + self.U_fs, + name="previous displacement increment") + self.dU = dolfin.Function( + self.U_fs, + name="displacement correction") + self.dU_trial = dolfin.TrialFunction(self.U_fs) + self.dU_test = dolfin.TestFunction(self.U_fs) + + # for mesh volume computation + self.I = dolfin.Identity(self.mesh_dimension) + self.F = self.I + dolfin.grad(self.U) + self.J = dolfin.det(self.F) + + + + def reinit(self): + + self.U.vector().zero() + self.U_norm = 0. + self.Uold.vector().zero() + self.Uold_norm = 0. + self.DUold.vector().zero() + + for energy in self.energies: + energy.reinit() + + + + def add_image_energy(self, + energy): + + if (hasattr(self, "images_n_frames") + and hasattr(self, "images_ref_frame")): + assert (energy.image_series.n_frames == self.images_n_frames) + assert (energy.ref_frame == self.images_ref_frame) + else: + self.images_n_frames = energy.image_series.n_frames + self.images_ref_frame = energy.ref_frame + + self.energies += [energy] + + + + def add_regul_energy(self, + energy): + + self.energies += [energy] + + + + def assemble_ener(self): + + ener_form = 0. + for energy in self.energies: + ener_form += dolfin.Constant(energy.w) * energy.ener_form + + ener = dolfin.assemble( + ener_form) + #self.printer.print_var("ener",ener) + + return ener + + + + def assemble_res(self, + res_vec): + + res_form = 0. + for energy in self.energies: + res_form -= dolfin.Constant(energy.w) * energy.res_form + + res_vec = dolfin.assemble( + res_form, + tensor=res_vec) + #self.printer.print_var("res_vec",res_vec.array()) + + + + def assemble_jac(self, + jac_mat): + + jac_form = 0. + for energy in self.energies: + jac_form += dolfin.Constant(energy.w) * energy.jac_form + + jac_mat = dolfin.assemble( + jac_form, + tensor=jac_mat) + #self.printer.print_var("jac_mat",jac_mat.array()) + + + + def call_before_solve(self, + *kargs, + **kwargs): + + for energy in self.energies: + energy.call_before_solve( + *kargs, + **kwargs) + + + + def call_after_solve(self, + *kargs, + **kwargs): + + self.DUold.vector()[:] = self.U.vector()[:] - self.Uold.vector()[:] + self.Uold.vector()[:] = self.U.vector()[:] + self.Uold_norm = self.U_norm + + for energy in self.energies: + energy.call_after_solve( + *kargs, + **kwargs) + + + + def get_qoi_names(self): + + names = ["mesh_V"] + + for energy in self.energies: + names += energy.get_qoi_names() + + return names + + + + def get_qoi_values(self): + + self.compute_mesh_volume() + values = [self.mesh_V] + + for energy in self.energies: + values += energy.get_qoi_values() + + return values + + + + def compute_mesh_volume(self): + + self.mesh_V = dolfin.assemble(self.J * self.dV) + self.printer.print_sci("mesh_V",self.mesh_V) + return self.mesh_V diff --git a/__init__.py b/__init__.py index 4e6273a053f9a6e870475f83f30f4aad186b02db..e67262458e7995999f7626e3578ad9fffdadb3e3 100644 --- a/__init__.py +++ b/__init__.py @@ -1,19 +1,29 @@ #this file was generated by __init__.py.py -from compute_warped_mesh import * -from image_expressions_py import * -from compute_warped_images import * -from compute_unwarped_images import * from fedic import * -from generate_images import * from plot_binned_strains_vs_radius import * -from plot_regional_strains import * -from generate_undersampled_images import * -from compute_strains import * -from compute_displacements import * -from compute_displacement_error import * +from NonlinearSolver import * +from plot_strains_vs_radius import * +from compute_unwarped_images import * +from Problem_ImageRegistration import * from compute_quadrature_degree import * -from image_expressions_cpp import * +from Energy_Regularization import * +from compute_warped_images import * from plot_strains import * +from image_expressions_cpp import * +from Energy import * +from compute_warped_mesh import * +from Energy_WarpedImage import * +from write_VTU_file import * +from generate_undersampled_images import * +from plot_regional_strains import * +from image_expressions_py import * +from ImageIterator import * +from fedic2 import * from plot_displacement_error import * -from plot_strains_vs_radius import * +from Problem import * +from compute_displacements import * +from generate_images import * +from ImageSeries import * +from compute_displacement_error import * +from compute_strains import * diff --git a/compute_quadrature_degree.py b/compute_quadrature_degree.py index 7a2c2312d658e3734d25176232058aa706314ac8..78755d55ebbca9ecfc145024a437b94374b02cc4 100644 --- a/compute_quadrature_degree.py +++ b/compute_quadrature_degree.py @@ -96,7 +96,8 @@ def compute_quadrature_degree_from_points_count( def compute_quadrature_degree_from_integral( image_filename, - mesh, + mesh=None, + mesh_filebasename=None, deg_min=1, deg_max=10, tol=1e-2, @@ -111,6 +112,8 @@ def compute_quadrature_degree_from_integral( verbose=verbose-1) if (verbose): print "image_dimension = " + str(image_dimension) + if (mesh is None): + mesh = dolfin.Mesh(mesh_filebasename+"."+"xml") dX = dolfin.dx(mesh) first_time = True diff --git a/fedic.py b/fedic.py index 833191e77649ef629fb25fd2180b4bbc0cb556d0..ee505f8193732d74952ae7c3d9f1207472a357af 100644 --- a/fedic.py +++ b/fedic.py @@ -100,7 +100,7 @@ def fedic( "images_n_frames = "+str(images_n_frames)+" <= 1. Aborting." mypy.print_var("images_n_frames",images_n_frames,tab+1) assert (abs(images_ref_frame) < images_n_frames),\ - "abs(images_ref_frame) = "+str(images_ref_frame)+" >= images_n_frames. Aborting." + "abs(images_ref_frame) = "+str(abs(images_ref_frame))+" >= images_n_frames. Aborting." images_ref_frame = images_ref_frame%images_n_frames mypy.print_var("images_ref_frame",images_ref_frame,tab+1) diff --git a/fedic2.py b/fedic2.py new file mode 100644 index 0000000000000000000000000000000000000000..ffe4b66b185f2c02de545ae6f8c3ee97d58f8f1e --- /dev/null +++ b/fedic2.py @@ -0,0 +1,136 @@ +#coding=utf8 + +################################################################################ +### ### +### Created by Martin Genet, 2016-2018 ### +### ### +### École Polytechnique, Palaiseau, France ### +### ### +################################################################################ + +import myPythonLibrary as mypy +import myVTKPythonLibrary as myvtk + +import dolfin_dic as ddic + +################################################################################ + +def fedic2( + working_folder, + working_basename, + images_folder, + images_basename, + images_grad_basename=None, + images_ext="vti", # vti, vtk + images_n_frames=None, + images_ref_frame=0, + images_quadrature=None, + images_quadrature_from="points_count", # points_count, integral + images_expressions_type="cpp", # cpp, py + images_dynamic_scaling=1, + mesh=None, + mesh_folder=None, + mesh_basename=None, + mesh_degree=1, + regul_type="equilibrated", # hyperelastic, equilibrated + regul_model="neohookean", # linear, kirchhoff, neohookean, mooneyrivlin + regul_quadrature=None, + regul_level=0.1, + regul_poisson=0.0, + tangent_type="Idef", # Idef, Idef-wHess, Iold, Iref + residual_type="Iref", # Iref, Iold, Iref-then-Iold + relax_type="gss", # constant, aitken, gss + relax_init=1.0, + initialize_DU_with_DUold=0, + tol_res=None, + tol_res_rel=None, + tol_dU=None, + tol_im=None, + n_iter_max=100, + continue_after_fail=0, + print_refined_mesh=0, + print_iterations=0): + + assert (images_expressions_type == "cpp"),\ + "Python image expression are deprecated. Aborting." + assert (tangent_type == "Idef"),\ + "tangent_type must be \"Idef\". Aborting." + assert (residual_type == "Iref"),\ + "residual_type must be \"Iref\". Aborting." + assert (relax_init == 1.),\ + "relax_init must be 1. Aborting." + assert (tol_res is None),\ + "tol_res is deprecated. Aborting." + assert (tol_im is None),\ + "tol_im is deprecated. Aborting." + assert (continue_after_fail == 0),\ + "continue_after_fail is deprecated. Aborting." + assert (print_refined_mesh == 0),\ + "print_refined_mesh is deprecated. Aborting." + + problem = ddic.ImageRegistrationProblem( + mesh=mesh, + mesh_folder=mesh_folder, + mesh_basename=mesh_basename, + U_degree=mesh_degree) + + image_series = ddic.ImageSeries( + problem=problem, + folder=images_folder, + basename=images_basename, + grad_basename=images_grad_basename, + n_frames=images_n_frames, + ext=images_ext) + + if (images_quadrature is None): + if (images_quadrature_from == "points_count"): + images_quadrature = ddic.compute_quadrature_degree_from_points_count( + image_filename=image_series.get_image_filename(images_ref_frame), + mesh_filebasename=mesh_folder+"/"+mesh_basename, + verbose=1) + elif (method == "integral"): + images_quadrature = ddic.compute_quadrature_degree_from_integral( + image_filename=self.get_image_filename(images_ref_frame), + mesh_filebasename=mesh_folder+"/"+mesh_basename, + verbose=1) + else: + assert (0), "\"images_quadrature_from\" (="+str(images_quadrature_from)+") must be \"points_count\" or \"integral\". Aborting." + + warped_image_energy = ddic.WarpedImageEnergy( + problem=problem, + image_series=image_series, + quadrature_degree=images_quadrature, + w=1.-regul_level, + ref_frame=images_ref_frame, + dynamic_scaling=images_dynamic_scaling) + problem.add_image_energy(warped_image_energy) + + regularization_energy = ddic.RegularizationEnergy( + problem=problem, + w=regul_level, + type=regul_type, + model=regul_model, + poisson=regul_poisson, + quadrature_degree=regul_quadrature) + problem.add_regul_energy(regularization_energy) + + solver = ddic.NonlinearSolver( + problem=problem, + parameters={ + "working_folder":working_folder, + "working_basename":working_basename, + "relax_type":relax_type, + "tol_res_rel":tol_res_rel, + "tol_dU":tol_dU, + "n_iter_max":n_iter_max, + "write_iterations":print_iterations}) + + image_iterator = ddic.ImageIterator( + problem=problem, + solver=solver, + parameters={ + "working_folder":working_folder, + "working_basename":working_basename, + "initialize_DU_with_DUold":initialize_DU_with_DUold}) + + image_iterator.iterate() diff --git a/plot_binned_strains_vs_radius.py b/plot_binned_strains_vs_radius.py index 3b3d6e8240a6d879c2a9249a38305244c32f5cf4..25bfc6fce9bc2c39451dd575ef8f0e7315fc5edd 100644 --- a/plot_binned_strains_vs_radius.py +++ b/plot_binned_strains_vs_radius.py @@ -8,8 +8,6 @@ ### ### ################################################################################ -import math -import numpy import os import sys diff --git a/plot_displacement_error.py b/plot_displacement_error.py index b0007aa42eb874a2bee6d281f1a9e0e42dd63dfe..727e80dc5f294f19f764cf04604f0af4a9d4d017 100644 --- a/plot_displacement_error.py +++ b/plot_displacement_error.py @@ -8,8 +8,6 @@ ### ### ################################################################################ -import math -import numpy import os import sys diff --git a/write_VTU_file.py b/write_VTU_file.py new file mode 100644 index 0000000000000000000000000000000000000000..9a71f67414a5b5c34e6861c7171a0fc721998709 --- /dev/null +++ b/write_VTU_file.py @@ -0,0 +1,34 @@ +#coding=utf8 + +################################################################################ +### ### +### Created by Martin Genet, 2016-2018 ### +### ### +### École Polytechnique, Palaiseau, France ### +### ### +################################################################################ + +import dolfin +import os +import shutil + +import myPythonLibrary as mypy +import myVTKPythonLibrary as myvtk + +import dolfin_dic as ddic + +################################################################################ + +def write_VTU_file( + filebasename, + function, + time, + zfill=6): + + file_pvd = dolfin.File(filebasename+"__.pvd") + file_pvd << (function, float(time)) + os.remove( + filebasename+"__.pvd") + shutil.move( + filebasename+"__"+"".zfill(zfill)+".vtu", + filebasename+"_"+str(time).zfill(zfill)+".vtu")