def equation_partial_second_derivative(self, adjointer, adjoint, i, variable, m_dot): form = adjresidual.get_residual(i) if form is not None: form = -form mesh = ufl.algorithms.extract_arguments(form)[0].function_space().mesh() fn_space = backend.FunctionSpace(mesh, "R", 0) dparam = backend.Function(fn_space) dparam.vector()[:] = 1.0 * float(self.coeff) d2param = backend.Function(fn_space) d2param.vector()[:] = 1.0 * float(self.coeff) * m_dot diff_form = ufl.algorithms.expand_derivatives(backend.derivative(form, get_constant(self.a), dparam)) if diff_form is None: return None diff_form = ufl.algorithms.expand_derivatives(backend.derivative(diff_form, get_constant(self.a), d2param)) if diff_form is None: return None # Let's see if the form actually depends on the parameter m if len(diff_form.integrals()) != 0: dFdm = backend.assemble(diff_form) # actually - dF/dm assert isinstance(dFdm, backend.GenericVector) out = dFdm.inner(adjoint.vector()) return out else: return None # dF/dm is zero, return None
def __call__(self, adjointer, i, dependencies, values, variable): form = adjresidual.get_residual(i) if form is not None: form = -form fn_space = ufl.algorithms.extract_arguments(form)[0].function_space() dparam = backend.Function(backend.FunctionSpace(fn_space.mesh(), "R", 0)) dparam.vector()[:] = 1.0 * float(self.coeff) diff_form = ufl.algorithms.expand_derivatives(backend.derivative(form, get_constant(self.a), dparam)) return adjlinalg.Vector(diff_form) else: return None
def equation_partial_derivative(self, adjointer, adjoint, i, variable): form = adjresidual.get_residual(i) if form is None: return None else: form = -form fn_space = ufl.algorithms.extract_arguments(form)[0].function_space() dparam = backend.Function(backend.FunctionSpace(fn_space.mesh(), "R", 0)) dparam.vector()[:] = 1.0 dJdv = numpy.zeros(len(self.v)) for (i, a) in enumerate(self.v): diff_form = ufl.algorithms.expand_derivatives(backend.derivative(form, a, dparam)) dFdm = backend.assemble(diff_form) # actually - dF/dm assert isinstance(dFdm, backend.GenericVector) out = dFdm.inner(adjoint.vector()) dJdv[i] = out return dJdv
def __call__(self, adjointer, i, dependencies, values, variable): diff_form = None assert self.dv is not None, "Need a perturbation direction to use in the TLM." form = adjresidual.get_residual(i) if form is None: return None else: form = -form fn_space = ufl.algorithms.extract_arguments(form)[0].function_space() dparam = backend.Function(backend.FunctionSpace(fn_space.mesh(), "R", 0)) dparam.vector()[:] = 1.0 for (a, da) in zip(self.v, self.dv): out_form = da * backend.derivative(form, a, dparam) if diff_form is None: diff_form = out_form else: diff_form += out_form return adjlinalg.Vector(diff_form)