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