# Copyright (c) 2023, The University of Texas at Austin
# & Georgia Institute of Technology
#
# All Rights reserved.
# See file COPYRIGHT for details.
#
# This file is part of the SOUPy package. For more information see
# https://github.com/hippylib/soupy/
#
# SOUPy is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License (as published by the Free
# Software Foundation) version 3.0 dated June 2007.
import dolfin as dl
import numpy as np
[docs]class AugmentedVector:
"""
Class representing an augmented optimization variable :math:`(z, t)`, \
where :math:`t` is a real number. \
Methods mirror that of :code:`dolfin.Vector`. \
Assumes the last element in the array is the :code:`t` variable
.. note:: Currently supports only sample parallelism (i.e. serial mesh)
"""
def __init__(self, v, copy_vector=True):
"""
:param v: :code:`dolfin.Vector` to be augmented
:param copy_vector: If :code:`True`, copy the vector, otherwise use the same memory
"""
assert v.mpi_comm().Get_size() == 1
if copy_vector:
self.v = v.copy()
else:
self.v = v
self.t = 0.0
self.v_dim = len(self.v.get_local())
[docs] def copy(self):
x = AugmentedVector(self.v, copy_vector=True)
x.set_scalar(self.t)
[docs] def add_local(self, vt_array):
self.v.add_local(vt_array[:-1])
self.v.apply("")
self.t += vt_array[-1]
[docs] def set_local(self, vt_array):
self.v.set_local(vt_array[:-1])
self.v.apply("")
self.t = vt_array[-1]
def apply(self, method):
self.v.apply(method)
[docs] def get_local(self):
return np.append(self.v.get_local(), self.t)
[docs] def zero(self):
self.v.zero()
self.t = 0.0
[docs] def get_vector(self):
return self.v
[docs] def set_vector(self, v):
self.v.set_local(v.get_local())
self.v.apply("")
[docs] def get_scalar(self):
return self.t
[docs] def set_scalar(self,t):
self.t = t
[docs] def axpy(self, a, vt):
self.v.axpy(a, vt.get_vector())
self.t += a * vt.get_scalar()
[docs] def inner(self, vt):
value = self.get_vector().inner(vt.get_vector()) + self.get_scalar() * vt.get_scalar()
return value
[docs] def apply(self, method):
self.v.apply(method)