From 869dbad8b36e18fd10309a225ec88be7a4391790 Mon Sep 17 00:00:00 2001 From: acrovato <adrien.crovato@onera.fr> Date: Wed, 2 Apr 2025 11:23:10 +0200 Subject: [PATCH] Update MPhys API to 2.0.0 --- dart/api/mphys.py | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/dart/api/mphys.py b/dart/api/mphys.py index 643cc44..63f6a14 100644 --- a/dart/api/mphys.py +++ b/dart/api/mphys.py @@ -38,7 +38,12 @@ import numpy as np import openmdao.api as om -from mphys.builder import Builder +from mphys import Builder, MPhysVariables + +# Define short aliases for convenience +XAERO0 = MPhysVariables.Aerodynamics.Surface.Mesh.COORDINATES +XAERO = MPhysVariables.Aerodynamics.Surface.COORDINATES +FAERO = MPhysVariables.Aerodynamics.Surface.LOADS # Surface mesh class DartMesh(om.IndepVarComp): @@ -64,7 +69,7 @@ class DartMesh(om.IndepVarComp): for i in range(len(self.bnd.nodes)): for j in range(3): x_aero0[3 * i + j] = self.bnd.nodes[i].pos[j] - self.add_output('x_aero0', distributed=True, val=x_aero0, desc='initial aerodynamic surface node coordinates', tags=['mphys_coordinates']) + self.add_output(XAERO0, distributed=True, val=x_aero0, desc='initial aerodynamic surface node coordinates', tags=['mphys_coordinates']) def get_triangulated_surface(self): """Triangulate the surface @@ -120,10 +125,10 @@ class DartMorpher(om.ImplicitComponent): self.mrf = self.options['mrf'] self.adj = self.options['adj'] # I/O - self.add_input('x_aero', distributed=True, shape_by_conn=True, desc='aerodynamic surface node coordinates', tags=['mphys_coupling']) + self.add_input(XAERO, distributed=True, shape_by_conn=True, desc='aerodynamic surface node coordinates', tags=['mphys_coupling']) self.add_output('xv', val=np.zeros(self.dim * len(self.mrf.msh.nodes)), desc='aerodynamic volume node coordinates', tags=['mphys_coupling']) # volume node coordinates can be 2D or 3D # Partials - # self.declare_partials(of=['xv'], wrt=['x_aero']) + # self.declare_partials(of=['xv'], wrt=[XAERO]) def solve_nonlinear(self, inputs, outputs): """Deform the volume mesh @@ -132,7 +137,7 @@ class DartMorpher(om.ImplicitComponent): self.mrf.savePos() for i in range(len(self.bnd.nodes)): for j in range(3): - self.bnd.nodes[i].pos[j] = inputs['x_aero'][3 * i + j] + self.bnd.nodes[i].pos[j] = inputs[XAERO][3 * i + j] # Compute self.mrf.deform() # Update outputs @@ -157,10 +162,10 @@ class DartMorpher(om.ImplicitComponent): if 'xv' in d_residuals: if 'xv' in d_outputs: d_outputs['xv'] += self.adj.computeJacVecMesh(d_residuals['xv']) # dX = dRx_dX^T * dRx - if 'x_aero' in d_inputs: + if XAERO in d_inputs: for i in range(len(self.bnd.nodes)): for j in range(self.dim): - d_inputs['x_aero'][3 * i + j] -= d_residuals['xv'][self.dim * self.bnd.nodes[i].row + j] # dXs = -dX + d_inputs[XAERO][3 * i + j] -= d_residuals['xv'][self.dim * self.bnd.nodes[i].row + j] # dXs = -dX elif mode == 'fwd': raise NotImplementedError('DartMorpher - forward mode not implemented!\n') @@ -191,7 +196,7 @@ class DartDummyMorpher(om.ExplicitComponent): for j in range(dim): xv[dim * i + j] = msh.nodes[i].pos[j] # I/O - self.add_input('x_aero', distributed=True, shape_by_conn=True, desc='aerodynamic surface node coordinates', tags=['mphys_coupling']) + self.add_input(XAERO, distributed=True, shape_by_conn=True, desc='aerodynamic surface node coordinates', tags=['mphys_coupling']) self.add_output('xv', val=xv, desc='aerodynamic volume node coordinates', tags=['mphys_coupling']) def compute(self, inputs, outputs): @@ -303,9 +308,9 @@ class DartLoads(om.ExplicitComponent): # I/O self.add_input('xv', shape_by_conn=True, desc='aerodynamic volume node coordinates', tags=['mphys_coupling']) self.add_input('phi', shape_by_conn=True, desc='flow variables (potential)', tags=['mphys_coupling']) - self.add_output('f_aero', distributed=True, val=np.zeros(3 * len(self.bnd.nodes)), desc='aerodynamic loads', tags=['mphys_coupling']) + self.add_output(FAERO, distributed=True, val=np.zeros(3 * len(self.bnd.nodes)), desc='aerodynamic loads', tags=['mphys_coupling']) # Partials - # self.declare_partials(of=['f_aero'], wrt=['xv', 'phi']) + # self.declare_partials(of=[FAERO], wrt=['xv', 'phi']) def compute(self, inputs, outputs): """Get the forces on moving body @@ -313,7 +318,7 @@ class DartLoads(om.ExplicitComponent): # NB: inputs already up-to-date because DartSolver has already been run for i in range(len(self.bnd.nodes)): for j in range(3): - outputs['f_aero'][3 * i + j] = self.qinf * self.bnd.nLoads[i][j] + outputs[FAERO][3 * i + j] = self.qinf * self.bnd.nLoads[i][j] def compute_partials(self, inputs, partials): """Compute the partials gradients of the loads @@ -324,11 +329,11 @@ class DartLoads(om.ExplicitComponent): """Perform the matrix-vector product using the partial gradients of the loads """ if mode == 'rev': - if 'f_aero' in d_outputs: + if FAERO in d_outputs: if 'xv' in d_inputs: - d_inputs['xv'] += self.qinf * np.asarray(self.adj.computeJacVecLoadsMesh(d_outputs['f_aero'])) # dX = dL_dX^T * dL + d_inputs['xv'] += self.qinf * np.asarray(self.adj.computeJacVecLoadsMesh(d_outputs[FAERO])) # dX = dL_dX^T * dL if 'phi' in d_inputs: - d_inputs['phi'] += self.qinf * np.asarray(self.adj.computeJacVecLoadsFlow(d_outputs['f_aero'])) # dU = dL_dU^T * dL + d_inputs['phi'] += self.qinf * np.asarray(self.adj.computeJacVecLoadsFlow(d_outputs[FAERO])) # dU = dL_dU^T * dL elif mode == 'fwd': raise NotImplementedError('DartLoads - forward mode not implemented!\n') @@ -449,12 +454,12 @@ class DartGroup(om.Group): def setup(self): # Components if self.options['mrf'] is None: - self.add_subsystem('morpher', DartDummyMorpher(dim=self.options['sol'].pbl.nDim, msh=self.options['sol'].pbl.msh), promotes_inputs=['x_aero'], promotes_outputs=['xv']) + self.add_subsystem('morpher', DartDummyMorpher(dim=self.options['sol'].pbl.nDim, msh=self.options['sol'].pbl.msh), promotes_inputs=[XAERO], promotes_outputs=['xv']) else: - self.add_subsystem('morpher', DartMorpher(dim=self.options['sol'].pbl.nDim, bnd=self.options['bnd'], mrf=self.options['mrf'], adj=self.options['adj']), promotes_inputs=['x_aero'], promotes_outputs=['xv']) + self.add_subsystem('morpher', DartMorpher(dim=self.options['sol'].pbl.nDim, bnd=self.options['bnd'], mrf=self.options['mrf'], adj=self.options['adj']), promotes_inputs=[XAERO], promotes_outputs=['xv']) self.add_subsystem('solver', DartSolver(sol=self.options['sol'], adj=self.options['adj'], rerr=self.options['rerr']), promotes_inputs=['aoa', 'xv'], promotes_outputs=['phi']) if self.options['qinf'] is not None: - self.add_subsystem('loads', DartLoads(qinf=self.options['qinf'], bnd=self.options['bnd'], adj=self.options['adj']), promotes_inputs=['xv', 'phi'], promotes_outputs=['f_aero']) + self.add_subsystem('loads', DartLoads(qinf=self.options['qinf'], bnd=self.options['bnd'], adj=self.options['adj']), promotes_inputs=['xv', 'phi'], promotes_outputs=[FAERO]) # Aerodynamic post-coupling group class DartPostGroup(om.Group): -- GitLab