GitHub

romtools.composite_vector_space

  1#
  2# ************************************************************************
  3#
  4#                         ROM Tools and Workflows
  5# Copyright 2019 National Technology & Engineering Solutions of Sandia,LLC
  6#                              (NTESS)
  7#
  8# Under the terms of Contract DE-NA0003525 with NTESS, the
  9# U.S. Government retains certain rights in this software.
 10#
 11# ROM Tools and Workflows is licensed under BSD-3-Clause terms of use:
 12#
 13# Redistribution and use in source and binary forms, with or without
 14# modification, are permitted provided that the following conditions
 15# are met:
 16#
 17# 1. Redistributions of source code must retain the above copyright
 18# notice, this list of conditions and the following disclaimer.
 19#
 20# 2. Redistributions in binary form must reproduce the above copyright
 21# notice, this list of conditions and the following disclaimer in the
 22# documentation and/or other materials provided with the distribution.
 23#
 24# 3. Neither the name of the copyright holder nor the names of its
 25# contributors may be used to endorse or promote products derived
 26# from this software without specific prior written permission.
 27#
 28# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 29# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 30# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 31# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 32# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 33# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 34# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 35# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 36# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 37# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 38# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 39# POSSIBILITY OF SUCH DAMAGE.
 40#
 41# Questions? Contact Eric Parish (ejparis@sandia.gov)
 42#
 43# ************************************************************************
 44#
 45
 46from typing import List
 47import numpy as np
 48from romtools.vector_space import VectorSpace
 49
 50
 51class CompositeVectorSpace:
 52    '''
 53    Constructs a composite vector space out of a list of vector spaces
 54    Different vector spaces need to have the same number of spatial DOFs
 55    '''
 56
 57    def __init__(self, list_of_vector_spaces: List[VectorSpace]):
 58        '''
 59        Inputs: list_of_vector_spaces: list[VectorSpace] containing the list of vector spaces to combine
 60        '''
 61        # Computed dimensions and ensure vector spaces are compatable
 62        self.__get_extent_and_check_compatability(list_of_vector_spaces)
 63
 64        # Construct basis as a list of local bases
 65        self.__construct_compact_basis(list_of_vector_spaces)
 66
 67    def extents(self) -> np.ndarray:
 68        return self.__extent
 69
 70    def get_shift_vector(self) -> np.ndarray:
 71        return self.__construct_global_shift_vector()
 72
 73    def get_basis(self) -> np.ndarray:
 74        return self.__construct_full_basis()
 75
 76    def get_compact_basis(self) -> List[np.ndarray]:
 77        return self.__compact_basis
 78
 79    def get_compact_shift_vector(self) -> List[np.ndarray]:
 80        return self.__compact_shift_vector
 81
 82    def __get_extent_and_check_compatability(self, list_of_vector_spaces):
 83        # Checks that dimensions of the vector spaces match
 84        # and assigns self.__extent
 85        dims = np.zeros(len(list_of_vector_spaces))
 86        n_vector_spaces = len(list_of_vector_spaces)
 87        n_vars = 0
 88        total_number_of_bases = 0
 89        for i in range(0, n_vector_spaces):
 90            local_vector_space = list_of_vector_spaces[i]
 91            local_vector_space_dimensions = local_vector_space.get_basis().shape
 92            n_vars += local_vector_space_dimensions[0]
 93            dims[i] = local_vector_space_dimensions[1]
 94            total_number_of_bases += local_vector_space_dimensions[2]
 95
 96        nx = int(dims[0])
 97        n_vars = int(n_vars)
 98        total_number_of_bases = int(total_number_of_bases)
 99        self.__extent = np.array([n_vars, nx, total_number_of_bases], dtype='int')
