-- |
-- Module      : Data.Manifold.Mesh
-- Copyright   : (c) Justus Sagemüller 2018
-- License     : GPL v3
-- 
-- Maintainer  : (@) jsagemue $ uni-koeln.de
-- Stability   : experimental
-- Portability : portable
-- 

{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE ConstraintKinds     #-}

module Data.Manifold.Mesh where

import Data.Manifold.Types.Primitive
import Math.Manifold.Core.PseudoAffine
import Data.Manifold.PseudoAffine
import Data.Simplex.Abstract

import Data.Manifold.Web
import Data.Manifold.Web.Internal
import Data.Manifold.FibreBundle

import GHC.Exts (Constraint)

-- | A mesh is a container data structure whose nodes are in some way located
--   distributed over a manifold, and are aware of the topology by way of having
--   access to their neighbours. Any such grid can be seen as a 'PointsWeb', but it
--   may have extra structure (e.g. rectangular) in addition to that.
class SimplexSpanning (MeshDomainSpace ) => Mesh  where
  type MeshDomainSpace  :: *
  type MeshGridDataConstraint  y :: Constraint
  type MeshGridDataConstraint  y = ()
  
  asWeb :: MeshGridDataConstraint  y
             =>  y -> PointsWeb (MeshDomainSpace ) y
  
  meshSimplicesInWeb ::  y -> [AbstractSimplex (Needle (MeshDomainSpace )) WebNodeId]
  
  meshSimplices :: MeshGridDataConstraint  y
             =>  y -> [SimplexF (MeshDomainSpace ) y]
  meshSimplices メ y
mesh
    = forall a b. (a -> b) -> [a] -> [b]
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a -> b) -> a -> b
$ \WebNodeId
i -> case forall x y. PointsWeb x y -> WebNodeId -> Maybe (x, y)
indexWeb PointsWeb (MeshDomainSpace メ) (WebLocally (MeshDomainSpace メ) y)
web WebNodeId
i of
                         Just (MeshDomainSpace メ
x,WebLocally (MeshDomainSpace メ) y
info) -> (WebLocally (MeshDomainSpace メ) y
infoforall s a. s -> Getting a s a -> a
^.forall x y. Lens' (WebLocally x y) y
thisNodeData)forall f m. f -> m -> FibreBundle m f
:@.MeshDomainSpace メ
x
                         Maybe (MeshDomainSpace メ, WebLocally (MeshDomainSpace メ) y)
Nothing -> forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Faulty `Mesh` instance: node #"forall a. [a] -> [a] -> [a]
++forall a. Show a => a -> [Char]
show WebNodeId
i
                                                     forall a. [a] -> [a] -> [a]
++[Char]
" not in web." )
          [AbstractSimplex (Needle (MeshDomainSpace メ)) WebNodeId]
nodeRefs
   where web :: PointsWeb (MeshDomainSpace メ) (WebLocally (MeshDomainSpace メ) y)
web = forall x y.
WithField ℝ Manifold x =>
PointsWeb x y -> PointsWeb x (WebLocally x y)
webLocalInfo forall a b. (a -> b) -> a -> b
$ forall (メ :: * -> *) y.
(Mesh メ, MeshGridDataConstraint メ y) =>
メ y -> PointsWeb (MeshDomainSpace メ) y
asWeb メ y
mesh
         nodeRefs :: [AbstractSimplex (Needle (MeshDomainSpace メ)) WebNodeId]
nodeRefs = forall (メ :: * -> *) y.
Mesh メ =>
メ y -> [AbstractSimplex (Needle (MeshDomainSpace メ)) WebNodeId]
meshSimplicesInWeb メ y
mesh
  
  extrapolateGrid :: (WithField  Manifold y, Connected y, MeshGridDataConstraint  y)
                        =>  y -> MeshDomainSpace  -> y

-- | A mesh that “covers” the entire manifold, i.e. any point lies between some nodes
--   of the mesh.
class Mesh  => CoveringMesh  where
  interpolateGrid :: (WithField  Manifold y, Connected y, MeshGridDataConstraint  y)
                        =>  y -> MeshDomainSpace  -> y
  interpolateGrid = forall (メ :: * -> *) y.
(Mesh メ, WithField ℝ Manifold y, Connected y,
 MeshGridDataConstraint メ y) =>
メ y -> MeshDomainSpace メ -> y
extrapolateGrid