776 {
777
778
779
780
781
782
783
784
785 int iX0 = 0, iX1 = 0;
786 int iY0 = 0, iY1 = 0;
787 int iZ0 = 0, iZ1 = 0;
788 double fX[4], fY[4], fZ[4];
789
790
791 const double x = std::min(std::max(xx, std::min(xAxis[0], xAxis[nx - 1])),
792 std::max(xAxis[0], xAxis[nx - 1]));
793 const double y = std::min(std::max(yy, std::min(yAxis[0], yAxis[ny - 1])),
794 std::max(yAxis[0], yAxis[ny - 1]));
795 const double z = std::min(std::max(zz, std::min(zAxis[0], zAxis[nz - 1])),
796 std::max(zAxis[0], zAxis[nz - 1]));
797
798
799 if (iOrder < 0 || iOrder > 2 || nx < 1 || ny < 1 || nz < 1) {
800 std::cerr << "Boxin3:\n";
801 std::cerr << " Incorrect order or number of points.\n";
802 std::cerr << " No interpolation.\n";
803 f = 0.;
804 return false;
805 }
806
807 if (iOrder == 0 || nx == 1) {
808
809
810 double dist = fabs(x - xAxis[0]);
811 int iNode = 0;
812 for (int i = 1; i < nx; i++) {
813 if (fabs(x - xAxis[i]) < dist) {
814 dist = fabs(x - xAxis[i]);
815 iNode = i;
816 }
817 }
818
819 iX0 = iNode;
820 iX1 = iNode;
821
822 fX[0] = 1.;
823 fX[1] = 0.;
824 fX[2] = 0.;
825 fX[3] = 0.;
826 } else if (iOrder == 1 || nx == 2) {
827
828
829 int iGrid = 0;
830 for (int i = 1; i < nx; i++) {
831 if ((xAxis[i - 1] - x) * (x - xAxis[i]) >= 0.) {
832 iGrid = i;
833 }
834 }
835
836 if (xAxis[iGrid] == xAxis[iGrid - 1]) {
837 std::cerr << "Boxin3:\n";
838 std::cerr << " Incorrect grid; no interpolation.\n";
839 f = 0.;
840 return false;
841 }
842
843 const double xLocal =
844 (x - xAxis[iGrid - 1]) / (xAxis[iGrid] - xAxis[iGrid - 1]);
845
846 iX0 = iGrid - 1;
847 iX1 = iGrid;
848
849 fX[0] = 1. - xLocal;
850 fX[1] = xLocal;
851 fX[2] = 0.;
852 fX[3] = 0.;
853 } else if (iOrder == 2) {
854
855
856 int iGrid = 0;
857 for (int i = 1; i < nx; i++) {
858 if ((xAxis[i - 1] - x) * (x - xAxis[i]) >= 0.) {
859 iGrid = i;
860 }
861 }
862
863 const double xLocal =
864 (x - xAxis[iGrid - 1]) / (xAxis[iGrid] - xAxis[iGrid - 1]);
865
866 if (iGrid == 1) {
867 iX0 = iGrid - 1;
868 iX1 = iGrid + 1;
869 if (xAxis[iX0] == xAxis[iX0 + 1] || xAxis[iX0] == xAxis[iX0 + 2] ||
870 xAxis[iX0 + 1] == xAxis[iX0 + 2]) {
871 std::cerr << "Boxin3:\n";
872 std::cerr << " One or more grid points in x coincide.\n";
873 std::cerr << " No interpolation.\n";
874 f = 0.;
875 return false;
876 }
877 fX[0] = (x - xAxis[iX0 + 1]) * (x - xAxis[iX0 + 2]) /
878 ((xAxis[iX0] - xAxis[iX0 + 1]) * (xAxis[iX0] - xAxis[iX0 + 2]));
879 fX[1] =
880 (x - xAxis[iX0]) * (x - xAxis[iX0 + 2]) /
881 ((xAxis[iX0 + 1] - xAxis[iX0]) * (xAxis[iX0 + 1] - xAxis[iX0 + 2]));
882 fX[2] =
883 (x - xAxis[iX0]) * (x - xAxis[iX0 + 1]) /
884 ((xAxis[iX0 + 2] - xAxis[iX0]) * (xAxis[iX0 + 2] - xAxis[iX0 + 1]));
885 } else if (iGrid == nx - 1) {
886 iX0 = iGrid - 2;
887 iX1 = iGrid;
888 if (xAxis[iX0] == xAxis[iX0 + 1] || xAxis[iX0] == xAxis[iX0 + 2] ||
889 xAxis[iX0 + 1] == xAxis[iX0 + 2]) {
890 std::cerr << "Boxin3:\n";
891 std::cerr << " One or more grid points in x coincide.\n";
892 std::cerr << " No interpolation.\n";
893 f = 0.;
894 return false;
895 }
896 fX[0] = (x - xAxis[iX0 + 1]) * (x - xAxis[iX0 + 2]) /
897 ((xAxis[iX0] - xAxis[iX0 + 1]) * (xAxis[iX0] - xAxis[iX0 + 2]));
898 fX[1] =
899 (x - xAxis[iX0]) * (x - xAxis[iX0 + 2]) /
900 ((xAxis[iX0 + 1] - xAxis[iX0]) * (xAxis[iX0 + 1] - xAxis[iX0 + 2]));
901 fX[2] =
902 (x - xAxis[iX0]) * (x - xAxis[iX0 + 1]) /
903 ((xAxis[iX0 + 2] - xAxis[iX0]) * (xAxis[iX0 + 2] - xAxis[iX0 + 1]));
904 } else {
905 iX0 = iGrid - 2;
906 iX1 = iGrid + 1;
907 if (xAxis[iX0] == xAxis[iX0 + 1] || xAxis[iX0] == xAxis[iX0 + 2] ||
908 xAxis[iX0] == xAxis[iX0 + 3] || xAxis[iX0 + 1] == xAxis[iX0 + 2] ||
909 xAxis[iX0 + 1] == xAxis[iX0 + 3] ||
910 xAxis[iX0 + 2] == xAxis[iX0 + 3]) {
911 std::cerr << "Boxin3:\n";
912 std::cerr << " One or more grid points in x coincide.\n";
913 std::cerr << " No interpolation.\n";
914 f = 0.;
915 return false;
916 }
917 fX[0] = (x - xAxis[iX0 + 1]) * (x - xAxis[iX0 + 2]) /
918 ((xAxis[iX0] - xAxis[iX0 + 1]) * (xAxis[iX0] - xAxis[iX0 + 2]));
919 fX[1] =
920 (x - xAxis[iX0]) * (x - xAxis[iX0 + 2]) /
921 ((xAxis[iX0 + 1] - xAxis[iX0]) * (xAxis[iX0 + 1] - xAxis[iX0 + 2]));
922 fX[2] =
923 (x - xAxis[iX0]) * (x - xAxis[iX0 + 1]) /
924 ((xAxis[iX0 + 2] - xAxis[iX0]) * (xAxis[iX0 + 2] - xAxis[iX0 + 1]));
925 fX[0] *= (1. - xLocal);
926 fX[1] = fX[1] * (1. - xLocal) + xLocal * (x - xAxis[iX0 + 2]) *
927 (x - xAxis[iX0 + 3]) /
928 ((xAxis[iX0 + 1] - xAxis[iX0 + 2]) *
929 (xAxis[iX0 + 1] - xAxis[iX0 + 3]));
930 fX[2] = fX[2] * (1. - xLocal) + xLocal * (x - xAxis[iX0 + 1]) *
931 (x - xAxis[iX0 + 3]) /
932 ((xAxis[iX0 + 2] - xAxis[iX0 + 1]) *
933 (xAxis[iX0 + 2] - xAxis[iX0 + 3]));
934 fX[3] = xLocal * (x - xAxis[iX0 + 1]) * (x - xAxis[iX0 + 2]) /
935 ((xAxis[iX0 + 3] - xAxis[iX0 + 1]) *
936 (xAxis[iX0 + 3] - xAxis[iX0 + 2]));
937 }
938 }
939
940 if (iOrder == 0 || ny == 1) {
941
942
943 double dist =
fabs(y - yAxis[0]);
944 int iNode = 0;
945 for (int i = 1; i < ny; i++) {
946 if (
fabs(y - yAxis[i]) < dist) {
947 dist =
fabs(y - yAxis[i]);
948 iNode = i;
949 }
950 }
951
952 iY0 = iNode;
953 iY1 = iNode;
954
955 fY[0] = 1.;
956 fY[1] = 0.;
957 fY[2] = 0.;
958 } else if (iOrder == 1 || ny == 2) {
959
960
961 int iGrid = 0;
962 for (int i = 1; i < ny; i++) {
963 if ((yAxis[i - 1] - y) * (y - yAxis[i]) >= 0.) {
964 iGrid = i;
965 }
966 }
967
968 if (yAxis[iGrid] == yAxis[iGrid - 1]) {
969 std::cerr << "Boxin3:\n";
970 std::cerr << " Incorrect grid; no interpolation.\n";
971 f = 0.;
972 return false;
973 }
974
975 const double yLocal =
976 (y - yAxis[iGrid - 1]) / (yAxis[iGrid] - yAxis[iGrid - 1]);
977
978 iY0 = iGrid - 1;
979 iY1 = iGrid;
980
981 fY[0] = 1. - yLocal;
982 fY[1] = yLocal;
983 fY[2] = 0.;
984 } else if (iOrder == 2) {
985
986
987 int iGrid = 0;
988 for (int i = 1; i < ny; i++) {
989 if ((yAxis[i - 1] - y) * (y - yAxis[i]) >= 0.) {
990 iGrid = i;
991 }
992 }
993
994 const double yLocal =
995 (y - yAxis[iGrid - 1]) / (yAxis[iGrid] - yAxis[iGrid - 1]);
996
997
998
999 fY[0] = (y - yAxis[iY0 + 1]) * (y - yAxis[iY0 + 2]) /
1000 ((yAxis[iY0] - yAxis[iY0 + 1]) * (yAxis[iY0] - yAxis[iY0 + 2]));
1001 fY[1] = (y - yAxis[iY0]) * (y - yAxis[iY0 + 2]) /
1002 ((yAxis[iY0 + 1] - yAxis[iY0]) * (yAxis[iY0 + 1] - yAxis[iY0 + 2]));
1003 fY[2] = (y - yAxis[iY0]) * (y - yAxis[iY0 + 1]) /
1004 ((yAxis[iY0 + 2] - yAxis[iY0]) * (yAxis[iY0 + 2] - yAxis[iY0 + 1]));
1005
1006 if (iGrid == 1) {
1007 iY0 = iGrid - 1;
1008 iY1 = iGrid + 1;
1009 if (yAxis[iY0] == yAxis[iY0 + 1] || yAxis[iY0] == yAxis[iY0 + 2] ||
1010 yAxis[iY0 + 1] == yAxis[iY0 + 2]) {
1011 std::cerr << "Boxin3:\n";
1012 std::cerr << " One or more grid points in y coincide.\n";
1013 std::cerr << " No interpolation.\n";
1014 f = 0.;
1015 return false;
1016 }
1017 fY[0] = (y - yAxis[iY0 + 1]) * (y - yAxis[iY0 + 2]) /
1018 ((yAxis[iY0] - yAxis[iY0 + 1]) * (yAxis[iY0] - yAxis[iY0 + 2]));
1019 fY[1] =
1020 (y - yAxis[iY0]) * (y - yAxis[iY0 + 2]) /
1021 ((yAxis[iY0 + 1] - yAxis[iY0]) * (yAxis[iY0 + 1] - yAxis[iY0 + 2]));
1022 fY[2] =
1023 (y - yAxis[iY0]) * (y - yAxis[iY0 + 1]) /
1024 ((yAxis[iY0 + 2] - yAxis[iY0]) * (yAxis[iY0 + 2] - yAxis[iY0 + 1]));
1025 } else if (iGrid == ny - 1) {
1026 iY0 = iGrid - 2;
1027 iY1 = iGrid;
1028 if (yAxis[iY0] == yAxis[iY0 + 1] || yAxis[iY0] == yAxis[iY0 + 2] ||
1029 yAxis[iY0 + 1] == yAxis[iY0 + 2]) {
1030 std::cerr << "Boxin3:\n";
1031 std::cerr << " One or more grid points in y coincide.\n";
1032 std::cerr << " No interpolation.\n";
1033 f = 0.;
1034 return false;
1035 }
1036 fY[0] = (y - yAxis[iY0 + 1]) * (y - yAxis[iY0 + 2]) /
1037 ((yAxis[iY0] - yAxis[iY0 + 1]) * (yAxis[iY0] - yAxis[iY0 + 2]));
1038 fY[1] =
1039 (y - yAxis[iY0]) * (y - yAxis[iY0 + 2]) /
1040 ((yAxis[iY0 + 1] - yAxis[iY0]) * (yAxis[iY0 + 1] - yAxis[iY0 + 2]));
1041 fY[2] =
1042 (y - yAxis[iY0]) * (y - yAxis[iY0 + 1]) /
1043 ((yAxis[iY0 + 2] - yAxis[iY0]) * (yAxis[iY0 + 2] - yAxis[iY0 + 1]));
1044 } else {
1045 iY0 = iGrid - 2;
1046 iY1 = iGrid + 1;
1047 if (yAxis[iY0] == yAxis[iY0 + 1] || yAxis[iY0] == yAxis[iY0 + 2] ||
1048 yAxis[iY0] == yAxis[iY0 + 3] || yAxis[iY0 + 1] == yAxis[iY0 + 2] ||
1049 yAxis[iY0 + 1] == yAxis[iY0 + 3] ||
1050 yAxis[iY0 + 2] == yAxis[iY0 + 3]) {
1051 std::cerr << "Boxin3:\n";
1052 std::cerr << " One or more grid points in y coincide.\n";
1053 std::cerr << " No interpolation.\n";
1054 f = 0.;
1055 return false;
1056 }
1057 fY[0] = (y - yAxis[iY0 + 1]) * (y - yAxis[iY0 + 2]) /
1058 ((yAxis[iY0] - yAxis[iY0 + 1]) * (yAxis[iY0] - yAxis[iY0 + 2]));
1059 fY[1] =
1060 (y - yAxis[iY0]) * (y - yAxis[iY0 + 2]) /
1061 ((yAxis[iY0 + 1] - yAxis[iY0]) * (yAxis[iY0 + 1] - yAxis[iY0 + 2]));
1062 fY[2] =
1063 (y - yAxis[iY0]) * (y - yAxis[iY0 + 1]) /
1064 ((yAxis[iY0 + 2] - yAxis[iY0]) * (yAxis[iY0 + 2] - yAxis[iY0 + 1]));
1065
1066 fY[0] *= (1. - yLocal);
1067 fY[1] = fY[1] * (1. - yLocal) + yLocal * (y - yAxis[iY0 + 2]) *
1068 (y - yAxis[iY0 + 3]) /
1069 ((yAxis[iY0 + 1] - yAxis[iY0 + 2]) *
1070 (yAxis[iY0 + 1] - yAxis[iY0 + 3]));
1071 fY[2] = fY[2] * (1. - yLocal) + yLocal * (y - yAxis[iY0 + 1]) *
1072 (y - yAxis[iY0 + 3]) /
1073 ((yAxis[iY0 + 2] - yAxis[iY0 + 1]) *
1074 (yAxis[iY0 + 2] - yAxis[iY0 + 3]));
1075 fY[3] = yLocal * (y - yAxis[iY0 + 1]) * (y - yAxis[iY0 + 2]) /
1076 ((yAxis[iY0 + 3] - yAxis[iY0 + 1]) *
1077 (yAxis[iY0 + 3] - yAxis[iY0 + 2]));
1078 }
1079 }
1080
1081 if (iOrder == 0 || nz == 1) {
1082
1083
1084 double dist =
fabs(z - zAxis[0]);
1085 int iNode = 0;
1086 for (int i = 1; i < nz; i++) {
1087 if (
fabs(z - zAxis[i]) < dist) {
1088 dist =
fabs(z - zAxis[i]);
1089 iNode = i;
1090 }
1091 }
1092
1093 iZ0 = iNode;
1094 iZ1 = iNode;
1095
1096 fZ[0] = 1.;
1097 fZ[1] = 0.;
1098 fZ[2] = 0.;
1099 } else if (iOrder == 1 || nz == 2) {
1100
1101
1102 int iGrid = 0;
1103 for (int i = 1; i < nz; i++) {
1104 if ((zAxis[i - 1] - z) * (z - zAxis[i]) >= 0.) {
1105 iGrid = i;
1106 }
1107 }
1108
1109 if (zAxis[iGrid] == zAxis[iGrid - 1]) {
1110 std::cerr << "Boxin3:\n";
1111 std::cerr << " Incorrect grid; no interpolation.\n";
1112 f = 0.;
1113 return false;
1114 }
1115
1116 const double zLocal =
1117 (z - zAxis[iGrid - 1]) / (zAxis[iGrid] - zAxis[iGrid - 1]);
1118
1119 iZ0 = iGrid - 1;
1120 iZ1 = iGrid;
1121
1122 fZ[0] = 1. - zLocal;
1123 fZ[1] = zLocal;
1124 fZ[2] = 0.;
1125 } else if (iOrder == 2) {
1126
1127
1128 int iGrid = 0;
1129 for (int i = 1; i < nz; i++) {
1130 if ((zAxis[i - 1] - z) * (z - zAxis[i]) >= 0.) {
1131 iGrid = i;
1132 }
1133 }
1134
1135 const double zLocal =
1136 (z - zAxis[iGrid - 1]) / (zAxis[iGrid] - zAxis[iGrid - 1]);
1137
1138
1139
1140 fZ[0] = (z - zAxis[iZ0 + 1]) * (z - zAxis[iZ0 + 2]) /
1141 ((zAxis[iZ0] - zAxis[iZ0 + 1]) * (zAxis[iZ0] - zAxis[iZ0 + 2]));
1142 fZ[1] = (z - zAxis[iZ0]) * (z - zAxis[iZ0 + 2]) /
1143 ((zAxis[iZ0 + 1] - zAxis[iZ0]) * (zAxis[iZ0 + 1] - zAxis[iZ0 + 2]));
1144 fZ[2] = (z - zAxis[iZ0]) * (z - zAxis[iZ0 + 1]) /
1145 ((zAxis[iZ0 + 2] - zAxis[iZ0]) * (zAxis[iZ0 + 2] - zAxis[iZ0 + 1]));
1146
1147 if (iGrid == 1) {
1148 iZ0 = iGrid - 1;
1149 iZ1 = iGrid + 1;
1150 if (zAxis[iZ0] == zAxis[iZ0 + 1] || zAxis[iZ0] == zAxis[iZ0 + 2] ||
1151 zAxis[iZ0 + 1] == zAxis[iZ0 + 2]) {
1152 std::cerr << "Boxin3:\n";
1153 std::cerr << " One or more grid points in z coincide.\n";
1154 std::cerr << " No interpolation.\n";
1155 f = 0.;
1156 return false;
1157 }
1158 fZ[0] = (z - zAxis[iZ0 + 1]) * (z - zAxis[iZ0 + 2]) /
1159 ((zAxis[iZ0] - zAxis[iZ0 + 1]) * (zAxis[iZ0] - zAxis[iZ0 + 2]));
1160 fZ[1] =
1161 (z - zAxis[iZ0]) * (z - zAxis[iZ0 + 2]) /
1162 ((zAxis[iZ0 + 1] - zAxis[iZ0]) * (zAxis[iZ0 + 1] - zAxis[iZ0 + 2]));
1163 fZ[2] =
1164 (z - zAxis[iZ0]) * (z - zAxis[iZ0 + 1]) /
1165 ((zAxis[iZ0 + 2] - zAxis[iZ0]) * (zAxis[iZ0 + 2] - zAxis[iZ0 + 1]));
1166 } else if (iGrid == nz - 1) {
1167 iZ0 = iGrid - 2;
1168 iZ1 = iGrid;
1169 if (zAxis[iZ0] == zAxis[iZ0 + 1] || zAxis[iZ0] == zAxis[iZ0 + 2] ||
1170 zAxis[iZ0 + 1] == zAxis[iZ0 + 2]) {
1171 std::cerr << "Boxin3:\n";
1172 std::cerr << " One or more grid points in z coincide.\n";
1173 std::cerr << " No interpolation.\n";
1174 f = 0.;
1175 return false;
1176 }
1177 fZ[0] = (z - zAxis[iZ0 + 1]) * (z - zAxis[iZ0 + 2]) /
1178 ((zAxis[iZ0] - zAxis[iZ0 + 1]) * (zAxis[iZ0] - zAxis[iZ0 + 2]));
1179 fZ[1] =
1180 (z - zAxis[iZ0]) * (z - zAxis[iZ0 + 2]) /
1181 ((zAxis[iZ0 + 1] - zAxis[iZ0]) * (zAxis[iZ0 + 1] - zAxis[iZ0 + 2]));
1182 fZ[2] =
1183 (z - zAxis[iZ0]) * (z - zAxis[iZ0 + 1]) /
1184 ((zAxis[iZ0 + 2] - zAxis[iZ0]) * (zAxis[iZ0 + 2] - zAxis[iZ0 + 1]));
1185 } else {
1186 iZ0 = iGrid - 2;
1187 iZ1 = iGrid + 1;
1188
1189 if (zAxis[iZ0] == zAxis[iZ0 + 1] || zAxis[iZ0] == zAxis[iZ0 + 2] ||
1190 zAxis[iZ0] == zAxis[iZ0 + 3] || zAxis[iZ0 + 1] == zAxis[iZ0 + 2] ||
1191 zAxis[iZ0 + 1] == zAxis[iZ0 + 3] ||
1192 zAxis[iZ0 + 2] == zAxis[iZ0 + 3]) {
1193 std::cerr << "Boxin3:\n";
1194 std::cerr << " One or more grid points in z coincide.\n";
1195 std::cerr << " No interpolation.\n";
1196 f = 0.;
1197 return false;
1198 }
1199
1200 fZ[0] = (z - zAxis[iZ0 + 1]) * (z - zAxis[iZ0 + 2]) /
1201 ((zAxis[iZ0] - zAxis[iZ0 + 1]) * (zAxis[iZ0] - zAxis[iZ0 + 2]));
1202 fZ[1] =
1203 (z - zAxis[iZ0]) * (z - zAxis[iZ0 + 2]) /
1204 ((zAxis[iZ0 + 1] - zAxis[iZ0]) * (zAxis[iZ0 + 1] - zAxis[iZ0 + 2]));
1205 fZ[2] =
1206 (z - zAxis[iZ0]) * (z - zAxis[iZ0 + 1]) /
1207 ((zAxis[iZ0 + 2] - zAxis[iZ0]) * (zAxis[iZ0 + 2] - zAxis[iZ0 + 1]));
1208
1209 fZ[0] *= (1. - zLocal);
1210 fZ[1] = fZ[1] * (1. - zLocal) + zLocal * (z - zAxis[iZ0 + 2]) *
1211 (z - zAxis[iZ0 + 3]) /
1212 ((zAxis[iZ0 + 1] - zAxis[iZ0 + 2]) *
1213 (zAxis[iZ0 + 1] - zAxis[iZ0 + 3]));
1214 fZ[2] = fZ[2] * (1. - zLocal) + zLocal * (z - zAxis[iZ0 + 1]) *
1215 (z - zAxis[iZ0 + 3]) /
1216 ((zAxis[iZ0 + 2] - zAxis[iZ0 + 1]) *
1217 (zAxis[iZ0 + 2] - zAxis[iZ0 + 3]));
1218 fZ[3] = zLocal * (z - zAxis[iZ0 + 1]) * (z - zAxis[iZ0 + 2]) /
1219 ((zAxis[iZ0 + 3] - zAxis[iZ0 + 1]) *
1220 (zAxis[iZ0 + 3] - zAxis[iZ0 + 2]));
1221 }
1222 }
1223
1224 f = 0.;
1225 for (int i = iX0; i <= iX1; ++i) {
1226 for (int j = iY0; j <= iY1; ++j) {
1227 for (int k = iZ0; k <= iZ1; ++k) {
1228
1229
1230
1231
1232 f += value[i][j][k] * fX[i - iX0] * fY[j - iY0] * fZ[k - iZ0];
1233 }
1234 }
1235 }
1236
1237 return true;
1238}
DoubleAc fabs(const DoubleAc &f)