100        assert np.allclose(np.diff(dims),
101                           np.zeros(dims.size-1)
102               ), "Error constructing composite vector space, not all spaces have the same spatial dimension"
103
104    def __construct_global_shift_vector(self):
105        # Constructs the shift vector for the composite vector space
106        shift_vector = self.__compact_shift_vector[0]
107        for local_shift_vector in self.__compact_shift_vector[1:]:
108            shift_vector = np.append(shift_vector, local_shift_vector, axis=0)
109        return shift_vector
110
111    def __construct_full_basis(self):
112        # Constructs a dense basis for the composite vector space
113        basis = np.zeros((self.__extent[0], self.__extent[1], self.__extent[2]))
114        start_var_index = 0
115        start_basis_index = 0
116        for local_basis in self.__compact_basis:
117            dim = local_basis.shape
118            basis[start_var_index:start_var_index+dim[0], :, start_basis_index:start_basis_index+dim[2]] = local_basis
119            start_var_index += dim[0]
120            start_basis_index += dim[2]
121        return basis
122
123    def __construct_compact_basis(self, list_of_vector_spaces):
124        # Constructs a list of bases.
125        # This is much more efficient in terms of memory
126        self.__compact_basis = [space.get_basis() for space in list_of_vector_spaces]
127        self.__compact_shift_vector = [space.get_shift_vector() for space in list_of_vector_spaces]
class CompositeVectorSpace:
 52class CompositeVectorSpace:
 53    '''
 54    Constructs a composite vector space out of a list of vector spaces
 55    Different vector spaces need to have the same number of spatial DOFs
 56    '''
 57
 58    def __init__(self, list_of_vector_spaces: List[VectorSpace]):
 59        '''
 60        Inputs: list_of_vector_spaces: list[VectorSpace] containing the list of vector spaces to combine
 61        '''
 62        # Computed dimensions and ensure vector spaces are compatable
 63        self.__get_extent_and_check_compatability(list_of_vector_spaces)
 64
 65        # Construct basis as a list of local bases
 66        self.__construct_compact_basis(list_of_vector_spaces)
 67
 68    def extents(self) -> np.ndarray:
 69        return self.__extent
 70
 71    def get_shift_vector(self) -> np.ndarray:
 72        return self.__construct_global_shift_vector()
 73
 74    def get_basis(self) -> np.ndarray:
 75        return self.__construct_full_basis()
 76
 77    def get_compact_basis(self) -> List[np.ndarray]:
 78        return self.__compact_basis
 79
 80    def get_compact_shift_vector(self) -> List[np.ndarray]:
 81        return self.__compact_shift_vector
 82
 83    def __get_extent_and_check_compatability(self, list_of_vector_spaces):
 84        # Checks that dimensions of the vector spaces match
 85        # and assigns self.__extent
 86        dims = np.zeros(len(list_of_vector_spaces))
 87        n_vector_spaces = len(list_of_vector_spaces)
 88        n_vars = 0
 89        total_number_of_bases = 0
 90        for i in range(0, n_vector_spaces):
 91            local_vector_space = list_of_vector_spaces[i]
 92            local_vector_space_dimensions = local_vector_space.get_basis().shape
 93            n_vars += local_vector_space_dimensions[0]
 94            dims[i] = local_vector_space_dimensions[1]
 95            total_number_of_bases += local_vector_space_dimensions[2]
 96
 97        nx = int(dims[0])
 98        n_vars = int(n_vars)
 99        total_number_of_bases = int(total_number_of_bases)
100        self.__extent = np.array([n_vars, nx, total_number_of_bases], dtype='int')
101        assert np.allclose(np.diff(dims),
102                           np.zeros(dims.size-1)
103               ), "Error constructing composite vector space, not all spaces have the same spatial dimension"
104
105    def __construct_global_shift_vector(self):
106        # Constructs the shift vector for the composite vector space
107        shift_vector = self.__compact_shift_vector[0]
108        for local_shift_vector in self.__compact_shift_vector[1:]:
109            shift_vector = np.append(shift_vector, local_shift_vector, axis=0)
110        return shift_vector
111
112    def __construct_full_basis(self):
113        # Constructs a dense basis for the composite vector space
114        basis = np.zeros((self.__extent[0], self.__extent[1], self.__extent[2]))
115        start_var_index = 0
116        start_basis_index = 0
117        for local_basis in self.__compact_basis:
118            dim = local_basis.shape
119            basis[start_var_index:start_var_index+dim[0], :, start_basis_index:start_basis_index+dim[2]] = local_basis
120            start_var_index += dim[0]
121            start_basis_index += dim[2]
122        return basis
123
124    def __construct_compact_basis(self, list_of_vector_spaces):
125        # Constructs a list of bases.
126        # This is much more efficient in terms of memory
127        self.__compact_basis = [space.get_basis() for space in list_of_vector_spaces]
128        self.__compact_shift_vector = [space.get_shift_vector() for space in list_of_vector_spaces]

Constructs a composite vector space out of a list of vector spaces Different vector spaces need to have the same number of spatial DOFs

CompositeVectorSpace(list_of_vector_spaces: List[romtools.vector_space.VectorSpace])
58    def __init__(self, list_of_vector_spaces: List[VectorSpace]):
59        '''
60        Inputs: list_of_vector_spaces: list[VectorSpace] containing the list of vector spaces to combine
61        '''
62        # Computed dimensions and ensure vector spaces are compatable
63        self.__get_extent_and_check_compatability(list_of_vector_spaces)
64
65        # Construct basis as a list of local bases
66        self.__construct_compact_basis(list_of_vector_spaces)

Inputs: list_of_vector_spaces: list[VectorSpace] containing the list of vector spaces to combine

def extents(self) -> numpy.ndarray:
68    def extents(self) -> np.ndarray:
69        return self.__extent
def get_shift_vector(self) -> numpy.ndarray:
71    def get_shift_vector(self) -> np.ndarray:
72        return self.__construct_global_shift_vector()
def get_basis(self) -> numpy.ndarray:
74    def get_basis(self) -> np.ndarray:
75        return self.__construct_full_basis()
def get_compact_basis(self) -> List[numpy.ndarray]:
77    def get_compact_basis(self) -> List[np.ndarray]:
78        return self.__compact_basis
def get_compact_shift_vector(self) -> List[numpy.ndarray]:
80    def get_compact_shift_vector(self) -> List[np.ndarray]:
81        return self.__compact_shift_vector