change json format
This commit is contained in:
		@@ -1,42 +1,52 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "grids": [
 | 
					    "grids": {
 | 
				
			||||||
        {
 | 
					        "default": {
 | 
				
			||||||
            "name": "grid0",
 | 
					            "operators": {
 | 
				
			||||||
            "x": "linspace:-5:0:50",
 | 
					                "xi": "upwind9",
 | 
				
			||||||
            "y": "linspace:0:5:50",
 | 
					                "eta": "upwind9"
 | 
				
			||||||
            "dirS": "grid1",
 | 
					 | 
				
			||||||
            "dirN": "grid1",
 | 
					 | 
				
			||||||
            "dirE": "grid3",
 | 
					 | 
				
			||||||
            "dirW": "grid3"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid1",
 | 
					 | 
				
			||||||
            "x": "linspace:-5:0:50",
 | 
					 | 
				
			||||||
            "y": "linspace:-5:0:50",
 | 
					 | 
				
			||||||
            "dirS": "grid0",
 | 
					 | 
				
			||||||
            "dirN": "grid0",
 | 
					 | 
				
			||||||
            "dirE": "grid2",
 | 
					 | 
				
			||||||
            "dirW": "grid2"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid2",
 | 
					 | 
				
			||||||
            "x": "linspace:0:5:50",
 | 
					 | 
				
			||||||
            "y": "linspace:-5:0:50",
 | 
					 | 
				
			||||||
            "dirS": "grid3",
 | 
					 | 
				
			||||||
            "dirN": "grid3",
 | 
					 | 
				
			||||||
            "dirE": "grid1",
 | 
					 | 
				
			||||||
            "dirW": "grid1"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid3",
 | 
					 | 
				
			||||||
            "x": "linspace:0:5:50",
 | 
					 | 
				
			||||||
            "y": "linspace:0:5:50",
 | 
					 | 
				
			||||||
            "dirS": "grid2",
 | 
					 | 
				
			||||||
            "dirN": "grid2",
 | 
					 | 
				
			||||||
            "dirE": "grid0",
 | 
					 | 
				
			||||||
            "dirW": "grid0"
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
    ],
 | 
					        },
 | 
				
			||||||
 | 
					        "grid0": {
 | 
				
			||||||
 | 
					            "x": "linspace:-5:0:50",
 | 
				
			||||||
 | 
					            "y": "linspace:0:5:50",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid1",
 | 
				
			||||||
 | 
					                "north": "grid1",
 | 
				
			||||||
 | 
					                "east": "grid3",
 | 
				
			||||||
 | 
					                "west": "grid3"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid1": {
 | 
				
			||||||
 | 
					            "x": "linspace:-5:0:50",
 | 
				
			||||||
 | 
					            "y": "linspace:-5:0:50",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid0",
 | 
				
			||||||
 | 
					                "north": "grid0",
 | 
				
			||||||
 | 
					                "east": "grid2",
 | 
				
			||||||
 | 
					                "west": "grid2"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid2": {
 | 
				
			||||||
 | 
					            "x": "linspace:0:5:50",
 | 
				
			||||||
 | 
					            "y": "linspace:-5:0:50",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid3",
 | 
				
			||||||
 | 
					                "north": "grid3",
 | 
				
			||||||
 | 
					                "east": "grid1",
 | 
				
			||||||
 | 
					                "west": "grid1"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid3": {
 | 
				
			||||||
 | 
					            "x": "linspace:0:5:50",
 | 
				
			||||||
 | 
					            "y": "linspace:0:5:50",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid2",
 | 
				
			||||||
 | 
					                "north": "grid2",
 | 
				
			||||||
 | 
					                "east": "grid0",
 | 
				
			||||||
 | 
					                "west": "grid0"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "integration_time": 2.0,
 | 
					    "integration_time": 2.0,
 | 
				
			||||||
    "vortex": {
 | 
					    "vortex": {
 | 
				
			||||||
        "x0": -1.0,
 | 
					        "x0": -1.0,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,150 +1,166 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "grids": [
 | 
					    "grids": {
 | 
				
			||||||
        {
 | 
					        "grid00": {
 | 
				
			||||||
            "name": "grid00",
 | 
					 | 
				
			||||||
            "x": "linspace:-5:-2.5:128",
 | 
					            "x": "linspace:-5:-2.5:128",
 | 
				
			||||||
            "y": "linspace:2.5:5:128",
 | 
					            "y": "linspace:2.5:5:128",
 | 
				
			||||||
            "dirS": "grid01",
 | 
					            "boundary_conditions": {
 | 
				
			||||||
            "dirN": "grid11",
 | 
					                "south": "grid01",
 | 
				
			||||||
            "dirE": "grid03",
 | 
					                "north": "grid11",
 | 
				
			||||||
            "dirW": "grid33"
 | 
					                "east": "grid03",
 | 
				
			||||||
        },
 | 
					                "west": "grid33"
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid01",
 | 
					 | 
				
			||||||
            "x": "linspace:-5:-2.5:128",
 | 
					 | 
				
			||||||
            "y": "linspace:0:2.5:128",
 | 
					 | 
				
			||||||
            "dirS": "grid10",
 | 
					 | 
				
			||||||
            "dirN": "grid00",
 | 
					 | 
				
			||||||
            "dirE": "grid02",
 | 
					 | 
				
			||||||
            "dirW": "grid32"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid02",
 | 
					 | 
				
			||||||
            "x": "linspace:-2.5:0:128",
 | 
					 | 
				
			||||||
            "y": "linspace:0:2.5:128",
 | 
					 | 
				
			||||||
            "dirS": "grid13",
 | 
					 | 
				
			||||||
            "dirN": "grid03",
 | 
					 | 
				
			||||||
            "dirE": "grid31",
 | 
					 | 
				
			||||||
            "dirW": "grid01"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid03",
 | 
					 | 
				
			||||||
            "x": "linspace:-2.5:0:128",
 | 
					 | 
				
			||||||
            "y": "linspace:2.5:5:128",
 | 
					 | 
				
			||||||
            "dirS": "grid02",
 | 
					 | 
				
			||||||
            "dirN": "grid12",
 | 
					 | 
				
			||||||
            "dirE": "grid30",
 | 
					 | 
				
			||||||
            "dirW": "grid00"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid10",
 | 
					 | 
				
			||||||
            "x": "linspace:-5:-2.5:128",
 | 
					 | 
				
			||||||
            "y": "linspace:-2.5:0:128",
 | 
					 | 
				
			||||||
            "dirS": "grid11",
 | 
					 | 
				
			||||||
            "dirN": "grid01",
 | 
					 | 
				
			||||||
            "dirE": "grid13",
 | 
					 | 
				
			||||||
            "dirW": "grid23"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid11",
 | 
					 | 
				
			||||||
            "x": "linspace:-5:-2.5:128",
 | 
					 | 
				
			||||||
            "y": "linspace:-5:-2.5:128",
 | 
					 | 
				
			||||||
            "dirS": "grid00",
 | 
					 | 
				
			||||||
            "dirN": "grid10",
 | 
					 | 
				
			||||||
            "dirE": "grid12",
 | 
					 | 
				
			||||||
            "dirW": "grid22"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid12",
 | 
					 | 
				
			||||||
            "x": "linspace:-2.5:0:128",
 | 
					 | 
				
			||||||
            "y": "linspace:-5:-2.5:128",
 | 
					 | 
				
			||||||
            "dirS": "grid03",
 | 
					 | 
				
			||||||
            "dirN": "grid13",
 | 
					 | 
				
			||||||
            "dirE": "grid21",
 | 
					 | 
				
			||||||
            "dirW": "grid11"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid13",
 | 
					 | 
				
			||||||
            "x": "linspace:-2.5:0:128",
 | 
					 | 
				
			||||||
            "y": "linspace:-2.5:0:128",
 | 
					 | 
				
			||||||
            "dirS": "grid12",
 | 
					 | 
				
			||||||
            "dirN": "grid02",
 | 
					 | 
				
			||||||
            "dirE": "grid20",
 | 
					 | 
				
			||||||
            "dirW": "grid10"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid20",
 | 
					 | 
				
			||||||
            "x": "linspace:0:2.5:128",
 | 
					 | 
				
			||||||
            "y": "linspace:-2.5:0:128",
 | 
					 | 
				
			||||||
            "dirS": "grid21",
 | 
					 | 
				
			||||||
            "dirN": "grid31",
 | 
					 | 
				
			||||||
            "dirE": "grid23",
 | 
					 | 
				
			||||||
            "dirW": "grid13"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid21",
 | 
					 | 
				
			||||||
            "x": "linspace:0:2.5:128",
 | 
					 | 
				
			||||||
            "y": "linspace:-5:-2.5:128",
 | 
					 | 
				
			||||||
            "dirS": "grid30",
 | 
					 | 
				
			||||||
            "dirN": "grid20",
 | 
					 | 
				
			||||||
            "dirE": "grid22",
 | 
					 | 
				
			||||||
            "dirW": "grid12"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid22",
 | 
					 | 
				
			||||||
            "x": "linspace:2.5:5:128",
 | 
					 | 
				
			||||||
            "y": "linspace:-5:-2.5:128",
 | 
					 | 
				
			||||||
            "dirS": "grid33",
 | 
					 | 
				
			||||||
            "dirN": "grid23",
 | 
					 | 
				
			||||||
            "dirE": "grid11",
 | 
					 | 
				
			||||||
            "dirW": "grid21"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid23",
 | 
					 | 
				
			||||||
            "x": "linspace:2.5:5:128",
 | 
					 | 
				
			||||||
            "y": "linspace:-2.5:0:128",
 | 
					 | 
				
			||||||
            "dirS": "grid22",
 | 
					 | 
				
			||||||
            "dirN": "grid32",
 | 
					 | 
				
			||||||
            "dirE": "grid10",
 | 
					 | 
				
			||||||
            "dirW": "grid20"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid30",
 | 
					 | 
				
			||||||
            "x": "linspace:0:2.5:128",
 | 
					 | 
				
			||||||
            "y": "linspace:2.5:5:128",
 | 
					 | 
				
			||||||
            "dirS": "grid31",
 | 
					 | 
				
			||||||
            "dirN": "grid21",
 | 
					 | 
				
			||||||
            "dirE": "grid33",
 | 
					 | 
				
			||||||
            "dirW": "grid03"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid31",
 | 
					 | 
				
			||||||
            "x": "linspace:0:2.5:128",
 | 
					 | 
				
			||||||
            "y": "linspace:0:2.5:128",
 | 
					 | 
				
			||||||
            "dirS": "grid20",
 | 
					 | 
				
			||||||
            "dirN": "grid30",
 | 
					 | 
				
			||||||
            "dirE": "grid32",
 | 
					 | 
				
			||||||
            "dirW": "grid02"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid32",
 | 
					 | 
				
			||||||
            "x": "linspace:2.5:5:128",
 | 
					 | 
				
			||||||
            "y": "linspace:0:2.5:128",
 | 
					 | 
				
			||||||
            "dirS": "grid23",
 | 
					 | 
				
			||||||
            "dirN": "grid33",
 | 
					 | 
				
			||||||
            "dirE": "grid01",
 | 
					 | 
				
			||||||
            "dirW": "grid31"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "grid33",
 | 
					 | 
				
			||||||
            "x": "linspace:2.5:5:128",
 | 
					 | 
				
			||||||
            "y": "linspace:2.5:5:128",
 | 
					 | 
				
			||||||
            "dirS": "grid32",
 | 
					 | 
				
			||||||
            "dirN": "grid22",
 | 
					 | 
				
			||||||
            "dirE": "grid00",
 | 
					 | 
				
			||||||
            "dirW": "grid30"
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
    ],
 | 
					        },
 | 
				
			||||||
 | 
					        "grid01": {
 | 
				
			||||||
 | 
					            "x": "linspace:-5:-2.5:128",
 | 
				
			||||||
 | 
					            "y": "linspace:0:2.5:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid10",
 | 
				
			||||||
 | 
					                "north": "grid00",
 | 
				
			||||||
 | 
					                "east": "grid02",
 | 
				
			||||||
 | 
					                "west": "grid32"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid02": {
 | 
				
			||||||
 | 
					            "x": "linspace:-2.5:0:128",
 | 
				
			||||||
 | 
					            "y": "linspace:0:2.5:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid13",
 | 
				
			||||||
 | 
					                "north": "grid03",
 | 
				
			||||||
 | 
					                "east": "grid31",
 | 
				
			||||||
 | 
					                "west": "grid01"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid03": {
 | 
				
			||||||
 | 
					            "x": "linspace:-2.5:0:128",
 | 
				
			||||||
 | 
					            "y": "linspace:2.5:5:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid02",
 | 
				
			||||||
 | 
					                "north": "grid12",
 | 
				
			||||||
 | 
					                "east": "grid30",
 | 
				
			||||||
 | 
					                "west": "grid00"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid10": {
 | 
				
			||||||
 | 
					            "x": "linspace:-5:-2.5:128",
 | 
				
			||||||
 | 
					            "y": "linspace:-2.5:0:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid11",
 | 
				
			||||||
 | 
					                "north": "grid01",
 | 
				
			||||||
 | 
					                "east": "grid13",
 | 
				
			||||||
 | 
					                "west": "grid23"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid11": {
 | 
				
			||||||
 | 
					            "x": "linspace:-5:-2.5:128",
 | 
				
			||||||
 | 
					            "y": "linspace:-5:-2.5:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid00",
 | 
				
			||||||
 | 
					                "north": "grid10",
 | 
				
			||||||
 | 
					                "east": "grid12",
 | 
				
			||||||
 | 
					                "west": "grid22"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid12": {
 | 
				
			||||||
 | 
					            "x": "linspace:-2.5:0:128",
 | 
				
			||||||
 | 
					            "y": "linspace:-5:-2.5:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid03",
 | 
				
			||||||
 | 
					                "north": "grid13",
 | 
				
			||||||
 | 
					                "east": "grid21",
 | 
				
			||||||
 | 
					                "west": "grid11"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid13": {
 | 
				
			||||||
 | 
					            "x": "linspace:-2.5:0:128",
 | 
				
			||||||
 | 
					            "y": "linspace:-2.5:0:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid12",
 | 
				
			||||||
 | 
					                "north": "grid02",
 | 
				
			||||||
 | 
					                "east": "grid20",
 | 
				
			||||||
 | 
					                "west": "grid10"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid20": {
 | 
				
			||||||
 | 
					            "x": "linspace:0:2.5:128",
 | 
				
			||||||
 | 
					            "y": "linspace:-2.5:0:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid21",
 | 
				
			||||||
 | 
					                "north": "grid31",
 | 
				
			||||||
 | 
					                "east": "grid23",
 | 
				
			||||||
 | 
					                "west": "grid13"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid21": {
 | 
				
			||||||
 | 
					            "x": "linspace:0:2.5:128",
 | 
				
			||||||
 | 
					            "y": "linspace:-5:-2.5:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid30",
 | 
				
			||||||
 | 
					                "north": "grid20",
 | 
				
			||||||
 | 
					                "east": "grid22",
 | 
				
			||||||
 | 
					                "west": "grid12"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid22": {
 | 
				
			||||||
 | 
					            "x": "linspace:2.5:5:128",
 | 
				
			||||||
 | 
					            "y": "linspace:-5:-2.5:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid33",
 | 
				
			||||||
 | 
					                "north": "grid23",
 | 
				
			||||||
 | 
					                "east": "grid11",
 | 
				
			||||||
 | 
					                "west": "grid21"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid23": {
 | 
				
			||||||
 | 
					            "x": "linspace:2.5:5:128",
 | 
				
			||||||
 | 
					            "y": "linspace:-2.5:0:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid22",
 | 
				
			||||||
 | 
					                "north": "grid32",
 | 
				
			||||||
 | 
					                "east": "grid10",
 | 
				
			||||||
 | 
					                "west": "grid20"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid30": {
 | 
				
			||||||
 | 
					            "x": "linspace:0:2.5:128",
 | 
				
			||||||
 | 
					            "y": "linspace:2.5:5:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid31",
 | 
				
			||||||
 | 
					                "north": "grid21",
 | 
				
			||||||
 | 
					                "east": "grid33",
 | 
				
			||||||
 | 
					                "west": "grid03"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid31": {
 | 
				
			||||||
 | 
					            "x": "linspace:0:2.5:128",
 | 
				
			||||||
 | 
					            "y": "linspace:0:2.5:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid20",
 | 
				
			||||||
 | 
					                "north": "grid30",
 | 
				
			||||||
 | 
					                "east": "grid32",
 | 
				
			||||||
 | 
					                "west": "grid02"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid32": {
 | 
				
			||||||
 | 
					            "x": "linspace:2.5:5:128",
 | 
				
			||||||
 | 
					            "y": "linspace:0:2.5:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid23",
 | 
				
			||||||
 | 
					                "north": "grid33",
 | 
				
			||||||
 | 
					                "east": "grid01",
 | 
				
			||||||
 | 
					                "west": "grid31"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "grid33": {
 | 
				
			||||||
 | 
					            "x": "linspace:2.5:5:128",
 | 
				
			||||||
 | 
					            "y": "linspace:2.5:5:128",
 | 
				
			||||||
 | 
					            "boundary_conditions": {
 | 
				
			||||||
 | 
					                "south": "grid32",
 | 
				
			||||||
 | 
					                "north": "grid22",
 | 
				
			||||||
 | 
					                "east": "grid00",
 | 
				
			||||||
 | 
					                "west": "grid30"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "integration_time": 2.0,
 | 
					    "integration_time": 2.0,
 | 
				
			||||||
    "vortex": {
 | 
					    "vortex": {
 | 
				
			||||||
        "x0": -1.0,
 | 
					        "x0": -1.0,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,8 @@ use parsing::{json_to_grids, json_to_vortex};
 | 
				
			|||||||
mod file;
 | 
					mod file;
 | 
				
			||||||
use file::*;
 | 
					use file::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub(crate) type DiffOp = Either<Box<dyn SbpOperator2d>, Box<dyn UpwindOperator2d>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct System {
 | 
					struct System {
 | 
				
			||||||
    fnow: Vec<euler::Field>,
 | 
					    fnow: Vec<euler::Field>,
 | 
				
			||||||
    fnext: Vec<euler::Field>,
 | 
					    fnext: Vec<euler::Field>,
 | 
				
			||||||
@@ -20,16 +22,14 @@ struct System {
 | 
				
			|||||||
    bt: Vec<euler::BoundaryCharacteristics>,
 | 
					    bt: Vec<euler::BoundaryCharacteristics>,
 | 
				
			||||||
    eb: Vec<euler::BoundaryStorage>,
 | 
					    eb: Vec<euler::BoundaryStorage>,
 | 
				
			||||||
    time: Float,
 | 
					    time: Float,
 | 
				
			||||||
    operators: Vec<Either<Box<dyn SbpOperator2d>, Box<dyn UpwindOperator2d>>>,
 | 
					    operators: Vec<DiffOp>,
 | 
				
			||||||
    interpolation_operators: Vec<euler::InterpolationOperators>,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl System {
 | 
					impl System {
 | 
				
			||||||
    fn new(
 | 
					    fn new(
 | 
				
			||||||
        grids: Vec<grid::Grid>,
 | 
					        grids: Vec<grid::Grid>,
 | 
				
			||||||
        bt: Vec<euler::BoundaryCharacteristics>,
 | 
					        bt: Vec<euler::BoundaryCharacteristics>,
 | 
				
			||||||
        interpolation_operators: Vec<euler::InterpolationOperators>,
 | 
					        operators: Vec<DiffOp>,
 | 
				
			||||||
        operators: Vec<Either<Box<dyn SbpOperator2d>, Box<dyn UpwindOperator2d>>>,
 | 
					 | 
				
			||||||
    ) -> Self {
 | 
					    ) -> Self {
 | 
				
			||||||
        let fnow = grids
 | 
					        let fnow = grids
 | 
				
			||||||
            .iter()
 | 
					            .iter()
 | 
				
			||||||
@@ -66,7 +66,6 @@ impl System {
 | 
				
			|||||||
            bt,
 | 
					            bt,
 | 
				
			||||||
            eb,
 | 
					            eb,
 | 
				
			||||||
            time: 0.0,
 | 
					            time: 0.0,
 | 
				
			||||||
            interpolation_operators,
 | 
					 | 
				
			||||||
            operators,
 | 
					            operators,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -83,7 +82,6 @@ impl System {
 | 
				
			|||||||
        let bt = &self.bt;
 | 
					        let bt = &self.bt;
 | 
				
			||||||
        let wb = &mut self.wb;
 | 
					        let wb = &mut self.wb;
 | 
				
			||||||
        let mut eb = &mut self.eb;
 | 
					        let mut eb = &mut self.eb;
 | 
				
			||||||
        let intops = &self.interpolation_operators;
 | 
					 | 
				
			||||||
        let operators = &self.operators;
 | 
					        let operators = &self.operators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let rhs = move |fut: &mut [euler::Field],
 | 
					        let rhs = move |fut: &mut [euler::Field],
 | 
				
			||||||
@@ -91,7 +89,7 @@ impl System {
 | 
				
			|||||||
                        time: Float,
 | 
					                        time: Float,
 | 
				
			||||||
                        _c: (),
 | 
					                        _c: (),
 | 
				
			||||||
                        _mt: &mut ()| {
 | 
					                        _mt: &mut ()| {
 | 
				
			||||||
            let bc = euler::extract_boundaries(prev, &bt, &mut eb, &grids, time, Some(intops));
 | 
					            let bc = euler::extract_boundaries(prev, &bt, &mut eb, &grids, time);
 | 
				
			||||||
            pool.scope(|s| {
 | 
					            pool.scope(|s| {
 | 
				
			||||||
                for (((((fut, prev), bc), wb), metrics), op) in fut
 | 
					                for (((((fut, prev), bc), wb), metrics), op) in fut
 | 
				
			||||||
                    .iter_mut()
 | 
					                    .iter_mut()
 | 
				
			||||||
@@ -162,63 +160,13 @@ fn main() {
 | 
				
			|||||||
    let filecontents = std::fs::read_to_string(&opt.json).unwrap();
 | 
					    let filecontents = std::fs::read_to_string(&opt.json).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let json = json::parse(&filecontents).unwrap();
 | 
					    let json = json::parse(&filecontents).unwrap();
 | 
				
			||||||
    let jgrids = json_to_grids(json["grids"].clone()).unwrap();
 | 
					
 | 
				
			||||||
    let vortexparams = json_to_vortex(json["vortex"].clone());
 | 
					    let vortexparams = json_to_vortex(json["vortex"].clone());
 | 
				
			||||||
 | 
					    let (_names, grids, bt, operators) = json_to_grids(json["grids"].clone(), vortexparams);
 | 
				
			||||||
    let mut bt = Vec::with_capacity(jgrids.len());
 | 
					 | 
				
			||||||
    let determine_bc = |dir: Option<&String>| match dir {
 | 
					 | 
				
			||||||
        Some(dir) => {
 | 
					 | 
				
			||||||
            if dir == "vortex" {
 | 
					 | 
				
			||||||
                euler::BoundaryCharacteristic::Vortex(vortexparams)
 | 
					 | 
				
			||||||
            } else if let Some(grid) = dir.strip_prefix("interpolate:") {
 | 
					 | 
				
			||||||
                euler::BoundaryCharacteristic::Interpolate(
 | 
					 | 
				
			||||||
                    jgrids
 | 
					 | 
				
			||||||
                        .iter()
 | 
					 | 
				
			||||||
                        .position(|other| other.name.as_ref().map_or(false, |name| name == grid))
 | 
					 | 
				
			||||||
                        .unwrap(),
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                euler::BoundaryCharacteristic::Grid(
 | 
					 | 
				
			||||||
                    jgrids
 | 
					 | 
				
			||||||
                        .iter()
 | 
					 | 
				
			||||||
                        .position(|other| other.name.as_ref().map_or(false, |name| name == dir))
 | 
					 | 
				
			||||||
                        .unwrap(),
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        None => euler::BoundaryCharacteristic::This,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    for grid in &jgrids {
 | 
					 | 
				
			||||||
        bt.push(euler::BoundaryCharacteristics {
 | 
					 | 
				
			||||||
            north: determine_bc(grid.dirn.as_ref()),
 | 
					 | 
				
			||||||
            south: determine_bc(grid.dirs.as_ref()),
 | 
					 | 
				
			||||||
            east: determine_bc(grid.dire.as_ref()),
 | 
					 | 
				
			||||||
            west: determine_bc(grid.dirw.as_ref()),
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    let interpolation_operators = jgrids
 | 
					 | 
				
			||||||
        .iter()
 | 
					 | 
				
			||||||
        .map(|_g| euler::InterpolationOperators {
 | 
					 | 
				
			||||||
            north: Some(Box::new(operators::Interpolation4)),
 | 
					 | 
				
			||||||
            south: Some(Box::new(operators::Interpolation4)),
 | 
					 | 
				
			||||||
            east: Some(Box::new(operators::Interpolation4)),
 | 
					 | 
				
			||||||
            west: Some(Box::new(operators::Interpolation4)),
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
        .collect::<Vec<_>>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let grids = jgrids
 | 
					 | 
				
			||||||
        .into_iter()
 | 
					 | 
				
			||||||
        .map(|egrid| egrid.grid)
 | 
					 | 
				
			||||||
        .collect::<Vec<grid::Grid>>();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let integration_time: Float = json["integration_time"].as_number().unwrap().into();
 | 
					    let integration_time: Float = json["integration_time"].as_number().unwrap().into();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let operators = grids
 | 
					    let mut sys = System::new(grids, bt, operators);
 | 
				
			||||||
        .iter()
 | 
					 | 
				
			||||||
        .map(|_| Right(Box::new(operators::Upwind4) as Box<dyn UpwindOperator2d>))
 | 
					 | 
				
			||||||
        .collect::<Vec<_>>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut sys = System::new(grids, bt, interpolation_operators, operators);
 | 
					 | 
				
			||||||
    sys.vortex(0.0, vortexparams);
 | 
					    sys.vortex(0.0, vortexparams);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let max_n = {
 | 
					    let max_n = {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,17 +1,180 @@
 | 
				
			|||||||
 | 
					use super::DiffOp;
 | 
				
			||||||
use crate::grid::Grid;
 | 
					use crate::grid::Grid;
 | 
				
			||||||
use crate::Float;
 | 
					use crate::Float;
 | 
				
			||||||
 | 
					use either::*;
 | 
				
			||||||
 | 
					use json::JsonValue;
 | 
				
			||||||
 | 
					use sbp::utils::h2linspace;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					pub fn json_to_grids(
 | 
				
			||||||
pub struct ExtendedGrid {
 | 
					    mut jsongrids: JsonValue,
 | 
				
			||||||
    pub grid: Grid,
 | 
					    vortexparams: sbp::euler::VortexParameters,
 | 
				
			||||||
    pub name: Option<String>,
 | 
					) -> (
 | 
				
			||||||
    pub dire: Option<String>,
 | 
					    Vec<String>,
 | 
				
			||||||
    pub dirw: Option<String>,
 | 
					    Vec<sbp::grid::Grid>,
 | 
				
			||||||
    pub dirn: Option<String>,
 | 
					    Vec<sbp::euler::BoundaryCharacteristics>,
 | 
				
			||||||
    pub dirs: Option<String>,
 | 
					    Vec<DiffOp>,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    let default = jsongrids.remove("default");
 | 
				
			||||||
 | 
					    let default_operator = {
 | 
				
			||||||
 | 
					        let operators = &default["operators"];
 | 
				
			||||||
 | 
					        let defaultxi = operators["xi"].as_str().unwrap_or("upwind4");
 | 
				
			||||||
 | 
					        let defaulteta = operators["eta"].as_str().unwrap_or("upwind4");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        (defaulteta.to_string(), defaultxi.to_string())
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					    let default_bc: sbp::utils::Direction<Option<String>> = {
 | 
				
			||||||
 | 
					        let bc = &default["boundary_conditions"];
 | 
				
			||||||
 | 
					        Direction {
 | 
				
			||||||
 | 
					            south: bc["south"].as_str().map(|x| x.to_string()),
 | 
				
			||||||
 | 
					            north: bc["north"].as_str().map(|x| x.to_string()),
 | 
				
			||||||
 | 
					            west: bc["west"].as_str().map(|x| x.to_string()),
 | 
				
			||||||
 | 
					            east: bc["east"].as_str().map(|x| x.to_string()),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    let mut names = Vec::new();
 | 
				
			||||||
 | 
					    let mut grids = Vec::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut operators: Vec<DiffOp> = Vec::new();
 | 
				
			||||||
 | 
					    for (name, grid) in jsongrids.entries() {
 | 
				
			||||||
 | 
					        names.push(name.to_string());
 | 
				
			||||||
 | 
					        grids.push(json2grid(grid["x"].clone(), grid["y"].clone()).unwrap());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        operators.push({
 | 
				
			||||||
 | 
					            use sbp::operators::*;
 | 
				
			||||||
 | 
					            let opxi = grid["operators"]["xi"]
 | 
				
			||||||
 | 
					                .as_str()
 | 
				
			||||||
 | 
					                .unwrap_or(&default_operator.1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let opeta = grid["operators"]["eta"]
 | 
				
			||||||
 | 
					                .as_str()
 | 
				
			||||||
 | 
					                .unwrap_or(&default_operator.1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            match (opeta, opxi) {
 | 
				
			||||||
 | 
					                ("upwind4", "upwind4") => Left(Box::new(Upwind4) as Box<dyn SbpOperator2d>),
 | 
				
			||||||
 | 
					                ("upwind9", "upwind9") => Left(Box::new(Upwind9) as Box<dyn SbpOperator2d>),
 | 
				
			||||||
 | 
					                ("upwind4h2", "upwind4h2") => Left(Box::new(Upwind4h2) as Box<dyn SbpOperator2d>),
 | 
				
			||||||
 | 
					                ("upwind9h2", "upwind9h2") => Left(Box::new(Upwind9h2) as Box<dyn SbpOperator2d>),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ("upwind4", "upwind9") => {
 | 
				
			||||||
 | 
					                    Left(Box::new((&Upwind4, &Upwind9)) as Box<dyn SbpOperator2d>)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ("upwind4", "upwind4h2") => {
 | 
				
			||||||
 | 
					                    Left(Box::new((&Upwind4, &Upwind4h2)) as Box<dyn SbpOperator2d>)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ("upwind4", "upwind9h2") => {
 | 
				
			||||||
 | 
					                    Left(Box::new((&Upwind4, &Upwind9h2)) as Box<dyn SbpOperator2d>)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ("upwind9", "upwind4") => {
 | 
				
			||||||
 | 
					                    Left(Box::new((&Upwind9, &Upwind4)) as Box<dyn SbpOperator2d>)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ("upwind9", "upwind4h2") => {
 | 
				
			||||||
 | 
					                    Left(Box::new((&Upwind9, &Upwind4h2)) as Box<dyn SbpOperator2d>)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ("upwind9", "upwind9h2") => {
 | 
				
			||||||
 | 
					                    Left(Box::new((&Upwind9, &Upwind9h2)) as Box<dyn SbpOperator2d>)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ("upwind4h2", "upwind4") => {
 | 
				
			||||||
 | 
					                    Left(Box::new((&Upwind4h2, &Upwind4)) as Box<dyn SbpOperator2d>)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ("upwind4h2", "upwind9") => {
 | 
				
			||||||
 | 
					                    Left(Box::new((&Upwind4h2, &Upwind9)) as Box<dyn SbpOperator2d>)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ("upwind4h2", "upwind9h2") => {
 | 
				
			||||||
 | 
					                    Left(Box::new((&Upwind4h2, &Upwind9h2)) as Box<dyn SbpOperator2d>)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ("upwind9h2", "upwind4") => {
 | 
				
			||||||
 | 
					                    Left(Box::new((&Upwind9h2, &Upwind4)) as Box<dyn SbpOperator2d>)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ("upwind9h2", "upwind9") => {
 | 
				
			||||||
 | 
					                    Left(Box::new((&Upwind9h2, &Upwind9)) as Box<dyn SbpOperator2d>)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ("upwind9h2", "upwind4h2") => {
 | 
				
			||||||
 | 
					                    Left(Box::new((&Upwind9h2, &Upwind4h2)) as Box<dyn SbpOperator2d>)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                (opeta, opxi) => panic!("combination {} {} not yet implemented", opeta, opxi),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut bcs = Vec::new();
 | 
				
			||||||
 | 
					    let determine_bc = |dir: Option<&str>| match dir {
 | 
				
			||||||
 | 
					        Some(dir) => {
 | 
				
			||||||
 | 
					            if dir == "vortex" {
 | 
				
			||||||
 | 
					                sbp::euler::BoundaryCharacteristic::Vortex(vortexparams)
 | 
				
			||||||
 | 
					            } else if let Some(grid) = dir.strip_prefix("interpolate:") {
 | 
				
			||||||
 | 
					                use sbp::operators::*;
 | 
				
			||||||
 | 
					                let (grid, int_op) = if let Some(rest) = grid.strip_prefix("4:") {
 | 
				
			||||||
 | 
					                    (
 | 
				
			||||||
 | 
					                        rest,
 | 
				
			||||||
 | 
					                        Box::new(Interpolation4) as Box<dyn InterpolationOperator>,
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                } else if let Some(rest) = grid.strip_prefix("9:") {
 | 
				
			||||||
 | 
					                    (
 | 
				
			||||||
 | 
					                        rest,
 | 
				
			||||||
 | 
					                        Box::new(Interpolation9) as Box<dyn InterpolationOperator>,
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                } else if let Some(rest) = grid.strip_prefix("8:") {
 | 
				
			||||||
 | 
					                    (
 | 
				
			||||||
 | 
					                        rest,
 | 
				
			||||||
 | 
					                        Box::new(Interpolation8) as Box<dyn InterpolationOperator>,
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                } else if let Some(rest) = grid.strip_prefix("9h2:") {
 | 
				
			||||||
 | 
					                    (
 | 
				
			||||||
 | 
					                        rest,
 | 
				
			||||||
 | 
					                        Box::new(Interpolation9h2) as Box<dyn InterpolationOperator>,
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    (
 | 
				
			||||||
 | 
					                        grid,
 | 
				
			||||||
 | 
					                        Box::new(Interpolation4) as Box<dyn InterpolationOperator>,
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                sbp::euler::BoundaryCharacteristic::Interpolate(
 | 
				
			||||||
 | 
					                    names.iter().position(|other| other == grid).unwrap(),
 | 
				
			||||||
 | 
					                    int_op,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                sbp::euler::BoundaryCharacteristic::Grid(
 | 
				
			||||||
 | 
					                    names.iter().position(|other| other == dir).unwrap(),
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        None => sbp::euler::BoundaryCharacteristic::This,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    for name in &names {
 | 
				
			||||||
 | 
					        let bc = &jsongrids[name]["boundary_conditions"];
 | 
				
			||||||
 | 
					        let bc_n = determine_bc(bc["north"].as_str());
 | 
				
			||||||
 | 
					        let bc_s = determine_bc(bc["south"].as_str());
 | 
				
			||||||
 | 
					        let bc_e = determine_bc(bc["east"].as_str());
 | 
				
			||||||
 | 
					        let bc_w = determine_bc(bc["west"].as_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let bc = sbp::euler::BoundaryCharacteristics {
 | 
				
			||||||
 | 
					            north: bc_n,
 | 
				
			||||||
 | 
					            south: bc_s,
 | 
				
			||||||
 | 
					            east: bc_e,
 | 
				
			||||||
 | 
					            west: bc_w,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bcs.push(bc);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (names, grids, bcs, operators)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					enum ArrayForm {
 | 
				
			||||||
 | 
					    /// Only know the one dimension, will broadcast to
 | 
				
			||||||
 | 
					    /// two dimensions once we know about both dims
 | 
				
			||||||
 | 
					    Array1(ndarray::Array1<Float>),
 | 
				
			||||||
 | 
					    /// The usize is the inner dimension (nx)
 | 
				
			||||||
 | 
					    Array2(ndarray::Array2<Float>),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use json::JsonValue;
 | 
					 | 
				
			||||||
/// Parsing json strings to some gridlike form
 | 
					/// Parsing json strings to some gridlike form
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Each grid should be an object with the descriptors on the form
 | 
					/// Each grid should be an object with the descriptors on the form
 | 
				
			||||||
@@ -29,25 +192,7 @@ use json::JsonValue;
 | 
				
			|||||||
/// Optional parameters:
 | 
					/// Optional parameters:
 | 
				
			||||||
/// * name (for relating boundaries)
 | 
					/// * name (for relating boundaries)
 | 
				
			||||||
/// * dir{e,w,n,s} (for boundary terms)
 | 
					/// * dir{e,w,n,s} (for boundary terms)
 | 
				
			||||||
pub fn json_to_grids(json: JsonValue) -> Result<Vec<ExtendedGrid>, String> {
 | 
					fn json2grid(x: JsonValue, y: JsonValue) -> Result<Grid, String> {
 | 
				
			||||||
    fn json_to_grid(mut grid: JsonValue) -> Result<ExtendedGrid, String> {
 | 
					 | 
				
			||||||
        #[derive(Debug)]
 | 
					 | 
				
			||||||
        enum ArrayForm {
 | 
					 | 
				
			||||||
            /// Only know the one dimension, will broadcast to
 | 
					 | 
				
			||||||
            /// two dimensions once we know about both dims
 | 
					 | 
				
			||||||
            Array1(ndarray::Array1<Float>),
 | 
					 | 
				
			||||||
            /// The usize is the inner dimension (nx)
 | 
					 | 
				
			||||||
            Array2(ndarray::Array2<Float>),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if grid.is_empty() {
 | 
					 | 
				
			||||||
            return Err("empty object".to_string());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        let name = grid.remove("name").take_string();
 | 
					 | 
				
			||||||
        let dire = grid.remove("dirE").take_string();
 | 
					 | 
				
			||||||
        let dirw = grid.remove("dirW").take_string();
 | 
					 | 
				
			||||||
        let dirn = grid.remove("dirN").take_string();
 | 
					 | 
				
			||||||
        let dirs = grid.remove("dirS").take_string();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let to_array_form = |mut x: JsonValue| {
 | 
					    let to_array_form = |mut x: JsonValue| {
 | 
				
			||||||
        if let Some(s) = x.take_string() {
 | 
					        if let Some(s) = x.take_string() {
 | 
				
			||||||
            if let Some(s) = s.strip_prefix("linspace:") {
 | 
					            if let Some(s) = s.strip_prefix("linspace:") {
 | 
				
			||||||
@@ -95,7 +240,12 @@ pub fn json_to_grids(json: JsonValue) -> Result<Vec<ExtendedGrid>, String> {
 | 
				
			|||||||
                let v = x
 | 
					                let v = x
 | 
				
			||||||
                    .members()
 | 
					                    .members()
 | 
				
			||||||
                    .map(|x: &JsonValue| -> Result<Float, String> {
 | 
					                    .map(|x: &JsonValue| -> Result<Float, String> {
 | 
				
			||||||
                            Ok(x.as_number().ok_or_else(|| "Array contained something that could not be converted to an array".to_string())?.into())
 | 
					                        Ok(x.as_number()
 | 
				
			||||||
 | 
					                            .ok_or_else(|| {
 | 
				
			||||||
 | 
					                                "Array contained something that could not be converted to an array"
 | 
				
			||||||
 | 
					                                    .to_string()
 | 
				
			||||||
 | 
					                            })?
 | 
				
			||||||
 | 
					                            .into())
 | 
				
			||||||
                    })
 | 
					                    })
 | 
				
			||||||
                    .collect::<Result<Vec<Float>, _>>()?;
 | 
					                    .collect::<Result<Vec<Float>, _>>()?;
 | 
				
			||||||
                Ok(ArrayForm::Array1(ndarray::Array::from(v)))
 | 
					                Ok(ArrayForm::Array1(ndarray::Array::from(v)))
 | 
				
			||||||
@@ -127,13 +277,11 @@ pub fn json_to_grids(json: JsonValue) -> Result<Vec<ExtendedGrid>, String> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let x = grid.remove("x");
 | 
					 | 
				
			||||||
    if x.is_empty() {
 | 
					    if x.is_empty() {
 | 
				
			||||||
        return Err("x was empty".to_string());
 | 
					        return Err("x was empty".to_string());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let x = to_array_form(x)?;
 | 
					    let x = to_array_form(x)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let y = grid.remove("y");
 | 
					 | 
				
			||||||
    if y.is_empty() {
 | 
					    if y.is_empty() {
 | 
				
			||||||
        return Err("y was empty".to_string());
 | 
					        return Err("y was empty".to_string());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -173,101 +321,7 @@ pub fn json_to_grids(json: JsonValue) -> Result<Vec<ExtendedGrid>, String> {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
    assert_eq!(x.shape(), y.shape());
 | 
					    assert_eq!(x.shape(), y.shape());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if !grid.is_empty() {
 | 
					    Ok(Grid::new(x, y).unwrap())
 | 
				
			||||||
            eprintln!("Grid contains some unused entries");
 | 
					 | 
				
			||||||
            for i in grid.entries() {
 | 
					 | 
				
			||||||
                eprintln!("{:#?}", i);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Ok(ExtendedGrid {
 | 
					 | 
				
			||||||
            grid: Grid::new(x, y).unwrap(),
 | 
					 | 
				
			||||||
            name,
 | 
					 | 
				
			||||||
            dire,
 | 
					 | 
				
			||||||
            dirw,
 | 
					 | 
				
			||||||
            dirn,
 | 
					 | 
				
			||||||
            dirs,
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    match json {
 | 
					 | 
				
			||||||
        JsonValue::Array(a) => a
 | 
					 | 
				
			||||||
            .into_iter()
 | 
					 | 
				
			||||||
            .map(json_to_grid)
 | 
					 | 
				
			||||||
            .collect::<Result<Vec<_>, _>>(),
 | 
					 | 
				
			||||||
        grid => Ok(vec![json_to_grid(grid)?]),
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn parse_linspace() {
 | 
					 | 
				
			||||||
    let grids = json_to_grids(
 | 
					 | 
				
			||||||
        json::parse(r#"[{"name": "main", "x": "linspace:0:10:20", "y": "linspace:0:10:21"}]"#)
 | 
					 | 
				
			||||||
            .unwrap(),
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    .unwrap();
 | 
					 | 
				
			||||||
    assert_eq!(grids.len(), 1);
 | 
					 | 
				
			||||||
    assert_eq!(grids[0].grid.x.shape(), [21, 20]);
 | 
					 | 
				
			||||||
    assert_eq!(grids[0].grid.y.shape(), [21, 20]);
 | 
					 | 
				
			||||||
    assert_eq!(grids[0].name.as_ref().unwrap(), "main");
 | 
					 | 
				
			||||||
    let grids = json_to_grids(
 | 
					 | 
				
			||||||
        json::parse(r#"{"name": "main", "x": "linspace:0:10:20", "y": "linspace:0:10:21"}"#)
 | 
					 | 
				
			||||||
            .unwrap(),
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    .unwrap();
 | 
					 | 
				
			||||||
    assert_eq!(grids.len(), 1);
 | 
					 | 
				
			||||||
    assert_eq!(grids[0].grid.x.shape(), [21, 20]);
 | 
					 | 
				
			||||||
    assert_eq!(grids[0].grid.y.shape(), [21, 20]);
 | 
					 | 
				
			||||||
    assert_eq!(grids[0].name.as_ref().unwrap(), "main");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn parse_1d() {
 | 
					 | 
				
			||||||
    let grids =
 | 
					 | 
				
			||||||
        json_to_grids(json::parse(r#"{"x": [1, 2, 3, 4, 5.1, 3], "y": [1, 2]}"#).unwrap()).unwrap();
 | 
					 | 
				
			||||||
    assert_eq!(grids.len(), 1);
 | 
					 | 
				
			||||||
    let grid = &grids[0];
 | 
					 | 
				
			||||||
    assert_eq!(grid.grid.x.shape(), &[2, 6]);
 | 
					 | 
				
			||||||
    assert_eq!(grid.grid.x.shape(), grid.grid.y.shape());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn parse_2d() {
 | 
					 | 
				
			||||||
    let grids =
 | 
					 | 
				
			||||||
        json_to_grids(json::parse(r#"{"x": [[1, 2], [3, 4], [5.1, 3]], "y": [1, 2, 3]}"#).unwrap())
 | 
					 | 
				
			||||||
            .unwrap();
 | 
					 | 
				
			||||||
    assert_eq!(grids.len(), 1);
 | 
					 | 
				
			||||||
    let grid = &grids[0];
 | 
					 | 
				
			||||||
    assert_eq!(grid.grid.x.shape(), &[3, 2]);
 | 
					 | 
				
			||||||
    assert_eq!(grid.grid.x.shape(), grid.grid.y.shape());
 | 
					 | 
				
			||||||
    json_to_grids(
 | 
					 | 
				
			||||||
        json::parse(r#"{"x": [[1, 2], [3, 4], [5.1, 3], [1]], "y": [1, 2, 3]}"#).unwrap(),
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    .unwrap_err();
 | 
					 | 
				
			||||||
    json_to_grids(
 | 
					 | 
				
			||||||
        json::parse(r#"{"y": [[1, 2], [3, 4], [5.1, 3], [1]], "x": [1, 2, 3]}"#).unwrap(),
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    .unwrap_err();
 | 
					 | 
				
			||||||
    let grids = json_to_grids(
 | 
					 | 
				
			||||||
        json::parse(r#"{"x": [[1, 2], [3, 4], [5.1, 3]], "y": [[1, 2], [3, 4], [5, 6]]}"#).unwrap(),
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    .unwrap();
 | 
					 | 
				
			||||||
    assert_eq!(grids.len(), 1);
 | 
					 | 
				
			||||||
    json_to_grids(
 | 
					 | 
				
			||||||
        json::parse(r#"{"x": [[1, 2], [3, 4], [5.1, 3]], "y": [[1, 2], [3, 4], [5]]}"#).unwrap(),
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    .unwrap_err();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn parse_err() {
 | 
					 | 
				
			||||||
    json_to_grids(json::parse(r#"{}"#).unwrap()).unwrap_err();
 | 
					 | 
				
			||||||
    json_to_grids(json::parse(r#"0.45"#).unwrap()).unwrap_err();
 | 
					 | 
				
			||||||
    json_to_grids(json::parse(r#"{"x": "linspace", "y": [0.1, 0.2]}"#).unwrap()).unwrap_err();
 | 
					 | 
				
			||||||
    json_to_grids(json::parse(r#"{"x": "linspace:::", "y": [0.1, 0.2]}"#).unwrap()).unwrap_err();
 | 
					 | 
				
			||||||
    json_to_grids(json::parse(r#"{"x": "linspace:1.2:3.1:412.2", "y": [0.1, 0.2]}"#).unwrap())
 | 
					 | 
				
			||||||
        .unwrap_err();
 | 
					 | 
				
			||||||
    json_to_grids(json::parse(r#"{"x": [-2, -3, "dfd"], "y": [0.1, 0.2]}"#).unwrap()).unwrap_err();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn json_to_vortex(mut json: JsonValue) -> super::euler::VortexParameters {
 | 
					pub fn json_to_vortex(mut json: JsonValue) -> super::euler::VortexParameters {
 | 
				
			||||||
@@ -292,27 +346,3 @@ pub fn json_to_vortex(mut json: JsonValue) -> super::euler::VortexParameters {
 | 
				
			|||||||
        eps,
 | 
					        eps,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn h2linspace(start: Float, end: Float, n: usize) -> ndarray::Array1<Float> {
 | 
					 | 
				
			||||||
    let h = (end - start) / (n - 2) as Float;
 | 
					 | 
				
			||||||
    ndarray::Array1::from_shape_fn(n, |i| match i {
 | 
					 | 
				
			||||||
        0 => start,
 | 
					 | 
				
			||||||
        i if i == n - 1 => end,
 | 
					 | 
				
			||||||
        i => start + h * (i as Float - 0.5),
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[test]
 | 
					 | 
				
			||||||
fn test_h2linspace() {
 | 
					 | 
				
			||||||
    let x = h2linspace(-1.0, 1.0, 50);
 | 
					 | 
				
			||||||
    println!("{}", x);
 | 
					 | 
				
			||||||
    approx::assert_abs_diff_eq!(x[0], -1.0, epsilon = 1e-6);
 | 
					 | 
				
			||||||
    approx::assert_abs_diff_eq!(x[49], 1.0, epsilon = 1e-6);
 | 
					 | 
				
			||||||
    let hend = x[1] - x[0];
 | 
					 | 
				
			||||||
    let h = x[2] - x[1];
 | 
					 | 
				
			||||||
    approx::assert_abs_diff_eq!(x[49] - x[48], hend, epsilon = 1e-6);
 | 
					 | 
				
			||||||
    approx::assert_abs_diff_eq!(2.0 * hend, h, epsilon = 1e-6);
 | 
					 | 
				
			||||||
    for i in 1..48 {
 | 
					 | 
				
			||||||
        approx::assert_abs_diff_eq!(x[i + 1] - x[i], h, epsilon = 1e-6);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -597,13 +597,12 @@ fn fluxes(k: (&mut Field, &mut Field), y: &Field, metrics: &Metrics) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone, Debug)]
 | 
					 | 
				
			||||||
pub enum BoundaryCharacteristic {
 | 
					pub enum BoundaryCharacteristic {
 | 
				
			||||||
    This,
 | 
					    This,
 | 
				
			||||||
    Grid(usize),
 | 
					    Grid(usize),
 | 
				
			||||||
    Vortex(VortexParameters),
 | 
					    Vortex(VortexParameters),
 | 
				
			||||||
    // Vortices(Vec<VortexParameters>),
 | 
					    // Vortices(Vec<VortexParameters>),
 | 
				
			||||||
    Interpolate(usize),
 | 
					    Interpolate(usize, Box<dyn InterpolationOperator>),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub type BoundaryTerms<'a> = Direction<ArrayView2<'a, Float>>;
 | 
					pub type BoundaryTerms<'a> = Direction<ArrayView2<'a, Float>>;
 | 
				
			||||||
@@ -618,68 +617,59 @@ fn boundary_extractor<'a>(
 | 
				
			|||||||
        north: match bc.north {
 | 
					        north: match bc.north {
 | 
				
			||||||
            BoundaryCharacteristic::This => field.south(),
 | 
					            BoundaryCharacteristic::This => field.south(),
 | 
				
			||||||
            BoundaryCharacteristic::Vortex(_params) => todo!(),
 | 
					            BoundaryCharacteristic::Vortex(_params) => todo!(),
 | 
				
			||||||
            BoundaryCharacteristic::Grid(_) | BoundaryCharacteristic::Interpolate(_) => {
 | 
					            BoundaryCharacteristic::Grid(_) | BoundaryCharacteristic::Interpolate(_, _) => {
 | 
				
			||||||
                panic!("Only working on self grid")
 | 
					                panic!("Only working on self grid")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        south: match bc.south {
 | 
					        south: match bc.south {
 | 
				
			||||||
            BoundaryCharacteristic::This => field.north(),
 | 
					            BoundaryCharacteristic::This => field.north(),
 | 
				
			||||||
            BoundaryCharacteristic::Vortex(_params) => todo!(),
 | 
					            BoundaryCharacteristic::Vortex(_params) => todo!(),
 | 
				
			||||||
            BoundaryCharacteristic::Grid(_) | BoundaryCharacteristic::Interpolate(_) => {
 | 
					            BoundaryCharacteristic::Grid(_) | BoundaryCharacteristic::Interpolate(_, _) => {
 | 
				
			||||||
                panic!("Only working on self grid")
 | 
					                panic!("Only working on self grid")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        west: match bc.west {
 | 
					        west: match bc.west {
 | 
				
			||||||
            BoundaryCharacteristic::This => field.east(),
 | 
					            BoundaryCharacteristic::This => field.east(),
 | 
				
			||||||
            BoundaryCharacteristic::Vortex(_params) => todo!(),
 | 
					            BoundaryCharacteristic::Vortex(_params) => todo!(),
 | 
				
			||||||
            BoundaryCharacteristic::Grid(_) | BoundaryCharacteristic::Interpolate(_) => {
 | 
					            BoundaryCharacteristic::Grid(_) | BoundaryCharacteristic::Interpolate(_, _) => {
 | 
				
			||||||
                panic!("Only working on self grid")
 | 
					                panic!("Only working on self grid")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        east: match bc.east {
 | 
					        east: match bc.east {
 | 
				
			||||||
            BoundaryCharacteristic::This => field.west(),
 | 
					            BoundaryCharacteristic::This => field.west(),
 | 
				
			||||||
            BoundaryCharacteristic::Vortex(_params) => todo!(),
 | 
					            BoundaryCharacteristic::Vortex(_params) => todo!(),
 | 
				
			||||||
            BoundaryCharacteristic::Grid(_) | BoundaryCharacteristic::Interpolate(_) => {
 | 
					            BoundaryCharacteristic::Grid(_) | BoundaryCharacteristic::Interpolate(_, _) => {
 | 
				
			||||||
                panic!("Only working on self grid")
 | 
					                panic!("Only working on self grid")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub type InterpolationOperators = Direction<Option<Box<dyn InterpolationOperator>>>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn extract_boundaries<'a>(
 | 
					pub fn extract_boundaries<'a>(
 | 
				
			||||||
    fields: &'a [Field],
 | 
					    fields: &'a [Field],
 | 
				
			||||||
    bt: &[BoundaryCharacteristics],
 | 
					    bt: &[BoundaryCharacteristics],
 | 
				
			||||||
    eb: &'a mut [BoundaryStorage],
 | 
					    eb: &'a mut [BoundaryStorage],
 | 
				
			||||||
    grids: &[Grid],
 | 
					    grids: &[Grid],
 | 
				
			||||||
    time: Float,
 | 
					    time: Float,
 | 
				
			||||||
    interpolation_operators: Option<&[InterpolationOperators]>,
 | 
					 | 
				
			||||||
) -> Vec<BoundaryTerms<'a>> {
 | 
					) -> Vec<BoundaryTerms<'a>> {
 | 
				
			||||||
    bt.iter()
 | 
					    bt.iter()
 | 
				
			||||||
        .zip(eb)
 | 
					        .zip(eb)
 | 
				
			||||||
        .zip(grids)
 | 
					        .zip(grids)
 | 
				
			||||||
        .zip(fields)
 | 
					        .zip(fields)
 | 
				
			||||||
        .enumerate()
 | 
					        .map(|(((bt, eb), grid), field)| BoundaryTerms {
 | 
				
			||||||
        .map(|(ig, (((bt, eb), grid), field))| BoundaryTerms {
 | 
					            north: match &bt.north {
 | 
				
			||||||
            north: match bt.north {
 | 
					 | 
				
			||||||
                BoundaryCharacteristic::This => field.south(),
 | 
					                BoundaryCharacteristic::This => field.south(),
 | 
				
			||||||
                BoundaryCharacteristic::Grid(g) => fields[g].south(),
 | 
					                BoundaryCharacteristic::Grid(g) => fields[*g].south(),
 | 
				
			||||||
                BoundaryCharacteristic::Vortex(v) => {
 | 
					                BoundaryCharacteristic::Vortex(v) => {
 | 
				
			||||||
                    let field = eb.north.as_mut().unwrap();
 | 
					                    let field = eb.north.as_mut().unwrap();
 | 
				
			||||||
                    vortexify(field.view_mut(), grid.north(), v, time);
 | 
					                    vortexify(field.view_mut(), grid.north(), *v, time);
 | 
				
			||||||
                    field.view()
 | 
					                    field.view()
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                BoundaryCharacteristic::Interpolate(g) => {
 | 
					                BoundaryCharacteristic::Interpolate(g, operator) => {
 | 
				
			||||||
                    let to = eb.north.as_mut().unwrap();
 | 
					                    let to = eb.north.as_mut().unwrap();
 | 
				
			||||||
                    let fine2coarse = field.nx() < fields[g].nx();
 | 
					                    let fine2coarse = field.nx() < fields[*g].nx();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    let operator = interpolation_operators.as_ref().unwrap()[ig]
 | 
					                    for (mut to, from) in to.outer_iter_mut().zip(fields[*g].south().outer_iter()) {
 | 
				
			||||||
                        .north
 | 
					 | 
				
			||||||
                        .as_ref()
 | 
					 | 
				
			||||||
                        .unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    for (mut to, from) in to.outer_iter_mut().zip(fields[g].south().outer_iter()) {
 | 
					 | 
				
			||||||
                        if fine2coarse {
 | 
					                        if fine2coarse {
 | 
				
			||||||
                            operator.fine2coarse(from.view(), to.view_mut());
 | 
					                            operator.fine2coarse(from.view(), to.view_mut());
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
@@ -689,23 +679,19 @@ pub fn extract_boundaries<'a>(
 | 
				
			|||||||
                    to.view()
 | 
					                    to.view()
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            south: match bt.south {
 | 
					            south: match &bt.south {
 | 
				
			||||||
                BoundaryCharacteristic::This => field.north(),
 | 
					                BoundaryCharacteristic::This => field.north(),
 | 
				
			||||||
                BoundaryCharacteristic::Grid(g) => fields[g].north(),
 | 
					                BoundaryCharacteristic::Grid(g) => fields[*g].north(),
 | 
				
			||||||
                BoundaryCharacteristic::Vortex(v) => {
 | 
					                BoundaryCharacteristic::Vortex(v) => {
 | 
				
			||||||
                    let field = eb.south.as_mut().unwrap();
 | 
					                    let field = eb.south.as_mut().unwrap();
 | 
				
			||||||
                    vortexify(field.view_mut(), grid.south(), v, time);
 | 
					                    vortexify(field.view_mut(), grid.south(), *v, time);
 | 
				
			||||||
                    field.view()
 | 
					                    field.view()
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                BoundaryCharacteristic::Interpolate(g) => {
 | 
					                BoundaryCharacteristic::Interpolate(g, operator) => {
 | 
				
			||||||
                    let to = eb.south.as_mut().unwrap();
 | 
					                    let to = eb.south.as_mut().unwrap();
 | 
				
			||||||
                    let fine2coarse = field.nx() < fields[g].nx();
 | 
					                    let fine2coarse = field.nx() < fields[*g].nx();
 | 
				
			||||||
                    let operator = interpolation_operators.as_ref().unwrap()[ig]
 | 
					 | 
				
			||||||
                        .south
 | 
					 | 
				
			||||||
                        .as_ref()
 | 
					 | 
				
			||||||
                        .unwrap();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    for (mut to, from) in to.outer_iter_mut().zip(fields[g].north().outer_iter()) {
 | 
					                    for (mut to, from) in to.outer_iter_mut().zip(fields[*g].north().outer_iter()) {
 | 
				
			||||||
                        if fine2coarse {
 | 
					                        if fine2coarse {
 | 
				
			||||||
                            operator.fine2coarse(from.view(), to.view_mut());
 | 
					                            operator.fine2coarse(from.view(), to.view_mut());
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
@@ -715,23 +701,19 @@ pub fn extract_boundaries<'a>(
 | 
				
			|||||||
                    to.view()
 | 
					                    to.view()
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            west: match bt.west {
 | 
					            west: match &bt.west {
 | 
				
			||||||
                BoundaryCharacteristic::This => field.east(),
 | 
					                BoundaryCharacteristic::This => field.east(),
 | 
				
			||||||
                BoundaryCharacteristic::Grid(g) => fields[g].east(),
 | 
					                BoundaryCharacteristic::Grid(g) => fields[*g].east(),
 | 
				
			||||||
                BoundaryCharacteristic::Vortex(v) => {
 | 
					                BoundaryCharacteristic::Vortex(v) => {
 | 
				
			||||||
                    let field = eb.west.as_mut().unwrap();
 | 
					                    let field = eb.west.as_mut().unwrap();
 | 
				
			||||||
                    vortexify(field.view_mut(), grid.west(), v, time);
 | 
					                    vortexify(field.view_mut(), grid.west(), *v, time);
 | 
				
			||||||
                    field.view()
 | 
					                    field.view()
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                BoundaryCharacteristic::Interpolate(g) => {
 | 
					                BoundaryCharacteristic::Interpolate(g, operator) => {
 | 
				
			||||||
                    let to = eb.west.as_mut().unwrap();
 | 
					                    let to = eb.west.as_mut().unwrap();
 | 
				
			||||||
                    let fine2coarse = field.ny() < fields[g].ny();
 | 
					                    let fine2coarse = field.ny() < fields[*g].ny();
 | 
				
			||||||
                    let operator = interpolation_operators.as_ref().unwrap()[ig]
 | 
					 | 
				
			||||||
                        .west
 | 
					 | 
				
			||||||
                        .as_ref()
 | 
					 | 
				
			||||||
                        .unwrap();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    for (mut to, from) in to.outer_iter_mut().zip(fields[g].east().outer_iter()) {
 | 
					                    for (mut to, from) in to.outer_iter_mut().zip(fields[*g].east().outer_iter()) {
 | 
				
			||||||
                        if fine2coarse {
 | 
					                        if fine2coarse {
 | 
				
			||||||
                            operator.fine2coarse(from.view(), to.view_mut());
 | 
					                            operator.fine2coarse(from.view(), to.view_mut());
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
@@ -741,23 +723,19 @@ pub fn extract_boundaries<'a>(
 | 
				
			|||||||
                    to.view()
 | 
					                    to.view()
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            east: match bt.east {
 | 
					            east: match &bt.east {
 | 
				
			||||||
                BoundaryCharacteristic::This => field.west(),
 | 
					                BoundaryCharacteristic::This => field.west(),
 | 
				
			||||||
                BoundaryCharacteristic::Grid(g) => fields[g].west(),
 | 
					                BoundaryCharacteristic::Grid(g) => fields[*g].west(),
 | 
				
			||||||
                BoundaryCharacteristic::Vortex(v) => {
 | 
					                BoundaryCharacteristic::Vortex(v) => {
 | 
				
			||||||
                    let field = eb.east.as_mut().unwrap();
 | 
					                    let field = eb.east.as_mut().unwrap();
 | 
				
			||||||
                    vortexify(field.view_mut(), grid.east(), v, time);
 | 
					                    vortexify(field.view_mut(), grid.east(), *v, time);
 | 
				
			||||||
                    field.view()
 | 
					                    field.view()
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                BoundaryCharacteristic::Interpolate(g) => {
 | 
					                BoundaryCharacteristic::Interpolate(g, operator) => {
 | 
				
			||||||
                    let to = eb.east.as_mut().unwrap();
 | 
					                    let to = eb.east.as_mut().unwrap();
 | 
				
			||||||
                    let fine2coarse = field.ny() < fields[g].ny();
 | 
					                    let fine2coarse = field.ny() < fields[*g].ny();
 | 
				
			||||||
                    let operator = interpolation_operators.as_ref().unwrap()[ig]
 | 
					 | 
				
			||||||
                        .east
 | 
					 | 
				
			||||||
                        .as_ref()
 | 
					 | 
				
			||||||
                        .unwrap();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    for (mut to, from) in to.outer_iter_mut().zip(fields[g].west().outer_iter()) {
 | 
					                    for (mut to, from) in to.outer_iter_mut().zip(fields[*g].west().outer_iter()) {
 | 
				
			||||||
                        if fine2coarse {
 | 
					                        if fine2coarse {
 | 
				
			||||||
                            operator.fine2coarse(from.view(), to.view_mut());
 | 
					                            operator.fine2coarse(from.view(), to.view_mut());
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
@@ -778,25 +756,25 @@ impl BoundaryStorage {
 | 
				
			|||||||
    pub fn new(bt: &BoundaryCharacteristics, grid: &Grid) -> Self {
 | 
					    pub fn new(bt: &BoundaryCharacteristics, grid: &Grid) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            north: match bt.north {
 | 
					            north: match bt.north {
 | 
				
			||||||
                BoundaryCharacteristic::Vortex(_) | BoundaryCharacteristic::Interpolate(_) => {
 | 
					                BoundaryCharacteristic::Vortex(_) | BoundaryCharacteristic::Interpolate(_, _) => {
 | 
				
			||||||
                    Some(ndarray::Array2::zeros((4, grid.nx())))
 | 
					                    Some(ndarray::Array2::zeros((4, grid.nx())))
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                _ => None,
 | 
					                _ => None,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            south: match bt.south {
 | 
					            south: match bt.south {
 | 
				
			||||||
                BoundaryCharacteristic::Vortex(_) | BoundaryCharacteristic::Interpolate(_) => {
 | 
					                BoundaryCharacteristic::Vortex(_) | BoundaryCharacteristic::Interpolate(_, _) => {
 | 
				
			||||||
                    Some(ndarray::Array2::zeros((4, grid.nx())))
 | 
					                    Some(ndarray::Array2::zeros((4, grid.nx())))
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                _ => None,
 | 
					                _ => None,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            east: match bt.east {
 | 
					            east: match bt.east {
 | 
				
			||||||
                BoundaryCharacteristic::Vortex(_) | BoundaryCharacteristic::Interpolate(_) => {
 | 
					                BoundaryCharacteristic::Vortex(_) | BoundaryCharacteristic::Interpolate(_, _) => {
 | 
				
			||||||
                    Some(ndarray::Array2::zeros((4, grid.ny())))
 | 
					                    Some(ndarray::Array2::zeros((4, grid.ny())))
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                _ => None,
 | 
					                _ => None,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            west: match bt.west {
 | 
					            west: match bt.west {
 | 
				
			||||||
                BoundaryCharacteristic::Vortex(_) | BoundaryCharacteristic::Interpolate(_) => {
 | 
					                BoundaryCharacteristic::Vortex(_) | BoundaryCharacteristic::Interpolate(_, _) => {
 | 
				
			||||||
                    Some(ndarray::Array2::zeros((4, grid.ny())))
 | 
					                    Some(ndarray::Array2::zeros((4, grid.ny())))
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                _ => None,
 | 
					                _ => None,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -185,7 +185,7 @@ mod traditional8;
 | 
				
			|||||||
pub use traditional8::SBP8;
 | 
					pub use traditional8::SBP8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod interpolation;
 | 
					mod interpolation;
 | 
				
			||||||
pub use interpolation::Interpolation4;
 | 
					pub use interpolation::{Interpolation4, Interpolation8, Interpolation9, Interpolation9h2};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
pub(crate) mod testing {
 | 
					pub(crate) mod testing {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,32 @@
 | 
				
			|||||||
 | 
					use crate::Float;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Direction<T> {
 | 
					pub struct Direction<T> {
 | 
				
			||||||
    pub north: T,
 | 
					    pub north: T,
 | 
				
			||||||
    pub south: T,
 | 
					    pub south: T,
 | 
				
			||||||
    pub west: T,
 | 
					    pub west: T,
 | 
				
			||||||
    pub east: T,
 | 
					    pub east: T,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn h2linspace(start: Float, end: Float, n: usize) -> ndarray::Array1<Float> {
 | 
				
			||||||
 | 
					    let h = (end - start) / (n - 2) as Float;
 | 
				
			||||||
 | 
					    ndarray::Array1::from_shape_fn(n, |i| match i {
 | 
				
			||||||
 | 
					        0 => start,
 | 
				
			||||||
 | 
					        i if i == n - 1 => end,
 | 
				
			||||||
 | 
					        i => start + h * (i as Float - 0.5),
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn test_h2linspace() {
 | 
				
			||||||
 | 
					    let x = h2linspace(-1.0, 1.0, 50);
 | 
				
			||||||
 | 
					    println!("{}", x);
 | 
				
			||||||
 | 
					    approx::assert_abs_diff_eq!(x[0], -1.0, epsilon = 1e-6);
 | 
				
			||||||
 | 
					    approx::assert_abs_diff_eq!(x[49], 1.0, epsilon = 1e-6);
 | 
				
			||||||
 | 
					    let hend = x[1] - x[0];
 | 
				
			||||||
 | 
					    let h = x[2] - x[1];
 | 
				
			||||||
 | 
					    approx::assert_abs_diff_eq!(x[49] - x[48], hend, epsilon = 1e-6);
 | 
				
			||||||
 | 
					    approx::assert_abs_diff_eq!(2.0 * hend, h, epsilon = 1e-6);
 | 
				
			||||||
 | 
					    for i in 1..48 {
 | 
				
			||||||
 | 
					        approx::assert_abs_diff_eq!(x[i + 1] - x[i], h, epsilon = 1e-6);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user